PackageManagerService.java revision 0cb43ef67b5d284f6c0afbca5a50e189355c0ab3
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.getFullCompilerFilter;
100import static com.android.server.pm.PackageManagerServiceCompilerMapping.getNonProfileGuidedCompilerFilter;
101import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_FAILURE;
102import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_SUCCESS;
103import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED;
104
105import android.Manifest;
106import android.annotation.NonNull;
107import android.annotation.Nullable;
108import android.app.ActivityManager;
109import android.app.AppOpsManager;
110import android.app.IActivityManager;
111import android.app.ResourcesManager;
112import android.app.admin.IDevicePolicyManager;
113import android.app.admin.SecurityLog;
114import android.app.backup.IBackupManager;
115import android.content.BroadcastReceiver;
116import android.content.ComponentName;
117import android.content.ContentResolver;
118import android.content.Context;
119import android.content.IIntentReceiver;
120import android.content.Intent;
121import android.content.IntentFilter;
122import android.content.IntentSender;
123import android.content.IntentSender.SendIntentException;
124import android.content.ServiceConnection;
125import android.content.pm.ActivityInfo;
126import android.content.pm.ApplicationInfo;
127import android.content.pm.AppsQueryHelper;
128import android.content.pm.ChangedPackages;
129import android.content.pm.ComponentInfo;
130import android.content.pm.InstantAppRequest;
131import android.content.pm.AuxiliaryResolveInfo;
132import android.content.pm.FallbackCategoryProvider;
133import android.content.pm.FeatureInfo;
134import android.content.pm.IOnPermissionsChangeListener;
135import android.content.pm.IPackageDataObserver;
136import android.content.pm.IPackageDeleteObserver;
137import android.content.pm.IPackageDeleteObserver2;
138import android.content.pm.IPackageInstallObserver2;
139import android.content.pm.IPackageInstaller;
140import android.content.pm.IPackageManager;
141import android.content.pm.IPackageMoveObserver;
142import android.content.pm.IPackageStatsObserver;
143import android.content.pm.InstantAppInfo;
144import android.content.pm.InstantAppResolveInfo;
145import android.content.pm.InstrumentationInfo;
146import android.content.pm.IntentFilterVerificationInfo;
147import android.content.pm.KeySet;
148import android.content.pm.PackageCleanItem;
149import android.content.pm.PackageInfo;
150import android.content.pm.PackageInfoLite;
151import android.content.pm.PackageInstaller;
152import android.content.pm.PackageManager;
153import android.content.pm.PackageManager.LegacyPackageDeleteObserver;
154import android.content.pm.PackageManagerInternal;
155import android.content.pm.PackageParser;
156import android.content.pm.PackageParser.ActivityIntentInfo;
157import android.content.pm.PackageParser.PackageLite;
158import android.content.pm.PackageParser.PackageParserException;
159import android.content.pm.PackageStats;
160import android.content.pm.PackageUserState;
161import android.content.pm.ParceledListSlice;
162import android.content.pm.PermissionGroupInfo;
163import android.content.pm.PermissionInfo;
164import android.content.pm.ProviderInfo;
165import android.content.pm.ResolveInfo;
166import android.content.pm.ServiceInfo;
167import android.content.pm.SharedLibraryInfo;
168import android.content.pm.Signature;
169import android.content.pm.UserInfo;
170import android.content.pm.VerifierDeviceIdentity;
171import android.content.pm.VerifierInfo;
172import android.content.pm.VersionedPackage;
173import android.content.res.Resources;
174import android.database.ContentObserver;
175import android.graphics.Bitmap;
176import android.hardware.display.DisplayManager;
177import android.net.Uri;
178import android.os.Binder;
179import android.os.Build;
180import android.os.Bundle;
181import android.os.Debug;
182import android.os.Environment;
183import android.os.Environment.UserEnvironment;
184import android.os.FileUtils;
185import android.os.Handler;
186import android.os.IBinder;
187import android.os.Looper;
188import android.os.Message;
189import android.os.Parcel;
190import android.os.ParcelFileDescriptor;
191import android.os.PatternMatcher;
192import android.os.Process;
193import android.os.RemoteCallbackList;
194import android.os.RemoteException;
195import android.os.ResultReceiver;
196import android.os.SELinux;
197import android.os.ServiceManager;
198import android.os.ShellCallback;
199import android.os.SystemClock;
200import android.os.SystemProperties;
201import android.os.Trace;
202import android.os.UserHandle;
203import android.os.UserManager;
204import android.os.UserManagerInternal;
205import android.os.storage.IStorageManager;
206import android.os.storage.StorageEventListener;
207import android.os.storage.StorageManager;
208import android.os.storage.StorageManagerInternal;
209import android.os.storage.VolumeInfo;
210import android.os.storage.VolumeRecord;
211import android.provider.Settings.Global;
212import android.provider.Settings.Secure;
213import android.security.KeyStore;
214import android.security.SystemKeyStore;
215import android.service.pm.PackageServiceDumpProto;
216import android.system.ErrnoException;
217import android.system.Os;
218import android.text.TextUtils;
219import android.text.format.DateUtils;
220import android.util.ArrayMap;
221import android.util.ArraySet;
222import android.util.Base64;
223import android.util.BootTimingsTraceLog;
224import android.util.DisplayMetrics;
225import android.util.EventLog;
226import android.util.ExceptionUtils;
227import android.util.Log;
228import android.util.LogPrinter;
229import android.util.MathUtils;
230import android.util.PackageUtils;
231import android.util.Pair;
232import android.util.PrintStreamPrinter;
233import android.util.Slog;
234import android.util.SparseArray;
235import android.util.SparseBooleanArray;
236import android.util.SparseIntArray;
237import android.util.Xml;
238import android.util.jar.StrictJarFile;
239import android.util.proto.ProtoOutputStream;
240import android.view.Display;
241
242import com.android.internal.R;
243import com.android.internal.annotations.GuardedBy;
244import com.android.internal.app.IMediaContainerService;
245import com.android.internal.app.ResolverActivity;
246import com.android.internal.content.NativeLibraryHelper;
247import com.android.internal.content.PackageHelper;
248import com.android.internal.logging.MetricsLogger;
249import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
250import com.android.internal.os.IParcelFileDescriptorFactory;
251import com.android.internal.os.RoSystemProperties;
252import com.android.internal.os.SomeArgs;
253import com.android.internal.os.Zygote;
254import com.android.internal.telephony.CarrierAppUtils;
255import com.android.internal.util.ArrayUtils;
256import com.android.internal.util.ConcurrentUtils;
257import com.android.internal.util.DumpUtils;
258import com.android.internal.util.FastPrintWriter;
259import com.android.internal.util.FastXmlSerializer;
260import com.android.internal.util.IndentingPrintWriter;
261import com.android.internal.util.Preconditions;
262import com.android.internal.util.XmlUtils;
263import com.android.server.AttributeCache;
264import com.android.server.DeviceIdleController;
265import com.android.server.EventLogTags;
266import com.android.server.FgThread;
267import com.android.server.IntentResolver;
268import com.android.server.LocalServices;
269import com.android.server.LockGuard;
270import com.android.server.ServiceThread;
271import com.android.server.SystemConfig;
272import com.android.server.SystemServerInitThreadPool;
273import com.android.server.Watchdog;
274import com.android.server.net.NetworkPolicyManagerInternal;
275import com.android.server.pm.Installer.InstallerException;
276import com.android.server.pm.PermissionsState.PermissionState;
277import com.android.server.pm.Settings.DatabaseVersion;
278import com.android.server.pm.Settings.VersionInfo;
279import com.android.server.pm.dex.DexManager;
280import com.android.server.storage.DeviceStorageMonitorInternal;
281
282import dalvik.system.CloseGuard;
283import dalvik.system.DexFile;
284import dalvik.system.VMRuntime;
285
286import libcore.io.IoUtils;
287import libcore.util.EmptyArray;
288
289import org.xmlpull.v1.XmlPullParser;
290import org.xmlpull.v1.XmlPullParserException;
291import org.xmlpull.v1.XmlSerializer;
292
293import java.io.BufferedOutputStream;
294import java.io.BufferedReader;
295import java.io.ByteArrayInputStream;
296import java.io.ByteArrayOutputStream;
297import java.io.File;
298import java.io.FileDescriptor;
299import java.io.FileInputStream;
300import java.io.FileOutputStream;
301import java.io.FileReader;
302import java.io.FilenameFilter;
303import java.io.IOException;
304import java.io.PrintWriter;
305import java.nio.charset.StandardCharsets;
306import java.security.DigestInputStream;
307import java.security.MessageDigest;
308import java.security.NoSuchAlgorithmException;
309import java.security.PublicKey;
310import java.security.SecureRandom;
311import java.security.cert.Certificate;
312import java.security.cert.CertificateEncodingException;
313import java.security.cert.CertificateException;
314import java.text.SimpleDateFormat;
315import java.util.ArrayList;
316import java.util.Arrays;
317import java.util.Collection;
318import java.util.Collections;
319import java.util.Comparator;
320import java.util.Date;
321import java.util.HashMap;
322import java.util.HashSet;
323import java.util.Iterator;
324import java.util.List;
325import java.util.Map;
326import java.util.Objects;
327import java.util.Set;
328import java.util.concurrent.CountDownLatch;
329import java.util.concurrent.Future;
330import java.util.concurrent.TimeUnit;
331import java.util.concurrent.atomic.AtomicBoolean;
332import java.util.concurrent.atomic.AtomicInteger;
333
334/**
335 * Keep track of all those APKs everywhere.
336 * <p>
337 * Internally there are two important locks:
338 * <ul>
339 * <li>{@link #mPackages} is used to guard all in-memory parsed package details
340 * and other related state. It is a fine-grained lock that should only be held
341 * momentarily, as it's one of the most contended locks in the system.
342 * <li>{@link #mInstallLock} is used to guard all {@code installd} access, whose
343 * operations typically involve heavy lifting of application data on disk. Since
344 * {@code installd} is single-threaded, and it's operations can often be slow,
345 * this lock should never be acquired while already holding {@link #mPackages}.
346 * Conversely, it's safe to acquire {@link #mPackages} momentarily while already
347 * holding {@link #mInstallLock}.
348 * </ul>
349 * Many internal methods rely on the caller to hold the appropriate locks, and
350 * this contract is expressed through method name suffixes:
351 * <ul>
352 * <li>fooLI(): the caller must hold {@link #mInstallLock}
353 * <li>fooLIF(): the caller must hold {@link #mInstallLock} and the package
354 * being modified must be frozen
355 * <li>fooLPr(): the caller must hold {@link #mPackages} for reading
356 * <li>fooLPw(): the caller must hold {@link #mPackages} for writing
357 * </ul>
358 * <p>
359 * Because this class is very central to the platform's security; please run all
360 * CTS and unit tests whenever making modifications:
361 *
362 * <pre>
363 * $ runtest -c android.content.pm.PackageManagerTests frameworks-core
364 * $ cts-tradefed run commandAndExit cts -m CtsAppSecurityHostTestCases
365 * </pre>
366 */
367public class PackageManagerService extends IPackageManager.Stub {
368    static final String TAG = "PackageManager";
369    static final boolean DEBUG_SETTINGS = false;
370    static final boolean DEBUG_PREFERRED = false;
371    static final boolean DEBUG_UPGRADE = false;
372    static final boolean DEBUG_DOMAIN_VERIFICATION = false;
373    private static final boolean DEBUG_BACKUP = false;
374    private static final boolean DEBUG_INSTALL = false;
375    private static final boolean DEBUG_REMOVE = false;
376    private static final boolean DEBUG_BROADCASTS = false;
377    private static final boolean DEBUG_SHOW_INFO = false;
378    private static final boolean DEBUG_PACKAGE_INFO = false;
379    private static final boolean DEBUG_INTENT_MATCHING = false;
380    private static final boolean DEBUG_PACKAGE_SCANNING = false;
381    private static final boolean DEBUG_VERIFY = false;
382    private static final boolean DEBUG_FILTERS = false;
383
384    // Debug output for dexopting. This is shared between PackageManagerService, OtaDexoptService
385    // and PackageDexOptimizer. All these classes have their own flag to allow switching a single
386    // user, but by default initialize to this.
387    public static final boolean DEBUG_DEXOPT = false;
388
389    private static final boolean DEBUG_ABI_SELECTION = false;
390    private static final boolean DEBUG_EPHEMERAL = Build.IS_DEBUGGABLE;
391    private static final boolean DEBUG_TRIAGED_MISSING = false;
392    private static final boolean DEBUG_APP_DATA = false;
393
394    /** REMOVE. According to Svet, this was only used to reset permissions during development. */
395    static final boolean CLEAR_RUNTIME_PERMISSIONS_ON_UPGRADE = false;
396
397    private static final boolean HIDE_EPHEMERAL_APIS = false;
398
399    private static final boolean ENABLE_FREE_CACHE_V2 =
400            SystemProperties.getBoolean("fw.free_cache_v2", true);
401
402    private static final int RADIO_UID = Process.PHONE_UID;
403    private static final int LOG_UID = Process.LOG_UID;
404    private static final int NFC_UID = Process.NFC_UID;
405    private static final int BLUETOOTH_UID = Process.BLUETOOTH_UID;
406    private static final int SHELL_UID = Process.SHELL_UID;
407
408    // Cap the size of permission trees that 3rd party apps can define
409    private static final int MAX_PERMISSION_TREE_FOOTPRINT = 32768;     // characters of text
410
411    // Suffix used during package installation when copying/moving
412    // package apks to install directory.
413    private static final String INSTALL_PACKAGE_SUFFIX = "-";
414
415    static final int SCAN_NO_DEX = 1<<1;
416    static final int SCAN_FORCE_DEX = 1<<2;
417    static final int SCAN_UPDATE_SIGNATURE = 1<<3;
418    static final int SCAN_NEW_INSTALL = 1<<4;
419    static final int SCAN_UPDATE_TIME = 1<<5;
420    static final int SCAN_BOOTING = 1<<6;
421    static final int SCAN_TRUSTED_OVERLAY = 1<<7;
422    static final int SCAN_DELETE_DATA_ON_FAILURES = 1<<8;
423    static final int SCAN_REPLACING = 1<<9;
424    static final int SCAN_REQUIRE_KNOWN = 1<<10;
425    static final int SCAN_MOVE = 1<<11;
426    static final int SCAN_INITIAL = 1<<12;
427    static final int SCAN_CHECK_ONLY = 1<<13;
428    static final int SCAN_DONT_KILL_APP = 1<<14;
429    static final int SCAN_IGNORE_FROZEN = 1<<15;
430    static final int SCAN_FIRST_BOOT_OR_UPGRADE = 1<<16;
431    static final int SCAN_AS_INSTANT_APP = 1<<17;
432    static final int SCAN_AS_FULL_APP = 1<<18;
433    /** Should not be with the scan flags */
434    static final int FLAGS_REMOVE_CHATTY = 1<<31;
435
436    private static final String STATIC_SHARED_LIB_DELIMITER = "_";
437
438    private static final int[] EMPTY_INT_ARRAY = new int[0];
439
440    /**
441     * Timeout (in milliseconds) after which the watchdog should declare that
442     * our handler thread is wedged.  The usual default for such things is one
443     * minute but we sometimes do very lengthy I/O operations on this thread,
444     * such as installing multi-gigabyte applications, so ours needs to be longer.
445     */
446    private static final long WATCHDOG_TIMEOUT = 1000*60*10;     // ten minutes
447
448    /**
449     * Wall-clock timeout (in milliseconds) after which we *require* that an fstrim
450     * be run on this device.  We use the value in the Settings.Global.MANDATORY_FSTRIM_INTERVAL
451     * settings entry if available, otherwise we use the hardcoded default.  If it's been
452     * more than this long since the last fstrim, we force one during the boot sequence.
453     *
454     * This backstops other fstrim scheduling:  if the device is alive at midnight+idle,
455     * one gets run at the next available charging+idle time.  This final mandatory
456     * no-fstrim check kicks in only of the other scheduling criteria is never met.
457     */
458    private static final long DEFAULT_MANDATORY_FSTRIM_INTERVAL = 3 * DateUtils.DAY_IN_MILLIS;
459
460    /**
461     * Whether verification is enabled by default.
462     */
463    private static final boolean DEFAULT_VERIFY_ENABLE = true;
464
465    /**
466     * The default maximum time to wait for the verification agent to return in
467     * milliseconds.
468     */
469    private static final long DEFAULT_VERIFICATION_TIMEOUT = 10 * 1000;
470
471    /**
472     * The default response for package verification timeout.
473     *
474     * This can be either PackageManager.VERIFICATION_ALLOW or
475     * PackageManager.VERIFICATION_REJECT.
476     */
477    private static final int DEFAULT_VERIFICATION_RESPONSE = PackageManager.VERIFICATION_ALLOW;
478
479    static final String PLATFORM_PACKAGE_NAME = "android";
480
481    static final String DEFAULT_CONTAINER_PACKAGE = "com.android.defcontainer";
482
483    static final ComponentName DEFAULT_CONTAINER_COMPONENT = new ComponentName(
484            DEFAULT_CONTAINER_PACKAGE,
485            "com.android.defcontainer.DefaultContainerService");
486
487    private static final String KILL_APP_REASON_GIDS_CHANGED =
488            "permission grant or revoke changed gids";
489
490    private static final String KILL_APP_REASON_PERMISSIONS_REVOKED =
491            "permissions revoked";
492
493    private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive";
494
495    private static final String PACKAGE_SCHEME = "package";
496
497    private static final String VENDOR_OVERLAY_DIR = "/vendor/overlay";
498
499    /** Permission grant: not grant the permission. */
500    private static final int GRANT_DENIED = 1;
501
502    /** Permission grant: grant the permission as an install permission. */
503    private static final int GRANT_INSTALL = 2;
504
505    /** Permission grant: grant the permission as a runtime one. */
506    private static final int GRANT_RUNTIME = 3;
507
508    /** Permission grant: grant as runtime a permission that was granted as an install time one. */
509    private static final int GRANT_UPGRADE = 4;
510
511    /** Canonical intent used to identify what counts as a "web browser" app */
512    private static final Intent sBrowserIntent;
513    static {
514        sBrowserIntent = new Intent();
515        sBrowserIntent.setAction(Intent.ACTION_VIEW);
516        sBrowserIntent.addCategory(Intent.CATEGORY_BROWSABLE);
517        sBrowserIntent.setData(Uri.parse("http:"));
518    }
519
520    /**
521     * The set of all protected actions [i.e. those actions for which a high priority
522     * intent filter is disallowed].
523     */
524    private static final Set<String> PROTECTED_ACTIONS = new ArraySet<>();
525    static {
526        PROTECTED_ACTIONS.add(Intent.ACTION_SEND);
527        PROTECTED_ACTIONS.add(Intent.ACTION_SENDTO);
528        PROTECTED_ACTIONS.add(Intent.ACTION_SEND_MULTIPLE);
529        PROTECTED_ACTIONS.add(Intent.ACTION_VIEW);
530    }
531
532    // Compilation reasons.
533    public static final int REASON_FIRST_BOOT = 0;
534    public static final int REASON_BOOT = 1;
535    public static final int REASON_INSTALL = 2;
536    public static final int REASON_BACKGROUND_DEXOPT = 3;
537    public static final int REASON_AB_OTA = 4;
538    public static final int REASON_FORCED_DEXOPT = 5;
539
540    public static final int REASON_LAST = REASON_FORCED_DEXOPT;
541
542    /** All dangerous permission names in the same order as the events in MetricsEvent */
543    private static final List<String> ALL_DANGEROUS_PERMISSIONS = Arrays.asList(
544            Manifest.permission.READ_CALENDAR,
545            Manifest.permission.WRITE_CALENDAR,
546            Manifest.permission.CAMERA,
547            Manifest.permission.READ_CONTACTS,
548            Manifest.permission.WRITE_CONTACTS,
549            Manifest.permission.GET_ACCOUNTS,
550            Manifest.permission.ACCESS_FINE_LOCATION,
551            Manifest.permission.ACCESS_COARSE_LOCATION,
552            Manifest.permission.RECORD_AUDIO,
553            Manifest.permission.READ_PHONE_STATE,
554            Manifest.permission.CALL_PHONE,
555            Manifest.permission.READ_CALL_LOG,
556            Manifest.permission.WRITE_CALL_LOG,
557            Manifest.permission.ADD_VOICEMAIL,
558            Manifest.permission.USE_SIP,
559            Manifest.permission.PROCESS_OUTGOING_CALLS,
560            Manifest.permission.READ_CELL_BROADCASTS,
561            Manifest.permission.BODY_SENSORS,
562            Manifest.permission.SEND_SMS,
563            Manifest.permission.RECEIVE_SMS,
564            Manifest.permission.READ_SMS,
565            Manifest.permission.RECEIVE_WAP_PUSH,
566            Manifest.permission.RECEIVE_MMS,
567            Manifest.permission.READ_EXTERNAL_STORAGE,
568            Manifest.permission.WRITE_EXTERNAL_STORAGE,
569            Manifest.permission.READ_PHONE_NUMBERS,
570            Manifest.permission.ANSWER_PHONE_CALLS);
571
572
573    /**
574     * Version number for the package parser cache. Increment this whenever the format or
575     * extent of cached data changes. See {@code PackageParser#setCacheDir}.
576     */
577    private static final String PACKAGE_PARSER_CACHE_VERSION = "1";
578
579    /**
580     * Whether the package parser cache is enabled.
581     */
582    private static final boolean DEFAULT_PACKAGE_PARSER_CACHE_ENABLED = true;
583
584    final ServiceThread mHandlerThread;
585
586    final PackageHandler mHandler;
587
588    private final ProcessLoggingHandler mProcessLoggingHandler;
589
590    /**
591     * Messages for {@link #mHandler} that need to wait for system ready before
592     * being dispatched.
593     */
594    private ArrayList<Message> mPostSystemReadyMessages;
595
596    final int mSdkVersion = Build.VERSION.SDK_INT;
597
598    final Context mContext;
599    final boolean mFactoryTest;
600    final boolean mOnlyCore;
601    final DisplayMetrics mMetrics;
602    final int mDefParseFlags;
603    final String[] mSeparateProcesses;
604    final boolean mIsUpgrade;
605    final boolean mIsPreNUpgrade;
606    final boolean mIsPreNMR1Upgrade;
607
608    // Have we told the Activity Manager to whitelist the default container service by uid yet?
609    @GuardedBy("mPackages")
610    boolean mDefaultContainerWhitelisted = false;
611
612    @GuardedBy("mPackages")
613    private boolean mDexOptDialogShown;
614
615    /** The location for ASEC container files on internal storage. */
616    final String mAsecInternalPath;
617
618    // Used for privilege escalation. MUST NOT BE CALLED WITH mPackages
619    // LOCK HELD.  Can be called with mInstallLock held.
620    @GuardedBy("mInstallLock")
621    final Installer mInstaller;
622
623    /** Directory where installed third-party apps stored */
624    final File mAppInstallDir;
625
626    /**
627     * Directory to which applications installed internally have their
628     * 32 bit native libraries copied.
629     */
630    private File mAppLib32InstallDir;
631
632    // Directory containing the private parts (e.g. code and non-resource assets) of forward-locked
633    // apps.
634    final File mDrmAppPrivateInstallDir;
635
636    // ----------------------------------------------------------------
637
638    // Lock for state used when installing and doing other long running
639    // operations.  Methods that must be called with this lock held have
640    // the suffix "LI".
641    final Object mInstallLock = new Object();
642
643    // ----------------------------------------------------------------
644
645    // Keys are String (package name), values are Package.  This also serves
646    // as the lock for the global state.  Methods that must be called with
647    // this lock held have the prefix "LP".
648    @GuardedBy("mPackages")
649    final ArrayMap<String, PackageParser.Package> mPackages =
650            new ArrayMap<String, PackageParser.Package>();
651
652    final ArrayMap<String, Set<String>> mKnownCodebase =
653            new ArrayMap<String, Set<String>>();
654
655    // Keys are isolated uids and values are the uid of the application
656    // that created the isolated proccess.
657    @GuardedBy("mPackages")
658    final SparseIntArray mIsolatedOwners = new SparseIntArray();
659
660    // List of APK paths to load for each user and package. This data is never
661    // persisted by the package manager. Instead, the overlay manager will
662    // ensure the data is up-to-date in runtime.
663    @GuardedBy("mPackages")
664    final SparseArray<ArrayMap<String, ArrayList<String>>> mEnabledOverlayPaths =
665        new SparseArray<ArrayMap<String, ArrayList<String>>>();
666
667    /**
668     * Tracks new system packages [received in an OTA] that we expect to
669     * find updated user-installed versions. Keys are package name, values
670     * are package location.
671     */
672    final private ArrayMap<String, File> mExpectingBetter = new ArrayMap<>();
673    /**
674     * Tracks high priority intent filters for protected actions. During boot, certain
675     * filter actions are protected and should never be allowed to have a high priority
676     * intent filter for them. However, there is one, and only one exception -- the
677     * setup wizard. It must be able to define a high priority intent filter for these
678     * actions to ensure there are no escapes from the wizard. We need to delay processing
679     * of these during boot as we need to look at all of the system packages in order
680     * to know which component is the setup wizard.
681     */
682    private final List<PackageParser.ActivityIntentInfo> mProtectedFilters = new ArrayList<>();
683    /**
684     * Whether or not processing protected filters should be deferred.
685     */
686    private boolean mDeferProtectedFilters = true;
687
688    /**
689     * Tracks existing system packages prior to receiving an OTA. Keys are package name.
690     */
691    final private ArraySet<String> mExistingSystemPackages = new ArraySet<>();
692    /**
693     * Whether or not system app permissions should be promoted from install to runtime.
694     */
695    boolean mPromoteSystemApps;
696
697    @GuardedBy("mPackages")
698    final Settings mSettings;
699
700    /**
701     * Set of package names that are currently "frozen", which means active
702     * surgery is being done on the code/data for that package. The platform
703     * will refuse to launch frozen packages to avoid race conditions.
704     *
705     * @see PackageFreezer
706     */
707    @GuardedBy("mPackages")
708    final ArraySet<String> mFrozenPackages = new ArraySet<>();
709
710    final ProtectedPackages mProtectedPackages;
711
712    boolean mFirstBoot;
713
714    PackageManagerInternal.ExternalSourcesPolicy mExternalSourcesPolicy;
715
716    // System configuration read by SystemConfig.
717    final int[] mGlobalGids;
718    final SparseArray<ArraySet<String>> mSystemPermissions;
719    @GuardedBy("mAvailableFeatures")
720    final ArrayMap<String, FeatureInfo> mAvailableFeatures;
721
722    // If mac_permissions.xml was found for seinfo labeling.
723    boolean mFoundPolicyFile;
724
725    private final InstantAppRegistry mInstantAppRegistry;
726
727    @GuardedBy("mPackages")
728    int mChangedPackagesSequenceNumber;
729    /**
730     * List of changed [installed, removed or updated] packages.
731     * mapping from user id -> sequence number -> package name
732     */
733    @GuardedBy("mPackages")
734    final SparseArray<SparseArray<String>> mChangedPackages = new SparseArray<>();
735    /**
736     * The sequence number of the last change to a package.
737     * mapping from user id -> package name -> sequence number
738     */
739    @GuardedBy("mPackages")
740    final SparseArray<Map<String, Integer>> mChangedPackagesSequenceNumbers = new SparseArray<>();
741
742    final PackageParser.Callback mPackageParserCallback = new PackageParser.Callback() {
743        @Override public boolean hasFeature(String feature) {
744            return PackageManagerService.this.hasSystemFeature(feature, 0);
745        }
746    };
747
748    public static final class SharedLibraryEntry {
749        public final String path;
750        public final String apk;
751        public final SharedLibraryInfo info;
752
753        SharedLibraryEntry(String _path, String _apk, String name, int version, int type,
754                String declaringPackageName, int declaringPackageVersionCode) {
755            path = _path;
756            apk = _apk;
757            info = new SharedLibraryInfo(name, version, type, new VersionedPackage(
758                    declaringPackageName, declaringPackageVersionCode), null);
759        }
760    }
761
762    // Currently known shared libraries.
763    final ArrayMap<String, SparseArray<SharedLibraryEntry>> mSharedLibraries = new ArrayMap<>();
764    final ArrayMap<String, SparseArray<SharedLibraryEntry>> mStaticLibsByDeclaringPackage =
765            new ArrayMap<>();
766
767    // All available activities, for your resolving pleasure.
768    final ActivityIntentResolver mActivities =
769            new ActivityIntentResolver();
770
771    // All available receivers, for your resolving pleasure.
772    final ActivityIntentResolver mReceivers =
773            new ActivityIntentResolver();
774
775    // All available services, for your resolving pleasure.
776    final ServiceIntentResolver mServices = new ServiceIntentResolver();
777
778    // All available providers, for your resolving pleasure.
779    final ProviderIntentResolver mProviders = new ProviderIntentResolver();
780
781    // Mapping from provider base names (first directory in content URI codePath)
782    // to the provider information.
783    final ArrayMap<String, PackageParser.Provider> mProvidersByAuthority =
784            new ArrayMap<String, PackageParser.Provider>();
785
786    // Mapping from instrumentation class names to info about them.
787    final ArrayMap<ComponentName, PackageParser.Instrumentation> mInstrumentation =
788            new ArrayMap<ComponentName, PackageParser.Instrumentation>();
789
790    // Mapping from permission names to info about them.
791    final ArrayMap<String, PackageParser.PermissionGroup> mPermissionGroups =
792            new ArrayMap<String, PackageParser.PermissionGroup>();
793
794    // Packages whose data we have transfered into another package, thus
795    // should no longer exist.
796    final ArraySet<String> mTransferedPackages = new ArraySet<String>();
797
798    // Broadcast actions that are only available to the system.
799    final ArraySet<String> mProtectedBroadcasts = new ArraySet<String>();
800
801    /** List of packages waiting for verification. */
802    final SparseArray<PackageVerificationState> mPendingVerification
803            = new SparseArray<PackageVerificationState>();
804
805    /** Set of packages associated with each app op permission. */
806    final ArrayMap<String, ArraySet<String>> mAppOpPermissionPackages = new ArrayMap<>();
807
808    final PackageInstallerService mInstallerService;
809
810    private final PackageDexOptimizer mPackageDexOptimizer;
811    // DexManager handles the usage of dex files (e.g. secondary files, whether or not a package
812    // is used by other apps).
813    private final DexManager mDexManager;
814
815    private AtomicInteger mNextMoveId = new AtomicInteger();
816    private final MoveCallbacks mMoveCallbacks;
817
818    private final OnPermissionChangeListeners mOnPermissionChangeListeners;
819
820    // Cache of users who need badging.
821    SparseBooleanArray mUserNeedsBadging = new SparseBooleanArray();
822
823    /** Token for keys in mPendingVerification. */
824    private int mPendingVerificationToken = 0;
825
826    volatile boolean mSystemReady;
827    volatile boolean mSafeMode;
828    volatile boolean mHasSystemUidErrors;
829    private volatile boolean mEphemeralAppsDisabled;
830
831    ApplicationInfo mAndroidApplication;
832    final ActivityInfo mResolveActivity = new ActivityInfo();
833    final ResolveInfo mResolveInfo = new ResolveInfo();
834    ComponentName mResolveComponentName;
835    PackageParser.Package mPlatformPackage;
836    ComponentName mCustomResolverComponentName;
837
838    boolean mResolverReplaced = false;
839
840    private final @Nullable ComponentName mIntentFilterVerifierComponent;
841    private final @Nullable IntentFilterVerifier<ActivityIntentInfo> mIntentFilterVerifier;
842
843    private int mIntentFilterVerificationToken = 0;
844
845    /** The service connection to the ephemeral resolver */
846    final EphemeralResolverConnection mInstantAppResolverConnection;
847    /** Component used to show resolver settings for Instant Apps */
848    final ComponentName mInstantAppResolverSettingsComponent;
849
850    /** Activity used to install instant applications */
851    ActivityInfo mInstantAppInstallerActivity;
852    final ResolveInfo mInstantAppInstallerInfo = new ResolveInfo();
853
854    final SparseArray<IntentFilterVerificationState> mIntentFilterVerificationStates
855            = new SparseArray<IntentFilterVerificationState>();
856
857    final DefaultPermissionGrantPolicy mDefaultPermissionPolicy;
858
859    // List of packages names to keep cached, even if they are uninstalled for all users
860    private List<String> mKeepUninstalledPackages;
861
862    private UserManagerInternal mUserManagerInternal;
863
864    private DeviceIdleController.LocalService mDeviceIdleController;
865
866    private File mCacheDir;
867
868    private ArraySet<String> mPrivappPermissionsViolations;
869
870    private Future<?> mPrepareAppDataFuture;
871
872    private static class IFVerificationParams {
873        PackageParser.Package pkg;
874        boolean replacing;
875        int userId;
876        int verifierUid;
877
878        public IFVerificationParams(PackageParser.Package _pkg, boolean _replacing,
879                int _userId, int _verifierUid) {
880            pkg = _pkg;
881            replacing = _replacing;
882            userId = _userId;
883            replacing = _replacing;
884            verifierUid = _verifierUid;
885        }
886    }
887
888    private interface IntentFilterVerifier<T extends IntentFilter> {
889        boolean addOneIntentFilterVerification(int verifierId, int userId, int verificationId,
890                                               T filter, String packageName);
891        void startVerifications(int userId);
892        void receiveVerificationResponse(int verificationId);
893    }
894
895    private class IntentVerifierProxy implements IntentFilterVerifier<ActivityIntentInfo> {
896        private Context mContext;
897        private ComponentName mIntentFilterVerifierComponent;
898        private ArrayList<Integer> mCurrentIntentFilterVerifications = new ArrayList<Integer>();
899
900        public IntentVerifierProxy(Context context, ComponentName verifierComponent) {
901            mContext = context;
902            mIntentFilterVerifierComponent = verifierComponent;
903        }
904
905        private String getDefaultScheme() {
906            return IntentFilter.SCHEME_HTTPS;
907        }
908
909        @Override
910        public void startVerifications(int userId) {
911            // Launch verifications requests
912            int count = mCurrentIntentFilterVerifications.size();
913            for (int n=0; n<count; n++) {
914                int verificationId = mCurrentIntentFilterVerifications.get(n);
915                final IntentFilterVerificationState ivs =
916                        mIntentFilterVerificationStates.get(verificationId);
917
918                String packageName = ivs.getPackageName();
919
920                ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters();
921                final int filterCount = filters.size();
922                ArraySet<String> domainsSet = new ArraySet<>();
923                for (int m=0; m<filterCount; m++) {
924                    PackageParser.ActivityIntentInfo filter = filters.get(m);
925                    domainsSet.addAll(filter.getHostsList());
926                }
927                synchronized (mPackages) {
928                    if (mSettings.createIntentFilterVerificationIfNeededLPw(
929                            packageName, domainsSet) != null) {
930                        scheduleWriteSettingsLocked();
931                    }
932                }
933                sendVerificationRequest(userId, verificationId, ivs);
934            }
935            mCurrentIntentFilterVerifications.clear();
936        }
937
938        private void sendVerificationRequest(int userId, int verificationId,
939                IntentFilterVerificationState ivs) {
940
941            Intent verificationIntent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION);
942            verificationIntent.putExtra(
943                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_ID,
944                    verificationId);
945            verificationIntent.putExtra(
946                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_URI_SCHEME,
947                    getDefaultScheme());
948            verificationIntent.putExtra(
949                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_HOSTS,
950                    ivs.getHostsString());
951            verificationIntent.putExtra(
952                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_PACKAGE_NAME,
953                    ivs.getPackageName());
954            verificationIntent.setComponent(mIntentFilterVerifierComponent);
955            verificationIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
956
957            UserHandle user = new UserHandle(userId);
958            mContext.sendBroadcastAsUser(verificationIntent, user);
959            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
960                    "Sending IntentFilter verification broadcast");
961        }
962
963        public void receiveVerificationResponse(int verificationId) {
964            IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId);
965
966            final boolean verified = ivs.isVerified();
967
968            ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters();
969            final int count = filters.size();
970            if (DEBUG_DOMAIN_VERIFICATION) {
971                Slog.i(TAG, "Received verification response " + verificationId
972                        + " for " + count + " filters, verified=" + verified);
973            }
974            for (int n=0; n<count; n++) {
975                PackageParser.ActivityIntentInfo filter = filters.get(n);
976                filter.setVerified(verified);
977
978                if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "IntentFilter " + filter.toString()
979                        + " verified with result:" + verified + " and hosts:"
980                        + ivs.getHostsString());
981            }
982
983            mIntentFilterVerificationStates.remove(verificationId);
984
985            final String packageName = ivs.getPackageName();
986            IntentFilterVerificationInfo ivi = null;
987
988            synchronized (mPackages) {
989                ivi = mSettings.getIntentFilterVerificationLPr(packageName);
990            }
991            if (ivi == null) {
992                Slog.w(TAG, "IntentFilterVerificationInfo not found for verificationId:"
993                        + verificationId + " packageName:" + packageName);
994                return;
995            }
996            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
997                    "Updating IntentFilterVerificationInfo for package " + packageName
998                            +" verificationId:" + verificationId);
999
1000            synchronized (mPackages) {
1001                if (verified) {
1002                    ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS);
1003                } else {
1004                    ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK);
1005                }
1006                scheduleWriteSettingsLocked();
1007
1008                final int userId = ivs.getUserId();
1009                if (userId != UserHandle.USER_ALL) {
1010                    final int userStatus =
1011                            mSettings.getIntentFilterVerificationStatusLPr(packageName, userId);
1012
1013                    int updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
1014                    boolean needUpdate = false;
1015
1016                    // We cannot override the STATUS_ALWAYS / STATUS_NEVER states if they have
1017                    // already been set by the User thru the Disambiguation dialog
1018                    switch (userStatus) {
1019                        case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED:
1020                            if (verified) {
1021                                updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
1022                            } else {
1023                                updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK;
1024                            }
1025                            needUpdate = true;
1026                            break;
1027
1028                        case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK:
1029                            if (verified) {
1030                                updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
1031                                needUpdate = true;
1032                            }
1033                            break;
1034
1035                        default:
1036                            // Nothing to do
1037                    }
1038
1039                    if (needUpdate) {
1040                        mSettings.updateIntentFilterVerificationStatusLPw(
1041                                packageName, updatedStatus, userId);
1042                        scheduleWritePackageRestrictionsLocked(userId);
1043                    }
1044                }
1045            }
1046        }
1047
1048        @Override
1049        public boolean addOneIntentFilterVerification(int verifierUid, int userId, int verificationId,
1050                    ActivityIntentInfo filter, String packageName) {
1051            if (!hasValidDomains(filter)) {
1052                return false;
1053            }
1054            IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId);
1055            if (ivs == null) {
1056                ivs = createDomainVerificationState(verifierUid, userId, verificationId,
1057                        packageName);
1058            }
1059            if (DEBUG_DOMAIN_VERIFICATION) {
1060                Slog.d(TAG, "Adding verification filter for " + packageName + ": " + filter);
1061            }
1062            ivs.addFilter(filter);
1063            return true;
1064        }
1065
1066        private IntentFilterVerificationState createDomainVerificationState(int verifierUid,
1067                int userId, int verificationId, String packageName) {
1068            IntentFilterVerificationState ivs = new IntentFilterVerificationState(
1069                    verifierUid, userId, packageName);
1070            ivs.setPendingState();
1071            synchronized (mPackages) {
1072                mIntentFilterVerificationStates.append(verificationId, ivs);
1073                mCurrentIntentFilterVerifications.add(verificationId);
1074            }
1075            return ivs;
1076        }
1077    }
1078
1079    private static boolean hasValidDomains(ActivityIntentInfo filter) {
1080        return filter.hasCategory(Intent.CATEGORY_BROWSABLE)
1081                && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) ||
1082                        filter.hasDataScheme(IntentFilter.SCHEME_HTTPS));
1083    }
1084
1085    // Set of pending broadcasts for aggregating enable/disable of components.
1086    static class PendingPackageBroadcasts {
1087        // for each user id, a map of <package name -> components within that package>
1088        final SparseArray<ArrayMap<String, ArrayList<String>>> mUidMap;
1089
1090        public PendingPackageBroadcasts() {
1091            mUidMap = new SparseArray<ArrayMap<String, ArrayList<String>>>(2);
1092        }
1093
1094        public ArrayList<String> get(int userId, String packageName) {
1095            ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId);
1096            return packages.get(packageName);
1097        }
1098
1099        public void put(int userId, String packageName, ArrayList<String> components) {
1100            ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId);
1101            packages.put(packageName, components);
1102        }
1103
1104        public void remove(int userId, String packageName) {
1105            ArrayMap<String, ArrayList<String>> packages = mUidMap.get(userId);
1106            if (packages != null) {
1107                packages.remove(packageName);
1108            }
1109        }
1110
1111        public void remove(int userId) {
1112            mUidMap.remove(userId);
1113        }
1114
1115        public int userIdCount() {
1116            return mUidMap.size();
1117        }
1118
1119        public int userIdAt(int n) {
1120            return mUidMap.keyAt(n);
1121        }
1122
1123        public ArrayMap<String, ArrayList<String>> packagesForUserId(int userId) {
1124            return mUidMap.get(userId);
1125        }
1126
1127        public int size() {
1128            // total number of pending broadcast entries across all userIds
1129            int num = 0;
1130            for (int i = 0; i< mUidMap.size(); i++) {
1131                num += mUidMap.valueAt(i).size();
1132            }
1133            return num;
1134        }
1135
1136        public void clear() {
1137            mUidMap.clear();
1138        }
1139
1140        private ArrayMap<String, ArrayList<String>> getOrAllocate(int userId) {
1141            ArrayMap<String, ArrayList<String>> map = mUidMap.get(userId);
1142            if (map == null) {
1143                map = new ArrayMap<String, ArrayList<String>>();
1144                mUidMap.put(userId, map);
1145            }
1146            return map;
1147        }
1148    }
1149    final PendingPackageBroadcasts mPendingBroadcasts = new PendingPackageBroadcasts();
1150
1151    // Service Connection to remote media container service to copy
1152    // package uri's from external media onto secure containers
1153    // or internal storage.
1154    private IMediaContainerService mContainerService = null;
1155
1156    static final int SEND_PENDING_BROADCAST = 1;
1157    static final int MCS_BOUND = 3;
1158    static final int END_COPY = 4;
1159    static final int INIT_COPY = 5;
1160    static final int MCS_UNBIND = 6;
1161    static final int START_CLEANING_PACKAGE = 7;
1162    static final int FIND_INSTALL_LOC = 8;
1163    static final int POST_INSTALL = 9;
1164    static final int MCS_RECONNECT = 10;
1165    static final int MCS_GIVE_UP = 11;
1166    static final int UPDATED_MEDIA_STATUS = 12;
1167    static final int WRITE_SETTINGS = 13;
1168    static final int WRITE_PACKAGE_RESTRICTIONS = 14;
1169    static final int PACKAGE_VERIFIED = 15;
1170    static final int CHECK_PENDING_VERIFICATION = 16;
1171    static final int START_INTENT_FILTER_VERIFICATIONS = 17;
1172    static final int INTENT_FILTER_VERIFIED = 18;
1173    static final int WRITE_PACKAGE_LIST = 19;
1174    static final int INSTANT_APP_RESOLUTION_PHASE_TWO = 20;
1175
1176    static final int WRITE_SETTINGS_DELAY = 10*1000;  // 10 seconds
1177
1178    // Delay time in millisecs
1179    static final int BROADCAST_DELAY = 10 * 1000;
1180
1181    static UserManagerService sUserManager;
1182
1183    // Stores a list of users whose package restrictions file needs to be updated
1184    private ArraySet<Integer> mDirtyUsers = new ArraySet<Integer>();
1185
1186    final private DefaultContainerConnection mDefContainerConn =
1187            new DefaultContainerConnection();
1188    class DefaultContainerConnection implements ServiceConnection {
1189        public void onServiceConnected(ComponentName name, IBinder service) {
1190            if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceConnected");
1191            final IMediaContainerService imcs = IMediaContainerService.Stub
1192                    .asInterface(Binder.allowBlocking(service));
1193            mHandler.sendMessage(mHandler.obtainMessage(MCS_BOUND, imcs));
1194        }
1195
1196        public void onServiceDisconnected(ComponentName name) {
1197            if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceDisconnected");
1198        }
1199    }
1200
1201    // Recordkeeping of restore-after-install operations that are currently in flight
1202    // between the Package Manager and the Backup Manager
1203    static class PostInstallData {
1204        public InstallArgs args;
1205        public PackageInstalledInfo res;
1206
1207        PostInstallData(InstallArgs _a, PackageInstalledInfo _r) {
1208            args = _a;
1209            res = _r;
1210        }
1211    }
1212
1213    final SparseArray<PostInstallData> mRunningInstalls = new SparseArray<PostInstallData>();
1214    int mNextInstallToken = 1;  // nonzero; will be wrapped back to 1 when ++ overflows
1215
1216    // XML tags for backup/restore of various bits of state
1217    private static final String TAG_PREFERRED_BACKUP = "pa";
1218    private static final String TAG_DEFAULT_APPS = "da";
1219    private static final String TAG_INTENT_FILTER_VERIFICATION = "iv";
1220
1221    private static final String TAG_PERMISSION_BACKUP = "perm-grant-backup";
1222    private static final String TAG_ALL_GRANTS = "rt-grants";
1223    private static final String TAG_GRANT = "grant";
1224    private static final String ATTR_PACKAGE_NAME = "pkg";
1225
1226    private static final String TAG_PERMISSION = "perm";
1227    private static final String ATTR_PERMISSION_NAME = "name";
1228    private static final String ATTR_IS_GRANTED = "g";
1229    private static final String ATTR_USER_SET = "set";
1230    private static final String ATTR_USER_FIXED = "fixed";
1231    private static final String ATTR_REVOKE_ON_UPGRADE = "rou";
1232
1233    // System/policy permission grants are not backed up
1234    private static final int SYSTEM_RUNTIME_GRANT_MASK =
1235            FLAG_PERMISSION_POLICY_FIXED
1236            | FLAG_PERMISSION_SYSTEM_FIXED
1237            | FLAG_PERMISSION_GRANTED_BY_DEFAULT;
1238
1239    // And we back up these user-adjusted states
1240    private static final int USER_RUNTIME_GRANT_MASK =
1241            FLAG_PERMISSION_USER_SET
1242            | FLAG_PERMISSION_USER_FIXED
1243            | FLAG_PERMISSION_REVOKE_ON_UPGRADE;
1244
1245    final @Nullable String mRequiredVerifierPackage;
1246    final @NonNull String mRequiredInstallerPackage;
1247    final @NonNull String mRequiredUninstallerPackage;
1248    final @Nullable String mSetupWizardPackage;
1249    final @Nullable String mStorageManagerPackage;
1250    final @NonNull String mServicesSystemSharedLibraryPackageName;
1251    final @NonNull String mSharedSystemSharedLibraryPackageName;
1252
1253    final boolean mPermissionReviewRequired;
1254
1255    private final PackageUsage mPackageUsage = new PackageUsage();
1256    private final CompilerStats mCompilerStats = new CompilerStats();
1257
1258    class PackageHandler extends Handler {
1259        private boolean mBound = false;
1260        final ArrayList<HandlerParams> mPendingInstalls =
1261            new ArrayList<HandlerParams>();
1262
1263        private boolean connectToService() {
1264            if (DEBUG_SD_INSTALL) Log.i(TAG, "Trying to bind to" +
1265                    " DefaultContainerService");
1266            Intent service = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
1267            Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1268            if (mContext.bindServiceAsUser(service, mDefContainerConn,
1269                    Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) {
1270                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1271                mBound = true;
1272                return true;
1273            }
1274            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1275            return false;
1276        }
1277
1278        private void disconnectService() {
1279            mContainerService = null;
1280            mBound = false;
1281            Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1282            mContext.unbindService(mDefContainerConn);
1283            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1284        }
1285
1286        PackageHandler(Looper looper) {
1287            super(looper);
1288        }
1289
1290        public void handleMessage(Message msg) {
1291            try {
1292                doHandleMessage(msg);
1293            } finally {
1294                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1295            }
1296        }
1297
1298        void doHandleMessage(Message msg) {
1299            switch (msg.what) {
1300                case INIT_COPY: {
1301                    HandlerParams params = (HandlerParams) msg.obj;
1302                    int idx = mPendingInstalls.size();
1303                    if (DEBUG_INSTALL) Slog.i(TAG, "init_copy idx=" + idx + ": " + params);
1304                    // If a bind was already initiated we dont really
1305                    // need to do anything. The pending install
1306                    // will be processed later on.
1307                    if (!mBound) {
1308                        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1309                                System.identityHashCode(mHandler));
1310                        // If this is the only one pending we might
1311                        // have to bind to the service again.
1312                        if (!connectToService()) {
1313                            Slog.e(TAG, "Failed to bind to media container service");
1314                            params.serviceError();
1315                            Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1316                                    System.identityHashCode(mHandler));
1317                            if (params.traceMethod != null) {
1318                                Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, params.traceMethod,
1319                                        params.traceCookie);
1320                            }
1321                            return;
1322                        } else {
1323                            // Once we bind to the service, the first
1324                            // pending request will be processed.
1325                            mPendingInstalls.add(idx, params);
1326                        }
1327                    } else {
1328                        mPendingInstalls.add(idx, params);
1329                        // Already bound to the service. Just make
1330                        // sure we trigger off processing the first request.
1331                        if (idx == 0) {
1332                            mHandler.sendEmptyMessage(MCS_BOUND);
1333                        }
1334                    }
1335                    break;
1336                }
1337                case MCS_BOUND: {
1338                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_bound");
1339                    if (msg.obj != null) {
1340                        mContainerService = (IMediaContainerService) msg.obj;
1341                        Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1342                                System.identityHashCode(mHandler));
1343                    }
1344                    if (mContainerService == null) {
1345                        if (!mBound) {
1346                            // Something seriously wrong since we are not bound and we are not
1347                            // waiting for connection. Bail out.
1348                            Slog.e(TAG, "Cannot bind to media container service");
1349                            for (HandlerParams params : mPendingInstalls) {
1350                                // Indicate service bind error
1351                                params.serviceError();
1352                                Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1353                                        System.identityHashCode(params));
1354                                if (params.traceMethod != null) {
1355                                    Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER,
1356                                            params.traceMethod, params.traceCookie);
1357                                }
1358                                return;
1359                            }
1360                            mPendingInstalls.clear();
1361                        } else {
1362                            Slog.w(TAG, "Waiting to connect to media container service");
1363                        }
1364                    } else if (mPendingInstalls.size() > 0) {
1365                        HandlerParams params = mPendingInstalls.get(0);
1366                        if (params != null) {
1367                            Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1368                                    System.identityHashCode(params));
1369                            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "startCopy");
1370                            if (params.startCopy()) {
1371                                // We are done...  look for more work or to
1372                                // go idle.
1373                                if (DEBUG_SD_INSTALL) Log.i(TAG,
1374                                        "Checking for more work or unbind...");
1375                                // Delete pending install
1376                                if (mPendingInstalls.size() > 0) {
1377                                    mPendingInstalls.remove(0);
1378                                }
1379                                if (mPendingInstalls.size() == 0) {
1380                                    if (mBound) {
1381                                        if (DEBUG_SD_INSTALL) Log.i(TAG,
1382                                                "Posting delayed MCS_UNBIND");
1383                                        removeMessages(MCS_UNBIND);
1384                                        Message ubmsg = obtainMessage(MCS_UNBIND);
1385                                        // Unbind after a little delay, to avoid
1386                                        // continual thrashing.
1387                                        sendMessageDelayed(ubmsg, 10000);
1388                                    }
1389                                } else {
1390                                    // There are more pending requests in queue.
1391                                    // Just post MCS_BOUND message to trigger processing
1392                                    // of next pending install.
1393                                    if (DEBUG_SD_INSTALL) Log.i(TAG,
1394                                            "Posting MCS_BOUND for next work");
1395                                    mHandler.sendEmptyMessage(MCS_BOUND);
1396                                }
1397                            }
1398                            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
1399                        }
1400                    } else {
1401                        // Should never happen ideally.
1402                        Slog.w(TAG, "Empty queue");
1403                    }
1404                    break;
1405                }
1406                case MCS_RECONNECT: {
1407                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_reconnect");
1408                    if (mPendingInstalls.size() > 0) {
1409                        if (mBound) {
1410                            disconnectService();
1411                        }
1412                        if (!connectToService()) {
1413                            Slog.e(TAG, "Failed to bind to media container service");
1414                            for (HandlerParams params : mPendingInstalls) {
1415                                // Indicate service bind error
1416                                params.serviceError();
1417                                Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1418                                        System.identityHashCode(params));
1419                            }
1420                            mPendingInstalls.clear();
1421                        }
1422                    }
1423                    break;
1424                }
1425                case MCS_UNBIND: {
1426                    // If there is no actual work left, then time to unbind.
1427                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_unbind");
1428
1429                    if (mPendingInstalls.size() == 0 && mPendingVerification.size() == 0) {
1430                        if (mBound) {
1431                            if (DEBUG_INSTALL) Slog.i(TAG, "calling disconnectService()");
1432
1433                            disconnectService();
1434                        }
1435                    } else if (mPendingInstalls.size() > 0) {
1436                        // There are more pending requests in queue.
1437                        // Just post MCS_BOUND message to trigger processing
1438                        // of next pending install.
1439                        mHandler.sendEmptyMessage(MCS_BOUND);
1440                    }
1441
1442                    break;
1443                }
1444                case MCS_GIVE_UP: {
1445                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_giveup too many retries");
1446                    HandlerParams params = mPendingInstalls.remove(0);
1447                    Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1448                            System.identityHashCode(params));
1449                    break;
1450                }
1451                case SEND_PENDING_BROADCAST: {
1452                    String packages[];
1453                    ArrayList<String> components[];
1454                    int size = 0;
1455                    int uids[];
1456                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1457                    synchronized (mPackages) {
1458                        if (mPendingBroadcasts == null) {
1459                            return;
1460                        }
1461                        size = mPendingBroadcasts.size();
1462                        if (size <= 0) {
1463                            // Nothing to be done. Just return
1464                            return;
1465                        }
1466                        packages = new String[size];
1467                        components = new ArrayList[size];
1468                        uids = new int[size];
1469                        int i = 0;  // filling out the above arrays
1470
1471                        for (int n = 0; n < mPendingBroadcasts.userIdCount(); n++) {
1472                            int packageUserId = mPendingBroadcasts.userIdAt(n);
1473                            Iterator<Map.Entry<String, ArrayList<String>>> it
1474                                    = mPendingBroadcasts.packagesForUserId(packageUserId)
1475                                            .entrySet().iterator();
1476                            while (it.hasNext() && i < size) {
1477                                Map.Entry<String, ArrayList<String>> ent = it.next();
1478                                packages[i] = ent.getKey();
1479                                components[i] = ent.getValue();
1480                                PackageSetting ps = mSettings.mPackages.get(ent.getKey());
1481                                uids[i] = (ps != null)
1482                                        ? UserHandle.getUid(packageUserId, ps.appId)
1483                                        : -1;
1484                                i++;
1485                            }
1486                        }
1487                        size = i;
1488                        mPendingBroadcasts.clear();
1489                    }
1490                    // Send broadcasts
1491                    for (int i = 0; i < size; i++) {
1492                        sendPackageChangedBroadcast(packages[i], true, components[i], uids[i]);
1493                    }
1494                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1495                    break;
1496                }
1497                case START_CLEANING_PACKAGE: {
1498                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1499                    final String packageName = (String)msg.obj;
1500                    final int userId = msg.arg1;
1501                    final boolean andCode = msg.arg2 != 0;
1502                    synchronized (mPackages) {
1503                        if (userId == UserHandle.USER_ALL) {
1504                            int[] users = sUserManager.getUserIds();
1505                            for (int user : users) {
1506                                mSettings.addPackageToCleanLPw(
1507                                        new PackageCleanItem(user, packageName, andCode));
1508                            }
1509                        } else {
1510                            mSettings.addPackageToCleanLPw(
1511                                    new PackageCleanItem(userId, packageName, andCode));
1512                        }
1513                    }
1514                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1515                    startCleaningPackages();
1516                } break;
1517                case POST_INSTALL: {
1518                    if (DEBUG_INSTALL) Log.v(TAG, "Handling post-install for " + msg.arg1);
1519
1520                    PostInstallData data = mRunningInstalls.get(msg.arg1);
1521                    final boolean didRestore = (msg.arg2 != 0);
1522                    mRunningInstalls.delete(msg.arg1);
1523
1524                    if (data != null) {
1525                        InstallArgs args = data.args;
1526                        PackageInstalledInfo parentRes = data.res;
1527
1528                        final boolean grantPermissions = (args.installFlags
1529                                & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0;
1530                        final boolean killApp = (args.installFlags
1531                                & PackageManager.INSTALL_DONT_KILL_APP) == 0;
1532                        final String[] grantedPermissions = args.installGrantPermissions;
1533
1534                        // Handle the parent package
1535                        handlePackagePostInstall(parentRes, grantPermissions, killApp,
1536                                grantedPermissions, didRestore, args.installerPackageName,
1537                                args.observer);
1538
1539                        // Handle the child packages
1540                        final int childCount = (parentRes.addedChildPackages != null)
1541                                ? parentRes.addedChildPackages.size() : 0;
1542                        for (int i = 0; i < childCount; i++) {
1543                            PackageInstalledInfo childRes = parentRes.addedChildPackages.valueAt(i);
1544                            handlePackagePostInstall(childRes, grantPermissions, killApp,
1545                                    grantedPermissions, false, args.installerPackageName,
1546                                    args.observer);
1547                        }
1548
1549                        // Log tracing if needed
1550                        if (args.traceMethod != null) {
1551                            Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, args.traceMethod,
1552                                    args.traceCookie);
1553                        }
1554                    } else {
1555                        Slog.e(TAG, "Bogus post-install token " + msg.arg1);
1556                    }
1557
1558                    Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "postInstall", msg.arg1);
1559                } break;
1560                case UPDATED_MEDIA_STATUS: {
1561                    if (DEBUG_SD_INSTALL) Log.i(TAG, "Got message UPDATED_MEDIA_STATUS");
1562                    boolean reportStatus = msg.arg1 == 1;
1563                    boolean doGc = msg.arg2 == 1;
1564                    if (DEBUG_SD_INSTALL) Log.i(TAG, "reportStatus=" + reportStatus + ", doGc = " + doGc);
1565                    if (doGc) {
1566                        // Force a gc to clear up stale containers.
1567                        Runtime.getRuntime().gc();
1568                    }
1569                    if (msg.obj != null) {
1570                        @SuppressWarnings("unchecked")
1571                        Set<AsecInstallArgs> args = (Set<AsecInstallArgs>) msg.obj;
1572                        if (DEBUG_SD_INSTALL) Log.i(TAG, "Unloading all containers");
1573                        // Unload containers
1574                        unloadAllContainers(args);
1575                    }
1576                    if (reportStatus) {
1577                        try {
1578                            if (DEBUG_SD_INSTALL) Log.i(TAG,
1579                                    "Invoking StorageManagerService call back");
1580                            PackageHelper.getStorageManager().finishMediaUpdate();
1581                        } catch (RemoteException e) {
1582                            Log.e(TAG, "StorageManagerService not running?");
1583                        }
1584                    }
1585                } break;
1586                case WRITE_SETTINGS: {
1587                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1588                    synchronized (mPackages) {
1589                        removeMessages(WRITE_SETTINGS);
1590                        removeMessages(WRITE_PACKAGE_RESTRICTIONS);
1591                        mSettings.writeLPr();
1592                        mDirtyUsers.clear();
1593                    }
1594                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1595                } break;
1596                case WRITE_PACKAGE_RESTRICTIONS: {
1597                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1598                    synchronized (mPackages) {
1599                        removeMessages(WRITE_PACKAGE_RESTRICTIONS);
1600                        for (int userId : mDirtyUsers) {
1601                            mSettings.writePackageRestrictionsLPr(userId);
1602                        }
1603                        mDirtyUsers.clear();
1604                    }
1605                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1606                } break;
1607                case WRITE_PACKAGE_LIST: {
1608                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1609                    synchronized (mPackages) {
1610                        removeMessages(WRITE_PACKAGE_LIST);
1611                        mSettings.writePackageListLPr(msg.arg1);
1612                    }
1613                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1614                } break;
1615                case CHECK_PENDING_VERIFICATION: {
1616                    final int verificationId = msg.arg1;
1617                    final PackageVerificationState state = mPendingVerification.get(verificationId);
1618
1619                    if ((state != null) && !state.timeoutExtended()) {
1620                        final InstallArgs args = state.getInstallArgs();
1621                        final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
1622
1623                        Slog.i(TAG, "Verification timed out for " + originUri);
1624                        mPendingVerification.remove(verificationId);
1625
1626                        int ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
1627
1628                        if (getDefaultVerificationResponse() == PackageManager.VERIFICATION_ALLOW) {
1629                            Slog.i(TAG, "Continuing with installation of " + originUri);
1630                            state.setVerifierResponse(Binder.getCallingUid(),
1631                                    PackageManager.VERIFICATION_ALLOW_WITHOUT_SUFFICIENT);
1632                            broadcastPackageVerified(verificationId, originUri,
1633                                    PackageManager.VERIFICATION_ALLOW,
1634                                    state.getInstallArgs().getUser());
1635                            try {
1636                                ret = args.copyApk(mContainerService, true);
1637                            } catch (RemoteException e) {
1638                                Slog.e(TAG, "Could not contact the ContainerService");
1639                            }
1640                        } else {
1641                            broadcastPackageVerified(verificationId, originUri,
1642                                    PackageManager.VERIFICATION_REJECT,
1643                                    state.getInstallArgs().getUser());
1644                        }
1645
1646                        Trace.asyncTraceEnd(
1647                                TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
1648
1649                        processPendingInstall(args, ret);
1650                        mHandler.sendEmptyMessage(MCS_UNBIND);
1651                    }
1652                    break;
1653                }
1654                case PACKAGE_VERIFIED: {
1655                    final int verificationId = msg.arg1;
1656
1657                    final PackageVerificationState state = mPendingVerification.get(verificationId);
1658                    if (state == null) {
1659                        Slog.w(TAG, "Invalid verification token " + verificationId + " received");
1660                        break;
1661                    }
1662
1663                    final PackageVerificationResponse response = (PackageVerificationResponse) msg.obj;
1664
1665                    state.setVerifierResponse(response.callerUid, response.code);
1666
1667                    if (state.isVerificationComplete()) {
1668                        mPendingVerification.remove(verificationId);
1669
1670                        final InstallArgs args = state.getInstallArgs();
1671                        final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
1672
1673                        int ret;
1674                        if (state.isInstallAllowed()) {
1675                            ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
1676                            broadcastPackageVerified(verificationId, originUri,
1677                                    response.code, state.getInstallArgs().getUser());
1678                            try {
1679                                ret = args.copyApk(mContainerService, true);
1680                            } catch (RemoteException e) {
1681                                Slog.e(TAG, "Could not contact the ContainerService");
1682                            }
1683                        } else {
1684                            ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
1685                        }
1686
1687                        Trace.asyncTraceEnd(
1688                                TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
1689
1690                        processPendingInstall(args, ret);
1691                        mHandler.sendEmptyMessage(MCS_UNBIND);
1692                    }
1693
1694                    break;
1695                }
1696                case START_INTENT_FILTER_VERIFICATIONS: {
1697                    IFVerificationParams params = (IFVerificationParams) msg.obj;
1698                    verifyIntentFiltersIfNeeded(params.userId, params.verifierUid,
1699                            params.replacing, params.pkg);
1700                    break;
1701                }
1702                case INTENT_FILTER_VERIFIED: {
1703                    final int verificationId = msg.arg1;
1704
1705                    final IntentFilterVerificationState state = mIntentFilterVerificationStates.get(
1706                            verificationId);
1707                    if (state == null) {
1708                        Slog.w(TAG, "Invalid IntentFilter verification token "
1709                                + verificationId + " received");
1710                        break;
1711                    }
1712
1713                    final int userId = state.getUserId();
1714
1715                    if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1716                            "Processing IntentFilter verification with token:"
1717                            + verificationId + " and userId:" + userId);
1718
1719                    final IntentFilterVerificationResponse response =
1720                            (IntentFilterVerificationResponse) msg.obj;
1721
1722                    state.setVerifierResponse(response.callerUid, response.code);
1723
1724                    if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1725                            "IntentFilter verification with token:" + verificationId
1726                            + " and userId:" + userId
1727                            + " is settings verifier response with response code:"
1728                            + response.code);
1729
1730                    if (response.code == PackageManager.INTENT_FILTER_VERIFICATION_FAILURE) {
1731                        if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Domains failing verification: "
1732                                + response.getFailedDomainsString());
1733                    }
1734
1735                    if (state.isVerificationComplete()) {
1736                        mIntentFilterVerifier.receiveVerificationResponse(verificationId);
1737                    } else {
1738                        if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1739                                "IntentFilter verification with token:" + verificationId
1740                                + " was not said to be complete");
1741                    }
1742
1743                    break;
1744                }
1745                case INSTANT_APP_RESOLUTION_PHASE_TWO: {
1746                    InstantAppResolver.doInstantAppResolutionPhaseTwo(mContext,
1747                            mInstantAppResolverConnection,
1748                            (InstantAppRequest) msg.obj,
1749                            mInstantAppInstallerActivity,
1750                            mHandler);
1751                }
1752            }
1753        }
1754    }
1755
1756    private void handlePackagePostInstall(PackageInstalledInfo res, boolean grantPermissions,
1757            boolean killApp, String[] grantedPermissions,
1758            boolean launchedForRestore, String installerPackage,
1759            IPackageInstallObserver2 installObserver) {
1760        if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
1761            // Send the removed broadcasts
1762            if (res.removedInfo != null) {
1763                res.removedInfo.sendPackageRemovedBroadcasts(killApp);
1764            }
1765
1766            // Now that we successfully installed the package, grant runtime
1767            // permissions if requested before broadcasting the install. Also
1768            // for legacy apps in permission review mode we clear the permission
1769            // review flag which is used to emulate runtime permissions for
1770            // legacy apps.
1771            if (grantPermissions) {
1772                grantRequestedRuntimePermissions(res.pkg, res.newUsers, grantedPermissions);
1773            }
1774
1775            final boolean update = res.removedInfo != null
1776                    && res.removedInfo.removedPackage != null;
1777
1778            // If this is the first time we have child packages for a disabled privileged
1779            // app that had no children, we grant requested runtime permissions to the new
1780            // children if the parent on the system image had them already granted.
1781            if (res.pkg.parentPackage != null) {
1782                synchronized (mPackages) {
1783                    grantRuntimePermissionsGrantedToDisabledPrivSysPackageParentLPw(res.pkg);
1784                }
1785            }
1786
1787            synchronized (mPackages) {
1788                mInstantAppRegistry.onPackageInstalledLPw(res.pkg, res.newUsers);
1789            }
1790
1791            final String packageName = res.pkg.applicationInfo.packageName;
1792
1793            // Determine the set of users who are adding this package for
1794            // the first time vs. those who are seeing an update.
1795            int[] firstUsers = EMPTY_INT_ARRAY;
1796            int[] updateUsers = EMPTY_INT_ARRAY;
1797            final boolean allNewUsers = res.origUsers == null || res.origUsers.length == 0;
1798            final PackageSetting ps = (PackageSetting) res.pkg.mExtras;
1799            for (int newUser : res.newUsers) {
1800                if (ps.getInstantApp(newUser)) {
1801                    continue;
1802                }
1803                if (allNewUsers) {
1804                    firstUsers = ArrayUtils.appendInt(firstUsers, newUser);
1805                    continue;
1806                }
1807                boolean isNew = true;
1808                for (int origUser : res.origUsers) {
1809                    if (origUser == newUser) {
1810                        isNew = false;
1811                        break;
1812                    }
1813                }
1814                if (isNew) {
1815                    firstUsers = ArrayUtils.appendInt(firstUsers, newUser);
1816                } else {
1817                    updateUsers = ArrayUtils.appendInt(updateUsers, newUser);
1818                }
1819            }
1820
1821            // Send installed broadcasts if the package is not a static shared lib.
1822            if (res.pkg.staticSharedLibName == null) {
1823                mProcessLoggingHandler.invalidateProcessLoggingBaseApkHash(res.pkg.baseCodePath);
1824
1825                // Send added for users that see the package for the first time
1826                // sendPackageAddedForNewUsers also deals with system apps
1827                int appId = UserHandle.getAppId(res.uid);
1828                boolean isSystem = res.pkg.applicationInfo.isSystemApp();
1829                sendPackageAddedForNewUsers(packageName, isSystem, appId, firstUsers);
1830
1831                // Send added for users that don't see the package for the first time
1832                Bundle extras = new Bundle(1);
1833                extras.putInt(Intent.EXTRA_UID, res.uid);
1834                if (update) {
1835                    extras.putBoolean(Intent.EXTRA_REPLACING, true);
1836                } else {
1837                    sendPackageBroadcast(Intent.ACTION_PACKAGE_FIRST_ADDED, packageName,
1838                            extras, Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND,
1839                            null /*targetPackage*/, null /*finishedReceiver*/, updateUsers);
1840                }
1841                sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
1842                        extras, 0 /*flags*/, null /*targetPackage*/,
1843                        null /*finishedReceiver*/, updateUsers);
1844
1845                // Send replaced for users that don't see the package for the first time
1846                if (update) {
1847                    sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
1848                            packageName, extras, 0 /*flags*/,
1849                            null /*targetPackage*/, null /*finishedReceiver*/,
1850                            updateUsers);
1851                    sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
1852                            null /*package*/, null /*extras*/, 0 /*flags*/,
1853                            packageName /*targetPackage*/,
1854                            null /*finishedReceiver*/, updateUsers);
1855                } else if (launchedForRestore && !isSystemApp(res.pkg)) {
1856                    // First-install and we did a restore, so we're responsible for the
1857                    // first-launch broadcast.
1858                    if (DEBUG_BACKUP) {
1859                        Slog.i(TAG, "Post-restore of " + packageName
1860                                + " sending FIRST_LAUNCH in " + Arrays.toString(firstUsers));
1861                    }
1862                    sendFirstLaunchBroadcast(packageName, installerPackage, firstUsers);
1863                }
1864
1865                // Send broadcast package appeared if forward locked/external for all users
1866                // treat asec-hosted packages like removable media on upgrade
1867                if (res.pkg.isForwardLocked() || isExternal(res.pkg)) {
1868                    if (DEBUG_INSTALL) {
1869                        Slog.i(TAG, "upgrading pkg " + res.pkg
1870                                + " is ASEC-hosted -> AVAILABLE");
1871                    }
1872                    final int[] uidArray = new int[]{res.pkg.applicationInfo.uid};
1873                    ArrayList<String> pkgList = new ArrayList<>(1);
1874                    pkgList.add(packageName);
1875                    sendResourcesChangedBroadcast(true, true, pkgList, uidArray, null);
1876                }
1877            }
1878
1879            // Work that needs to happen on first install within each user
1880            if (firstUsers != null && firstUsers.length > 0) {
1881                synchronized (mPackages) {
1882                    for (int userId : firstUsers) {
1883                        // If this app is a browser and it's newly-installed for some
1884                        // users, clear any default-browser state in those users. The
1885                        // app's nature doesn't depend on the user, so we can just check
1886                        // its browser nature in any user and generalize.
1887                        if (packageIsBrowser(packageName, userId)) {
1888                            mSettings.setDefaultBrowserPackageNameLPw(null, userId);
1889                        }
1890
1891                        // We may also need to apply pending (restored) runtime
1892                        // permission grants within these users.
1893                        mSettings.applyPendingPermissionGrantsLPw(packageName, userId);
1894                    }
1895                }
1896            }
1897
1898            // Log current value of "unknown sources" setting
1899            EventLog.writeEvent(EventLogTags.UNKNOWN_SOURCES_ENABLED,
1900                    getUnknownSourcesSettings());
1901
1902            // Force a gc to clear up things
1903            Runtime.getRuntime().gc();
1904
1905            // Remove the replaced package's older resources safely now
1906            // We delete after a gc for applications  on sdcard.
1907            if (res.removedInfo != null && res.removedInfo.args != null) {
1908                synchronized (mInstallLock) {
1909                    res.removedInfo.args.doPostDeleteLI(true);
1910                }
1911            }
1912
1913            // Notify DexManager that the package was installed for new users.
1914            // The updated users should already be indexed and the package code paths
1915            // should not change.
1916            // Don't notify the manager for ephemeral apps as they are not expected to
1917            // survive long enough to benefit of background optimizations.
1918            for (int userId : firstUsers) {
1919                PackageInfo info = getPackageInfo(packageName, /*flags*/ 0, userId);
1920                // There's a race currently where some install events may interleave with an uninstall.
1921                // This can lead to package info being null (b/36642664).
1922                if (info != null) {
1923                    mDexManager.notifyPackageInstalled(info, userId);
1924                }
1925            }
1926        }
1927
1928        // If someone is watching installs - notify them
1929        if (installObserver != null) {
1930            try {
1931                Bundle extras = extrasForInstallResult(res);
1932                installObserver.onPackageInstalled(res.name, res.returnCode,
1933                        res.returnMsg, extras);
1934            } catch (RemoteException e) {
1935                Slog.i(TAG, "Observer no longer exists.");
1936            }
1937        }
1938    }
1939
1940    private void grantRuntimePermissionsGrantedToDisabledPrivSysPackageParentLPw(
1941            PackageParser.Package pkg) {
1942        if (pkg.parentPackage == null) {
1943            return;
1944        }
1945        if (pkg.requestedPermissions == null) {
1946            return;
1947        }
1948        final PackageSetting disabledSysParentPs = mSettings
1949                .getDisabledSystemPkgLPr(pkg.parentPackage.packageName);
1950        if (disabledSysParentPs == null || disabledSysParentPs.pkg == null
1951                || !disabledSysParentPs.isPrivileged()
1952                || (disabledSysParentPs.childPackageNames != null
1953                        && !disabledSysParentPs.childPackageNames.isEmpty())) {
1954            return;
1955        }
1956        final int[] allUserIds = sUserManager.getUserIds();
1957        final int permCount = pkg.requestedPermissions.size();
1958        for (int i = 0; i < permCount; i++) {
1959            String permission = pkg.requestedPermissions.get(i);
1960            BasePermission bp = mSettings.mPermissions.get(permission);
1961            if (bp == null || !(bp.isRuntime() || bp.isDevelopment())) {
1962                continue;
1963            }
1964            for (int userId : allUserIds) {
1965                if (disabledSysParentPs.getPermissionsState().hasRuntimePermission(
1966                        permission, userId)) {
1967                    grantRuntimePermission(pkg.packageName, permission, userId);
1968                }
1969            }
1970        }
1971    }
1972
1973    private StorageEventListener mStorageListener = new StorageEventListener() {
1974        @Override
1975        public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState) {
1976            if (vol.type == VolumeInfo.TYPE_PRIVATE) {
1977                if (vol.state == VolumeInfo.STATE_MOUNTED) {
1978                    final String volumeUuid = vol.getFsUuid();
1979
1980                    // Clean up any users or apps that were removed or recreated
1981                    // while this volume was missing
1982                    sUserManager.reconcileUsers(volumeUuid);
1983                    reconcileApps(volumeUuid);
1984
1985                    // Clean up any install sessions that expired or were
1986                    // cancelled while this volume was missing
1987                    mInstallerService.onPrivateVolumeMounted(volumeUuid);
1988
1989                    loadPrivatePackages(vol);
1990
1991                } else if (vol.state == VolumeInfo.STATE_EJECTING) {
1992                    unloadPrivatePackages(vol);
1993                }
1994            }
1995
1996            if (vol.type == VolumeInfo.TYPE_PUBLIC && vol.isPrimary()) {
1997                if (vol.state == VolumeInfo.STATE_MOUNTED) {
1998                    updateExternalMediaStatus(true, false);
1999                } else if (vol.state == VolumeInfo.STATE_EJECTING) {
2000                    updateExternalMediaStatus(false, false);
2001                }
2002            }
2003        }
2004
2005        @Override
2006        public void onVolumeForgotten(String fsUuid) {
2007            if (TextUtils.isEmpty(fsUuid)) {
2008                Slog.e(TAG, "Forgetting internal storage is probably a mistake; ignoring");
2009                return;
2010            }
2011
2012            // Remove any apps installed on the forgotten volume
2013            synchronized (mPackages) {
2014                final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(fsUuid);
2015                for (PackageSetting ps : packages) {
2016                    Slog.d(TAG, "Destroying " + ps.name + " because volume was forgotten");
2017                    deletePackageVersioned(new VersionedPackage(ps.name,
2018                            PackageManager.VERSION_CODE_HIGHEST),
2019                            new LegacyPackageDeleteObserver(null).getBinder(),
2020                            UserHandle.USER_SYSTEM, PackageManager.DELETE_ALL_USERS);
2021                    // Try very hard to release any references to this package
2022                    // so we don't risk the system server being killed due to
2023                    // open FDs
2024                    AttributeCache.instance().removePackage(ps.name);
2025                }
2026
2027                mSettings.onVolumeForgotten(fsUuid);
2028                mSettings.writeLPr();
2029            }
2030        }
2031    };
2032
2033    private void grantRequestedRuntimePermissions(PackageParser.Package pkg, int[] userIds,
2034            String[] grantedPermissions) {
2035        for (int userId : userIds) {
2036            grantRequestedRuntimePermissionsForUser(pkg, userId, grantedPermissions);
2037        }
2038    }
2039
2040    private void grantRequestedRuntimePermissionsForUser(PackageParser.Package pkg, int userId,
2041            String[] grantedPermissions) {
2042        SettingBase sb = (SettingBase) pkg.mExtras;
2043        if (sb == null) {
2044            return;
2045        }
2046
2047        PermissionsState permissionsState = sb.getPermissionsState();
2048
2049        final int immutableFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
2050                | PackageManager.FLAG_PERMISSION_POLICY_FIXED;
2051
2052        final boolean supportsRuntimePermissions = pkg.applicationInfo.targetSdkVersion
2053                >= Build.VERSION_CODES.M;
2054
2055        final boolean instantApp = isInstantApp(pkg.packageName, userId);
2056
2057        for (String permission : pkg.requestedPermissions) {
2058            final BasePermission bp;
2059            synchronized (mPackages) {
2060                bp = mSettings.mPermissions.get(permission);
2061            }
2062            if (bp != null && (bp.isRuntime() || bp.isDevelopment())
2063                    && (!instantApp || bp.isInstant())
2064                    && (supportsRuntimePermissions || !bp.isRuntimeOnly())
2065                    && (grantedPermissions == null
2066                           || ArrayUtils.contains(grantedPermissions, permission))) {
2067                final int flags = permissionsState.getPermissionFlags(permission, userId);
2068                if (supportsRuntimePermissions) {
2069                    // Installer cannot change immutable permissions.
2070                    if ((flags & immutableFlags) == 0) {
2071                        grantRuntimePermission(pkg.packageName, permission, userId);
2072                    }
2073                } else if (mPermissionReviewRequired) {
2074                    // In permission review mode we clear the review flag when we
2075                    // are asked to install the app with all permissions granted.
2076                    if ((flags & PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
2077                        updatePermissionFlags(permission, pkg.packageName,
2078                                PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED, 0, userId);
2079                    }
2080                }
2081            }
2082        }
2083    }
2084
2085    Bundle extrasForInstallResult(PackageInstalledInfo res) {
2086        Bundle extras = null;
2087        switch (res.returnCode) {
2088            case PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION: {
2089                extras = new Bundle();
2090                extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PERMISSION,
2091                        res.origPermission);
2092                extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PACKAGE,
2093                        res.origPackage);
2094                break;
2095            }
2096            case PackageManager.INSTALL_SUCCEEDED: {
2097                extras = new Bundle();
2098                extras.putBoolean(Intent.EXTRA_REPLACING,
2099                        res.removedInfo != null && res.removedInfo.removedPackage != null);
2100                break;
2101            }
2102        }
2103        return extras;
2104    }
2105
2106    void scheduleWriteSettingsLocked() {
2107        if (!mHandler.hasMessages(WRITE_SETTINGS)) {
2108            mHandler.sendEmptyMessageDelayed(WRITE_SETTINGS, WRITE_SETTINGS_DELAY);
2109        }
2110    }
2111
2112    void scheduleWritePackageListLocked(int userId) {
2113        if (!mHandler.hasMessages(WRITE_PACKAGE_LIST)) {
2114            Message msg = mHandler.obtainMessage(WRITE_PACKAGE_LIST);
2115            msg.arg1 = userId;
2116            mHandler.sendMessageDelayed(msg, WRITE_SETTINGS_DELAY);
2117        }
2118    }
2119
2120    void scheduleWritePackageRestrictionsLocked(UserHandle user) {
2121        final int userId = user == null ? UserHandle.USER_ALL : user.getIdentifier();
2122        scheduleWritePackageRestrictionsLocked(userId);
2123    }
2124
2125    void scheduleWritePackageRestrictionsLocked(int userId) {
2126        final int[] userIds = (userId == UserHandle.USER_ALL)
2127                ? sUserManager.getUserIds() : new int[]{userId};
2128        for (int nextUserId : userIds) {
2129            if (!sUserManager.exists(nextUserId)) return;
2130            mDirtyUsers.add(nextUserId);
2131            if (!mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) {
2132                mHandler.sendEmptyMessageDelayed(WRITE_PACKAGE_RESTRICTIONS, WRITE_SETTINGS_DELAY);
2133            }
2134        }
2135    }
2136
2137    public static PackageManagerService main(Context context, Installer installer,
2138            boolean factoryTest, boolean onlyCore) {
2139        // Self-check for initial settings.
2140        PackageManagerServiceCompilerMapping.checkProperties();
2141
2142        PackageManagerService m = new PackageManagerService(context, installer,
2143                factoryTest, onlyCore);
2144        m.enableSystemUserPackages();
2145        ServiceManager.addService("package", m);
2146        return m;
2147    }
2148
2149    private void enableSystemUserPackages() {
2150        if (!UserManager.isSplitSystemUser()) {
2151            return;
2152        }
2153        // For system user, enable apps based on the following conditions:
2154        // - app is whitelisted or belong to one of these groups:
2155        //   -- system app which has no launcher icons
2156        //   -- system app which has INTERACT_ACROSS_USERS permission
2157        //   -- system IME app
2158        // - app is not in the blacklist
2159        AppsQueryHelper queryHelper = new AppsQueryHelper(this);
2160        Set<String> enableApps = new ArraySet<>();
2161        enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_NON_LAUNCHABLE_APPS
2162                | AppsQueryHelper.GET_APPS_WITH_INTERACT_ACROSS_USERS_PERM
2163                | AppsQueryHelper.GET_IMES, /* systemAppsOnly */ true, UserHandle.SYSTEM));
2164        ArraySet<String> wlApps = SystemConfig.getInstance().getSystemUserWhitelistedApps();
2165        enableApps.addAll(wlApps);
2166        enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_REQUIRED_FOR_SYSTEM_USER,
2167                /* systemAppsOnly */ false, UserHandle.SYSTEM));
2168        ArraySet<String> blApps = SystemConfig.getInstance().getSystemUserBlacklistedApps();
2169        enableApps.removeAll(blApps);
2170        Log.i(TAG, "Applications installed for system user: " + enableApps);
2171        List<String> allAps = queryHelper.queryApps(0, /* systemAppsOnly */ false,
2172                UserHandle.SYSTEM);
2173        final int allAppsSize = allAps.size();
2174        synchronized (mPackages) {
2175            for (int i = 0; i < allAppsSize; i++) {
2176                String pName = allAps.get(i);
2177                PackageSetting pkgSetting = mSettings.mPackages.get(pName);
2178                // Should not happen, but we shouldn't be failing if it does
2179                if (pkgSetting == null) {
2180                    continue;
2181                }
2182                boolean install = enableApps.contains(pName);
2183                if (pkgSetting.getInstalled(UserHandle.USER_SYSTEM) != install) {
2184                    Log.i(TAG, (install ? "Installing " : "Uninstalling ") + pName
2185                            + " for system user");
2186                    pkgSetting.setInstalled(install, UserHandle.USER_SYSTEM);
2187                }
2188            }
2189            scheduleWritePackageRestrictionsLocked(UserHandle.USER_SYSTEM);
2190        }
2191    }
2192
2193    private static void getDefaultDisplayMetrics(Context context, DisplayMetrics metrics) {
2194        DisplayManager displayManager = (DisplayManager) context.getSystemService(
2195                Context.DISPLAY_SERVICE);
2196        displayManager.getDisplay(Display.DEFAULT_DISPLAY).getMetrics(metrics);
2197    }
2198
2199    /**
2200     * Requests that files preopted on a secondary system partition be copied to the data partition
2201     * if possible.  Note that the actual copying of the files is accomplished by init for security
2202     * reasons. This simply requests that the copy takes place and awaits confirmation of its
2203     * completion. See platform/system/extras/cppreopt/ for the implementation of the actual copy.
2204     */
2205    private static void requestCopyPreoptedFiles() {
2206        final int WAIT_TIME_MS = 100;
2207        final String CP_PREOPT_PROPERTY = "sys.cppreopt";
2208        if (SystemProperties.getInt("ro.cp_system_other_odex", 0) == 1) {
2209            SystemProperties.set(CP_PREOPT_PROPERTY, "requested");
2210            // We will wait for up to 100 seconds.
2211            final long timeStart = SystemClock.uptimeMillis();
2212            final long timeEnd = timeStart + 100 * 1000;
2213            long timeNow = timeStart;
2214            while (!SystemProperties.get(CP_PREOPT_PROPERTY).equals("finished")) {
2215                try {
2216                    Thread.sleep(WAIT_TIME_MS);
2217                } catch (InterruptedException e) {
2218                    // Do nothing
2219                }
2220                timeNow = SystemClock.uptimeMillis();
2221                if (timeNow > timeEnd) {
2222                    SystemProperties.set(CP_PREOPT_PROPERTY, "timed-out");
2223                    Slog.wtf(TAG, "cppreopt did not finish!");
2224                    break;
2225                }
2226            }
2227
2228            Slog.i(TAG, "cppreopts took " + (timeNow - timeStart) + " ms");
2229        }
2230    }
2231
2232    public PackageManagerService(Context context, Installer installer,
2233            boolean factoryTest, boolean onlyCore) {
2234        LockGuard.installLock(mPackages, LockGuard.INDEX_PACKAGES);
2235        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "create package manager");
2236        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START,
2237                SystemClock.uptimeMillis());
2238
2239        if (mSdkVersion <= 0) {
2240            Slog.w(TAG, "**** ro.build.version.sdk not set!");
2241        }
2242
2243        mContext = context;
2244
2245        mPermissionReviewRequired = context.getResources().getBoolean(
2246                R.bool.config_permissionReviewRequired);
2247
2248        mFactoryTest = factoryTest;
2249        mOnlyCore = onlyCore;
2250        mMetrics = new DisplayMetrics();
2251        mSettings = new Settings(mPackages);
2252        mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID,
2253                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2254        mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID,
2255                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2256        mSettings.addSharedUserLPw("android.uid.log", LOG_UID,
2257                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2258        mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID,
2259                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2260        mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID,
2261                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2262        mSettings.addSharedUserLPw("android.uid.shell", SHELL_UID,
2263                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2264
2265        String separateProcesses = SystemProperties.get("debug.separate_processes");
2266        if (separateProcesses != null && separateProcesses.length() > 0) {
2267            if ("*".equals(separateProcesses)) {
2268                mDefParseFlags = PackageParser.PARSE_IGNORE_PROCESSES;
2269                mSeparateProcesses = null;
2270                Slog.w(TAG, "Running with debug.separate_processes: * (ALL)");
2271            } else {
2272                mDefParseFlags = 0;
2273                mSeparateProcesses = separateProcesses.split(",");
2274                Slog.w(TAG, "Running with debug.separate_processes: "
2275                        + separateProcesses);
2276            }
2277        } else {
2278            mDefParseFlags = 0;
2279            mSeparateProcesses = null;
2280        }
2281
2282        mInstaller = installer;
2283        mPackageDexOptimizer = new PackageDexOptimizer(installer, mInstallLock, context,
2284                "*dexopt*");
2285        mDexManager = new DexManager(this, mPackageDexOptimizer, installer, mInstallLock);
2286        mMoveCallbacks = new MoveCallbacks(FgThread.get().getLooper());
2287
2288        mOnPermissionChangeListeners = new OnPermissionChangeListeners(
2289                FgThread.get().getLooper());
2290
2291        getDefaultDisplayMetrics(context, mMetrics);
2292
2293        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "get system config");
2294        SystemConfig systemConfig = SystemConfig.getInstance();
2295        mGlobalGids = systemConfig.getGlobalGids();
2296        mSystemPermissions = systemConfig.getSystemPermissions();
2297        mAvailableFeatures = systemConfig.getAvailableFeatures();
2298        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2299
2300        mProtectedPackages = new ProtectedPackages(mContext);
2301
2302        synchronized (mInstallLock) {
2303        // writer
2304        synchronized (mPackages) {
2305            mHandlerThread = new ServiceThread(TAG,
2306                    Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
2307            mHandlerThread.start();
2308            mHandler = new PackageHandler(mHandlerThread.getLooper());
2309            mProcessLoggingHandler = new ProcessLoggingHandler();
2310            Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT);
2311
2312            mDefaultPermissionPolicy = new DefaultPermissionGrantPolicy(this);
2313            mInstantAppRegistry = new InstantAppRegistry(this);
2314
2315            File dataDir = Environment.getDataDirectory();
2316            mAppInstallDir = new File(dataDir, "app");
2317            mAppLib32InstallDir = new File(dataDir, "app-lib");
2318            mAsecInternalPath = new File(dataDir, "app-asec").getPath();
2319            mDrmAppPrivateInstallDir = new File(dataDir, "app-private");
2320            sUserManager = new UserManagerService(context, this,
2321                    new UserDataPreparer(mInstaller, mInstallLock, mContext, mOnlyCore), mPackages);
2322
2323            // Propagate permission configuration in to package manager.
2324            ArrayMap<String, SystemConfig.PermissionEntry> permConfig
2325                    = systemConfig.getPermissions();
2326            for (int i=0; i<permConfig.size(); i++) {
2327                SystemConfig.PermissionEntry perm = permConfig.valueAt(i);
2328                BasePermission bp = mSettings.mPermissions.get(perm.name);
2329                if (bp == null) {
2330                    bp = new BasePermission(perm.name, "android", BasePermission.TYPE_BUILTIN);
2331                    mSettings.mPermissions.put(perm.name, bp);
2332                }
2333                if (perm.gids != null) {
2334                    bp.setGids(perm.gids, perm.perUser);
2335                }
2336            }
2337
2338            ArrayMap<String, String> libConfig = systemConfig.getSharedLibraries();
2339            final int builtInLibCount = libConfig.size();
2340            for (int i = 0; i < builtInLibCount; i++) {
2341                String name = libConfig.keyAt(i);
2342                String path = libConfig.valueAt(i);
2343                addSharedLibraryLPw(path, null, name, SharedLibraryInfo.VERSION_UNDEFINED,
2344                        SharedLibraryInfo.TYPE_BUILTIN, PLATFORM_PACKAGE_NAME, 0);
2345            }
2346
2347            mFoundPolicyFile = SELinuxMMAC.readInstallPolicy();
2348
2349            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "read user settings");
2350            mFirstBoot = !mSettings.readLPw(sUserManager.getUsers(false));
2351            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2352
2353            // Clean up orphaned packages for which the code path doesn't exist
2354            // and they are an update to a system app - caused by bug/32321269
2355            final int packageSettingCount = mSettings.mPackages.size();
2356            for (int i = packageSettingCount - 1; i >= 0; i--) {
2357                PackageSetting ps = mSettings.mPackages.valueAt(i);
2358                if (!isExternal(ps) && (ps.codePath == null || !ps.codePath.exists())
2359                        && mSettings.getDisabledSystemPkgLPr(ps.name) != null) {
2360                    mSettings.mPackages.removeAt(i);
2361                    mSettings.enableSystemPackageLPw(ps.name);
2362                }
2363            }
2364
2365            if (mFirstBoot) {
2366                requestCopyPreoptedFiles();
2367            }
2368
2369            String customResolverActivity = Resources.getSystem().getString(
2370                    R.string.config_customResolverActivity);
2371            if (TextUtils.isEmpty(customResolverActivity)) {
2372                customResolverActivity = null;
2373            } else {
2374                mCustomResolverComponentName = ComponentName.unflattenFromString(
2375                        customResolverActivity);
2376            }
2377
2378            long startTime = SystemClock.uptimeMillis();
2379
2380            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START,
2381                    startTime);
2382
2383            final String bootClassPath = System.getenv("BOOTCLASSPATH");
2384            final String systemServerClassPath = System.getenv("SYSTEMSERVERCLASSPATH");
2385
2386            if (bootClassPath == null) {
2387                Slog.w(TAG, "No BOOTCLASSPATH found!");
2388            }
2389
2390            if (systemServerClassPath == null) {
2391                Slog.w(TAG, "No SYSTEMSERVERCLASSPATH found!");
2392            }
2393
2394            File frameworkDir = new File(Environment.getRootDirectory(), "framework");
2395
2396            final VersionInfo ver = mSettings.getInternalVersion();
2397            mIsUpgrade = !Build.FINGERPRINT.equals(ver.fingerprint);
2398            if (mIsUpgrade) {
2399                logCriticalInfo(Log.INFO,
2400                        "Upgrading from " + ver.fingerprint + " to " + Build.FINGERPRINT);
2401            }
2402
2403            // when upgrading from pre-M, promote system app permissions from install to runtime
2404            mPromoteSystemApps =
2405                    mIsUpgrade && ver.sdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1;
2406
2407            // When upgrading from pre-N, we need to handle package extraction like first boot,
2408            // as there is no profiling data available.
2409            mIsPreNUpgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N;
2410
2411            mIsPreNMR1Upgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N_MR1;
2412
2413            // save off the names of pre-existing system packages prior to scanning; we don't
2414            // want to automatically grant runtime permissions for new system apps
2415            if (mPromoteSystemApps) {
2416                Iterator<PackageSetting> pkgSettingIter = mSettings.mPackages.values().iterator();
2417                while (pkgSettingIter.hasNext()) {
2418                    PackageSetting ps = pkgSettingIter.next();
2419                    if (isSystemApp(ps)) {
2420                        mExistingSystemPackages.add(ps.name);
2421                    }
2422                }
2423            }
2424
2425            mCacheDir = preparePackageParserCache(mIsUpgrade);
2426
2427            // Set flag to monitor and not change apk file paths when
2428            // scanning install directories.
2429            int scanFlags = SCAN_BOOTING | SCAN_INITIAL;
2430
2431            if (mIsUpgrade || mFirstBoot) {
2432                scanFlags = scanFlags | SCAN_FIRST_BOOT_OR_UPGRADE;
2433            }
2434
2435            // Collect vendor overlay packages. (Do this before scanning any apps.)
2436            // For security and version matching reason, only consider
2437            // overlay packages if they reside in the right directory.
2438            scanDirTracedLI(new File(VENDOR_OVERLAY_DIR), mDefParseFlags
2439                    | PackageParser.PARSE_IS_SYSTEM
2440                    | PackageParser.PARSE_IS_SYSTEM_DIR
2441                    | PackageParser.PARSE_TRUSTED_OVERLAY, scanFlags | SCAN_TRUSTED_OVERLAY, 0);
2442
2443            // Find base frameworks (resource packages without code).
2444            scanDirTracedLI(frameworkDir, mDefParseFlags
2445                    | PackageParser.PARSE_IS_SYSTEM
2446                    | PackageParser.PARSE_IS_SYSTEM_DIR
2447                    | PackageParser.PARSE_IS_PRIVILEGED,
2448                    scanFlags | SCAN_NO_DEX, 0);
2449
2450            // Collected privileged system packages.
2451            final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app");
2452            scanDirTracedLI(privilegedAppDir, mDefParseFlags
2453                    | PackageParser.PARSE_IS_SYSTEM
2454                    | PackageParser.PARSE_IS_SYSTEM_DIR
2455                    | PackageParser.PARSE_IS_PRIVILEGED, scanFlags, 0);
2456
2457            // Collect ordinary system packages.
2458            final File systemAppDir = new File(Environment.getRootDirectory(), "app");
2459            scanDirTracedLI(systemAppDir, mDefParseFlags
2460                    | PackageParser.PARSE_IS_SYSTEM
2461                    | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
2462
2463            // Collect all vendor packages.
2464            File vendorAppDir = new File("/vendor/app");
2465            try {
2466                vendorAppDir = vendorAppDir.getCanonicalFile();
2467            } catch (IOException e) {
2468                // failed to look up canonical path, continue with original one
2469            }
2470            scanDirTracedLI(vendorAppDir, mDefParseFlags
2471                    | PackageParser.PARSE_IS_SYSTEM
2472                    | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
2473
2474            // Collect all OEM packages.
2475            final File oemAppDir = new File(Environment.getOemDirectory(), "app");
2476            scanDirTracedLI(oemAppDir, mDefParseFlags
2477                    | PackageParser.PARSE_IS_SYSTEM
2478                    | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
2479
2480            // Prune any system packages that no longer exist.
2481            final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<String>();
2482            if (!mOnlyCore) {
2483                Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
2484                while (psit.hasNext()) {
2485                    PackageSetting ps = psit.next();
2486
2487                    /*
2488                     * If this is not a system app, it can't be a
2489                     * disable system app.
2490                     */
2491                    if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
2492                        continue;
2493                    }
2494
2495                    /*
2496                     * If the package is scanned, it's not erased.
2497                     */
2498                    final PackageParser.Package scannedPkg = mPackages.get(ps.name);
2499                    if (scannedPkg != null) {
2500                        /*
2501                         * If the system app is both scanned and in the
2502                         * disabled packages list, then it must have been
2503                         * added via OTA. Remove it from the currently
2504                         * scanned package so the previously user-installed
2505                         * application can be scanned.
2506                         */
2507                        if (mSettings.isDisabledSystemPackageLPr(ps.name)) {
2508                            logCriticalInfo(Log.WARN, "Expecting better updated system app for "
2509                                    + ps.name + "; removing system app.  Last known codePath="
2510                                    + ps.codePathString + ", installStatus=" + ps.installStatus
2511                                    + ", versionCode=" + ps.versionCode + "; scanned versionCode="
2512                                    + scannedPkg.mVersionCode);
2513                            removePackageLI(scannedPkg, true);
2514                            mExpectingBetter.put(ps.name, ps.codePath);
2515                        }
2516
2517                        continue;
2518                    }
2519
2520                    if (!mSettings.isDisabledSystemPackageLPr(ps.name)) {
2521                        psit.remove();
2522                        logCriticalInfo(Log.WARN, "System package " + ps.name
2523                                + " no longer exists; it's data will be wiped");
2524                        // Actual deletion of code and data will be handled by later
2525                        // reconciliation step
2526                    } else {
2527                        final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(ps.name);
2528                        if (disabledPs.codePath == null || !disabledPs.codePath.exists()) {
2529                            possiblyDeletedUpdatedSystemApps.add(ps.name);
2530                        }
2531                    }
2532                }
2533            }
2534
2535            //look for any incomplete package installations
2536            ArrayList<PackageSetting> deletePkgsList = mSettings.getListOfIncompleteInstallPackagesLPr();
2537            for (int i = 0; i < deletePkgsList.size(); i++) {
2538                // Actual deletion of code and data will be handled by later
2539                // reconciliation step
2540                final String packageName = deletePkgsList.get(i).name;
2541                logCriticalInfo(Log.WARN, "Cleaning up incompletely installed app: " + packageName);
2542                synchronized (mPackages) {
2543                    mSettings.removePackageLPw(packageName);
2544                }
2545            }
2546
2547            //delete tmp files
2548            deleteTempPackageFiles();
2549
2550            // Remove any shared userIDs that have no associated packages
2551            mSettings.pruneSharedUsersLPw();
2552
2553            if (!mOnlyCore) {
2554                EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,
2555                        SystemClock.uptimeMillis());
2556                scanDirTracedLI(mAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0);
2557
2558                scanDirTracedLI(mDrmAppPrivateInstallDir, mDefParseFlags
2559                        | PackageParser.PARSE_FORWARD_LOCK,
2560                        scanFlags | SCAN_REQUIRE_KNOWN, 0);
2561
2562                /**
2563                 * Remove disable package settings for any updated system
2564                 * apps that were removed via an OTA. If they're not a
2565                 * previously-updated app, remove them completely.
2566                 * Otherwise, just revoke their system-level permissions.
2567                 */
2568                for (String deletedAppName : possiblyDeletedUpdatedSystemApps) {
2569                    PackageParser.Package deletedPkg = mPackages.get(deletedAppName);
2570                    mSettings.removeDisabledSystemPackageLPw(deletedAppName);
2571
2572                    String msg;
2573                    if (deletedPkg == null) {
2574                        msg = "Updated system package " + deletedAppName
2575                                + " no longer exists; it's data will be wiped";
2576                        // Actual deletion of code and data will be handled by later
2577                        // reconciliation step
2578                    } else {
2579                        msg = "Updated system app + " + deletedAppName
2580                                + " no longer present; removing system privileges for "
2581                                + deletedAppName;
2582
2583                        deletedPkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM;
2584
2585                        PackageSetting deletedPs = mSettings.mPackages.get(deletedAppName);
2586                        deletedPs.pkgFlags &= ~ApplicationInfo.FLAG_SYSTEM;
2587                    }
2588                    logCriticalInfo(Log.WARN, msg);
2589                }
2590
2591                /**
2592                 * Make sure all system apps that we expected to appear on
2593                 * the userdata partition actually showed up. If they never
2594                 * appeared, crawl back and revive the system version.
2595                 */
2596                for (int i = 0; i < mExpectingBetter.size(); i++) {
2597                    final String packageName = mExpectingBetter.keyAt(i);
2598                    if (!mPackages.containsKey(packageName)) {
2599                        final File scanFile = mExpectingBetter.valueAt(i);
2600
2601                        logCriticalInfo(Log.WARN, "Expected better " + packageName
2602                                + " but never showed up; reverting to system");
2603
2604                        int reparseFlags = mDefParseFlags;
2605                        if (FileUtils.contains(privilegedAppDir, scanFile)) {
2606                            reparseFlags = PackageParser.PARSE_IS_SYSTEM
2607                                    | PackageParser.PARSE_IS_SYSTEM_DIR
2608                                    | PackageParser.PARSE_IS_PRIVILEGED;
2609                        } else if (FileUtils.contains(systemAppDir, scanFile)) {
2610                            reparseFlags = PackageParser.PARSE_IS_SYSTEM
2611                                    | PackageParser.PARSE_IS_SYSTEM_DIR;
2612                        } else if (FileUtils.contains(vendorAppDir, scanFile)) {
2613                            reparseFlags = PackageParser.PARSE_IS_SYSTEM
2614                                    | PackageParser.PARSE_IS_SYSTEM_DIR;
2615                        } else if (FileUtils.contains(oemAppDir, scanFile)) {
2616                            reparseFlags = PackageParser.PARSE_IS_SYSTEM
2617                                    | PackageParser.PARSE_IS_SYSTEM_DIR;
2618                        } else {
2619                            Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile);
2620                            continue;
2621                        }
2622
2623                        mSettings.enableSystemPackageLPw(packageName);
2624
2625                        try {
2626                            scanPackageTracedLI(scanFile, reparseFlags, scanFlags, 0, null);
2627                        } catch (PackageManagerException e) {
2628                            Slog.e(TAG, "Failed to parse original system package: "
2629                                    + e.getMessage());
2630                        }
2631                    }
2632                }
2633            }
2634            mExpectingBetter.clear();
2635
2636            // Resolve the storage manager.
2637            mStorageManagerPackage = getStorageManagerPackageName();
2638
2639            // Resolve protected action filters. Only the setup wizard is allowed to
2640            // have a high priority filter for these actions.
2641            mSetupWizardPackage = getSetupWizardPackageName();
2642            if (mProtectedFilters.size() > 0) {
2643                if (DEBUG_FILTERS && mSetupWizardPackage == null) {
2644                    Slog.i(TAG, "No setup wizard;"
2645                        + " All protected intents capped to priority 0");
2646                }
2647                for (ActivityIntentInfo filter : mProtectedFilters) {
2648                    if (filter.activity.info.packageName.equals(mSetupWizardPackage)) {
2649                        if (DEBUG_FILTERS) {
2650                            Slog.i(TAG, "Found setup wizard;"
2651                                + " allow priority " + filter.getPriority() + ";"
2652                                + " package: " + filter.activity.info.packageName
2653                                + " activity: " + filter.activity.className
2654                                + " priority: " + filter.getPriority());
2655                        }
2656                        // skip setup wizard; allow it to keep the high priority filter
2657                        continue;
2658                    }
2659                    Slog.w(TAG, "Protected action; cap priority to 0;"
2660                            + " package: " + filter.activity.info.packageName
2661                            + " activity: " + filter.activity.className
2662                            + " origPrio: " + filter.getPriority());
2663                    filter.setPriority(0);
2664                }
2665            }
2666            mDeferProtectedFilters = false;
2667            mProtectedFilters.clear();
2668
2669            // Now that we know all of the shared libraries, update all clients to have
2670            // the correct library paths.
2671            updateAllSharedLibrariesLPw(null);
2672
2673            for (SharedUserSetting setting : mSettings.getAllSharedUsersLPw()) {
2674                // NOTE: We ignore potential failures here during a system scan (like
2675                // the rest of the commands above) because there's precious little we
2676                // can do about it. A settings error is reported, though.
2677                adjustCpuAbisForSharedUserLPw(setting.packages, null /*scannedPackage*/);
2678            }
2679
2680            // Now that we know all the packages we are keeping,
2681            // read and update their last usage times.
2682            mPackageUsage.read(mPackages);
2683            mCompilerStats.read();
2684
2685            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END,
2686                    SystemClock.uptimeMillis());
2687            Slog.i(TAG, "Time to scan packages: "
2688                    + ((SystemClock.uptimeMillis()-startTime)/1000f)
2689                    + " seconds");
2690
2691            // If the platform SDK has changed since the last time we booted,
2692            // we need to re-grant app permission to catch any new ones that
2693            // appear.  This is really a hack, and means that apps can in some
2694            // cases get permissions that the user didn't initially explicitly
2695            // allow...  it would be nice to have some better way to handle
2696            // this situation.
2697            int updateFlags = UPDATE_PERMISSIONS_ALL;
2698            if (ver.sdkVersion != mSdkVersion) {
2699                Slog.i(TAG, "Platform changed from " + ver.sdkVersion + " to "
2700                        + mSdkVersion + "; regranting permissions for internal storage");
2701                updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
2702            }
2703            updatePermissionsLPw(null, null, StorageManager.UUID_PRIVATE_INTERNAL, updateFlags);
2704            ver.sdkVersion = mSdkVersion;
2705
2706            // If this is the first boot or an update from pre-M, and it is a normal
2707            // boot, then we need to initialize the default preferred apps across
2708            // all defined users.
2709            if (!onlyCore && (mPromoteSystemApps || mFirstBoot)) {
2710                for (UserInfo user : sUserManager.getUsers(true)) {
2711                    mSettings.applyDefaultPreferredAppsLPw(this, user.id);
2712                    applyFactoryDefaultBrowserLPw(user.id);
2713                    primeDomainVerificationsLPw(user.id);
2714                }
2715            }
2716
2717            // Prepare storage for system user really early during boot,
2718            // since core system apps like SettingsProvider and SystemUI
2719            // can't wait for user to start
2720            final int storageFlags;
2721            if (StorageManager.isFileEncryptedNativeOrEmulated()) {
2722                storageFlags = StorageManager.FLAG_STORAGE_DE;
2723            } else {
2724                storageFlags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
2725            }
2726            List<String> deferPackages = reconcileAppsDataLI(StorageManager.UUID_PRIVATE_INTERNAL,
2727                    UserHandle.USER_SYSTEM, storageFlags, true /* migrateAppData */,
2728                    true /* onlyCoreApps */);
2729            mPrepareAppDataFuture = SystemServerInitThreadPool.get().submit(() -> {
2730                BootTimingsTraceLog traceLog = new BootTimingsTraceLog("SystemServerTimingAsync",
2731                        Trace.TRACE_TAG_PACKAGE_MANAGER);
2732                traceLog.traceBegin("AppDataFixup");
2733                try {
2734                    mInstaller.fixupAppData(StorageManager.UUID_PRIVATE_INTERNAL,
2735                            StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
2736                } catch (InstallerException e) {
2737                    Slog.w(TAG, "Trouble fixing GIDs", e);
2738                }
2739                traceLog.traceEnd();
2740
2741                traceLog.traceBegin("AppDataPrepare");
2742                if (deferPackages == null || deferPackages.isEmpty()) {
2743                    return;
2744                }
2745                int count = 0;
2746                for (String pkgName : deferPackages) {
2747                    PackageParser.Package pkg = null;
2748                    synchronized (mPackages) {
2749                        PackageSetting ps = mSettings.getPackageLPr(pkgName);
2750                        if (ps != null && ps.getInstalled(UserHandle.USER_SYSTEM)) {
2751                            pkg = ps.pkg;
2752                        }
2753                    }
2754                    if (pkg != null) {
2755                        synchronized (mInstallLock) {
2756                            prepareAppDataAndMigrateLIF(pkg, UserHandle.USER_SYSTEM, storageFlags,
2757                                    true /* maybeMigrateAppData */);
2758                        }
2759                        count++;
2760                    }
2761                }
2762                traceLog.traceEnd();
2763                Slog.i(TAG, "Deferred reconcileAppsData finished " + count + " packages");
2764            }, "prepareAppData");
2765
2766            // If this is first boot after an OTA, and a normal boot, then
2767            // we need to clear code cache directories.
2768            // Note that we do *not* clear the application profiles. These remain valid
2769            // across OTAs and are used to drive profile verification (post OTA) and
2770            // profile compilation (without waiting to collect a fresh set of profiles).
2771            if (mIsUpgrade && !onlyCore) {
2772                Slog.i(TAG, "Build fingerprint changed; clearing code caches");
2773                for (int i = 0; i < mSettings.mPackages.size(); i++) {
2774                    final PackageSetting ps = mSettings.mPackages.valueAt(i);
2775                    if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, ps.volumeUuid)) {
2776                        // No apps are running this early, so no need to freeze
2777                        clearAppDataLIF(ps.pkg, UserHandle.USER_ALL,
2778                                StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE
2779                                        | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
2780                    }
2781                }
2782                ver.fingerprint = Build.FINGERPRINT;
2783            }
2784
2785            checkDefaultBrowser();
2786
2787            // clear only after permissions and other defaults have been updated
2788            mExistingSystemPackages.clear();
2789            mPromoteSystemApps = false;
2790
2791            // All the changes are done during package scanning.
2792            ver.databaseVersion = Settings.CURRENT_DATABASE_VERSION;
2793
2794            // can downgrade to reader
2795            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "write settings");
2796            mSettings.writeLPr();
2797            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2798
2799            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY,
2800                    SystemClock.uptimeMillis());
2801
2802            if (!mOnlyCore) {
2803                mRequiredVerifierPackage = getRequiredButNotReallyRequiredVerifierLPr();
2804                mRequiredInstallerPackage = getRequiredInstallerLPr();
2805                mRequiredUninstallerPackage = getRequiredUninstallerLPr();
2806                mIntentFilterVerifierComponent = getIntentFilterVerifierComponentNameLPr();
2807                mIntentFilterVerifier = new IntentVerifierProxy(mContext,
2808                        mIntentFilterVerifierComponent);
2809                mServicesSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr(
2810                        PackageManager.SYSTEM_SHARED_LIBRARY_SERVICES,
2811                        SharedLibraryInfo.VERSION_UNDEFINED);
2812                mSharedSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr(
2813                        PackageManager.SYSTEM_SHARED_LIBRARY_SHARED,
2814                        SharedLibraryInfo.VERSION_UNDEFINED);
2815            } else {
2816                mRequiredVerifierPackage = null;
2817                mRequiredInstallerPackage = null;
2818                mRequiredUninstallerPackage = null;
2819                mIntentFilterVerifierComponent = null;
2820                mIntentFilterVerifier = null;
2821                mServicesSystemSharedLibraryPackageName = null;
2822                mSharedSystemSharedLibraryPackageName = null;
2823            }
2824
2825            mInstallerService = new PackageInstallerService(context, this);
2826            final Pair<ComponentName, String> instantAppResolverComponent =
2827                    getInstantAppResolverLPr();
2828            if (instantAppResolverComponent != null) {
2829                if (DEBUG_EPHEMERAL) {
2830                    Slog.d(TAG, "Set ephemeral resolver: " + instantAppResolverComponent);
2831                }
2832                mInstantAppResolverConnection = new EphemeralResolverConnection(
2833                        mContext, instantAppResolverComponent.first,
2834                        instantAppResolverComponent.second);
2835                mInstantAppResolverSettingsComponent =
2836                        getInstantAppResolverSettingsLPr(instantAppResolverComponent.first);
2837            } else {
2838                mInstantAppResolverConnection = null;
2839                mInstantAppResolverSettingsComponent = null;
2840            }
2841            updateInstantAppInstallerLocked(null);
2842
2843            // Read and update the usage of dex files.
2844            // Do this at the end of PM init so that all the packages have their
2845            // data directory reconciled.
2846            // At this point we know the code paths of the packages, so we can validate
2847            // the disk file and build the internal cache.
2848            // The usage file is expected to be small so loading and verifying it
2849            // should take a fairly small time compare to the other activities (e.g. package
2850            // scanning).
2851            final Map<Integer, List<PackageInfo>> userPackages = new HashMap<>();
2852            final int[] currentUserIds = UserManagerService.getInstance().getUserIds();
2853            for (int userId : currentUserIds) {
2854                userPackages.put(userId, getInstalledPackages(/*flags*/ 0, userId).getList());
2855            }
2856            mDexManager.load(userPackages);
2857        } // synchronized (mPackages)
2858        } // synchronized (mInstallLock)
2859
2860        // Now after opening every single application zip, make sure they
2861        // are all flushed.  Not really needed, but keeps things nice and
2862        // tidy.
2863        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "GC");
2864        Runtime.getRuntime().gc();
2865        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2866
2867        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "loadFallbacks");
2868        FallbackCategoryProvider.loadFallbacks();
2869        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2870
2871        // The initial scanning above does many calls into installd while
2872        // holding the mPackages lock, but we're mostly interested in yelling
2873        // once we have a booted system.
2874        mInstaller.setWarnIfHeld(mPackages);
2875
2876        // Expose private service for system components to use.
2877        LocalServices.addService(PackageManagerInternal.class, new PackageManagerInternalImpl());
2878        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2879    }
2880
2881    private void updateInstantAppInstallerLocked(String modifiedPackage) {
2882        // we're only interested in updating the installer appliction when 1) it's not
2883        // already set or 2) the modified package is the installer
2884        if (mInstantAppInstallerActivity != null
2885                && !mInstantAppInstallerActivity.getComponentName().getPackageName()
2886                        .equals(modifiedPackage)) {
2887            return;
2888        }
2889        setUpInstantAppInstallerActivityLP(getInstantAppInstallerLPr());
2890    }
2891
2892    private static File preparePackageParserCache(boolean isUpgrade) {
2893        if (!DEFAULT_PACKAGE_PARSER_CACHE_ENABLED) {
2894            return null;
2895        }
2896
2897        // Disable package parsing on eng builds to allow for faster incremental development.
2898        if ("eng".equals(Build.TYPE)) {
2899            return null;
2900        }
2901
2902        if (SystemProperties.getBoolean("pm.boot.disable_package_cache", false)) {
2903            Slog.i(TAG, "Disabling package parser cache due to system property.");
2904            return null;
2905        }
2906
2907        // The base directory for the package parser cache lives under /data/system/.
2908        final File cacheBaseDir = FileUtils.createDir(Environment.getDataSystemDirectory(),
2909                "package_cache");
2910        if (cacheBaseDir == null) {
2911            return null;
2912        }
2913
2914        // If this is a system upgrade scenario, delete the contents of the package cache dir.
2915        // This also serves to "GC" unused entries when the package cache version changes (which
2916        // can only happen during upgrades).
2917        if (isUpgrade) {
2918            FileUtils.deleteContents(cacheBaseDir);
2919        }
2920
2921
2922        // Return the versioned package cache directory. This is something like
2923        // "/data/system/package_cache/1"
2924        File cacheDir = FileUtils.createDir(cacheBaseDir, PACKAGE_PARSER_CACHE_VERSION);
2925
2926        // The following is a workaround to aid development on non-numbered userdebug
2927        // builds or cases where "adb sync" is used on userdebug builds. If we detect that
2928        // the system partition is newer.
2929        //
2930        // NOTE: When no BUILD_NUMBER is set by the build system, it defaults to a build
2931        // that starts with "eng." to signify that this is an engineering build and not
2932        // destined for release.
2933        if ("userdebug".equals(Build.TYPE) && Build.VERSION.INCREMENTAL.startsWith("eng.")) {
2934            Slog.w(TAG, "Wiping cache directory because the system partition changed.");
2935
2936            // Heuristic: If the /system directory has been modified recently due to an "adb sync"
2937            // or a regular make, then blow away the cache. Note that mtimes are *NOT* reliable
2938            // in general and should not be used for production changes. In this specific case,
2939            // we know that they will work.
2940            File frameworkDir = new File(Environment.getRootDirectory(), "framework");
2941            if (cacheDir.lastModified() < frameworkDir.lastModified()) {
2942                FileUtils.deleteContents(cacheBaseDir);
2943                cacheDir = FileUtils.createDir(cacheBaseDir, PACKAGE_PARSER_CACHE_VERSION);
2944            }
2945        }
2946
2947        return cacheDir;
2948    }
2949
2950    @Override
2951    public boolean isFirstBoot() {
2952        return mFirstBoot;
2953    }
2954
2955    @Override
2956    public boolean isOnlyCoreApps() {
2957        return mOnlyCore;
2958    }
2959
2960    @Override
2961    public boolean isUpgrade() {
2962        return mIsUpgrade;
2963    }
2964
2965    private @Nullable String getRequiredButNotReallyRequiredVerifierLPr() {
2966        final Intent intent = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
2967
2968        final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE,
2969                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
2970                UserHandle.USER_SYSTEM);
2971        if (matches.size() == 1) {
2972            return matches.get(0).getComponentInfo().packageName;
2973        } else if (matches.size() == 0) {
2974            Log.e(TAG, "There should probably be a verifier, but, none were found");
2975            return null;
2976        }
2977        throw new RuntimeException("There must be exactly one verifier; found " + matches);
2978    }
2979
2980    private @NonNull String getRequiredSharedLibraryLPr(String name, int version) {
2981        synchronized (mPackages) {
2982            SharedLibraryEntry libraryEntry = getSharedLibraryEntryLPr(name, version);
2983            if (libraryEntry == null) {
2984                throw new IllegalStateException("Missing required shared library:" + name);
2985            }
2986            return libraryEntry.apk;
2987        }
2988    }
2989
2990    private @NonNull String getRequiredInstallerLPr() {
2991        final Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
2992        intent.addCategory(Intent.CATEGORY_DEFAULT);
2993        intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE);
2994
2995        final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
2996                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
2997                UserHandle.USER_SYSTEM);
2998        if (matches.size() == 1) {
2999            ResolveInfo resolveInfo = matches.get(0);
3000            if (!resolveInfo.activityInfo.applicationInfo.isPrivilegedApp()) {
3001                throw new RuntimeException("The installer must be a privileged app");
3002            }
3003            return matches.get(0).getComponentInfo().packageName;
3004        } else {
3005            throw new RuntimeException("There must be exactly one installer; found " + matches);
3006        }
3007    }
3008
3009    private @NonNull String getRequiredUninstallerLPr() {
3010        final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE);
3011        intent.addCategory(Intent.CATEGORY_DEFAULT);
3012        intent.setData(Uri.fromParts(PACKAGE_SCHEME, "foo.bar", null));
3013
3014        final ResolveInfo resolveInfo = resolveIntent(intent, null,
3015                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3016                UserHandle.USER_SYSTEM);
3017        if (resolveInfo == null ||
3018                mResolveActivity.name.equals(resolveInfo.getComponentInfo().name)) {
3019            throw new RuntimeException("There must be exactly one uninstaller; found "
3020                    + resolveInfo);
3021        }
3022        return resolveInfo.getComponentInfo().packageName;
3023    }
3024
3025    private @NonNull ComponentName getIntentFilterVerifierComponentNameLPr() {
3026        final Intent intent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION);
3027
3028        final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE,
3029                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3030                UserHandle.USER_SYSTEM);
3031        ResolveInfo best = null;
3032        final int N = matches.size();
3033        for (int i = 0; i < N; i++) {
3034            final ResolveInfo cur = matches.get(i);
3035            final String packageName = cur.getComponentInfo().packageName;
3036            if (checkPermission(android.Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT,
3037                    packageName, UserHandle.USER_SYSTEM) != PackageManager.PERMISSION_GRANTED) {
3038                continue;
3039            }
3040
3041            if (best == null || cur.priority > best.priority) {
3042                best = cur;
3043            }
3044        }
3045
3046        if (best != null) {
3047            return best.getComponentInfo().getComponentName();
3048        } else {
3049            throw new RuntimeException("There must be at least one intent filter verifier");
3050        }
3051    }
3052
3053    private @Nullable Pair<ComponentName, String> getInstantAppResolverLPr() {
3054        final String[] packageArray =
3055                mContext.getResources().getStringArray(R.array.config_ephemeralResolverPackage);
3056        if (packageArray.length == 0 && !Build.IS_DEBUGGABLE) {
3057            if (DEBUG_EPHEMERAL) {
3058                Slog.d(TAG, "Ephemeral resolver NOT found; empty package list");
3059            }
3060            return null;
3061        }
3062
3063        final int callingUid = Binder.getCallingUid();
3064        final int resolveFlags =
3065                MATCH_DIRECT_BOOT_AWARE
3066                | MATCH_DIRECT_BOOT_UNAWARE
3067                | (!Build.IS_DEBUGGABLE ? MATCH_SYSTEM_ONLY : 0);
3068        String actionName = Intent.ACTION_RESOLVE_INSTANT_APP_PACKAGE;
3069        final Intent resolverIntent = new Intent(actionName);
3070        List<ResolveInfo> resolvers = queryIntentServicesInternal(resolverIntent, null,
3071                resolveFlags, UserHandle.USER_SYSTEM, callingUid, false /*includeInstantApps*/);
3072        // temporarily look for the old action
3073        if (resolvers.size() == 0) {
3074            if (DEBUG_EPHEMERAL) {
3075                Slog.d(TAG, "Ephemeral resolver not found with new action; try old one");
3076            }
3077            actionName = Intent.ACTION_RESOLVE_EPHEMERAL_PACKAGE;
3078            resolverIntent.setAction(actionName);
3079            resolvers = queryIntentServicesInternal(resolverIntent, null,
3080                    resolveFlags, UserHandle.USER_SYSTEM, callingUid, false /*includeInstantApps*/);
3081        }
3082        final int N = resolvers.size();
3083        if (N == 0) {
3084            if (DEBUG_EPHEMERAL) {
3085                Slog.d(TAG, "Ephemeral resolver NOT found; no matching intent filters");
3086            }
3087            return null;
3088        }
3089
3090        final Set<String> possiblePackages = new ArraySet<>(Arrays.asList(packageArray));
3091        for (int i = 0; i < N; i++) {
3092            final ResolveInfo info = resolvers.get(i);
3093
3094            if (info.serviceInfo == null) {
3095                continue;
3096            }
3097
3098            final String packageName = info.serviceInfo.packageName;
3099            if (!possiblePackages.contains(packageName) && !Build.IS_DEBUGGABLE) {
3100                if (DEBUG_EPHEMERAL) {
3101                    Slog.d(TAG, "Ephemeral resolver not in allowed package list;"
3102                            + " pkg: " + packageName + ", info:" + info);
3103                }
3104                continue;
3105            }
3106
3107            if (DEBUG_EPHEMERAL) {
3108                Slog.v(TAG, "Ephemeral resolver found;"
3109                        + " pkg: " + packageName + ", info:" + info);
3110            }
3111            return new Pair<>(new ComponentName(packageName, info.serviceInfo.name), actionName);
3112        }
3113        if (DEBUG_EPHEMERAL) {
3114            Slog.v(TAG, "Ephemeral resolver NOT found");
3115        }
3116        return null;
3117    }
3118
3119    private @Nullable ActivityInfo getInstantAppInstallerLPr() {
3120        final Intent intent = new Intent(Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE);
3121        intent.addCategory(Intent.CATEGORY_DEFAULT);
3122        intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE);
3123
3124        final int resolveFlags =
3125                MATCH_DIRECT_BOOT_AWARE
3126                | MATCH_DIRECT_BOOT_UNAWARE
3127                | (!Build.IS_DEBUGGABLE ? MATCH_SYSTEM_ONLY : 0);
3128        List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
3129                resolveFlags, UserHandle.USER_SYSTEM);
3130        // temporarily look for the old action
3131        if (matches.isEmpty()) {
3132            if (DEBUG_EPHEMERAL) {
3133                Slog.d(TAG, "Ephemeral installer not found with new action; try old one");
3134            }
3135            intent.setAction(Intent.ACTION_INSTALL_EPHEMERAL_PACKAGE);
3136            matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
3137                    resolveFlags, UserHandle.USER_SYSTEM);
3138        }
3139        Iterator<ResolveInfo> iter = matches.iterator();
3140        while (iter.hasNext()) {
3141            final ResolveInfo rInfo = iter.next();
3142            final PackageSetting ps = mSettings.mPackages.get(rInfo.activityInfo.packageName);
3143            if (ps != null) {
3144                final PermissionsState permissionsState = ps.getPermissionsState();
3145                if (permissionsState.hasPermission(Manifest.permission.INSTALL_PACKAGES, 0)) {
3146                    continue;
3147                }
3148            }
3149            iter.remove();
3150        }
3151        if (matches.size() == 0) {
3152            return null;
3153        } else if (matches.size() == 1) {
3154            return (ActivityInfo) matches.get(0).getComponentInfo();
3155        } else {
3156            throw new RuntimeException(
3157                    "There must be at most one ephemeral installer; found " + matches);
3158        }
3159    }
3160
3161    private @Nullable ComponentName getInstantAppResolverSettingsLPr(
3162            @NonNull ComponentName resolver) {
3163        final Intent intent =  new Intent(Intent.ACTION_INSTANT_APP_RESOLVER_SETTINGS)
3164                .addCategory(Intent.CATEGORY_DEFAULT)
3165                .setPackage(resolver.getPackageName());
3166        final int resolveFlags = MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE;
3167        List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null, resolveFlags,
3168                UserHandle.USER_SYSTEM);
3169        // temporarily look for the old action
3170        if (matches.isEmpty()) {
3171            if (DEBUG_EPHEMERAL) {
3172                Slog.d(TAG, "Ephemeral resolver settings not found with new action; try old one");
3173            }
3174            intent.setAction(Intent.ACTION_EPHEMERAL_RESOLVER_SETTINGS);
3175            matches = queryIntentActivitiesInternal(intent, null, resolveFlags,
3176                    UserHandle.USER_SYSTEM);
3177        }
3178        if (matches.isEmpty()) {
3179            return null;
3180        }
3181        return matches.get(0).getComponentInfo().getComponentName();
3182    }
3183
3184    private void primeDomainVerificationsLPw(int userId) {
3185        if (DEBUG_DOMAIN_VERIFICATION) {
3186            Slog.d(TAG, "Priming domain verifications in user " + userId);
3187        }
3188
3189        SystemConfig systemConfig = SystemConfig.getInstance();
3190        ArraySet<String> packages = systemConfig.getLinkedApps();
3191
3192        for (String packageName : packages) {
3193            PackageParser.Package pkg = mPackages.get(packageName);
3194            if (pkg != null) {
3195                if (!pkg.isSystemApp()) {
3196                    Slog.w(TAG, "Non-system app '" + packageName + "' in sysconfig <app-link>");
3197                    continue;
3198                }
3199
3200                ArraySet<String> domains = null;
3201                for (PackageParser.Activity a : pkg.activities) {
3202                    for (ActivityIntentInfo filter : a.intents) {
3203                        if (hasValidDomains(filter)) {
3204                            if (domains == null) {
3205                                domains = new ArraySet<String>();
3206                            }
3207                            domains.addAll(filter.getHostsList());
3208                        }
3209                    }
3210                }
3211
3212                if (domains != null && domains.size() > 0) {
3213                    if (DEBUG_DOMAIN_VERIFICATION) {
3214                        Slog.v(TAG, "      + " + packageName);
3215                    }
3216                    // 'Undefined' in the global IntentFilterVerificationInfo, i.e. the usual
3217                    // state w.r.t. the formal app-linkage "no verification attempted" state;
3218                    // and then 'always' in the per-user state actually used for intent resolution.
3219                    final IntentFilterVerificationInfo ivi;
3220                    ivi = mSettings.createIntentFilterVerificationIfNeededLPw(packageName, domains);
3221                    ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED);
3222                    mSettings.updateIntentFilterVerificationStatusLPw(packageName,
3223                            INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS, userId);
3224                } else {
3225                    Slog.w(TAG, "Sysconfig <app-link> package '" + packageName
3226                            + "' does not handle web links");
3227                }
3228            } else {
3229                Slog.w(TAG, "Unknown package " + packageName + " in sysconfig <app-link>");
3230            }
3231        }
3232
3233        scheduleWritePackageRestrictionsLocked(userId);
3234        scheduleWriteSettingsLocked();
3235    }
3236
3237    private void applyFactoryDefaultBrowserLPw(int userId) {
3238        // The default browser app's package name is stored in a string resource,
3239        // with a product-specific overlay used for vendor customization.
3240        String browserPkg = mContext.getResources().getString(
3241                com.android.internal.R.string.default_browser);
3242        if (!TextUtils.isEmpty(browserPkg)) {
3243            // non-empty string => required to be a known package
3244            PackageSetting ps = mSettings.mPackages.get(browserPkg);
3245            if (ps == null) {
3246                Slog.e(TAG, "Product default browser app does not exist: " + browserPkg);
3247                browserPkg = null;
3248            } else {
3249                mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId);
3250            }
3251        }
3252
3253        // Nothing valid explicitly set? Make the factory-installed browser the explicit
3254        // default.  If there's more than one, just leave everything alone.
3255        if (browserPkg == null) {
3256            calculateDefaultBrowserLPw(userId);
3257        }
3258    }
3259
3260    private void calculateDefaultBrowserLPw(int userId) {
3261        List<String> allBrowsers = resolveAllBrowserApps(userId);
3262        final String browserPkg = (allBrowsers.size() == 1) ? allBrowsers.get(0) : null;
3263        mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId);
3264    }
3265
3266    private List<String> resolveAllBrowserApps(int userId) {
3267        // Resolve the canonical browser intent and check that the handleAllWebDataURI boolean is set
3268        List<ResolveInfo> list = queryIntentActivitiesInternal(sBrowserIntent, null,
3269                PackageManager.MATCH_ALL, userId);
3270
3271        final int count = list.size();
3272        List<String> result = new ArrayList<String>(count);
3273        for (int i=0; i<count; i++) {
3274            ResolveInfo info = list.get(i);
3275            if (info.activityInfo == null
3276                    || !info.handleAllWebDataURI
3277                    || (info.activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0
3278                    || result.contains(info.activityInfo.packageName)) {
3279                continue;
3280            }
3281            result.add(info.activityInfo.packageName);
3282        }
3283
3284        return result;
3285    }
3286
3287    private boolean packageIsBrowser(String packageName, int userId) {
3288        List<ResolveInfo> list = queryIntentActivitiesInternal(sBrowserIntent, null,
3289                PackageManager.MATCH_ALL, userId);
3290        final int N = list.size();
3291        for (int i = 0; i < N; i++) {
3292            ResolveInfo info = list.get(i);
3293            if (packageName.equals(info.activityInfo.packageName)) {
3294                return true;
3295            }
3296        }
3297        return false;
3298    }
3299
3300    private void checkDefaultBrowser() {
3301        final int myUserId = UserHandle.myUserId();
3302        final String packageName = getDefaultBrowserPackageName(myUserId);
3303        if (packageName != null) {
3304            PackageInfo info = getPackageInfo(packageName, 0, myUserId);
3305            if (info == null) {
3306                Slog.w(TAG, "Default browser no longer installed: " + packageName);
3307                synchronized (mPackages) {
3308                    applyFactoryDefaultBrowserLPw(myUserId);    // leaves ambiguous when > 1
3309                }
3310            }
3311        }
3312    }
3313
3314    @Override
3315    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
3316            throws RemoteException {
3317        try {
3318            return super.onTransact(code, data, reply, flags);
3319        } catch (RuntimeException e) {
3320            if (!(e instanceof SecurityException) && !(e instanceof IllegalArgumentException)) {
3321                Slog.wtf(TAG, "Package Manager Crash", e);
3322            }
3323            throw e;
3324        }
3325    }
3326
3327    static int[] appendInts(int[] cur, int[] add) {
3328        if (add == null) return cur;
3329        if (cur == null) return add;
3330        final int N = add.length;
3331        for (int i=0; i<N; i++) {
3332            cur = appendInt(cur, add[i]);
3333        }
3334        return cur;
3335    }
3336
3337    private PackageInfo generatePackageInfo(PackageSetting ps, int flags, int userId) {
3338        if (!sUserManager.exists(userId)) return null;
3339        if (ps == null) {
3340            return null;
3341        }
3342        final PackageParser.Package p = ps.pkg;
3343        if (p == null) {
3344            return null;
3345        }
3346        // Filter out ephemeral app metadata:
3347        //   * The system/shell/root can see metadata for any app
3348        //   * An installed app can see metadata for 1) other installed apps
3349        //     and 2) ephemeral apps that have explicitly interacted with it
3350        //   * Ephemeral apps can only see their own data and exposed installed apps
3351        //   * Holding a signature permission allows seeing instant apps
3352        final int callingAppId = UserHandle.getAppId(Binder.getCallingUid());
3353        if (callingAppId != Process.SYSTEM_UID
3354                && callingAppId != Process.SHELL_UID
3355                && callingAppId != Process.ROOT_UID
3356                && checkUidPermission(Manifest.permission.ACCESS_INSTANT_APPS,
3357                        Binder.getCallingUid()) != PackageManager.PERMISSION_GRANTED) {
3358            final String instantAppPackageName = getInstantAppPackageName(Binder.getCallingUid());
3359            if (instantAppPackageName != null) {
3360                // ephemeral apps can only get information on themselves or
3361                // installed apps that are exposed.
3362                if (!instantAppPackageName.equals(p.packageName)
3363                        && (ps.getInstantApp(userId) || !p.visibleToInstantApps)) {
3364                    return null;
3365                }
3366            } else {
3367                if (ps.getInstantApp(userId)) {
3368                    // only get access to the ephemeral app if we've been granted access
3369                    if (!mInstantAppRegistry.isInstantAccessGranted(
3370                            userId, callingAppId, ps.appId)) {
3371                        return null;
3372                    }
3373                }
3374            }
3375        }
3376
3377        final PermissionsState permissionsState = ps.getPermissionsState();
3378
3379        // Compute GIDs only if requested
3380        final int[] gids = (flags & PackageManager.GET_GIDS) == 0
3381                ? EMPTY_INT_ARRAY : permissionsState.computeGids(userId);
3382        // Compute granted permissions only if package has requested permissions
3383        final Set<String> permissions = ArrayUtils.isEmpty(p.requestedPermissions)
3384                ? Collections.<String>emptySet() : permissionsState.getPermissions(userId);
3385        final PackageUserState state = ps.readUserState(userId);
3386
3387        if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0
3388                && ps.isSystem()) {
3389            flags |= MATCH_ANY_USER;
3390        }
3391
3392        PackageInfo packageInfo = PackageParser.generatePackageInfo(p, gids, flags,
3393                ps.firstInstallTime, ps.lastUpdateTime, permissions, state, userId);
3394
3395        if (packageInfo == null) {
3396            return null;
3397        }
3398
3399        rebaseEnabledOverlays(packageInfo.applicationInfo, userId);
3400
3401        packageInfo.packageName = packageInfo.applicationInfo.packageName =
3402                resolveExternalPackageNameLPr(p);
3403
3404        return packageInfo;
3405    }
3406
3407    @Override
3408    public void checkPackageStartable(String packageName, int userId) {
3409        final boolean userKeyUnlocked = StorageManager.isUserKeyUnlocked(userId);
3410
3411        synchronized (mPackages) {
3412            final PackageSetting ps = mSettings.mPackages.get(packageName);
3413            if (ps == null) {
3414                throw new SecurityException("Package " + packageName + " was not found!");
3415            }
3416
3417            if (!ps.getInstalled(userId)) {
3418                throw new SecurityException(
3419                        "Package " + packageName + " was not installed for user " + userId + "!");
3420            }
3421
3422            if (mSafeMode && !ps.isSystem()) {
3423                throw new SecurityException("Package " + packageName + " not a system app!");
3424            }
3425
3426            if (mFrozenPackages.contains(packageName)) {
3427                throw new SecurityException("Package " + packageName + " is currently frozen!");
3428            }
3429
3430            if (!userKeyUnlocked && !(ps.pkg.applicationInfo.isDirectBootAware()
3431                    || ps.pkg.applicationInfo.isPartiallyDirectBootAware())) {
3432                throw new SecurityException("Package " + packageName + " is not encryption aware!");
3433            }
3434        }
3435    }
3436
3437    @Override
3438    public boolean isPackageAvailable(String packageName, int userId) {
3439        if (!sUserManager.exists(userId)) return false;
3440        enforceCrossUserPermission(Binder.getCallingUid(), userId,
3441                false /* requireFullPermission */, false /* checkShell */, "is package available");
3442        synchronized (mPackages) {
3443            PackageParser.Package p = mPackages.get(packageName);
3444            if (p != null) {
3445                final PackageSetting ps = (PackageSetting) p.mExtras;
3446                if (ps != null) {
3447                    final PackageUserState state = ps.readUserState(userId);
3448                    if (state != null) {
3449                        return PackageParser.isAvailable(state);
3450                    }
3451                }
3452            }
3453        }
3454        return false;
3455    }
3456
3457    @Override
3458    public PackageInfo getPackageInfo(String packageName, int flags, int userId) {
3459        return getPackageInfoInternal(packageName, PackageManager.VERSION_CODE_HIGHEST,
3460                flags, userId);
3461    }
3462
3463    @Override
3464    public PackageInfo getPackageInfoVersioned(VersionedPackage versionedPackage,
3465            int flags, int userId) {
3466        return getPackageInfoInternal(versionedPackage.getPackageName(),
3467                // TODO: We will change version code to long, so in the new API it is long
3468                (int) versionedPackage.getVersionCode(), flags, userId);
3469    }
3470
3471    private PackageInfo getPackageInfoInternal(String packageName, int versionCode,
3472            int flags, int userId) {
3473        if (!sUserManager.exists(userId)) return null;
3474        flags = updateFlagsForPackage(flags, userId, packageName);
3475        enforceCrossUserPermission(Binder.getCallingUid(), userId,
3476                false /* requireFullPermission */, false /* checkShell */, "get package info");
3477
3478        // reader
3479        synchronized (mPackages) {
3480            // Normalize package name to handle renamed packages and static libs
3481            packageName = resolveInternalPackageNameLPr(packageName, versionCode);
3482
3483            final boolean matchFactoryOnly = (flags & MATCH_FACTORY_ONLY) != 0;
3484            if (matchFactoryOnly) {
3485                final PackageSetting ps = mSettings.getDisabledSystemPkgLPr(packageName);
3486                if (ps != null) {
3487                    if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId)) {
3488                        return null;
3489                    }
3490                    return generatePackageInfo(ps, flags, userId);
3491                }
3492            }
3493
3494            PackageParser.Package p = mPackages.get(packageName);
3495            if (matchFactoryOnly && p != null && !isSystemApp(p)) {
3496                return null;
3497            }
3498            if (DEBUG_PACKAGE_INFO)
3499                Log.v(TAG, "getPackageInfo " + packageName + ": " + p);
3500            if (p != null) {
3501                if (filterSharedLibPackageLPr((PackageSetting) p.mExtras,
3502                        Binder.getCallingUid(), userId)) {
3503                    return null;
3504                }
3505                return generatePackageInfo((PackageSetting)p.mExtras, flags, userId);
3506            }
3507            if (!matchFactoryOnly && (flags & MATCH_KNOWN_PACKAGES) != 0) {
3508                final PackageSetting ps = mSettings.mPackages.get(packageName);
3509                if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId)) {
3510                    return null;
3511                }
3512                return generatePackageInfo(ps, flags, userId);
3513            }
3514        }
3515        return null;
3516    }
3517
3518
3519    private boolean filterSharedLibPackageLPr(@Nullable PackageSetting ps, int uid, int userId) {
3520        // System/shell/root get to see all static libs
3521        final int appId = UserHandle.getAppId(uid);
3522        if (appId == Process.SYSTEM_UID || appId == Process.SHELL_UID
3523                || appId == Process.ROOT_UID) {
3524            return false;
3525        }
3526
3527        // No package means no static lib as it is always on internal storage
3528        if (ps == null || ps.pkg == null || !ps.pkg.applicationInfo.isStaticSharedLibrary()) {
3529            return false;
3530        }
3531
3532        final SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(ps.pkg.staticSharedLibName,
3533                ps.pkg.staticSharedLibVersion);
3534        if (libEntry == null) {
3535            return false;
3536        }
3537
3538        final int resolvedUid = UserHandle.getUid(userId, UserHandle.getAppId(uid));
3539        final String[] uidPackageNames = getPackagesForUid(resolvedUid);
3540        if (uidPackageNames == null) {
3541            return true;
3542        }
3543
3544        for (String uidPackageName : uidPackageNames) {
3545            if (ps.name.equals(uidPackageName)) {
3546                return false;
3547            }
3548            PackageSetting uidPs = mSettings.getPackageLPr(uidPackageName);
3549            if (uidPs != null) {
3550                final int index = ArrayUtils.indexOf(uidPs.usesStaticLibraries,
3551                        libEntry.info.getName());
3552                if (index < 0) {
3553                    continue;
3554                }
3555                if (uidPs.pkg.usesStaticLibrariesVersions[index] == libEntry.info.getVersion()) {
3556                    return false;
3557                }
3558            }
3559        }
3560        return true;
3561    }
3562
3563    @Override
3564    public String[] currentToCanonicalPackageNames(String[] names) {
3565        String[] out = new String[names.length];
3566        // reader
3567        synchronized (mPackages) {
3568            for (int i=names.length-1; i>=0; i--) {
3569                PackageSetting ps = mSettings.mPackages.get(names[i]);
3570                out[i] = ps != null && ps.realName != null ? ps.realName : names[i];
3571            }
3572        }
3573        return out;
3574    }
3575
3576    @Override
3577    public String[] canonicalToCurrentPackageNames(String[] names) {
3578        String[] out = new String[names.length];
3579        // reader
3580        synchronized (mPackages) {
3581            for (int i=names.length-1; i>=0; i--) {
3582                String cur = mSettings.getRenamedPackageLPr(names[i]);
3583                out[i] = cur != null ? cur : names[i];
3584            }
3585        }
3586        return out;
3587    }
3588
3589    @Override
3590    public int getPackageUid(String packageName, int flags, int userId) {
3591        if (!sUserManager.exists(userId)) return -1;
3592        flags = updateFlagsForPackage(flags, userId, packageName);
3593        enforceCrossUserPermission(Binder.getCallingUid(), userId,
3594                false /* requireFullPermission */, false /* checkShell */, "get package uid");
3595
3596        // reader
3597        synchronized (mPackages) {
3598            final PackageParser.Package p = mPackages.get(packageName);
3599            if (p != null && p.isMatch(flags)) {
3600                return UserHandle.getUid(userId, p.applicationInfo.uid);
3601            }
3602            if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
3603                final PackageSetting ps = mSettings.mPackages.get(packageName);
3604                if (ps != null && ps.isMatch(flags)) {
3605                    return UserHandle.getUid(userId, ps.appId);
3606                }
3607            }
3608        }
3609
3610        return -1;
3611    }
3612
3613    @Override
3614    public int[] getPackageGids(String packageName, int flags, int userId) {
3615        if (!sUserManager.exists(userId)) return null;
3616        flags = updateFlagsForPackage(flags, userId, packageName);
3617        enforceCrossUserPermission(Binder.getCallingUid(), userId,
3618                false /* requireFullPermission */, false /* checkShell */,
3619                "getPackageGids");
3620
3621        // reader
3622        synchronized (mPackages) {
3623            final PackageParser.Package p = mPackages.get(packageName);
3624            if (p != null && p.isMatch(flags)) {
3625                PackageSetting ps = (PackageSetting) p.mExtras;
3626                // TODO: Shouldn't this be checking for package installed state for userId and
3627                // return null?
3628                return ps.getPermissionsState().computeGids(userId);
3629            }
3630            if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
3631                final PackageSetting ps = mSettings.mPackages.get(packageName);
3632                if (ps != null && ps.isMatch(flags)) {
3633                    return ps.getPermissionsState().computeGids(userId);
3634                }
3635            }
3636        }
3637
3638        return null;
3639    }
3640
3641    static PermissionInfo generatePermissionInfo(BasePermission bp, int flags) {
3642        if (bp.perm != null) {
3643            return PackageParser.generatePermissionInfo(bp.perm, flags);
3644        }
3645        PermissionInfo pi = new PermissionInfo();
3646        pi.name = bp.name;
3647        pi.packageName = bp.sourcePackage;
3648        pi.nonLocalizedLabel = bp.name;
3649        pi.protectionLevel = bp.protectionLevel;
3650        return pi;
3651    }
3652
3653    @Override
3654    public PermissionInfo getPermissionInfo(String name, int flags) {
3655        // reader
3656        synchronized (mPackages) {
3657            final BasePermission p = mSettings.mPermissions.get(name);
3658            if (p != null) {
3659                return generatePermissionInfo(p, flags);
3660            }
3661            return null;
3662        }
3663    }
3664
3665    @Override
3666    public @Nullable ParceledListSlice<PermissionInfo> queryPermissionsByGroup(String group,
3667            int flags) {
3668        // reader
3669        synchronized (mPackages) {
3670            if (group != null && !mPermissionGroups.containsKey(group)) {
3671                // This is thrown as NameNotFoundException
3672                return null;
3673            }
3674
3675            ArrayList<PermissionInfo> out = new ArrayList<PermissionInfo>(10);
3676            for (BasePermission p : mSettings.mPermissions.values()) {
3677                if (group == null) {
3678                    if (p.perm == null || p.perm.info.group == null) {
3679                        out.add(generatePermissionInfo(p, flags));
3680                    }
3681                } else {
3682                    if (p.perm != null && group.equals(p.perm.info.group)) {
3683                        out.add(PackageParser.generatePermissionInfo(p.perm, flags));
3684                    }
3685                }
3686            }
3687            return new ParceledListSlice<>(out);
3688        }
3689    }
3690
3691    @Override
3692    public PermissionGroupInfo getPermissionGroupInfo(String name, int flags) {
3693        // reader
3694        synchronized (mPackages) {
3695            return PackageParser.generatePermissionGroupInfo(
3696                    mPermissionGroups.get(name), flags);
3697        }
3698    }
3699
3700    @Override
3701    public @NonNull ParceledListSlice<PermissionGroupInfo> getAllPermissionGroups(int flags) {
3702        // reader
3703        synchronized (mPackages) {
3704            final int N = mPermissionGroups.size();
3705            ArrayList<PermissionGroupInfo> out
3706                    = new ArrayList<PermissionGroupInfo>(N);
3707            for (PackageParser.PermissionGroup pg : mPermissionGroups.values()) {
3708                out.add(PackageParser.generatePermissionGroupInfo(pg, flags));
3709            }
3710            return new ParceledListSlice<>(out);
3711        }
3712    }
3713
3714    private ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName, int flags,
3715            int uid, int userId) {
3716        if (!sUserManager.exists(userId)) return null;
3717        PackageSetting ps = mSettings.mPackages.get(packageName);
3718        if (ps != null) {
3719            if (filterSharedLibPackageLPr(ps, uid, userId)) {
3720                return null;
3721            }
3722            if (ps.pkg == null) {
3723                final PackageInfo pInfo = generatePackageInfo(ps, flags, userId);
3724                if (pInfo != null) {
3725                    return pInfo.applicationInfo;
3726                }
3727                return null;
3728            }
3729            ApplicationInfo ai = PackageParser.generateApplicationInfo(ps.pkg, flags,
3730                    ps.readUserState(userId), userId);
3731            if (ai != null) {
3732                rebaseEnabledOverlays(ai, userId);
3733                ai.packageName = resolveExternalPackageNameLPr(ps.pkg);
3734            }
3735            return ai;
3736        }
3737        return null;
3738    }
3739
3740    @Override
3741    public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) {
3742        if (!sUserManager.exists(userId)) return null;
3743        flags = updateFlagsForApplication(flags, userId, packageName);
3744        enforceCrossUserPermission(Binder.getCallingUid(), userId,
3745                false /* requireFullPermission */, false /* checkShell */, "get application info");
3746
3747        // writer
3748        synchronized (mPackages) {
3749            // Normalize package name to handle renamed packages and static libs
3750            packageName = resolveInternalPackageNameLPr(packageName,
3751                    PackageManager.VERSION_CODE_HIGHEST);
3752
3753            PackageParser.Package p = mPackages.get(packageName);
3754            if (DEBUG_PACKAGE_INFO) Log.v(
3755                    TAG, "getApplicationInfo " + packageName
3756                    + ": " + p);
3757            if (p != null) {
3758                PackageSetting ps = mSettings.mPackages.get(packageName);
3759                if (ps == null) return null;
3760                if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId)) {
3761                    return null;
3762                }
3763                // Note: isEnabledLP() does not apply here - always return info
3764                ApplicationInfo ai = PackageParser.generateApplicationInfo(
3765                        p, flags, ps.readUserState(userId), userId);
3766                if (ai != null) {
3767                    rebaseEnabledOverlays(ai, userId);
3768                    ai.packageName = resolveExternalPackageNameLPr(p);
3769                }
3770                return ai;
3771            }
3772            if ("android".equals(packageName)||"system".equals(packageName)) {
3773                return mAndroidApplication;
3774            }
3775            if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
3776                // Already generates the external package name
3777                return generateApplicationInfoFromSettingsLPw(packageName,
3778                        Binder.getCallingUid(), flags, userId);
3779            }
3780        }
3781        return null;
3782    }
3783
3784    private void rebaseEnabledOverlays(@NonNull ApplicationInfo ai, int userId) {
3785        List<String> paths = new ArrayList<>();
3786        ArrayMap<String, ArrayList<String>> userSpecificOverlays =
3787            mEnabledOverlayPaths.get(userId);
3788        if (userSpecificOverlays != null) {
3789            if (!"android".equals(ai.packageName)) {
3790                ArrayList<String> frameworkOverlays = userSpecificOverlays.get("android");
3791                if (frameworkOverlays != null) {
3792                    paths.addAll(frameworkOverlays);
3793                }
3794            }
3795
3796            ArrayList<String> appOverlays = userSpecificOverlays.get(ai.packageName);
3797            if (appOverlays != null) {
3798                paths.addAll(appOverlays);
3799            }
3800        }
3801        ai.resourceDirs = paths.size() > 0 ? paths.toArray(new String[paths.size()]) : null;
3802    }
3803
3804    private String normalizePackageNameLPr(String packageName) {
3805        String normalizedPackageName = mSettings.getRenamedPackageLPr(packageName);
3806        return normalizedPackageName != null ? normalizedPackageName : packageName;
3807    }
3808
3809    @Override
3810    public void deletePreloadsFileCache() {
3811        if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.SYSTEM_UID)) {
3812            throw new SecurityException("Only system or settings may call deletePreloadsFileCache");
3813        }
3814        File dir = Environment.getDataPreloadsFileCacheDirectory();
3815        Slog.i(TAG, "Deleting preloaded file cache " + dir);
3816        FileUtils.deleteContents(dir);
3817    }
3818
3819    @Override
3820    public void freeStorageAndNotify(final String volumeUuid, final long freeStorageSize,
3821            final IPackageDataObserver observer) {
3822        mContext.enforceCallingOrSelfPermission(
3823                android.Manifest.permission.CLEAR_APP_CACHE, null);
3824        mHandler.post(() -> {
3825            boolean success = false;
3826            try {
3827                freeStorage(volumeUuid, freeStorageSize, 0);
3828                success = true;
3829            } catch (IOException e) {
3830                Slog.w(TAG, e);
3831            }
3832            if (observer != null) {
3833                try {
3834                    observer.onRemoveCompleted(null, success);
3835                } catch (RemoteException e) {
3836                    Slog.w(TAG, e);
3837                }
3838            }
3839        });
3840    }
3841
3842    @Override
3843    public void freeStorage(final String volumeUuid, final long freeStorageSize,
3844            final IntentSender pi) {
3845        mContext.enforceCallingOrSelfPermission(
3846                android.Manifest.permission.CLEAR_APP_CACHE, TAG);
3847        mHandler.post(() -> {
3848            boolean success = false;
3849            try {
3850                freeStorage(volumeUuid, freeStorageSize, 0);
3851                success = true;
3852            } catch (IOException e) {
3853                Slog.w(TAG, e);
3854            }
3855            if (pi != null) {
3856                try {
3857                    pi.sendIntent(null, success ? 1 : 0, null, null, null);
3858                } catch (SendIntentException e) {
3859                    Slog.w(TAG, e);
3860                }
3861            }
3862        });
3863    }
3864
3865    /**
3866     * Blocking call to clear various types of cached data across the system
3867     * until the requested bytes are available.
3868     */
3869    public void freeStorage(String volumeUuid, long bytes, int storageFlags) throws IOException {
3870        final StorageManager storage = mContext.getSystemService(StorageManager.class);
3871        final File file = storage.findPathForUuid(volumeUuid);
3872        if (file.getUsableSpace() >= bytes) return;
3873
3874        if (ENABLE_FREE_CACHE_V2) {
3875            final boolean aggressive = (storageFlags
3876                    & StorageManager.FLAG_ALLOCATE_AGGRESSIVE) != 0;
3877            final boolean internalVolume = Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL,
3878                    volumeUuid);
3879
3880            // 1. Pre-flight to determine if we have any chance to succeed
3881            // 2. Consider preloaded data (after 1w honeymoon, unless aggressive)
3882            if (internalVolume && (aggressive || SystemProperties
3883                    .getBoolean("persist.sys.preloads.file_cache_expired", false))) {
3884                deletePreloadsFileCache();
3885                if (file.getUsableSpace() >= bytes) return;
3886            }
3887
3888            // 3. Consider parsed APK data (aggressive only)
3889            if (internalVolume && aggressive) {
3890                FileUtils.deleteContents(mCacheDir);
3891                if (file.getUsableSpace() >= bytes) return;
3892            }
3893
3894            // 4. Consider cached app data (above quotas)
3895            try {
3896                mInstaller.freeCache(volumeUuid, bytes, Installer.FLAG_FREE_CACHE_V2);
3897            } catch (InstallerException ignored) {
3898            }
3899            if (file.getUsableSpace() >= bytes) return;
3900
3901            // 5. Consider shared libraries with refcount=0 and age>2h
3902            // 6. Consider dexopt output (aggressive only)
3903            // 7. Consider ephemeral apps not used in last week
3904
3905            // 8. Consider cached app data (below quotas)
3906            try {
3907                mInstaller.freeCache(volumeUuid, bytes, Installer.FLAG_FREE_CACHE_V2
3908                        | Installer.FLAG_FREE_CACHE_V2_DEFY_QUOTA);
3909            } catch (InstallerException ignored) {
3910            }
3911            if (file.getUsableSpace() >= bytes) return;
3912
3913            // 9. Consider DropBox entries
3914            // 10. Consider ephemeral cookies
3915
3916        } else {
3917            try {
3918                mInstaller.freeCache(volumeUuid, bytes, 0);
3919            } catch (InstallerException ignored) {
3920            }
3921            if (file.getUsableSpace() >= bytes) return;
3922        }
3923
3924        throw new IOException("Failed to free " + bytes + " on storage device at " + file);
3925    }
3926
3927    /**
3928     * Update given flags based on encryption status of current user.
3929     */
3930    private int updateFlags(int flags, int userId) {
3931        if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
3932                | PackageManager.MATCH_DIRECT_BOOT_AWARE)) != 0) {
3933            // Caller expressed an explicit opinion about what encryption
3934            // aware/unaware components they want to see, so fall through and
3935            // give them what they want
3936        } else {
3937            // Caller expressed no opinion, so match based on user state
3938            if (getUserManagerInternal().isUserUnlockingOrUnlocked(userId)) {
3939                flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE;
3940            } else {
3941                flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE;
3942            }
3943        }
3944        return flags;
3945    }
3946
3947    private UserManagerInternal getUserManagerInternal() {
3948        if (mUserManagerInternal == null) {
3949            mUserManagerInternal = LocalServices.getService(UserManagerInternal.class);
3950        }
3951        return mUserManagerInternal;
3952    }
3953
3954    private DeviceIdleController.LocalService getDeviceIdleController() {
3955        if (mDeviceIdleController == null) {
3956            mDeviceIdleController =
3957                    LocalServices.getService(DeviceIdleController.LocalService.class);
3958        }
3959        return mDeviceIdleController;
3960    }
3961
3962    /**
3963     * Update given flags when being used to request {@link PackageInfo}.
3964     */
3965    private int updateFlagsForPackage(int flags, int userId, Object cookie) {
3966        final boolean isCallerSystemUser = UserHandle.getCallingUserId() == UserHandle.USER_SYSTEM;
3967        boolean triaged = true;
3968        if ((flags & (PackageManager.GET_ACTIVITIES | PackageManager.GET_RECEIVERS
3969                | PackageManager.GET_SERVICES | PackageManager.GET_PROVIDERS)) != 0) {
3970            // Caller is asking for component details, so they'd better be
3971            // asking for specific encryption matching behavior, or be triaged
3972            if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
3973                    | PackageManager.MATCH_DIRECT_BOOT_AWARE
3974                    | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
3975                triaged = false;
3976            }
3977        }
3978        if ((flags & (PackageManager.MATCH_UNINSTALLED_PACKAGES
3979                | PackageManager.MATCH_SYSTEM_ONLY
3980                | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
3981            triaged = false;
3982        }
3983        if ((flags & PackageManager.MATCH_ANY_USER) != 0) {
3984            enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false,
3985                    "MATCH_ANY_USER flag requires INTERACT_ACROSS_USERS permission at "
3986                    + Debug.getCallers(5));
3987        } else if ((flags & PackageManager.MATCH_UNINSTALLED_PACKAGES) != 0 && isCallerSystemUser
3988                && sUserManager.hasManagedProfile(UserHandle.USER_SYSTEM)) {
3989            // If the caller wants all packages and has a restricted profile associated with it,
3990            // then match all users. This is to make sure that launchers that need to access work
3991            // profile apps don't start breaking. TODO: Remove this hack when launchers stop using
3992            // MATCH_UNINSTALLED_PACKAGES to query apps in other profiles. b/31000380
3993            flags |= PackageManager.MATCH_ANY_USER;
3994        }
3995        if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) {
3996            Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie
3997                    + " with flags 0x" + Integer.toHexString(flags), new Throwable());
3998        }
3999        return updateFlags(flags, userId);
4000    }
4001
4002    /**
4003     * Update given flags when being used to request {@link ApplicationInfo}.
4004     */
4005    private int updateFlagsForApplication(int flags, int userId, Object cookie) {
4006        return updateFlagsForPackage(flags, userId, cookie);
4007    }
4008
4009    /**
4010     * Update given flags when being used to request {@link ComponentInfo}.
4011     */
4012    private int updateFlagsForComponent(int flags, int userId, Object cookie) {
4013        if (cookie instanceof Intent) {
4014            if ((((Intent) cookie).getFlags() & Intent.FLAG_DEBUG_TRIAGED_MISSING) != 0) {
4015                flags |= PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
4016            }
4017        }
4018
4019        boolean triaged = true;
4020        // Caller is asking for component details, so they'd better be
4021        // asking for specific encryption matching behavior, or be triaged
4022        if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
4023                | PackageManager.MATCH_DIRECT_BOOT_AWARE
4024                | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
4025            triaged = false;
4026        }
4027        if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) {
4028            Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie
4029                    + " with flags 0x" + Integer.toHexString(flags), new Throwable());
4030        }
4031
4032        return updateFlags(flags, userId);
4033    }
4034
4035    /**
4036     * Update given intent when being used to request {@link ResolveInfo}.
4037     */
4038    private Intent updateIntentForResolve(Intent intent) {
4039        if (intent.getSelector() != null) {
4040            intent = intent.getSelector();
4041        }
4042        if (DEBUG_PREFERRED) {
4043            intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION);
4044        }
4045        return intent;
4046    }
4047
4048    /**
4049     * Update given flags when being used to request {@link ResolveInfo}.
4050     * <p>Instant apps are resolved specially, depending upon context. Minimally,
4051     * {@code}flags{@code} must have the {@link PackageManager#MATCH_INSTANT}
4052     * flag set. However, this flag is only honoured in three circumstances:
4053     * <ul>
4054     * <li>when called from a system process</li>
4055     * <li>when the caller holds the permission {@code android.permission.ACCESS_INSTANT_APPS}</li>
4056     * <li>when resolution occurs to start an activity with a {@code android.intent.action.VIEW}
4057     * action and a {@code android.intent.category.BROWSABLE} category</li>
4058     * </ul>
4059     */
4060    int updateFlagsForResolve(int flags, int userId, Intent intent, int callingUid,
4061            boolean includeInstantApps) {
4062        // Safe mode means we shouldn't match any third-party components
4063        if (mSafeMode) {
4064            flags |= PackageManager.MATCH_SYSTEM_ONLY;
4065        }
4066        if (getInstantAppPackageName(callingUid) != null) {
4067            // But, ephemeral apps see both ephemeral and exposed, non-ephemeral components
4068            flags |= PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY;
4069            flags |= PackageManager.MATCH_INSTANT;
4070        } else {
4071            // Otherwise, prevent leaking ephemeral components
4072            final boolean isSpecialProcess =
4073                    callingUid == Process.SYSTEM_UID
4074                    || callingUid == Process.SHELL_UID
4075                    || callingUid == 0;
4076            final boolean allowMatchInstant =
4077                    (includeInstantApps
4078                            && Intent.ACTION_VIEW.equals(intent.getAction())
4079                            && intent.hasCategory(Intent.CATEGORY_BROWSABLE)
4080                            && hasWebURI(intent))
4081                    || isSpecialProcess
4082                    || mContext.checkCallingOrSelfPermission(
4083                            android.Manifest.permission.ACCESS_INSTANT_APPS) == PERMISSION_GRANTED;
4084            flags &= ~PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY;
4085            if (!allowMatchInstant) {
4086                flags &= ~PackageManager.MATCH_INSTANT;
4087            }
4088        }
4089        return updateFlagsForComponent(flags, userId, intent /*cookie*/);
4090    }
4091
4092    private ActivityInfo generateActivityInfo(ActivityInfo ai, int flags, PackageUserState state,
4093            int userId) {
4094        ActivityInfo ret = PackageParser.generateActivityInfo(ai, flags, state, userId);
4095        if (ret != null) {
4096            rebaseEnabledOverlays(ret.applicationInfo, userId);
4097        }
4098        return ret;
4099    }
4100
4101    private ActivityInfo generateActivityInfo(PackageParser.Activity a, int flags,
4102            PackageUserState state, int userId) {
4103        ActivityInfo ai = PackageParser.generateActivityInfo(a, flags, state, userId);
4104        if (ai != null) {
4105            rebaseEnabledOverlays(ai.applicationInfo, userId);
4106        }
4107        return ai;
4108    }
4109
4110    @Override
4111    public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) {
4112        if (!sUserManager.exists(userId)) return null;
4113        flags = updateFlagsForComponent(flags, userId, component);
4114        enforceCrossUserPermission(Binder.getCallingUid(), userId,
4115                false /* requireFullPermission */, false /* checkShell */, "get activity info");
4116        synchronized (mPackages) {
4117            PackageParser.Activity a = mActivities.mActivities.get(component);
4118
4119            if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a);
4120            if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) {
4121                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
4122                if (ps == null) return null;
4123                return generateActivityInfo(a, flags, ps.readUserState(userId), userId);
4124            }
4125            if (mResolveComponentName.equals(component)) {
4126                return generateActivityInfo(mResolveActivity, flags, new PackageUserState(),
4127                        userId);
4128            }
4129        }
4130        return null;
4131    }
4132
4133    @Override
4134    public boolean activitySupportsIntent(ComponentName component, Intent intent,
4135            String resolvedType) {
4136        synchronized (mPackages) {
4137            if (component.equals(mResolveComponentName)) {
4138                // The resolver supports EVERYTHING!
4139                return true;
4140            }
4141            PackageParser.Activity a = mActivities.mActivities.get(component);
4142            if (a == null) {
4143                return false;
4144            }
4145            for (int i=0; i<a.intents.size(); i++) {
4146                if (a.intents.get(i).match(intent.getAction(), resolvedType, intent.getScheme(),
4147                        intent.getData(), intent.getCategories(), TAG) >= 0) {
4148                    return true;
4149                }
4150            }
4151            return false;
4152        }
4153    }
4154
4155    @Override
4156    public ActivityInfo getReceiverInfo(ComponentName component, int flags, int userId) {
4157        if (!sUserManager.exists(userId)) return null;
4158        flags = updateFlagsForComponent(flags, userId, component);
4159        enforceCrossUserPermission(Binder.getCallingUid(), userId,
4160                false /* requireFullPermission */, false /* checkShell */, "get receiver info");
4161        synchronized (mPackages) {
4162            PackageParser.Activity a = mReceivers.mActivities.get(component);
4163            if (DEBUG_PACKAGE_INFO) Log.v(
4164                TAG, "getReceiverInfo " + component + ": " + a);
4165            if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) {
4166                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
4167                if (ps == null) return null;
4168                return generateActivityInfo(a, flags, ps.readUserState(userId), userId);
4169            }
4170        }
4171        return null;
4172    }
4173
4174    @Override
4175    public ParceledListSlice<SharedLibraryInfo> getSharedLibraries(int flags, int userId) {
4176        if (!sUserManager.exists(userId)) return null;
4177        Preconditions.checkArgumentNonnegative(userId, "userId must be >= 0");
4178
4179        flags = updateFlagsForPackage(flags, userId, null);
4180
4181        final boolean canSeeStaticLibraries =
4182                mContext.checkCallingOrSelfPermission(INSTALL_PACKAGES)
4183                        == PERMISSION_GRANTED
4184                || mContext.checkCallingOrSelfPermission(DELETE_PACKAGES)
4185                        == PERMISSION_GRANTED
4186                || mContext.checkCallingOrSelfPermission(REQUEST_INSTALL_PACKAGES)
4187                        == PERMISSION_GRANTED
4188                || mContext.checkCallingOrSelfPermission(REQUEST_DELETE_PACKAGES)
4189                        == PERMISSION_GRANTED;
4190
4191        synchronized (mPackages) {
4192            List<SharedLibraryInfo> result = null;
4193
4194            final int libCount = mSharedLibraries.size();
4195            for (int i = 0; i < libCount; i++) {
4196                SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.valueAt(i);
4197                if (versionedLib == null) {
4198                    continue;
4199                }
4200
4201                final int versionCount = versionedLib.size();
4202                for (int j = 0; j < versionCount; j++) {
4203                    SharedLibraryInfo libInfo = versionedLib.valueAt(j).info;
4204                    if (!canSeeStaticLibraries && libInfo.isStatic()) {
4205                        break;
4206                    }
4207                    final long identity = Binder.clearCallingIdentity();
4208                    try {
4209                        // TODO: We will change version code to long, so in the new API it is long
4210                        PackageInfo packageInfo = getPackageInfoVersioned(
4211                                libInfo.getDeclaringPackage(), flags, userId);
4212                        if (packageInfo == null) {
4213                            continue;
4214                        }
4215                    } finally {
4216                        Binder.restoreCallingIdentity(identity);
4217                    }
4218
4219                    SharedLibraryInfo resLibInfo = new SharedLibraryInfo(libInfo.getName(),
4220                            // TODO: Remove cast for lib version once internally we support longs.
4221                            (int) libInfo.getVersion(), libInfo.getType(),
4222                            libInfo.getDeclaringPackage(), getPackagesUsingSharedLibraryLPr(libInfo,
4223                            flags, userId));
4224
4225                    if (result == null) {
4226                        result = new ArrayList<>();
4227                    }
4228                    result.add(resLibInfo);
4229                }
4230            }
4231
4232            return result != null ? new ParceledListSlice<>(result) : null;
4233        }
4234    }
4235
4236    private List<VersionedPackage> getPackagesUsingSharedLibraryLPr(
4237            SharedLibraryInfo libInfo, int flags, int userId) {
4238        List<VersionedPackage> versionedPackages = null;
4239        final int packageCount = mSettings.mPackages.size();
4240        for (int i = 0; i < packageCount; i++) {
4241            PackageSetting ps = mSettings.mPackages.valueAt(i);
4242
4243            if (ps == null) {
4244                continue;
4245            }
4246
4247            if (!ps.getUserState().get(userId).isAvailable(flags)) {
4248                continue;
4249            }
4250
4251            final String libName = libInfo.getName();
4252            if (libInfo.isStatic()) {
4253                final int libIdx = ArrayUtils.indexOf(ps.usesStaticLibraries, libName);
4254                if (libIdx < 0) {
4255                    continue;
4256                }
4257                if (ps.usesStaticLibrariesVersions[libIdx] != libInfo.getVersion()) {
4258                    continue;
4259                }
4260                if (versionedPackages == null) {
4261                    versionedPackages = new ArrayList<>();
4262                }
4263                // If the dependent is a static shared lib, use the public package name
4264                String dependentPackageName = ps.name;
4265                if (ps.pkg != null && ps.pkg.applicationInfo.isStaticSharedLibrary()) {
4266                    dependentPackageName = ps.pkg.manifestPackageName;
4267                }
4268                versionedPackages.add(new VersionedPackage(dependentPackageName, ps.versionCode));
4269            } else if (ps.pkg != null) {
4270                if (ArrayUtils.contains(ps.pkg.usesLibraries, libName)
4271                        || ArrayUtils.contains(ps.pkg.usesOptionalLibraries, libName)) {
4272                    if (versionedPackages == null) {
4273                        versionedPackages = new ArrayList<>();
4274                    }
4275                    versionedPackages.add(new VersionedPackage(ps.name, ps.versionCode));
4276                }
4277            }
4278        }
4279
4280        return versionedPackages;
4281    }
4282
4283    @Override
4284    public ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) {
4285        if (!sUserManager.exists(userId)) return null;
4286        flags = updateFlagsForComponent(flags, userId, component);
4287        enforceCrossUserPermission(Binder.getCallingUid(), userId,
4288                false /* requireFullPermission */, false /* checkShell */, "get service info");
4289        synchronized (mPackages) {
4290            PackageParser.Service s = mServices.mServices.get(component);
4291            if (DEBUG_PACKAGE_INFO) Log.v(
4292                TAG, "getServiceInfo " + component + ": " + s);
4293            if (s != null && mSettings.isEnabledAndMatchLPr(s.info, flags, userId)) {
4294                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
4295                if (ps == null) return null;
4296                ServiceInfo si = PackageParser.generateServiceInfo(s, flags,
4297                        ps.readUserState(userId), userId);
4298                if (si != null) {
4299                    rebaseEnabledOverlays(si.applicationInfo, userId);
4300                }
4301                return si;
4302            }
4303        }
4304        return null;
4305    }
4306
4307    @Override
4308    public ProviderInfo getProviderInfo(ComponentName component, int flags, int userId) {
4309        if (!sUserManager.exists(userId)) return null;
4310        flags = updateFlagsForComponent(flags, userId, component);
4311        enforceCrossUserPermission(Binder.getCallingUid(), userId,
4312                false /* requireFullPermission */, false /* checkShell */, "get provider info");
4313        synchronized (mPackages) {
4314            PackageParser.Provider p = mProviders.mProviders.get(component);
4315            if (DEBUG_PACKAGE_INFO) Log.v(
4316                TAG, "getProviderInfo " + component + ": " + p);
4317            if (p != null && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) {
4318                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
4319                if (ps == null) return null;
4320                ProviderInfo pi = PackageParser.generateProviderInfo(p, flags,
4321                        ps.readUserState(userId), userId);
4322                if (pi != null) {
4323                    rebaseEnabledOverlays(pi.applicationInfo, userId);
4324                }
4325                return pi;
4326            }
4327        }
4328        return null;
4329    }
4330
4331    @Override
4332    public String[] getSystemSharedLibraryNames() {
4333        synchronized (mPackages) {
4334            Set<String> libs = null;
4335            final int libCount = mSharedLibraries.size();
4336            for (int i = 0; i < libCount; i++) {
4337                SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.valueAt(i);
4338                if (versionedLib == null) {
4339                    continue;
4340                }
4341                final int versionCount = versionedLib.size();
4342                for (int j = 0; j < versionCount; j++) {
4343                    SharedLibraryEntry libEntry = versionedLib.valueAt(j);
4344                    if (!libEntry.info.isStatic()) {
4345                        if (libs == null) {
4346                            libs = new ArraySet<>();
4347                        }
4348                        libs.add(libEntry.info.getName());
4349                        break;
4350                    }
4351                    PackageSetting ps = mSettings.getPackageLPr(libEntry.apk);
4352                    if (ps != null && !filterSharedLibPackageLPr(ps, Binder.getCallingUid(),
4353                            UserHandle.getUserId(Binder.getCallingUid()))) {
4354                        if (libs == null) {
4355                            libs = new ArraySet<>();
4356                        }
4357                        libs.add(libEntry.info.getName());
4358                        break;
4359                    }
4360                }
4361            }
4362
4363            if (libs != null) {
4364                String[] libsArray = new String[libs.size()];
4365                libs.toArray(libsArray);
4366                return libsArray;
4367            }
4368
4369            return null;
4370        }
4371    }
4372
4373    @Override
4374    public @NonNull String getServicesSystemSharedLibraryPackageName() {
4375        synchronized (mPackages) {
4376            return mServicesSystemSharedLibraryPackageName;
4377        }
4378    }
4379
4380    @Override
4381    public @NonNull String getSharedSystemSharedLibraryPackageName() {
4382        synchronized (mPackages) {
4383            return mSharedSystemSharedLibraryPackageName;
4384        }
4385    }
4386
4387    private void updateSequenceNumberLP(String packageName, int[] userList) {
4388        for (int i = userList.length - 1; i >= 0; --i) {
4389            final int userId = userList[i];
4390            SparseArray<String> changedPackages = mChangedPackages.get(userId);
4391            if (changedPackages == null) {
4392                changedPackages = new SparseArray<>();
4393                mChangedPackages.put(userId, changedPackages);
4394            }
4395            Map<String, Integer> sequenceNumbers = mChangedPackagesSequenceNumbers.get(userId);
4396            if (sequenceNumbers == null) {
4397                sequenceNumbers = new HashMap<>();
4398                mChangedPackagesSequenceNumbers.put(userId, sequenceNumbers);
4399            }
4400            final Integer sequenceNumber = sequenceNumbers.get(packageName);
4401            if (sequenceNumber != null) {
4402                changedPackages.remove(sequenceNumber);
4403            }
4404            changedPackages.put(mChangedPackagesSequenceNumber, packageName);
4405            sequenceNumbers.put(packageName, mChangedPackagesSequenceNumber);
4406        }
4407        mChangedPackagesSequenceNumber++;
4408    }
4409
4410    @Override
4411    public ChangedPackages getChangedPackages(int sequenceNumber, int userId) {
4412        synchronized (mPackages) {
4413            if (sequenceNumber >= mChangedPackagesSequenceNumber) {
4414                return null;
4415            }
4416            final SparseArray<String> changedPackages = mChangedPackages.get(userId);
4417            if (changedPackages == null) {
4418                return null;
4419            }
4420            final List<String> packageNames =
4421                    new ArrayList<>(mChangedPackagesSequenceNumber - sequenceNumber);
4422            for (int i = sequenceNumber; i < mChangedPackagesSequenceNumber; i++) {
4423                final String packageName = changedPackages.get(i);
4424                if (packageName != null) {
4425                    packageNames.add(packageName);
4426                }
4427            }
4428            return packageNames.isEmpty()
4429                    ? null : new ChangedPackages(mChangedPackagesSequenceNumber, packageNames);
4430        }
4431    }
4432
4433    @Override
4434    public @NonNull ParceledListSlice<FeatureInfo> getSystemAvailableFeatures() {
4435        ArrayList<FeatureInfo> res;
4436        synchronized (mAvailableFeatures) {
4437            res = new ArrayList<>(mAvailableFeatures.size() + 1);
4438            res.addAll(mAvailableFeatures.values());
4439        }
4440        final FeatureInfo fi = new FeatureInfo();
4441        fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version",
4442                FeatureInfo.GL_ES_VERSION_UNDEFINED);
4443        res.add(fi);
4444
4445        return new ParceledListSlice<>(res);
4446    }
4447
4448    @Override
4449    public boolean hasSystemFeature(String name, int version) {
4450        synchronized (mAvailableFeatures) {
4451            final FeatureInfo feat = mAvailableFeatures.get(name);
4452            if (feat == null) {
4453                return false;
4454            } else {
4455                return feat.version >= version;
4456            }
4457        }
4458    }
4459
4460    @Override
4461    public int checkPermission(String permName, String pkgName, int userId) {
4462        if (!sUserManager.exists(userId)) {
4463            return PackageManager.PERMISSION_DENIED;
4464        }
4465
4466        synchronized (mPackages) {
4467            final PackageParser.Package p = mPackages.get(pkgName);
4468            if (p != null && p.mExtras != null) {
4469                final PackageSetting ps = (PackageSetting) p.mExtras;
4470                final PermissionsState permissionsState = ps.getPermissionsState();
4471                if (permissionsState.hasPermission(permName, userId)) {
4472                    return PackageManager.PERMISSION_GRANTED;
4473                }
4474                // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION
4475                if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState
4476                        .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) {
4477                    return PackageManager.PERMISSION_GRANTED;
4478                }
4479            }
4480        }
4481
4482        return PackageManager.PERMISSION_DENIED;
4483    }
4484
4485    @Override
4486    public int checkUidPermission(String permName, int uid) {
4487        final int userId = UserHandle.getUserId(uid);
4488
4489        if (!sUserManager.exists(userId)) {
4490            return PackageManager.PERMISSION_DENIED;
4491        }
4492
4493        synchronized (mPackages) {
4494            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
4495            if (obj != null) {
4496                final SettingBase ps = (SettingBase) obj;
4497                final PermissionsState permissionsState = ps.getPermissionsState();
4498                if (permissionsState.hasPermission(permName, userId)) {
4499                    return PackageManager.PERMISSION_GRANTED;
4500                }
4501                // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION
4502                if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState
4503                        .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) {
4504                    return PackageManager.PERMISSION_GRANTED;
4505                }
4506            } else {
4507                ArraySet<String> perms = mSystemPermissions.get(uid);
4508                if (perms != null) {
4509                    if (perms.contains(permName)) {
4510                        return PackageManager.PERMISSION_GRANTED;
4511                    }
4512                    if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && perms
4513                            .contains(Manifest.permission.ACCESS_FINE_LOCATION)) {
4514                        return PackageManager.PERMISSION_GRANTED;
4515                    }
4516                }
4517            }
4518        }
4519
4520        return PackageManager.PERMISSION_DENIED;
4521    }
4522
4523    @Override
4524    public boolean isPermissionRevokedByPolicy(String permission, String packageName, int userId) {
4525        if (UserHandle.getCallingUserId() != userId) {
4526            mContext.enforceCallingPermission(
4527                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
4528                    "isPermissionRevokedByPolicy for user " + userId);
4529        }
4530
4531        if (checkPermission(permission, packageName, userId)
4532                == PackageManager.PERMISSION_GRANTED) {
4533            return false;
4534        }
4535
4536        final long identity = Binder.clearCallingIdentity();
4537        try {
4538            final int flags = getPermissionFlags(permission, packageName, userId);
4539            return (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0;
4540        } finally {
4541            Binder.restoreCallingIdentity(identity);
4542        }
4543    }
4544
4545    @Override
4546    public String getPermissionControllerPackageName() {
4547        synchronized (mPackages) {
4548            return mRequiredInstallerPackage;
4549        }
4550    }
4551
4552    /**
4553     * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS
4554     * or INTERACT_ACROSS_USERS_FULL permissions, if the userid is not for the caller.
4555     * @param checkShell whether to prevent shell from access if there's a debugging restriction
4556     * @param message the message to log on security exception
4557     */
4558    void enforceCrossUserPermission(int callingUid, int userId, boolean requireFullPermission,
4559            boolean checkShell, String message) {
4560        if (userId < 0) {
4561            throw new IllegalArgumentException("Invalid userId " + userId);
4562        }
4563        if (checkShell) {
4564            enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId);
4565        }
4566        if (userId == UserHandle.getUserId(callingUid)) return;
4567        if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
4568            if (requireFullPermission) {
4569                mContext.enforceCallingOrSelfPermission(
4570                        android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
4571            } else {
4572                try {
4573                    mContext.enforceCallingOrSelfPermission(
4574                            android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
4575                } catch (SecurityException se) {
4576                    mContext.enforceCallingOrSelfPermission(
4577                            android.Manifest.permission.INTERACT_ACROSS_USERS, message);
4578                }
4579            }
4580        }
4581    }
4582
4583    void enforceShellRestriction(String restriction, int callingUid, int userHandle) {
4584        if (callingUid == Process.SHELL_UID) {
4585            if (userHandle >= 0
4586                    && sUserManager.hasUserRestriction(restriction, userHandle)) {
4587                throw new SecurityException("Shell does not have permission to access user "
4588                        + userHandle);
4589            } else if (userHandle < 0) {
4590                Slog.e(TAG, "Unable to check shell permission for user " + userHandle + "\n\t"
4591                        + Debug.getCallers(3));
4592            }
4593        }
4594    }
4595
4596    private BasePermission findPermissionTreeLP(String permName) {
4597        for(BasePermission bp : mSettings.mPermissionTrees.values()) {
4598            if (permName.startsWith(bp.name) &&
4599                    permName.length() > bp.name.length() &&
4600                    permName.charAt(bp.name.length()) == '.') {
4601                return bp;
4602            }
4603        }
4604        return null;
4605    }
4606
4607    private BasePermission checkPermissionTreeLP(String permName) {
4608        if (permName != null) {
4609            BasePermission bp = findPermissionTreeLP(permName);
4610            if (bp != null) {
4611                if (bp.uid == UserHandle.getAppId(Binder.getCallingUid())) {
4612                    return bp;
4613                }
4614                throw new SecurityException("Calling uid "
4615                        + Binder.getCallingUid()
4616                        + " is not allowed to add to permission tree "
4617                        + bp.name + " owned by uid " + bp.uid);
4618            }
4619        }
4620        throw new SecurityException("No permission tree found for " + permName);
4621    }
4622
4623    static boolean compareStrings(CharSequence s1, CharSequence s2) {
4624        if (s1 == null) {
4625            return s2 == null;
4626        }
4627        if (s2 == null) {
4628            return false;
4629        }
4630        if (s1.getClass() != s2.getClass()) {
4631            return false;
4632        }
4633        return s1.equals(s2);
4634    }
4635
4636    static boolean comparePermissionInfos(PermissionInfo pi1, PermissionInfo pi2) {
4637        if (pi1.icon != pi2.icon) return false;
4638        if (pi1.logo != pi2.logo) return false;
4639        if (pi1.protectionLevel != pi2.protectionLevel) return false;
4640        if (!compareStrings(pi1.name, pi2.name)) return false;
4641        if (!compareStrings(pi1.nonLocalizedLabel, pi2.nonLocalizedLabel)) return false;
4642        // We'll take care of setting this one.
4643        if (!compareStrings(pi1.packageName, pi2.packageName)) return false;
4644        // These are not currently stored in settings.
4645        //if (!compareStrings(pi1.group, pi2.group)) return false;
4646        //if (!compareStrings(pi1.nonLocalizedDescription, pi2.nonLocalizedDescription)) return false;
4647        //if (pi1.labelRes != pi2.labelRes) return false;
4648        //if (pi1.descriptionRes != pi2.descriptionRes) return false;
4649        return true;
4650    }
4651
4652    int permissionInfoFootprint(PermissionInfo info) {
4653        int size = info.name.length();
4654        if (info.nonLocalizedLabel != null) size += info.nonLocalizedLabel.length();
4655        if (info.nonLocalizedDescription != null) size += info.nonLocalizedDescription.length();
4656        return size;
4657    }
4658
4659    int calculateCurrentPermissionFootprintLocked(BasePermission tree) {
4660        int size = 0;
4661        for (BasePermission perm : mSettings.mPermissions.values()) {
4662            if (perm.uid == tree.uid) {
4663                size += perm.name.length() + permissionInfoFootprint(perm.perm.info);
4664            }
4665        }
4666        return size;
4667    }
4668
4669    void enforcePermissionCapLocked(PermissionInfo info, BasePermission tree) {
4670        // We calculate the max size of permissions defined by this uid and throw
4671        // if that plus the size of 'info' would exceed our stated maximum.
4672        if (tree.uid != Process.SYSTEM_UID) {
4673            final int curTreeSize = calculateCurrentPermissionFootprintLocked(tree);
4674            if (curTreeSize + permissionInfoFootprint(info) > MAX_PERMISSION_TREE_FOOTPRINT) {
4675                throw new SecurityException("Permission tree size cap exceeded");
4676            }
4677        }
4678    }
4679
4680    boolean addPermissionLocked(PermissionInfo info, boolean async) {
4681        if (info.labelRes == 0 && info.nonLocalizedLabel == null) {
4682            throw new SecurityException("Label must be specified in permission");
4683        }
4684        BasePermission tree = checkPermissionTreeLP(info.name);
4685        BasePermission bp = mSettings.mPermissions.get(info.name);
4686        boolean added = bp == null;
4687        boolean changed = true;
4688        int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel);
4689        if (added) {
4690            enforcePermissionCapLocked(info, tree);
4691            bp = new BasePermission(info.name, tree.sourcePackage,
4692                    BasePermission.TYPE_DYNAMIC);
4693        } else if (bp.type != BasePermission.TYPE_DYNAMIC) {
4694            throw new SecurityException(
4695                    "Not allowed to modify non-dynamic permission "
4696                    + info.name);
4697        } else {
4698            if (bp.protectionLevel == fixedLevel
4699                    && bp.perm.owner.equals(tree.perm.owner)
4700                    && bp.uid == tree.uid
4701                    && comparePermissionInfos(bp.perm.info, info)) {
4702                changed = false;
4703            }
4704        }
4705        bp.protectionLevel = fixedLevel;
4706        info = new PermissionInfo(info);
4707        info.protectionLevel = fixedLevel;
4708        bp.perm = new PackageParser.Permission(tree.perm.owner, info);
4709        bp.perm.info.packageName = tree.perm.info.packageName;
4710        bp.uid = tree.uid;
4711        if (added) {
4712            mSettings.mPermissions.put(info.name, bp);
4713        }
4714        if (changed) {
4715            if (!async) {
4716                mSettings.writeLPr();
4717            } else {
4718                scheduleWriteSettingsLocked();
4719            }
4720        }
4721        return added;
4722    }
4723
4724    @Override
4725    public boolean addPermission(PermissionInfo info) {
4726        synchronized (mPackages) {
4727            return addPermissionLocked(info, false);
4728        }
4729    }
4730
4731    @Override
4732    public boolean addPermissionAsync(PermissionInfo info) {
4733        synchronized (mPackages) {
4734            return addPermissionLocked(info, true);
4735        }
4736    }
4737
4738    @Override
4739    public void removePermission(String name) {
4740        synchronized (mPackages) {
4741            checkPermissionTreeLP(name);
4742            BasePermission bp = mSettings.mPermissions.get(name);
4743            if (bp != null) {
4744                if (bp.type != BasePermission.TYPE_DYNAMIC) {
4745                    throw new SecurityException(
4746                            "Not allowed to modify non-dynamic permission "
4747                            + name);
4748                }
4749                mSettings.mPermissions.remove(name);
4750                mSettings.writeLPr();
4751            }
4752        }
4753    }
4754
4755    private static void enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(PackageParser.Package pkg,
4756            BasePermission bp) {
4757        int index = pkg.requestedPermissions.indexOf(bp.name);
4758        if (index == -1) {
4759            throw new SecurityException("Package " + pkg.packageName
4760                    + " has not requested permission " + bp.name);
4761        }
4762        if (!bp.isRuntime() && !bp.isDevelopment()) {
4763            throw new SecurityException("Permission " + bp.name
4764                    + " is not a changeable permission type");
4765        }
4766    }
4767
4768    @Override
4769    public void grantRuntimePermission(String packageName, String name, final int userId) {
4770        grantRuntimePermission(packageName, name, userId, false /* Only if not fixed by policy */);
4771    }
4772
4773    private void grantRuntimePermission(String packageName, String name, final int userId,
4774            boolean overridePolicy) {
4775        if (!sUserManager.exists(userId)) {
4776            Log.e(TAG, "No such user:" + userId);
4777            return;
4778        }
4779
4780        mContext.enforceCallingOrSelfPermission(
4781                android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
4782                "grantRuntimePermission");
4783
4784        enforceCrossUserPermission(Binder.getCallingUid(), userId,
4785                true /* requireFullPermission */, true /* checkShell */,
4786                "grantRuntimePermission");
4787
4788        final int uid;
4789        final SettingBase sb;
4790
4791        synchronized (mPackages) {
4792            final PackageParser.Package pkg = mPackages.get(packageName);
4793            if (pkg == null) {
4794                throw new IllegalArgumentException("Unknown package: " + packageName);
4795            }
4796
4797            final BasePermission bp = mSettings.mPermissions.get(name);
4798            if (bp == null) {
4799                throw new IllegalArgumentException("Unknown permission: " + name);
4800            }
4801
4802            enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(pkg, bp);
4803
4804            // If a permission review is required for legacy apps we represent
4805            // their permissions as always granted runtime ones since we need
4806            // to keep the review required permission flag per user while an
4807            // install permission's state is shared across all users.
4808            if (mPermissionReviewRequired
4809                    && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
4810                    && bp.isRuntime()) {
4811                return;
4812            }
4813
4814            uid = UserHandle.getUid(userId, pkg.applicationInfo.uid);
4815            sb = (SettingBase) pkg.mExtras;
4816            if (sb == null) {
4817                throw new IllegalArgumentException("Unknown package: " + packageName);
4818            }
4819
4820            final PermissionsState permissionsState = sb.getPermissionsState();
4821
4822            final int flags = permissionsState.getPermissionFlags(name, userId);
4823            if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
4824                throw new SecurityException("Cannot grant system fixed permission "
4825                        + name + " for package " + packageName);
4826            }
4827            if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
4828                throw new SecurityException("Cannot grant policy fixed permission "
4829                        + name + " for package " + packageName);
4830            }
4831
4832            if (bp.isDevelopment()) {
4833                // Development permissions must be handled specially, since they are not
4834                // normal runtime permissions.  For now they apply to all users.
4835                if (permissionsState.grantInstallPermission(bp) !=
4836                        PermissionsState.PERMISSION_OPERATION_FAILURE) {
4837                    scheduleWriteSettingsLocked();
4838                }
4839                return;
4840            }
4841
4842            final PackageSetting ps = mSettings.mPackages.get(packageName);
4843            if (ps.getInstantApp(userId) && !bp.isInstant()) {
4844                throw new SecurityException("Cannot grant non-ephemeral permission"
4845                        + name + " for package " + packageName);
4846            }
4847
4848            if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
4849                Slog.w(TAG, "Cannot grant runtime permission to a legacy app");
4850                return;
4851            }
4852
4853            final int result = permissionsState.grantRuntimePermission(bp, userId);
4854            switch (result) {
4855                case PermissionsState.PERMISSION_OPERATION_FAILURE: {
4856                    return;
4857                }
4858
4859                case PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
4860                    final int appId = UserHandle.getAppId(pkg.applicationInfo.uid);
4861                    mHandler.post(new Runnable() {
4862                        @Override
4863                        public void run() {
4864                            killUid(appId, userId, KILL_APP_REASON_GIDS_CHANGED);
4865                        }
4866                    });
4867                }
4868                break;
4869            }
4870
4871            if (bp.isRuntime()) {
4872                logPermissionGranted(mContext, name, packageName);
4873            }
4874
4875            mOnPermissionChangeListeners.onPermissionsChanged(uid);
4876
4877            // Not critical if that is lost - app has to request again.
4878            mSettings.writeRuntimePermissionsForUserLPr(userId, false);
4879        }
4880
4881        // Only need to do this if user is initialized. Otherwise it's a new user
4882        // and there are no processes running as the user yet and there's no need
4883        // to make an expensive call to remount processes for the changed permissions.
4884        if (READ_EXTERNAL_STORAGE.equals(name)
4885                || WRITE_EXTERNAL_STORAGE.equals(name)) {
4886            final long token = Binder.clearCallingIdentity();
4887            try {
4888                if (sUserManager.isInitialized(userId)) {
4889                    StorageManagerInternal storageManagerInternal = LocalServices.getService(
4890                            StorageManagerInternal.class);
4891                    storageManagerInternal.onExternalStoragePolicyChanged(uid, packageName);
4892                }
4893            } finally {
4894                Binder.restoreCallingIdentity(token);
4895            }
4896        }
4897    }
4898
4899    @Override
4900    public void revokeRuntimePermission(String packageName, String name, int userId) {
4901        revokeRuntimePermission(packageName, name, userId, false /* Only if not fixed by policy */);
4902    }
4903
4904    private void revokeRuntimePermission(String packageName, String name, int userId,
4905            boolean overridePolicy) {
4906        if (!sUserManager.exists(userId)) {
4907            Log.e(TAG, "No such user:" + userId);
4908            return;
4909        }
4910
4911        mContext.enforceCallingOrSelfPermission(
4912                android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
4913                "revokeRuntimePermission");
4914
4915        enforceCrossUserPermission(Binder.getCallingUid(), userId,
4916                true /* requireFullPermission */, true /* checkShell */,
4917                "revokeRuntimePermission");
4918
4919        final int appId;
4920
4921        synchronized (mPackages) {
4922            final PackageParser.Package pkg = mPackages.get(packageName);
4923            if (pkg == null) {
4924                throw new IllegalArgumentException("Unknown package: " + packageName);
4925            }
4926
4927            final BasePermission bp = mSettings.mPermissions.get(name);
4928            if (bp == null) {
4929                throw new IllegalArgumentException("Unknown permission: " + name);
4930            }
4931
4932            enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(pkg, bp);
4933
4934            // If a permission review is required for legacy apps we represent
4935            // their permissions as always granted runtime ones since we need
4936            // to keep the review required permission flag per user while an
4937            // install permission's state is shared across all users.
4938            if (mPermissionReviewRequired
4939                    && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
4940                    && bp.isRuntime()) {
4941                return;
4942            }
4943
4944            SettingBase sb = (SettingBase) pkg.mExtras;
4945            if (sb == null) {
4946                throw new IllegalArgumentException("Unknown package: " + packageName);
4947            }
4948
4949            final PermissionsState permissionsState = sb.getPermissionsState();
4950
4951            final int flags = permissionsState.getPermissionFlags(name, userId);
4952            if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
4953                throw new SecurityException("Cannot revoke system fixed permission "
4954                        + name + " for package " + packageName);
4955            }
4956            if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
4957                throw new SecurityException("Cannot revoke policy fixed permission "
4958                        + name + " for package " + packageName);
4959            }
4960
4961            if (bp.isDevelopment()) {
4962                // Development permissions must be handled specially, since they are not
4963                // normal runtime permissions.  For now they apply to all users.
4964                if (permissionsState.revokeInstallPermission(bp) !=
4965                        PermissionsState.PERMISSION_OPERATION_FAILURE) {
4966                    scheduleWriteSettingsLocked();
4967                }
4968                return;
4969            }
4970
4971            if (permissionsState.revokeRuntimePermission(bp, userId) ==
4972                    PermissionsState.PERMISSION_OPERATION_FAILURE) {
4973                return;
4974            }
4975
4976            if (bp.isRuntime()) {
4977                logPermissionRevoked(mContext, name, packageName);
4978            }
4979
4980            mOnPermissionChangeListeners.onPermissionsChanged(pkg.applicationInfo.uid);
4981
4982            // Critical, after this call app should never have the permission.
4983            mSettings.writeRuntimePermissionsForUserLPr(userId, true);
4984
4985            appId = UserHandle.getAppId(pkg.applicationInfo.uid);
4986        }
4987
4988        killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED);
4989    }
4990
4991    /**
4992     * Get the first event id for the permission.
4993     *
4994     * <p>There are four events for each permission: <ul>
4995     *     <li>Request permission: first id + 0</li>
4996     *     <li>Grant permission: first id + 1</li>
4997     *     <li>Request for permission denied: first id + 2</li>
4998     *     <li>Revoke permission: first id + 3</li>
4999     * </ul></p>
5000     *
5001     * @param name name of the permission
5002     *
5003     * @return The first event id for the permission
5004     */
5005    private static int getBaseEventId(@NonNull String name) {
5006        int eventIdIndex = ALL_DANGEROUS_PERMISSIONS.indexOf(name);
5007
5008        if (eventIdIndex == -1) {
5009            if (AppOpsManager.permissionToOpCode(name) == AppOpsManager.OP_NONE
5010                    || "user".equals(Build.TYPE)) {
5011                Log.i(TAG, "Unknown permission " + name);
5012
5013                return MetricsEvent.ACTION_PERMISSION_REQUEST_UNKNOWN;
5014            } else {
5015                // Most likely #ALL_DANGEROUS_PERMISSIONS needs to be updated.
5016                //
5017                // Also update
5018                // - EventLogger#ALL_DANGEROUS_PERMISSIONS
5019                // - metrics_constants.proto
5020                throw new IllegalStateException("Unknown permission " + name);
5021            }
5022        }
5023
5024        return MetricsEvent.ACTION_PERMISSION_REQUEST_READ_CALENDAR + eventIdIndex * 4;
5025    }
5026
5027    /**
5028     * Log that a permission was revoked.
5029     *
5030     * @param context Context of the caller
5031     * @param name name of the permission
5032     * @param packageName package permission if for
5033     */
5034    private static void logPermissionRevoked(@NonNull Context context, @NonNull String name,
5035            @NonNull String packageName) {
5036        MetricsLogger.action(context, getBaseEventId(name) + 3, packageName);
5037    }
5038
5039    /**
5040     * Log that a permission request was granted.
5041     *
5042     * @param context Context of the caller
5043     * @param name name of the permission
5044     * @param packageName package permission if for
5045     */
5046    private static void logPermissionGranted(@NonNull Context context, @NonNull String name,
5047            @NonNull String packageName) {
5048        MetricsLogger.action(context, getBaseEventId(name) + 1, packageName);
5049    }
5050
5051    @Override
5052    public void resetRuntimePermissions() {
5053        mContext.enforceCallingOrSelfPermission(
5054                android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
5055                "revokeRuntimePermission");
5056
5057        int callingUid = Binder.getCallingUid();
5058        if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
5059            mContext.enforceCallingOrSelfPermission(
5060                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
5061                    "resetRuntimePermissions");
5062        }
5063
5064        synchronized (mPackages) {
5065            updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL);
5066            for (int userId : UserManagerService.getInstance().getUserIds()) {
5067                final int packageCount = mPackages.size();
5068                for (int i = 0; i < packageCount; i++) {
5069                    PackageParser.Package pkg = mPackages.valueAt(i);
5070                    if (!(pkg.mExtras instanceof PackageSetting)) {
5071                        continue;
5072                    }
5073                    PackageSetting ps = (PackageSetting) pkg.mExtras;
5074                    resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
5075                }
5076            }
5077        }
5078    }
5079
5080    @Override
5081    public int getPermissionFlags(String name, String packageName, int userId) {
5082        if (!sUserManager.exists(userId)) {
5083            return 0;
5084        }
5085
5086        enforceGrantRevokeRuntimePermissionPermissions("getPermissionFlags");
5087
5088        enforceCrossUserPermission(Binder.getCallingUid(), userId,
5089                true /* requireFullPermission */, false /* checkShell */,
5090                "getPermissionFlags");
5091
5092        synchronized (mPackages) {
5093            final PackageParser.Package pkg = mPackages.get(packageName);
5094            if (pkg == null) {
5095                return 0;
5096            }
5097
5098            final BasePermission bp = mSettings.mPermissions.get(name);
5099            if (bp == null) {
5100                return 0;
5101            }
5102
5103            SettingBase sb = (SettingBase) pkg.mExtras;
5104            if (sb == null) {
5105                return 0;
5106            }
5107
5108            PermissionsState permissionsState = sb.getPermissionsState();
5109            return permissionsState.getPermissionFlags(name, userId);
5110        }
5111    }
5112
5113    @Override
5114    public void updatePermissionFlags(String name, String packageName, int flagMask,
5115            int flagValues, int userId) {
5116        if (!sUserManager.exists(userId)) {
5117            return;
5118        }
5119
5120        enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlags");
5121
5122        enforceCrossUserPermission(Binder.getCallingUid(), userId,
5123                true /* requireFullPermission */, true /* checkShell */,
5124                "updatePermissionFlags");
5125
5126        // Only the system can change these flags and nothing else.
5127        if (getCallingUid() != Process.SYSTEM_UID) {
5128            flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
5129            flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
5130            flagMask &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
5131            flagValues &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
5132            flagValues &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
5133        }
5134
5135        synchronized (mPackages) {
5136            final PackageParser.Package pkg = mPackages.get(packageName);
5137            if (pkg == null) {
5138                throw new IllegalArgumentException("Unknown package: " + packageName);
5139            }
5140
5141            final BasePermission bp = mSettings.mPermissions.get(name);
5142            if (bp == null) {
5143                throw new IllegalArgumentException("Unknown permission: " + name);
5144            }
5145
5146            SettingBase sb = (SettingBase) pkg.mExtras;
5147            if (sb == null) {
5148                throw new IllegalArgumentException("Unknown package: " + packageName);
5149            }
5150
5151            PermissionsState permissionsState = sb.getPermissionsState();
5152
5153            boolean hadState = permissionsState.getRuntimePermissionState(name, userId) != null;
5154
5155            if (permissionsState.updatePermissionFlags(bp, userId, flagMask, flagValues)) {
5156                // Install and runtime permissions are stored in different places,
5157                // so figure out what permission changed and persist the change.
5158                if (permissionsState.getInstallPermissionState(name) != null) {
5159                    scheduleWriteSettingsLocked();
5160                } else if (permissionsState.getRuntimePermissionState(name, userId) != null
5161                        || hadState) {
5162                    mSettings.writeRuntimePermissionsForUserLPr(userId, false);
5163                }
5164            }
5165        }
5166    }
5167
5168    /**
5169     * Update the permission flags for all packages and runtime permissions of a user in order
5170     * to allow device or profile owner to remove POLICY_FIXED.
5171     */
5172    @Override
5173    public void updatePermissionFlagsForAllApps(int flagMask, int flagValues, int userId) {
5174        if (!sUserManager.exists(userId)) {
5175            return;
5176        }
5177
5178        enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlagsForAllApps");
5179
5180        enforceCrossUserPermission(Binder.getCallingUid(), userId,
5181                true /* requireFullPermission */, true /* checkShell */,
5182                "updatePermissionFlagsForAllApps");
5183
5184        // Only the system can change system fixed flags.
5185        if (getCallingUid() != Process.SYSTEM_UID) {
5186            flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
5187            flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
5188        }
5189
5190        synchronized (mPackages) {
5191            boolean changed = false;
5192            final int packageCount = mPackages.size();
5193            for (int pkgIndex = 0; pkgIndex < packageCount; pkgIndex++) {
5194                final PackageParser.Package pkg = mPackages.valueAt(pkgIndex);
5195                SettingBase sb = (SettingBase) pkg.mExtras;
5196                if (sb == null) {
5197                    continue;
5198                }
5199                PermissionsState permissionsState = sb.getPermissionsState();
5200                changed |= permissionsState.updatePermissionFlagsForAllPermissions(
5201                        userId, flagMask, flagValues);
5202            }
5203            if (changed) {
5204                mSettings.writeRuntimePermissionsForUserLPr(userId, false);
5205            }
5206        }
5207    }
5208
5209    private void enforceGrantRevokeRuntimePermissionPermissions(String message) {
5210        if (mContext.checkCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS)
5211                != PackageManager.PERMISSION_GRANTED
5212            && mContext.checkCallingOrSelfPermission(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS)
5213                != PackageManager.PERMISSION_GRANTED) {
5214            throw new SecurityException(message + " requires "
5215                    + Manifest.permission.GRANT_RUNTIME_PERMISSIONS + " or "
5216                    + Manifest.permission.REVOKE_RUNTIME_PERMISSIONS);
5217        }
5218    }
5219
5220    @Override
5221    public boolean shouldShowRequestPermissionRationale(String permissionName,
5222            String packageName, int userId) {
5223        if (UserHandle.getCallingUserId() != userId) {
5224            mContext.enforceCallingPermission(
5225                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
5226                    "canShowRequestPermissionRationale for user " + userId);
5227        }
5228
5229        final int uid = getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
5230        if (UserHandle.getAppId(getCallingUid()) != UserHandle.getAppId(uid)) {
5231            return false;
5232        }
5233
5234        if (checkPermission(permissionName, packageName, userId)
5235                == PackageManager.PERMISSION_GRANTED) {
5236            return false;
5237        }
5238
5239        final int flags;
5240
5241        final long identity = Binder.clearCallingIdentity();
5242        try {
5243            flags = getPermissionFlags(permissionName,
5244                    packageName, userId);
5245        } finally {
5246            Binder.restoreCallingIdentity(identity);
5247        }
5248
5249        final int fixedFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
5250                | PackageManager.FLAG_PERMISSION_POLICY_FIXED
5251                | PackageManager.FLAG_PERMISSION_USER_FIXED;
5252
5253        if ((flags & fixedFlags) != 0) {
5254            return false;
5255        }
5256
5257        return (flags & PackageManager.FLAG_PERMISSION_USER_SET) != 0;
5258    }
5259
5260    @Override
5261    public void addOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
5262        mContext.enforceCallingOrSelfPermission(
5263                Manifest.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS,
5264                "addOnPermissionsChangeListener");
5265
5266        synchronized (mPackages) {
5267            mOnPermissionChangeListeners.addListenerLocked(listener);
5268        }
5269    }
5270
5271    @Override
5272    public void removeOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
5273        synchronized (mPackages) {
5274            mOnPermissionChangeListeners.removeListenerLocked(listener);
5275        }
5276    }
5277
5278    @Override
5279    public boolean isProtectedBroadcast(String actionName) {
5280        synchronized (mPackages) {
5281            if (mProtectedBroadcasts.contains(actionName)) {
5282                return true;
5283            } else if (actionName != null) {
5284                // TODO: remove these terrible hacks
5285                if (actionName.startsWith("android.net.netmon.lingerExpired")
5286                        || actionName.startsWith("com.android.server.sip.SipWakeupTimer")
5287                        || actionName.startsWith("com.android.internal.telephony.data-reconnect")
5288                        || actionName.startsWith("android.net.netmon.launchCaptivePortalApp")) {
5289                    return true;
5290                }
5291            }
5292        }
5293        return false;
5294    }
5295
5296    @Override
5297    public int checkSignatures(String pkg1, String pkg2) {
5298        synchronized (mPackages) {
5299            final PackageParser.Package p1 = mPackages.get(pkg1);
5300            final PackageParser.Package p2 = mPackages.get(pkg2);
5301            if (p1 == null || p1.mExtras == null
5302                    || p2 == null || p2.mExtras == null) {
5303                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5304            }
5305            return compareSignatures(p1.mSignatures, p2.mSignatures);
5306        }
5307    }
5308
5309    @Override
5310    public int checkUidSignatures(int uid1, int uid2) {
5311        // Map to base uids.
5312        uid1 = UserHandle.getAppId(uid1);
5313        uid2 = UserHandle.getAppId(uid2);
5314        // reader
5315        synchronized (mPackages) {
5316            Signature[] s1;
5317            Signature[] s2;
5318            Object obj = mSettings.getUserIdLPr(uid1);
5319            if (obj != null) {
5320                if (obj instanceof SharedUserSetting) {
5321                    s1 = ((SharedUserSetting)obj).signatures.mSignatures;
5322                } else if (obj instanceof PackageSetting) {
5323                    s1 = ((PackageSetting)obj).signatures.mSignatures;
5324                } else {
5325                    return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5326                }
5327            } else {
5328                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5329            }
5330            obj = mSettings.getUserIdLPr(uid2);
5331            if (obj != null) {
5332                if (obj instanceof SharedUserSetting) {
5333                    s2 = ((SharedUserSetting)obj).signatures.mSignatures;
5334                } else if (obj instanceof PackageSetting) {
5335                    s2 = ((PackageSetting)obj).signatures.mSignatures;
5336                } else {
5337                    return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5338                }
5339            } else {
5340                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5341            }
5342            return compareSignatures(s1, s2);
5343        }
5344    }
5345
5346    /**
5347     * This method should typically only be used when granting or revoking
5348     * permissions, since the app may immediately restart after this call.
5349     * <p>
5350     * If you're doing surgery on app code/data, use {@link PackageFreezer} to
5351     * guard your work against the app being relaunched.
5352     */
5353    private void killUid(int appId, int userId, String reason) {
5354        final long identity = Binder.clearCallingIdentity();
5355        try {
5356            IActivityManager am = ActivityManager.getService();
5357            if (am != null) {
5358                try {
5359                    am.killUid(appId, userId, reason);
5360                } catch (RemoteException e) {
5361                    /* ignore - same process */
5362                }
5363            }
5364        } finally {
5365            Binder.restoreCallingIdentity(identity);
5366        }
5367    }
5368
5369    /**
5370     * Compares two sets of signatures. Returns:
5371     * <br />
5372     * {@link PackageManager#SIGNATURE_NEITHER_SIGNED}: if both signature sets are null,
5373     * <br />
5374     * {@link PackageManager#SIGNATURE_FIRST_NOT_SIGNED}: if the first signature set is null,
5375     * <br />
5376     * {@link PackageManager#SIGNATURE_SECOND_NOT_SIGNED}: if the second signature set is null,
5377     * <br />
5378     * {@link PackageManager#SIGNATURE_MATCH}: if the two signature sets are identical,
5379     * <br />
5380     * {@link PackageManager#SIGNATURE_NO_MATCH}: if the two signature sets differ.
5381     */
5382    static int compareSignatures(Signature[] s1, Signature[] s2) {
5383        if (s1 == null) {
5384            return s2 == null
5385                    ? PackageManager.SIGNATURE_NEITHER_SIGNED
5386                    : PackageManager.SIGNATURE_FIRST_NOT_SIGNED;
5387        }
5388
5389        if (s2 == null) {
5390            return PackageManager.SIGNATURE_SECOND_NOT_SIGNED;
5391        }
5392
5393        if (s1.length != s2.length) {
5394            return PackageManager.SIGNATURE_NO_MATCH;
5395        }
5396
5397        // Since both signature sets are of size 1, we can compare without HashSets.
5398        if (s1.length == 1) {
5399            return s1[0].equals(s2[0]) ?
5400                    PackageManager.SIGNATURE_MATCH :
5401                    PackageManager.SIGNATURE_NO_MATCH;
5402        }
5403
5404        ArraySet<Signature> set1 = new ArraySet<Signature>();
5405        for (Signature sig : s1) {
5406            set1.add(sig);
5407        }
5408        ArraySet<Signature> set2 = new ArraySet<Signature>();
5409        for (Signature sig : s2) {
5410            set2.add(sig);
5411        }
5412        // Make sure s2 contains all signatures in s1.
5413        if (set1.equals(set2)) {
5414            return PackageManager.SIGNATURE_MATCH;
5415        }
5416        return PackageManager.SIGNATURE_NO_MATCH;
5417    }
5418
5419    /**
5420     * If the database version for this type of package (internal storage or
5421     * external storage) is less than the version where package signatures
5422     * were updated, return true.
5423     */
5424    private boolean isCompatSignatureUpdateNeeded(PackageParser.Package scannedPkg) {
5425        final VersionInfo ver = getSettingsVersionForPackage(scannedPkg);
5426        return ver.databaseVersion < DatabaseVersion.SIGNATURE_END_ENTITY;
5427    }
5428
5429    /**
5430     * Used for backward compatibility to make sure any packages with
5431     * certificate chains get upgraded to the new style. {@code existingSigs}
5432     * will be in the old format (since they were stored on disk from before the
5433     * system upgrade) and {@code scannedSigs} will be in the newer format.
5434     */
5435    private int compareSignaturesCompat(PackageSignatures existingSigs,
5436            PackageParser.Package scannedPkg) {
5437        if (!isCompatSignatureUpdateNeeded(scannedPkg)) {
5438            return PackageManager.SIGNATURE_NO_MATCH;
5439        }
5440
5441        ArraySet<Signature> existingSet = new ArraySet<Signature>();
5442        for (Signature sig : existingSigs.mSignatures) {
5443            existingSet.add(sig);
5444        }
5445        ArraySet<Signature> scannedCompatSet = new ArraySet<Signature>();
5446        for (Signature sig : scannedPkg.mSignatures) {
5447            try {
5448                Signature[] chainSignatures = sig.getChainSignatures();
5449                for (Signature chainSig : chainSignatures) {
5450                    scannedCompatSet.add(chainSig);
5451                }
5452            } catch (CertificateEncodingException e) {
5453                scannedCompatSet.add(sig);
5454            }
5455        }
5456        /*
5457         * Make sure the expanded scanned set contains all signatures in the
5458         * existing one.
5459         */
5460        if (scannedCompatSet.equals(existingSet)) {
5461            // Migrate the old signatures to the new scheme.
5462            existingSigs.assignSignatures(scannedPkg.mSignatures);
5463            // The new KeySets will be re-added later in the scanning process.
5464            synchronized (mPackages) {
5465                mSettings.mKeySetManagerService.removeAppKeySetDataLPw(scannedPkg.packageName);
5466            }
5467            return PackageManager.SIGNATURE_MATCH;
5468        }
5469        return PackageManager.SIGNATURE_NO_MATCH;
5470    }
5471
5472    private boolean isRecoverSignatureUpdateNeeded(PackageParser.Package scannedPkg) {
5473        final VersionInfo ver = getSettingsVersionForPackage(scannedPkg);
5474        return ver.databaseVersion < DatabaseVersion.SIGNATURE_MALFORMED_RECOVER;
5475    }
5476
5477    private int compareSignaturesRecover(PackageSignatures existingSigs,
5478            PackageParser.Package scannedPkg) {
5479        if (!isRecoverSignatureUpdateNeeded(scannedPkg)) {
5480            return PackageManager.SIGNATURE_NO_MATCH;
5481        }
5482
5483        String msg = null;
5484        try {
5485            if (Signature.areEffectiveMatch(existingSigs.mSignatures, scannedPkg.mSignatures)) {
5486                logCriticalInfo(Log.INFO, "Recovered effectively matching certificates for "
5487                        + scannedPkg.packageName);
5488                return PackageManager.SIGNATURE_MATCH;
5489            }
5490        } catch (CertificateException e) {
5491            msg = e.getMessage();
5492        }
5493
5494        logCriticalInfo(Log.INFO,
5495                "Failed to recover certificates for " + scannedPkg.packageName + ": " + msg);
5496        return PackageManager.SIGNATURE_NO_MATCH;
5497    }
5498
5499    @Override
5500    public List<String> getAllPackages() {
5501        synchronized (mPackages) {
5502            return new ArrayList<String>(mPackages.keySet());
5503        }
5504    }
5505
5506    @Override
5507    public String[] getPackagesForUid(int uid) {
5508        final int userId = UserHandle.getUserId(uid);
5509        uid = UserHandle.getAppId(uid);
5510        // reader
5511        synchronized (mPackages) {
5512            Object obj = mSettings.getUserIdLPr(uid);
5513            if (obj instanceof SharedUserSetting) {
5514                final SharedUserSetting sus = (SharedUserSetting) obj;
5515                final int N = sus.packages.size();
5516                String[] res = new String[N];
5517                final Iterator<PackageSetting> it = sus.packages.iterator();
5518                int i = 0;
5519                while (it.hasNext()) {
5520                    PackageSetting ps = it.next();
5521                    if (ps.getInstalled(userId)) {
5522                        res[i++] = ps.name;
5523                    } else {
5524                        res = ArrayUtils.removeElement(String.class, res, res[i]);
5525                    }
5526                }
5527                return res;
5528            } else if (obj instanceof PackageSetting) {
5529                final PackageSetting ps = (PackageSetting) obj;
5530                if (ps.getInstalled(userId)) {
5531                    return new String[]{ps.name};
5532                }
5533            }
5534        }
5535        return null;
5536    }
5537
5538    @Override
5539    public String getNameForUid(int uid) {
5540        // reader
5541        synchronized (mPackages) {
5542            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
5543            if (obj instanceof SharedUserSetting) {
5544                final SharedUserSetting sus = (SharedUserSetting) obj;
5545                return sus.name + ":" + sus.userId;
5546            } else if (obj instanceof PackageSetting) {
5547                final PackageSetting ps = (PackageSetting) obj;
5548                return ps.name;
5549            }
5550        }
5551        return null;
5552    }
5553
5554    @Override
5555    public int getUidForSharedUser(String sharedUserName) {
5556        if(sharedUserName == null) {
5557            return -1;
5558        }
5559        // reader
5560        synchronized (mPackages) {
5561            SharedUserSetting suid;
5562            try {
5563                suid = mSettings.getSharedUserLPw(sharedUserName, 0, 0, false);
5564                if (suid != null) {
5565                    return suid.userId;
5566                }
5567            } catch (PackageManagerException ignore) {
5568                // can't happen, but, still need to catch it
5569            }
5570            return -1;
5571        }
5572    }
5573
5574    @Override
5575    public int getFlagsForUid(int uid) {
5576        synchronized (mPackages) {
5577            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
5578            if (obj instanceof SharedUserSetting) {
5579                final SharedUserSetting sus = (SharedUserSetting) obj;
5580                return sus.pkgFlags;
5581            } else if (obj instanceof PackageSetting) {
5582                final PackageSetting ps = (PackageSetting) obj;
5583                return ps.pkgFlags;
5584            }
5585        }
5586        return 0;
5587    }
5588
5589    @Override
5590    public int getPrivateFlagsForUid(int uid) {
5591        synchronized (mPackages) {
5592            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
5593            if (obj instanceof SharedUserSetting) {
5594                final SharedUserSetting sus = (SharedUserSetting) obj;
5595                return sus.pkgPrivateFlags;
5596            } else if (obj instanceof PackageSetting) {
5597                final PackageSetting ps = (PackageSetting) obj;
5598                return ps.pkgPrivateFlags;
5599            }
5600        }
5601        return 0;
5602    }
5603
5604    @Override
5605    public boolean isUidPrivileged(int uid) {
5606        uid = UserHandle.getAppId(uid);
5607        // reader
5608        synchronized (mPackages) {
5609            Object obj = mSettings.getUserIdLPr(uid);
5610            if (obj instanceof SharedUserSetting) {
5611                final SharedUserSetting sus = (SharedUserSetting) obj;
5612                final Iterator<PackageSetting> it = sus.packages.iterator();
5613                while (it.hasNext()) {
5614                    if (it.next().isPrivileged()) {
5615                        return true;
5616                    }
5617                }
5618            } else if (obj instanceof PackageSetting) {
5619                final PackageSetting ps = (PackageSetting) obj;
5620                return ps.isPrivileged();
5621            }
5622        }
5623        return false;
5624    }
5625
5626    @Override
5627    public String[] getAppOpPermissionPackages(String permissionName) {
5628        synchronized (mPackages) {
5629            ArraySet<String> pkgs = mAppOpPermissionPackages.get(permissionName);
5630            if (pkgs == null) {
5631                return null;
5632            }
5633            return pkgs.toArray(new String[pkgs.size()]);
5634        }
5635    }
5636
5637    @Override
5638    public ResolveInfo resolveIntent(Intent intent, String resolvedType,
5639            int flags, int userId) {
5640        return resolveIntentInternal(
5641                intent, resolvedType, flags, userId, false /*includeInstantApps*/);
5642    }
5643
5644    private ResolveInfo resolveIntentInternal(Intent intent, String resolvedType,
5645            int flags, int userId, boolean includeInstantApps) {
5646        try {
5647            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveIntent");
5648
5649            if (!sUserManager.exists(userId)) return null;
5650            final int callingUid = Binder.getCallingUid();
5651            flags = updateFlagsForResolve(flags, userId, intent, callingUid, includeInstantApps);
5652            enforceCrossUserPermission(callingUid, userId,
5653                    false /*requireFullPermission*/, false /*checkShell*/, "resolve intent");
5654
5655            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities");
5656            final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType,
5657                    flags, userId, includeInstantApps);
5658            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
5659
5660            final ResolveInfo bestChoice =
5661                    chooseBestActivity(intent, resolvedType, flags, query, userId);
5662            return bestChoice;
5663        } finally {
5664            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
5665        }
5666    }
5667
5668    @Override
5669    public ResolveInfo findPersistentPreferredActivity(Intent intent, int userId) {
5670        if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.SYSTEM_UID)) {
5671            throw new SecurityException(
5672                    "findPersistentPreferredActivity can only be run by the system");
5673        }
5674        if (!sUserManager.exists(userId)) {
5675            return null;
5676        }
5677        final int callingUid = Binder.getCallingUid();
5678        intent = updateIntentForResolve(intent);
5679        final String resolvedType = intent.resolveTypeIfNeeded(mContext.getContentResolver());
5680        final int flags = updateFlagsForResolve(
5681                0, userId, intent, callingUid, false /*includeInstantApps*/);
5682        final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
5683                userId);
5684        synchronized (mPackages) {
5685            return findPersistentPreferredActivityLP(intent, resolvedType, flags, query, false,
5686                    userId);
5687        }
5688    }
5689
5690    @Override
5691    public void setLastChosenActivity(Intent intent, String resolvedType, int flags,
5692            IntentFilter filter, int match, ComponentName activity) {
5693        final int userId = UserHandle.getCallingUserId();
5694        if (DEBUG_PREFERRED) {
5695            Log.v(TAG, "setLastChosenActivity intent=" + intent
5696                + " resolvedType=" + resolvedType
5697                + " flags=" + flags
5698                + " filter=" + filter
5699                + " match=" + match
5700                + " activity=" + activity);
5701            filter.dump(new PrintStreamPrinter(System.out), "    ");
5702        }
5703        intent.setComponent(null);
5704        final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
5705                userId);
5706        // Find any earlier preferred or last chosen entries and nuke them
5707        findPreferredActivity(intent, resolvedType,
5708                flags, query, 0, false, true, false, userId);
5709        // Add the new activity as the last chosen for this filter
5710        addPreferredActivityInternal(filter, match, null, activity, false, userId,
5711                "Setting last chosen");
5712    }
5713
5714    @Override
5715    public ResolveInfo getLastChosenActivity(Intent intent, String resolvedType, int flags) {
5716        final int userId = UserHandle.getCallingUserId();
5717        if (DEBUG_PREFERRED) Log.v(TAG, "Querying last chosen activity for " + intent);
5718        final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
5719                userId);
5720        return findPreferredActivity(intent, resolvedType, flags, query, 0,
5721                false, false, false, userId);
5722    }
5723
5724    /**
5725     * Returns whether or not instant apps have been disabled remotely.
5726     */
5727    private boolean isEphemeralDisabled() {
5728        return mEphemeralAppsDisabled;
5729    }
5730
5731    private boolean isEphemeralAllowed(
5732            Intent intent, List<ResolveInfo> resolvedActivities, int userId,
5733            boolean skipPackageCheck) {
5734        final int callingUser = UserHandle.getCallingUserId();
5735        if (mInstantAppResolverConnection == null) {
5736            return false;
5737        }
5738        if (mInstantAppInstallerActivity == null) {
5739            return false;
5740        }
5741        if (intent.getComponent() != null) {
5742            return false;
5743        }
5744        if ((intent.getFlags() & Intent.FLAG_IGNORE_EPHEMERAL) != 0) {
5745            return false;
5746        }
5747        if (!skipPackageCheck && intent.getPackage() != null) {
5748            return false;
5749        }
5750        final boolean isWebUri = hasWebURI(intent);
5751        if (!isWebUri || intent.getData().getHost() == null) {
5752            return false;
5753        }
5754        // Deny ephemeral apps if the user chose _ALWAYS or _ALWAYS_ASK for intent resolution.
5755        // Or if there's already an ephemeral app installed that handles the action
5756        synchronized (mPackages) {
5757            final int count = (resolvedActivities == null ? 0 : resolvedActivities.size());
5758            for (int n = 0; n < count; n++) {
5759                final ResolveInfo info = resolvedActivities.get(n);
5760                final String packageName = info.activityInfo.packageName;
5761                final PackageSetting ps = mSettings.mPackages.get(packageName);
5762                if (ps != null) {
5763                    // only check domain verification status if the app is not a browser
5764                    if (!info.handleAllWebDataURI) {
5765                        // Try to get the status from User settings first
5766                        final long packedStatus = getDomainVerificationStatusLPr(ps, userId);
5767                        final int status = (int) (packedStatus >> 32);
5768                        if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS
5769                            || status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
5770                            if (DEBUG_EPHEMERAL) {
5771                                Slog.v(TAG, "DENY instant app;"
5772                                    + " pkg: " + packageName + ", status: " + status);
5773                            }
5774                            return false;
5775                        }
5776                    }
5777                    if (ps.getInstantApp(userId)) {
5778                        if (DEBUG_EPHEMERAL) {
5779                            Slog.v(TAG, "DENY instant app installed;"
5780                                    + " pkg: " + packageName);
5781                        }
5782                        return false;
5783                    }
5784                }
5785            }
5786        }
5787        // We've exhausted all ways to deny ephemeral application; let the system look for them.
5788        return true;
5789    }
5790
5791    private void requestInstantAppResolutionPhaseTwo(AuxiliaryResolveInfo responseObj,
5792            Intent origIntent, String resolvedType, String callingPackage,
5793            int userId) {
5794        final Message msg = mHandler.obtainMessage(INSTANT_APP_RESOLUTION_PHASE_TWO,
5795                new InstantAppRequest(responseObj, origIntent, resolvedType,
5796                        callingPackage, userId));
5797        mHandler.sendMessage(msg);
5798    }
5799
5800    private ResolveInfo chooseBestActivity(Intent intent, String resolvedType,
5801            int flags, List<ResolveInfo> query, int userId) {
5802        if (query != null) {
5803            final int N = query.size();
5804            if (N == 1) {
5805                return query.get(0);
5806            } else if (N > 1) {
5807                final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
5808                // If there is more than one activity with the same priority,
5809                // then let the user decide between them.
5810                ResolveInfo r0 = query.get(0);
5811                ResolveInfo r1 = query.get(1);
5812                if (DEBUG_INTENT_MATCHING || debug) {
5813                    Slog.v(TAG, r0.activityInfo.name + "=" + r0.priority + " vs "
5814                            + r1.activityInfo.name + "=" + r1.priority);
5815                }
5816                // If the first activity has a higher priority, or a different
5817                // default, then it is always desirable to pick it.
5818                if (r0.priority != r1.priority
5819                        || r0.preferredOrder != r1.preferredOrder
5820                        || r0.isDefault != r1.isDefault) {
5821                    return query.get(0);
5822                }
5823                // If we have saved a preference for a preferred activity for
5824                // this Intent, use that.
5825                ResolveInfo ri = findPreferredActivity(intent, resolvedType,
5826                        flags, query, r0.priority, true, false, debug, userId);
5827                if (ri != null) {
5828                    return ri;
5829                }
5830                // If we have an ephemeral app, use it
5831                for (int i = 0; i < N; i++) {
5832                    ri = query.get(i);
5833                    if (ri.activityInfo.applicationInfo.isInstantApp()) {
5834                        return ri;
5835                    }
5836                }
5837                ri = new ResolveInfo(mResolveInfo);
5838                ri.activityInfo = new ActivityInfo(ri.activityInfo);
5839                ri.activityInfo.labelRes = ResolverActivity.getLabelRes(intent.getAction());
5840                // If all of the options come from the same package, show the application's
5841                // label and icon instead of the generic resolver's.
5842                // Some calls like Intent.resolveActivityInfo query the ResolveInfo from here
5843                // and then throw away the ResolveInfo itself, meaning that the caller loses
5844                // the resolvePackageName. Therefore the activityInfo.labelRes above provides
5845                // a fallback for this case; we only set the target package's resources on
5846                // the ResolveInfo, not the ActivityInfo.
5847                final String intentPackage = intent.getPackage();
5848                if (!TextUtils.isEmpty(intentPackage) && allHavePackage(query, intentPackage)) {
5849                    final ApplicationInfo appi = query.get(0).activityInfo.applicationInfo;
5850                    ri.resolvePackageName = intentPackage;
5851                    if (userNeedsBadging(userId)) {
5852                        ri.noResourceId = true;
5853                    } else {
5854                        ri.icon = appi.icon;
5855                    }
5856                    ri.iconResourceId = appi.icon;
5857                    ri.labelRes = appi.labelRes;
5858                }
5859                ri.activityInfo.applicationInfo = new ApplicationInfo(
5860                        ri.activityInfo.applicationInfo);
5861                if (userId != 0) {
5862                    ri.activityInfo.applicationInfo.uid = UserHandle.getUid(userId,
5863                            UserHandle.getAppId(ri.activityInfo.applicationInfo.uid));
5864                }
5865                // Make sure that the resolver is displayable in car mode
5866                if (ri.activityInfo.metaData == null) ri.activityInfo.metaData = new Bundle();
5867                ri.activityInfo.metaData.putBoolean(Intent.METADATA_DOCK_HOME, true);
5868                return ri;
5869            }
5870        }
5871        return null;
5872    }
5873
5874    /**
5875     * Return true if the given list is not empty and all of its contents have
5876     * an activityInfo with the given package name.
5877     */
5878    private boolean allHavePackage(List<ResolveInfo> list, String packageName) {
5879        if (ArrayUtils.isEmpty(list)) {
5880            return false;
5881        }
5882        for (int i = 0, N = list.size(); i < N; i++) {
5883            final ResolveInfo ri = list.get(i);
5884            final ActivityInfo ai = ri != null ? ri.activityInfo : null;
5885            if (ai == null || !packageName.equals(ai.packageName)) {
5886                return false;
5887            }
5888        }
5889        return true;
5890    }
5891
5892    private ResolveInfo findPersistentPreferredActivityLP(Intent intent, String resolvedType,
5893            int flags, List<ResolveInfo> query, boolean debug, int userId) {
5894        final int N = query.size();
5895        PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
5896                .get(userId);
5897        // Get the list of persistent preferred activities that handle the intent
5898        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for presistent preferred activities...");
5899        List<PersistentPreferredActivity> pprefs = ppir != null
5900                ? ppir.queryIntent(intent, resolvedType,
5901                        (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
5902                        userId)
5903                : null;
5904        if (pprefs != null && pprefs.size() > 0) {
5905            final int M = pprefs.size();
5906            for (int i=0; i<M; i++) {
5907                final PersistentPreferredActivity ppa = pprefs.get(i);
5908                if (DEBUG_PREFERRED || debug) {
5909                    Slog.v(TAG, "Checking PersistentPreferredActivity ds="
5910                            + (ppa.countDataSchemes() > 0 ? ppa.getDataScheme(0) : "<none>")
5911                            + "\n  component=" + ppa.mComponent);
5912                    ppa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
5913                }
5914                final ActivityInfo ai = getActivityInfo(ppa.mComponent,
5915                        flags | MATCH_DISABLED_COMPONENTS, userId);
5916                if (DEBUG_PREFERRED || debug) {
5917                    Slog.v(TAG, "Found persistent preferred activity:");
5918                    if (ai != null) {
5919                        ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
5920                    } else {
5921                        Slog.v(TAG, "  null");
5922                    }
5923                }
5924                if (ai == null) {
5925                    // This previously registered persistent preferred activity
5926                    // component is no longer known. Ignore it and do NOT remove it.
5927                    continue;
5928                }
5929                for (int j=0; j<N; j++) {
5930                    final ResolveInfo ri = query.get(j);
5931                    if (!ri.activityInfo.applicationInfo.packageName
5932                            .equals(ai.applicationInfo.packageName)) {
5933                        continue;
5934                    }
5935                    if (!ri.activityInfo.name.equals(ai.name)) {
5936                        continue;
5937                    }
5938                    //  Found a persistent preference that can handle the intent.
5939                    if (DEBUG_PREFERRED || debug) {
5940                        Slog.v(TAG, "Returning persistent preferred activity: " +
5941                                ri.activityInfo.packageName + "/" + ri.activityInfo.name);
5942                    }
5943                    return ri;
5944                }
5945            }
5946        }
5947        return null;
5948    }
5949
5950    // TODO: handle preferred activities missing while user has amnesia
5951    ResolveInfo findPreferredActivity(Intent intent, String resolvedType, int flags,
5952            List<ResolveInfo> query, int priority, boolean always,
5953            boolean removeMatches, boolean debug, int userId) {
5954        if (!sUserManager.exists(userId)) return null;
5955        final int callingUid = Binder.getCallingUid();
5956        flags = updateFlagsForResolve(
5957                flags, userId, intent, callingUid, false /*includeInstantApps*/);
5958        intent = updateIntentForResolve(intent);
5959        // writer
5960        synchronized (mPackages) {
5961            // Try to find a matching persistent preferred activity.
5962            ResolveInfo pri = findPersistentPreferredActivityLP(intent, resolvedType, flags, query,
5963                    debug, userId);
5964
5965            // If a persistent preferred activity matched, use it.
5966            if (pri != null) {
5967                return pri;
5968            }
5969
5970            PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
5971            // Get the list of preferred activities that handle the intent
5972            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for preferred activities...");
5973            List<PreferredActivity> prefs = pir != null
5974                    ? pir.queryIntent(intent, resolvedType,
5975                            (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
5976                            userId)
5977                    : null;
5978            if (prefs != null && prefs.size() > 0) {
5979                boolean changed = false;
5980                try {
5981                    // First figure out how good the original match set is.
5982                    // We will only allow preferred activities that came
5983                    // from the same match quality.
5984                    int match = 0;
5985
5986                    if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Figuring out best match...");
5987
5988                    final int N = query.size();
5989                    for (int j=0; j<N; j++) {
5990                        final ResolveInfo ri = query.get(j);
5991                        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Match for " + ri.activityInfo
5992                                + ": 0x" + Integer.toHexString(match));
5993                        if (ri.match > match) {
5994                            match = ri.match;
5995                        }
5996                    }
5997
5998                    if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Best match: 0x"
5999                            + Integer.toHexString(match));
6000
6001                    match &= IntentFilter.MATCH_CATEGORY_MASK;
6002                    final int M = prefs.size();
6003                    for (int i=0; i<M; i++) {
6004                        final PreferredActivity pa = prefs.get(i);
6005                        if (DEBUG_PREFERRED || debug) {
6006                            Slog.v(TAG, "Checking PreferredActivity ds="
6007                                    + (pa.countDataSchemes() > 0 ? pa.getDataScheme(0) : "<none>")
6008                                    + "\n  component=" + pa.mPref.mComponent);
6009                            pa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
6010                        }
6011                        if (pa.mPref.mMatch != match) {
6012                            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping bad match "
6013                                    + Integer.toHexString(pa.mPref.mMatch));
6014                            continue;
6015                        }
6016                        // If it's not an "always" type preferred activity and that's what we're
6017                        // looking for, skip it.
6018                        if (always && !pa.mPref.mAlways) {
6019                            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping mAlways=false entry");
6020                            continue;
6021                        }
6022                        final ActivityInfo ai = getActivityInfo(
6023                                pa.mPref.mComponent, flags | MATCH_DISABLED_COMPONENTS
6024                                        | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
6025                                userId);
6026                        if (DEBUG_PREFERRED || debug) {
6027                            Slog.v(TAG, "Found preferred activity:");
6028                            if (ai != null) {
6029                                ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
6030                            } else {
6031                                Slog.v(TAG, "  null");
6032                            }
6033                        }
6034                        if (ai == null) {
6035                            // This previously registered preferred activity
6036                            // component is no longer known.  Most likely an update
6037                            // to the app was installed and in the new version this
6038                            // component no longer exists.  Clean it up by removing
6039                            // it from the preferred activities list, and skip it.
6040                            Slog.w(TAG, "Removing dangling preferred activity: "
6041                                    + pa.mPref.mComponent);
6042                            pir.removeFilter(pa);
6043                            changed = true;
6044                            continue;
6045                        }
6046                        for (int j=0; j<N; j++) {
6047                            final ResolveInfo ri = query.get(j);
6048                            if (!ri.activityInfo.applicationInfo.packageName
6049                                    .equals(ai.applicationInfo.packageName)) {
6050                                continue;
6051                            }
6052                            if (!ri.activityInfo.name.equals(ai.name)) {
6053                                continue;
6054                            }
6055
6056                            if (removeMatches) {
6057                                pir.removeFilter(pa);
6058                                changed = true;
6059                                if (DEBUG_PREFERRED) {
6060                                    Slog.v(TAG, "Removing match " + pa.mPref.mComponent);
6061                                }
6062                                break;
6063                            }
6064
6065                            // Okay we found a previously set preferred or last chosen app.
6066                            // If the result set is different from when this
6067                            // was created, we need to clear it and re-ask the
6068                            // user their preference, if we're looking for an "always" type entry.
6069                            if (always && !pa.mPref.sameSet(query)) {
6070                                Slog.i(TAG, "Result set changed, dropping preferred activity for "
6071                                        + intent + " type " + resolvedType);
6072                                if (DEBUG_PREFERRED) {
6073                                    Slog.v(TAG, "Removing preferred activity since set changed "
6074                                            + pa.mPref.mComponent);
6075                                }
6076                                pir.removeFilter(pa);
6077                                // Re-add the filter as a "last chosen" entry (!always)
6078                                PreferredActivity lastChosen = new PreferredActivity(
6079                                        pa, pa.mPref.mMatch, null, pa.mPref.mComponent, false);
6080                                pir.addFilter(lastChosen);
6081                                changed = true;
6082                                return null;
6083                            }
6084
6085                            // Yay! Either the set matched or we're looking for the last chosen
6086                            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Returning preferred activity: "
6087                                    + ri.activityInfo.packageName + "/" + ri.activityInfo.name);
6088                            return ri;
6089                        }
6090                    }
6091                } finally {
6092                    if (changed) {
6093                        if (DEBUG_PREFERRED) {
6094                            Slog.v(TAG, "Preferred activity bookkeeping changed; writing restrictions");
6095                        }
6096                        scheduleWritePackageRestrictionsLocked(userId);
6097                    }
6098                }
6099            }
6100        }
6101        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "No preferred activity to return");
6102        return null;
6103    }
6104
6105    /*
6106     * Returns if intent can be forwarded from the sourceUserId to the targetUserId
6107     */
6108    @Override
6109    public boolean canForwardTo(Intent intent, String resolvedType, int sourceUserId,
6110            int targetUserId) {
6111        mContext.enforceCallingOrSelfPermission(
6112                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
6113        List<CrossProfileIntentFilter> matches =
6114                getMatchingCrossProfileIntentFilters(intent, resolvedType, sourceUserId);
6115        if (matches != null) {
6116            int size = matches.size();
6117            for (int i = 0; i < size; i++) {
6118                if (matches.get(i).getTargetUserId() == targetUserId) return true;
6119            }
6120        }
6121        if (hasWebURI(intent)) {
6122            // cross-profile app linking works only towards the parent.
6123            final int callingUid = Binder.getCallingUid();
6124            final UserInfo parent = getProfileParent(sourceUserId);
6125            synchronized(mPackages) {
6126                int flags = updateFlagsForResolve(0, parent.id, intent, callingUid,
6127                        false /*includeInstantApps*/);
6128                CrossProfileDomainInfo xpDomainInfo = getCrossProfileDomainPreferredLpr(
6129                        intent, resolvedType, flags, sourceUserId, parent.id);
6130                return xpDomainInfo != null;
6131            }
6132        }
6133        return false;
6134    }
6135
6136    private UserInfo getProfileParent(int userId) {
6137        final long identity = Binder.clearCallingIdentity();
6138        try {
6139            return sUserManager.getProfileParent(userId);
6140        } finally {
6141            Binder.restoreCallingIdentity(identity);
6142        }
6143    }
6144
6145    private List<CrossProfileIntentFilter> getMatchingCrossProfileIntentFilters(Intent intent,
6146            String resolvedType, int userId) {
6147        CrossProfileIntentResolver resolver = mSettings.mCrossProfileIntentResolvers.get(userId);
6148        if (resolver != null) {
6149            return resolver.queryIntent(intent, resolvedType, false /*defaultOnly*/, userId);
6150        }
6151        return null;
6152    }
6153
6154    @Override
6155    public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivities(Intent intent,
6156            String resolvedType, int flags, int userId) {
6157        try {
6158            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities");
6159
6160            return new ParceledListSlice<>(
6161                    queryIntentActivitiesInternal(intent, resolvedType, flags, userId));
6162        } finally {
6163            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
6164        }
6165    }
6166
6167    /**
6168     * Returns the package name of the calling Uid if it's an instant app. If it isn't
6169     * instant, returns {@code null}.
6170     */
6171    private String getInstantAppPackageName(int callingUid) {
6172        // If the caller is an isolated app use the owner's uid for the lookup.
6173        if (Process.isIsolated(callingUid)) {
6174            callingUid = mIsolatedOwners.get(callingUid);
6175        }
6176        final int appId = UserHandle.getAppId(callingUid);
6177        synchronized (mPackages) {
6178            final Object obj = mSettings.getUserIdLPr(appId);
6179            if (obj instanceof PackageSetting) {
6180                final PackageSetting ps = (PackageSetting) obj;
6181                final boolean isInstantApp = ps.getInstantApp(UserHandle.getUserId(callingUid));
6182                return isInstantApp ? ps.pkg.packageName : null;
6183            }
6184        }
6185        return null;
6186    }
6187
6188    private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
6189            String resolvedType, int flags, int userId) {
6190        return queryIntentActivitiesInternal(intent, resolvedType, flags, userId, false);
6191    }
6192
6193    private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
6194            String resolvedType, int flags, int userId, boolean includeInstantApps) {
6195        if (!sUserManager.exists(userId)) return Collections.emptyList();
6196        final int callingUid = Binder.getCallingUid();
6197        final String instantAppPkgName = getInstantAppPackageName(callingUid);
6198        flags = updateFlagsForResolve(flags, userId, intent, callingUid, includeInstantApps);
6199        enforceCrossUserPermission(callingUid, userId,
6200                false /* requireFullPermission */, false /* checkShell */,
6201                "query intent activities");
6202        ComponentName comp = intent.getComponent();
6203        if (comp == null) {
6204            if (intent.getSelector() != null) {
6205                intent = intent.getSelector();
6206                comp = intent.getComponent();
6207            }
6208        }
6209
6210        if (comp != null) {
6211            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
6212            final ActivityInfo ai = getActivityInfo(comp, flags, userId);
6213            if (ai != null) {
6214                // When specifying an explicit component, we prevent the activity from being
6215                // used when either 1) the calling package is normal and the activity is within
6216                // an ephemeral application or 2) the calling package is ephemeral and the
6217                // activity is not visible to ephemeral applications.
6218                final boolean matchInstantApp =
6219                        (flags & PackageManager.MATCH_INSTANT) != 0;
6220                final boolean matchVisibleToInstantAppOnly =
6221                        (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
6222                final boolean isCallerInstantApp =
6223                        instantAppPkgName != null;
6224                final boolean isTargetSameInstantApp =
6225                        comp.getPackageName().equals(instantAppPkgName);
6226                final boolean isTargetInstantApp =
6227                        (ai.applicationInfo.privateFlags
6228                                & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
6229                final boolean isTargetHiddenFromInstantApp =
6230                        (ai.flags & ActivityInfo.FLAG_VISIBLE_TO_EPHEMERAL) == 0;
6231                final boolean blockResolution =
6232                        !isTargetSameInstantApp
6233                        && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
6234                                || (matchVisibleToInstantAppOnly && isCallerInstantApp
6235                                        && isTargetHiddenFromInstantApp));
6236                if (!blockResolution) {
6237                    final ResolveInfo ri = new ResolveInfo();
6238                    ri.activityInfo = ai;
6239                    list.add(ri);
6240                }
6241            }
6242            return applyPostResolutionFilter(list, instantAppPkgName);
6243        }
6244
6245        // reader
6246        boolean sortResult = false;
6247        boolean addEphemeral = false;
6248        List<ResolveInfo> result;
6249        final String pkgName = intent.getPackage();
6250        final boolean ephemeralDisabled = isEphemeralDisabled();
6251        synchronized (mPackages) {
6252            if (pkgName == null) {
6253                List<CrossProfileIntentFilter> matchingFilters =
6254                        getMatchingCrossProfileIntentFilters(intent, resolvedType, userId);
6255                // Check for results that need to skip the current profile.
6256                ResolveInfo xpResolveInfo  = querySkipCurrentProfileIntents(matchingFilters, intent,
6257                        resolvedType, flags, userId);
6258                if (xpResolveInfo != null) {
6259                    List<ResolveInfo> xpResult = new ArrayList<ResolveInfo>(1);
6260                    xpResult.add(xpResolveInfo);
6261                    return applyPostResolutionFilter(
6262                            filterIfNotSystemUser(xpResult, userId), instantAppPkgName);
6263                }
6264
6265                // Check for results in the current profile.
6266                result = filterIfNotSystemUser(mActivities.queryIntent(
6267                        intent, resolvedType, flags, userId), userId);
6268                addEphemeral = !ephemeralDisabled
6269                        && isEphemeralAllowed(intent, result, userId, false /*skipPackageCheck*/);
6270                // Check for cross profile results.
6271                boolean hasNonNegativePriorityResult = hasNonNegativePriority(result);
6272                xpResolveInfo = queryCrossProfileIntents(
6273                        matchingFilters, intent, resolvedType, flags, userId,
6274                        hasNonNegativePriorityResult);
6275                if (xpResolveInfo != null && isUserEnabled(xpResolveInfo.targetUserId)) {
6276                    boolean isVisibleToUser = filterIfNotSystemUser(
6277                            Collections.singletonList(xpResolveInfo), userId).size() > 0;
6278                    if (isVisibleToUser) {
6279                        result.add(xpResolveInfo);
6280                        sortResult = true;
6281                    }
6282                }
6283                if (hasWebURI(intent)) {
6284                    CrossProfileDomainInfo xpDomainInfo = null;
6285                    final UserInfo parent = getProfileParent(userId);
6286                    if (parent != null) {
6287                        xpDomainInfo = getCrossProfileDomainPreferredLpr(intent, resolvedType,
6288                                flags, userId, parent.id);
6289                    }
6290                    if (xpDomainInfo != null) {
6291                        if (xpResolveInfo != null) {
6292                            // If we didn't remove it, the cross-profile ResolveInfo would be twice
6293                            // in the result.
6294                            result.remove(xpResolveInfo);
6295                        }
6296                        if (result.size() == 0 && !addEphemeral) {
6297                            // No result in current profile, but found candidate in parent user.
6298                            // And we are not going to add emphemeral app, so we can return the
6299                            // result straight away.
6300                            result.add(xpDomainInfo.resolveInfo);
6301                            return applyPostResolutionFilter(result, instantAppPkgName);
6302                        }
6303                    } else if (result.size() <= 1 && !addEphemeral) {
6304                        // No result in parent user and <= 1 result in current profile, and we
6305                        // are not going to add emphemeral app, so we can return the result without
6306                        // further processing.
6307                        return applyPostResolutionFilter(result, instantAppPkgName);
6308                    }
6309                    // We have more than one candidate (combining results from current and parent
6310                    // profile), so we need filtering and sorting.
6311                    result = filterCandidatesWithDomainPreferredActivitiesLPr(
6312                            intent, flags, result, xpDomainInfo, userId);
6313                    sortResult = true;
6314                }
6315            } else {
6316                final PackageParser.Package pkg = mPackages.get(pkgName);
6317                if (pkg != null) {
6318                    return applyPostResolutionFilter(filterIfNotSystemUser(
6319                            mActivities.queryIntentForPackage(
6320                                    intent, resolvedType, flags, pkg.activities, userId),
6321                            userId), instantAppPkgName);
6322                } else {
6323                    // the caller wants to resolve for a particular package; however, there
6324                    // were no installed results, so, try to find an ephemeral result
6325                    addEphemeral = !ephemeralDisabled
6326                            && isEphemeralAllowed(
6327                                    intent, null /*result*/, userId, true /*skipPackageCheck*/);
6328                    result = new ArrayList<ResolveInfo>();
6329                }
6330            }
6331        }
6332        if (addEphemeral) {
6333            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveEphemeral");
6334            final InstantAppRequest requestObject = new InstantAppRequest(
6335                    null /*responseObj*/, intent /*origIntent*/, resolvedType,
6336                    null /*callingPackage*/, userId);
6337            final AuxiliaryResolveInfo auxiliaryResponse =
6338                    InstantAppResolver.doInstantAppResolutionPhaseOne(
6339                            mContext, mInstantAppResolverConnection, requestObject);
6340            if (auxiliaryResponse != null) {
6341                if (DEBUG_EPHEMERAL) {
6342                    Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
6343                }
6344                final ResolveInfo ephemeralInstaller = new ResolveInfo(mInstantAppInstallerInfo);
6345                final PackageSetting ps =
6346                        mSettings.mPackages.get(mInstantAppInstallerActivity.packageName);
6347                if (ps != null) {
6348                    ephemeralInstaller.activityInfo = PackageParser.generateActivityInfo(
6349                            mInstantAppInstallerActivity, 0, ps.readUserState(userId), userId);
6350                    ephemeralInstaller.activityInfo.launchToken = auxiliaryResponse.token;
6351                    ephemeralInstaller.auxiliaryInfo = auxiliaryResponse;
6352                    // make sure this resolver is the default
6353                    ephemeralInstaller.isDefault = true;
6354                    ephemeralInstaller.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
6355                            | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
6356                    // add a non-generic filter
6357                    ephemeralInstaller.filter = new IntentFilter(intent.getAction());
6358                    ephemeralInstaller.filter.addDataPath(
6359                            intent.getData().getPath(), PatternMatcher.PATTERN_LITERAL);
6360                    ephemeralInstaller.instantAppAvailable = true;
6361                    result.add(ephemeralInstaller);
6362                }
6363            }
6364            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
6365        }
6366        if (sortResult) {
6367            Collections.sort(result, mResolvePrioritySorter);
6368        }
6369        return applyPostResolutionFilter(result, instantAppPkgName);
6370    }
6371
6372    private static class CrossProfileDomainInfo {
6373        /* ResolveInfo for IntentForwarderActivity to send the intent to the other profile */
6374        ResolveInfo resolveInfo;
6375        /* Best domain verification status of the activities found in the other profile */
6376        int bestDomainVerificationStatus;
6377    }
6378
6379    private CrossProfileDomainInfo getCrossProfileDomainPreferredLpr(Intent intent,
6380            String resolvedType, int flags, int sourceUserId, int parentUserId) {
6381        if (!sUserManager.hasUserRestriction(UserManager.ALLOW_PARENT_PROFILE_APP_LINKING,
6382                sourceUserId)) {
6383            return null;
6384        }
6385        List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent,
6386                resolvedType, flags, parentUserId);
6387
6388        if (resultTargetUser == null || resultTargetUser.isEmpty()) {
6389            return null;
6390        }
6391        CrossProfileDomainInfo result = null;
6392        int size = resultTargetUser.size();
6393        for (int i = 0; i < size; i++) {
6394            ResolveInfo riTargetUser = resultTargetUser.get(i);
6395            // Intent filter verification is only for filters that specify a host. So don't return
6396            // those that handle all web uris.
6397            if (riTargetUser.handleAllWebDataURI) {
6398                continue;
6399            }
6400            String packageName = riTargetUser.activityInfo.packageName;
6401            PackageSetting ps = mSettings.mPackages.get(packageName);
6402            if (ps == null) {
6403                continue;
6404            }
6405            long verificationState = getDomainVerificationStatusLPr(ps, parentUserId);
6406            int status = (int)(verificationState >> 32);
6407            if (result == null) {
6408                result = new CrossProfileDomainInfo();
6409                result.resolveInfo = createForwardingResolveInfoUnchecked(new IntentFilter(),
6410                        sourceUserId, parentUserId);
6411                result.bestDomainVerificationStatus = status;
6412            } else {
6413                result.bestDomainVerificationStatus = bestDomainVerificationStatus(status,
6414                        result.bestDomainVerificationStatus);
6415            }
6416        }
6417        // Don't consider matches with status NEVER across profiles.
6418        if (result != null && result.bestDomainVerificationStatus
6419                == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
6420            return null;
6421        }
6422        return result;
6423    }
6424
6425    /**
6426     * Verification statuses are ordered from the worse to the best, except for
6427     * INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER, which is the worse.
6428     */
6429    private int bestDomainVerificationStatus(int status1, int status2) {
6430        if (status1 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
6431            return status2;
6432        }
6433        if (status2 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
6434            return status1;
6435        }
6436        return (int) MathUtils.max(status1, status2);
6437    }
6438
6439    private boolean isUserEnabled(int userId) {
6440        long callingId = Binder.clearCallingIdentity();
6441        try {
6442            UserInfo userInfo = sUserManager.getUserInfo(userId);
6443            return userInfo != null && userInfo.isEnabled();
6444        } finally {
6445            Binder.restoreCallingIdentity(callingId);
6446        }
6447    }
6448
6449    /**
6450     * Filter out activities with systemUserOnly flag set, when current user is not System.
6451     *
6452     * @return filtered list
6453     */
6454    private List<ResolveInfo> filterIfNotSystemUser(List<ResolveInfo> resolveInfos, int userId) {
6455        if (userId == UserHandle.USER_SYSTEM) {
6456            return resolveInfos;
6457        }
6458        for (int i = resolveInfos.size() - 1; i >= 0; i--) {
6459            ResolveInfo info = resolveInfos.get(i);
6460            if ((info.activityInfo.flags & ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
6461                resolveInfos.remove(i);
6462            }
6463        }
6464        return resolveInfos;
6465    }
6466
6467    /**
6468     * Filters out ephemeral activities.
6469     * <p>When resolving for an ephemeral app, only activities that 1) are defined in the
6470     * ephemeral app or 2) marked with {@code visibleToEphemeral} are returned.
6471     *
6472     * @param resolveInfos The pre-filtered list of resolved activities
6473     * @param ephemeralPkgName The ephemeral package name. If {@code null}, no filtering
6474     *          is performed.
6475     * @return A filtered list of resolved activities.
6476     */
6477    private List<ResolveInfo> applyPostResolutionFilter(List<ResolveInfo> resolveInfos,
6478            String ephemeralPkgName) {
6479        // TODO: When adding on-demand split support for non-instant apps, remove this check
6480        // and always apply post filtering
6481        if (ephemeralPkgName == null) {
6482            return resolveInfos;
6483        }
6484        for (int i = resolveInfos.size() - 1; i >= 0; i--) {
6485            final ResolveInfo info = resolveInfos.get(i);
6486            final boolean isEphemeralApp = info.activityInfo.applicationInfo.isInstantApp();
6487            // allow activities that are defined in the provided package
6488            if (isEphemeralApp && ephemeralPkgName.equals(info.activityInfo.packageName)) {
6489                if (info.activityInfo.splitName != null
6490                        && !ArrayUtils.contains(info.activityInfo.applicationInfo.splitNames,
6491                                info.activityInfo.splitName)) {
6492                    // requested activity is defined in a split that hasn't been installed yet.
6493                    // add the installer to the resolve list
6494                    if (DEBUG_EPHEMERAL) {
6495                        Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
6496                    }
6497                    final ResolveInfo installerInfo = new ResolveInfo(mInstantAppInstallerInfo);
6498                    installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
6499                            info.activityInfo.packageName, info.activityInfo.splitName,
6500                            info.activityInfo.applicationInfo.versionCode);
6501                    // make sure this resolver is the default
6502                    installerInfo.isDefault = true;
6503                    installerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
6504                            | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
6505                    // add a non-generic filter
6506                    installerInfo.filter = new IntentFilter();
6507                    // load resources from the correct package
6508                    installerInfo.resolvePackageName = info.getComponentInfo().packageName;
6509                    resolveInfos.set(i, installerInfo);
6510                }
6511                continue;
6512            }
6513            // allow activities that have been explicitly exposed to ephemeral apps
6514            if (!isEphemeralApp
6515                    && ((info.activityInfo.flags & ActivityInfo.FLAG_VISIBLE_TO_EPHEMERAL) != 0)) {
6516                continue;
6517            }
6518            resolveInfos.remove(i);
6519        }
6520        return resolveInfos;
6521    }
6522
6523    /**
6524     * @param resolveInfos list of resolve infos in descending priority order
6525     * @return if the list contains a resolve info with non-negative priority
6526     */
6527    private boolean hasNonNegativePriority(List<ResolveInfo> resolveInfos) {
6528        return resolveInfos.size() > 0 && resolveInfos.get(0).priority >= 0;
6529    }
6530
6531    private static boolean hasWebURI(Intent intent) {
6532        if (intent.getData() == null) {
6533            return false;
6534        }
6535        final String scheme = intent.getScheme();
6536        if (TextUtils.isEmpty(scheme)) {
6537            return false;
6538        }
6539        return scheme.equals(IntentFilter.SCHEME_HTTP) || scheme.equals(IntentFilter.SCHEME_HTTPS);
6540    }
6541
6542    private List<ResolveInfo> filterCandidatesWithDomainPreferredActivitiesLPr(Intent intent,
6543            int matchFlags, List<ResolveInfo> candidates, CrossProfileDomainInfo xpDomainInfo,
6544            int userId) {
6545        final boolean debug = (intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0;
6546
6547        if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) {
6548            Slog.v(TAG, "Filtering results with preferred activities. Candidates count: " +
6549                    candidates.size());
6550        }
6551
6552        ArrayList<ResolveInfo> result = new ArrayList<ResolveInfo>();
6553        ArrayList<ResolveInfo> alwaysList = new ArrayList<ResolveInfo>();
6554        ArrayList<ResolveInfo> undefinedList = new ArrayList<ResolveInfo>();
6555        ArrayList<ResolveInfo> alwaysAskList = new ArrayList<ResolveInfo>();
6556        ArrayList<ResolveInfo> neverList = new ArrayList<ResolveInfo>();
6557        ArrayList<ResolveInfo> matchAllList = new ArrayList<ResolveInfo>();
6558
6559        synchronized (mPackages) {
6560            final int count = candidates.size();
6561            // First, try to use linked apps. Partition the candidates into four lists:
6562            // one for the final results, one for the "do not use ever", one for "undefined status"
6563            // and finally one for "browser app type".
6564            for (int n=0; n<count; n++) {
6565                ResolveInfo info = candidates.get(n);
6566                String packageName = info.activityInfo.packageName;
6567                PackageSetting ps = mSettings.mPackages.get(packageName);
6568                if (ps != null) {
6569                    // Add to the special match all list (Browser use case)
6570                    if (info.handleAllWebDataURI) {
6571                        matchAllList.add(info);
6572                        continue;
6573                    }
6574                    // Try to get the status from User settings first
6575                    long packedStatus = getDomainVerificationStatusLPr(ps, userId);
6576                    int status = (int)(packedStatus >> 32);
6577                    int linkGeneration = (int)(packedStatus & 0xFFFFFFFF);
6578                    if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) {
6579                        if (DEBUG_DOMAIN_VERIFICATION || debug) {
6580                            Slog.i(TAG, "  + always: " + info.activityInfo.packageName
6581                                    + " : linkgen=" + linkGeneration);
6582                        }
6583                        // Use link-enabled generation as preferredOrder, i.e.
6584                        // prefer newly-enabled over earlier-enabled.
6585                        info.preferredOrder = linkGeneration;
6586                        alwaysList.add(info);
6587                    } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
6588                        if (DEBUG_DOMAIN_VERIFICATION || debug) {
6589                            Slog.i(TAG, "  + never: " + info.activityInfo.packageName);
6590                        }
6591                        neverList.add(info);
6592                    } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
6593                        if (DEBUG_DOMAIN_VERIFICATION || debug) {
6594                            Slog.i(TAG, "  + always-ask: " + info.activityInfo.packageName);
6595                        }
6596                        alwaysAskList.add(info);
6597                    } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED ||
6598                            status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK) {
6599                        if (DEBUG_DOMAIN_VERIFICATION || debug) {
6600                            Slog.i(TAG, "  + ask: " + info.activityInfo.packageName);
6601                        }
6602                        undefinedList.add(info);
6603                    }
6604                }
6605            }
6606
6607            // We'll want to include browser possibilities in a few cases
6608            boolean includeBrowser = false;
6609
6610            // First try to add the "always" resolution(s) for the current user, if any
6611            if (alwaysList.size() > 0) {
6612                result.addAll(alwaysList);
6613            } else {
6614                // Add all undefined apps as we want them to appear in the disambiguation dialog.
6615                result.addAll(undefinedList);
6616                // Maybe add one for the other profile.
6617                if (xpDomainInfo != null && (
6618                        xpDomainInfo.bestDomainVerificationStatus
6619                        != INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER)) {
6620                    result.add(xpDomainInfo.resolveInfo);
6621                }
6622                includeBrowser = true;
6623            }
6624
6625            // The presence of any 'always ask' alternatives means we'll also offer browsers.
6626            // If there were 'always' entries their preferred order has been set, so we also
6627            // back that off to make the alternatives equivalent
6628            if (alwaysAskList.size() > 0) {
6629                for (ResolveInfo i : result) {
6630                    i.preferredOrder = 0;
6631                }
6632                result.addAll(alwaysAskList);
6633                includeBrowser = true;
6634            }
6635
6636            if (includeBrowser) {
6637                // Also add browsers (all of them or only the default one)
6638                if (DEBUG_DOMAIN_VERIFICATION) {
6639                    Slog.v(TAG, "   ...including browsers in candidate set");
6640                }
6641                if ((matchFlags & MATCH_ALL) != 0) {
6642                    result.addAll(matchAllList);
6643                } else {
6644                    // Browser/generic handling case.  If there's a default browser, go straight
6645                    // to that (but only if there is no other higher-priority match).
6646                    final String defaultBrowserPackageName = getDefaultBrowserPackageName(userId);
6647                    int maxMatchPrio = 0;
6648                    ResolveInfo defaultBrowserMatch = null;
6649                    final int numCandidates = matchAllList.size();
6650                    for (int n = 0; n < numCandidates; n++) {
6651                        ResolveInfo info = matchAllList.get(n);
6652                        // track the highest overall match priority...
6653                        if (info.priority > maxMatchPrio) {
6654                            maxMatchPrio = info.priority;
6655                        }
6656                        // ...and the highest-priority default browser match
6657                        if (info.activityInfo.packageName.equals(defaultBrowserPackageName)) {
6658                            if (defaultBrowserMatch == null
6659                                    || (defaultBrowserMatch.priority < info.priority)) {
6660                                if (debug) {
6661                                    Slog.v(TAG, "Considering default browser match " + info);
6662                                }
6663                                defaultBrowserMatch = info;
6664                            }
6665                        }
6666                    }
6667                    if (defaultBrowserMatch != null
6668                            && defaultBrowserMatch.priority >= maxMatchPrio
6669                            && !TextUtils.isEmpty(defaultBrowserPackageName))
6670                    {
6671                        if (debug) {
6672                            Slog.v(TAG, "Default browser match " + defaultBrowserMatch);
6673                        }
6674                        result.add(defaultBrowserMatch);
6675                    } else {
6676                        result.addAll(matchAllList);
6677                    }
6678                }
6679
6680                // If there is nothing selected, add all candidates and remove the ones that the user
6681                // has explicitly put into the INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER state
6682                if (result.size() == 0) {
6683                    result.addAll(candidates);
6684                    result.removeAll(neverList);
6685                }
6686            }
6687        }
6688        if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) {
6689            Slog.v(TAG, "Filtered results with preferred activities. New candidates count: " +
6690                    result.size());
6691            for (ResolveInfo info : result) {
6692                Slog.v(TAG, "  + " + info.activityInfo);
6693            }
6694        }
6695        return result;
6696    }
6697
6698    // Returns a packed value as a long:
6699    //
6700    // high 'int'-sized word: link status: undefined/ask/never/always.
6701    // low 'int'-sized word: relative priority among 'always' results.
6702    private long getDomainVerificationStatusLPr(PackageSetting ps, int userId) {
6703        long result = ps.getDomainVerificationStatusForUser(userId);
6704        // if none available, get the master status
6705        if (result >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) {
6706            if (ps.getIntentFilterVerificationInfo() != null) {
6707                result = ((long)ps.getIntentFilterVerificationInfo().getStatus()) << 32;
6708            }
6709        }
6710        return result;
6711    }
6712
6713    private ResolveInfo querySkipCurrentProfileIntents(
6714            List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
6715            int flags, int sourceUserId) {
6716        if (matchingFilters != null) {
6717            int size = matchingFilters.size();
6718            for (int i = 0; i < size; i ++) {
6719                CrossProfileIntentFilter filter = matchingFilters.get(i);
6720                if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0) {
6721                    // Checking if there are activities in the target user that can handle the
6722                    // intent.
6723                    ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent,
6724                            resolvedType, flags, sourceUserId);
6725                    if (resolveInfo != null) {
6726                        return resolveInfo;
6727                    }
6728                }
6729            }
6730        }
6731        return null;
6732    }
6733
6734    // Return matching ResolveInfo in target user if any.
6735    private ResolveInfo queryCrossProfileIntents(
6736            List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
6737            int flags, int sourceUserId, boolean matchInCurrentProfile) {
6738        if (matchingFilters != null) {
6739            // Two {@link CrossProfileIntentFilter}s can have the same targetUserId and
6740            // match the same intent. For performance reasons, it is better not to
6741            // run queryIntent twice for the same userId
6742            SparseBooleanArray alreadyTriedUserIds = new SparseBooleanArray();
6743            int size = matchingFilters.size();
6744            for (int i = 0; i < size; i++) {
6745                CrossProfileIntentFilter filter = matchingFilters.get(i);
6746                int targetUserId = filter.getTargetUserId();
6747                boolean skipCurrentProfile =
6748                        (filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0;
6749                boolean skipCurrentProfileIfNoMatchFound =
6750                        (filter.getFlags() & PackageManager.ONLY_IF_NO_MATCH_FOUND) != 0;
6751                if (!skipCurrentProfile && !alreadyTriedUserIds.get(targetUserId)
6752                        && (!skipCurrentProfileIfNoMatchFound || !matchInCurrentProfile)) {
6753                    // Checking if there are activities in the target user that can handle the
6754                    // intent.
6755                    ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent,
6756                            resolvedType, flags, sourceUserId);
6757                    if (resolveInfo != null) return resolveInfo;
6758                    alreadyTriedUserIds.put(targetUserId, true);
6759                }
6760            }
6761        }
6762        return null;
6763    }
6764
6765    /**
6766     * If the filter's target user can handle the intent and is enabled: returns a ResolveInfo that
6767     * will forward the intent to the filter's target user.
6768     * Otherwise, returns null.
6769     */
6770    private ResolveInfo createForwardingResolveInfo(CrossProfileIntentFilter filter, Intent intent,
6771            String resolvedType, int flags, int sourceUserId) {
6772        int targetUserId = filter.getTargetUserId();
6773        List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent,
6774                resolvedType, flags, targetUserId);
6775        if (resultTargetUser != null && isUserEnabled(targetUserId)) {
6776            // If all the matches in the target profile are suspended, return null.
6777            for (int i = resultTargetUser.size() - 1; i >= 0; i--) {
6778                if ((resultTargetUser.get(i).activityInfo.applicationInfo.flags
6779                        & ApplicationInfo.FLAG_SUSPENDED) == 0) {
6780                    return createForwardingResolveInfoUnchecked(filter, sourceUserId,
6781                            targetUserId);
6782                }
6783            }
6784        }
6785        return null;
6786    }
6787
6788    private ResolveInfo createForwardingResolveInfoUnchecked(IntentFilter filter,
6789            int sourceUserId, int targetUserId) {
6790        ResolveInfo forwardingResolveInfo = new ResolveInfo();
6791        long ident = Binder.clearCallingIdentity();
6792        boolean targetIsProfile;
6793        try {
6794            targetIsProfile = sUserManager.getUserInfo(targetUserId).isManagedProfile();
6795        } finally {
6796            Binder.restoreCallingIdentity(ident);
6797        }
6798        String className;
6799        if (targetIsProfile) {
6800            className = FORWARD_INTENT_TO_MANAGED_PROFILE;
6801        } else {
6802            className = FORWARD_INTENT_TO_PARENT;
6803        }
6804        ComponentName forwardingActivityComponentName = new ComponentName(
6805                mAndroidApplication.packageName, className);
6806        ActivityInfo forwardingActivityInfo = getActivityInfo(forwardingActivityComponentName, 0,
6807                sourceUserId);
6808        if (!targetIsProfile) {
6809            forwardingActivityInfo.showUserIcon = targetUserId;
6810            forwardingResolveInfo.noResourceId = true;
6811        }
6812        forwardingResolveInfo.activityInfo = forwardingActivityInfo;
6813        forwardingResolveInfo.priority = 0;
6814        forwardingResolveInfo.preferredOrder = 0;
6815        forwardingResolveInfo.match = 0;
6816        forwardingResolveInfo.isDefault = true;
6817        forwardingResolveInfo.filter = filter;
6818        forwardingResolveInfo.targetUserId = targetUserId;
6819        return forwardingResolveInfo;
6820    }
6821
6822    @Override
6823    public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivityOptions(ComponentName caller,
6824            Intent[] specifics, String[] specificTypes, Intent intent,
6825            String resolvedType, int flags, int userId) {
6826        return new ParceledListSlice<>(queryIntentActivityOptionsInternal(caller, specifics,
6827                specificTypes, intent, resolvedType, flags, userId));
6828    }
6829
6830    private @NonNull List<ResolveInfo> queryIntentActivityOptionsInternal(ComponentName caller,
6831            Intent[] specifics, String[] specificTypes, Intent intent,
6832            String resolvedType, int flags, int userId) {
6833        if (!sUserManager.exists(userId)) return Collections.emptyList();
6834        final int callingUid = Binder.getCallingUid();
6835        flags = updateFlagsForResolve(flags, userId, intent, callingUid,
6836                false /*includeInstantApps*/);
6837        enforceCrossUserPermission(callingUid, userId,
6838                false /*requireFullPermission*/, false /*checkShell*/,
6839                "query intent activity options");
6840        final String resultsAction = intent.getAction();
6841
6842        final List<ResolveInfo> results = queryIntentActivitiesInternal(intent, resolvedType, flags
6843                | PackageManager.GET_RESOLVED_FILTER, userId);
6844
6845        if (DEBUG_INTENT_MATCHING) {
6846            Log.v(TAG, "Query " + intent + ": " + results);
6847        }
6848
6849        int specificsPos = 0;
6850        int N;
6851
6852        // todo: note that the algorithm used here is O(N^2).  This
6853        // isn't a problem in our current environment, but if we start running
6854        // into situations where we have more than 5 or 10 matches then this
6855        // should probably be changed to something smarter...
6856
6857        // First we go through and resolve each of the specific items
6858        // that were supplied, taking care of removing any corresponding
6859        // duplicate items in the generic resolve list.
6860        if (specifics != null) {
6861            for (int i=0; i<specifics.length; i++) {
6862                final Intent sintent = specifics[i];
6863                if (sintent == null) {
6864                    continue;
6865                }
6866
6867                if (DEBUG_INTENT_MATCHING) {
6868                    Log.v(TAG, "Specific #" + i + ": " + sintent);
6869                }
6870
6871                String action = sintent.getAction();
6872                if (resultsAction != null && resultsAction.equals(action)) {
6873                    // If this action was explicitly requested, then don't
6874                    // remove things that have it.
6875                    action = null;
6876                }
6877
6878                ResolveInfo ri = null;
6879                ActivityInfo ai = null;
6880
6881                ComponentName comp = sintent.getComponent();
6882                if (comp == null) {
6883                    ri = resolveIntent(
6884                        sintent,
6885                        specificTypes != null ? specificTypes[i] : null,
6886                            flags, userId);
6887                    if (ri == null) {
6888                        continue;
6889                    }
6890                    if (ri == mResolveInfo) {
6891                        // ACK!  Must do something better with this.
6892                    }
6893                    ai = ri.activityInfo;
6894                    comp = new ComponentName(ai.applicationInfo.packageName,
6895                            ai.name);
6896                } else {
6897                    ai = getActivityInfo(comp, flags, userId);
6898                    if (ai == null) {
6899                        continue;
6900                    }
6901                }
6902
6903                // Look for any generic query activities that are duplicates
6904                // of this specific one, and remove them from the results.
6905                if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Specific #" + i + ": " + ai);
6906                N = results.size();
6907                int j;
6908                for (j=specificsPos; j<N; j++) {
6909                    ResolveInfo sri = results.get(j);
6910                    if ((sri.activityInfo.name.equals(comp.getClassName())
6911                            && sri.activityInfo.applicationInfo.packageName.equals(
6912                                    comp.getPackageName()))
6913                        || (action != null && sri.filter.matchAction(action))) {
6914                        results.remove(j);
6915                        if (DEBUG_INTENT_MATCHING) Log.v(
6916                            TAG, "Removing duplicate item from " + j
6917                            + " due to specific " + specificsPos);
6918                        if (ri == null) {
6919                            ri = sri;
6920                        }
6921                        j--;
6922                        N--;
6923                    }
6924                }
6925
6926                // Add this specific item to its proper place.
6927                if (ri == null) {
6928                    ri = new ResolveInfo();
6929                    ri.activityInfo = ai;
6930                }
6931                results.add(specificsPos, ri);
6932                ri.specificIndex = i;
6933                specificsPos++;
6934            }
6935        }
6936
6937        // Now we go through the remaining generic results and remove any
6938        // duplicate actions that are found here.
6939        N = results.size();
6940        for (int i=specificsPos; i<N-1; i++) {
6941            final ResolveInfo rii = results.get(i);
6942            if (rii.filter == null) {
6943                continue;
6944            }
6945
6946            // Iterate over all of the actions of this result's intent
6947            // filter...  typically this should be just one.
6948            final Iterator<String> it = rii.filter.actionsIterator();
6949            if (it == null) {
6950                continue;
6951            }
6952            while (it.hasNext()) {
6953                final String action = it.next();
6954                if (resultsAction != null && resultsAction.equals(action)) {
6955                    // If this action was explicitly requested, then don't
6956                    // remove things that have it.
6957                    continue;
6958                }
6959                for (int j=i+1; j<N; j++) {
6960                    final ResolveInfo rij = results.get(j);
6961                    if (rij.filter != null && rij.filter.hasAction(action)) {
6962                        results.remove(j);
6963                        if (DEBUG_INTENT_MATCHING) Log.v(
6964                            TAG, "Removing duplicate item from " + j
6965                            + " due to action " + action + " at " + i);
6966                        j--;
6967                        N--;
6968                    }
6969                }
6970            }
6971
6972            // If the caller didn't request filter information, drop it now
6973            // so we don't have to marshall/unmarshall it.
6974            if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
6975                rii.filter = null;
6976            }
6977        }
6978
6979        // Filter out the caller activity if so requested.
6980        if (caller != null) {
6981            N = results.size();
6982            for (int i=0; i<N; i++) {
6983                ActivityInfo ainfo = results.get(i).activityInfo;
6984                if (caller.getPackageName().equals(ainfo.applicationInfo.packageName)
6985                        && caller.getClassName().equals(ainfo.name)) {
6986                    results.remove(i);
6987                    break;
6988                }
6989            }
6990        }
6991
6992        // If the caller didn't request filter information,
6993        // drop them now so we don't have to
6994        // marshall/unmarshall it.
6995        if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
6996            N = results.size();
6997            for (int i=0; i<N; i++) {
6998                results.get(i).filter = null;
6999            }
7000        }
7001
7002        if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Result: " + results);
7003        return results;
7004    }
7005
7006    @Override
7007    public @NonNull ParceledListSlice<ResolveInfo> queryIntentReceivers(Intent intent,
7008            String resolvedType, int flags, int userId) {
7009        return new ParceledListSlice<>(
7010                queryIntentReceiversInternal(intent, resolvedType, flags, userId));
7011    }
7012
7013    private @NonNull List<ResolveInfo> queryIntentReceiversInternal(Intent intent,
7014            String resolvedType, int flags, int userId) {
7015        if (!sUserManager.exists(userId)) return Collections.emptyList();
7016        final int callingUid = Binder.getCallingUid();
7017        flags = updateFlagsForResolve(flags, userId, intent, callingUid,
7018                false /*includeInstantApps*/);
7019        ComponentName comp = intent.getComponent();
7020        if (comp == null) {
7021            if (intent.getSelector() != null) {
7022                intent = intent.getSelector();
7023                comp = intent.getComponent();
7024            }
7025        }
7026        if (comp != null) {
7027            List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
7028            ActivityInfo ai = getReceiverInfo(comp, flags, userId);
7029            if (ai != null) {
7030                ResolveInfo ri = new ResolveInfo();
7031                ri.activityInfo = ai;
7032                list.add(ri);
7033            }
7034            return list;
7035        }
7036
7037        // reader
7038        synchronized (mPackages) {
7039            String pkgName = intent.getPackage();
7040            if (pkgName == null) {
7041                return mReceivers.queryIntent(intent, resolvedType, flags, userId);
7042            }
7043            final PackageParser.Package pkg = mPackages.get(pkgName);
7044            if (pkg != null) {
7045                return mReceivers.queryIntentForPackage(intent, resolvedType, flags, pkg.receivers,
7046                        userId);
7047            }
7048            return Collections.emptyList();
7049        }
7050    }
7051
7052    @Override
7053    public ResolveInfo resolveService(Intent intent, String resolvedType, int flags, int userId) {
7054        final int callingUid = Binder.getCallingUid();
7055        return resolveServiceInternal(
7056                intent, resolvedType, flags, userId, callingUid, false /*includeInstantApps*/);
7057    }
7058
7059    private ResolveInfo resolveServiceInternal(Intent intent, String resolvedType, int flags,
7060            int userId, int callingUid, boolean includeInstantApps) {
7061        if (!sUserManager.exists(userId)) return null;
7062        flags = updateFlagsForResolve(flags, userId, intent, callingUid, includeInstantApps);
7063        List<ResolveInfo> query = queryIntentServicesInternal(
7064                intent, resolvedType, flags, userId, callingUid, includeInstantApps);
7065        if (query != null) {
7066            if (query.size() >= 1) {
7067                // If there is more than one service with the same priority,
7068                // just arbitrarily pick the first one.
7069                return query.get(0);
7070            }
7071        }
7072        return null;
7073    }
7074
7075    @Override
7076    public @NonNull ParceledListSlice<ResolveInfo> queryIntentServices(Intent intent,
7077            String resolvedType, int flags, int userId) {
7078        final int callingUid = Binder.getCallingUid();
7079        return new ParceledListSlice<>(queryIntentServicesInternal(
7080                intent, resolvedType, flags, userId, callingUid, false /*includeInstantApps*/));
7081    }
7082
7083    private @NonNull List<ResolveInfo> queryIntentServicesInternal(Intent intent,
7084            String resolvedType, int flags, int userId, int callingUid,
7085            boolean includeInstantApps) {
7086        if (!sUserManager.exists(userId)) return Collections.emptyList();
7087        final String instantAppPkgName = getInstantAppPackageName(callingUid);
7088        flags = updateFlagsForResolve(flags, userId, intent, callingUid, includeInstantApps);
7089        ComponentName comp = intent.getComponent();
7090        if (comp == null) {
7091            if (intent.getSelector() != null) {
7092                intent = intent.getSelector();
7093                comp = intent.getComponent();
7094            }
7095        }
7096        if (comp != null) {
7097            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
7098            final ServiceInfo si = getServiceInfo(comp, flags, userId);
7099            if (si != null) {
7100                // When specifying an explicit component, we prevent the service from being
7101                // used when either 1) the service is in an instant application and the
7102                // caller is not the same instant application or 2) the calling package is
7103                // ephemeral and the activity is not visible to ephemeral applications.
7104                final boolean matchInstantApp =
7105                        (flags & PackageManager.MATCH_INSTANT) != 0;
7106                final boolean matchVisibleToInstantAppOnly =
7107                        (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
7108                final boolean isCallerInstantApp =
7109                        instantAppPkgName != null;
7110                final boolean isTargetSameInstantApp =
7111                        comp.getPackageName().equals(instantAppPkgName);
7112                final boolean isTargetInstantApp =
7113                        (si.applicationInfo.privateFlags
7114                                & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
7115                final boolean isTargetHiddenFromInstantApp =
7116                        (si.flags & ServiceInfo.FLAG_VISIBLE_TO_EPHEMERAL) == 0;
7117                final boolean blockResolution =
7118                        !isTargetSameInstantApp
7119                        && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
7120                                || (matchVisibleToInstantAppOnly && isCallerInstantApp
7121                                        && isTargetHiddenFromInstantApp));
7122                if (!blockResolution) {
7123                    final ResolveInfo ri = new ResolveInfo();
7124                    ri.serviceInfo = si;
7125                    list.add(ri);
7126                }
7127            }
7128            return list;
7129        }
7130
7131        // reader
7132        synchronized (mPackages) {
7133            String pkgName = intent.getPackage();
7134            if (pkgName == null) {
7135                return applyPostServiceResolutionFilter(
7136                        mServices.queryIntent(intent, resolvedType, flags, userId),
7137                        instantAppPkgName);
7138            }
7139            final PackageParser.Package pkg = mPackages.get(pkgName);
7140            if (pkg != null) {
7141                return applyPostServiceResolutionFilter(
7142                        mServices.queryIntentForPackage(intent, resolvedType, flags, pkg.services,
7143                                userId),
7144                        instantAppPkgName);
7145            }
7146            return Collections.emptyList();
7147        }
7148    }
7149
7150    private List<ResolveInfo> applyPostServiceResolutionFilter(List<ResolveInfo> resolveInfos,
7151            String instantAppPkgName) {
7152        // TODO: When adding on-demand split support for non-instant apps, remove this check
7153        // and always apply post filtering
7154        if (instantAppPkgName == null) {
7155            return resolveInfos;
7156        }
7157        for (int i = resolveInfos.size() - 1; i >= 0; i--) {
7158            final ResolveInfo info = resolveInfos.get(i);
7159            final boolean isEphemeralApp = info.serviceInfo.applicationInfo.isInstantApp();
7160            // allow services that are defined in the provided package
7161            if (isEphemeralApp && instantAppPkgName.equals(info.serviceInfo.packageName)) {
7162                if (info.serviceInfo.splitName != null
7163                        && !ArrayUtils.contains(info.serviceInfo.applicationInfo.splitNames,
7164                                info.serviceInfo.splitName)) {
7165                    // requested service is defined in a split that hasn't been installed yet.
7166                    // add the installer to the resolve list
7167                    if (DEBUG_EPHEMERAL) {
7168                        Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
7169                    }
7170                    final ResolveInfo installerInfo = new ResolveInfo(mInstantAppInstallerInfo);
7171                    installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
7172                            info.serviceInfo.packageName, info.serviceInfo.splitName,
7173                            info.serviceInfo.applicationInfo.versionCode);
7174                    // make sure this resolver is the default
7175                    installerInfo.isDefault = true;
7176                    installerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
7177                            | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
7178                    // add a non-generic filter
7179                    installerInfo.filter = new IntentFilter();
7180                    // load resources from the correct package
7181                    installerInfo.resolvePackageName = info.getComponentInfo().packageName;
7182                    resolveInfos.set(i, installerInfo);
7183                }
7184                continue;
7185            }
7186            // allow services that have been explicitly exposed to ephemeral apps
7187            if (!isEphemeralApp
7188                    && ((info.serviceInfo.flags & ActivityInfo.FLAG_VISIBLE_TO_EPHEMERAL) != 0)) {
7189                continue;
7190            }
7191            resolveInfos.remove(i);
7192        }
7193        return resolveInfos;
7194    }
7195
7196    @Override
7197    public @NonNull ParceledListSlice<ResolveInfo> queryIntentContentProviders(Intent intent,
7198            String resolvedType, int flags, int userId) {
7199        return new ParceledListSlice<>(
7200                queryIntentContentProvidersInternal(intent, resolvedType, flags, userId));
7201    }
7202
7203    private @NonNull List<ResolveInfo> queryIntentContentProvidersInternal(
7204            Intent intent, String resolvedType, int flags, int userId) {
7205        if (!sUserManager.exists(userId)) return Collections.emptyList();
7206        final int callingUid = Binder.getCallingUid();
7207        final String instantAppPkgName = getInstantAppPackageName(callingUid);
7208        flags = updateFlagsForResolve(flags, userId, intent, callingUid,
7209                false /*includeInstantApps*/);
7210        ComponentName comp = intent.getComponent();
7211        if (comp == null) {
7212            if (intent.getSelector() != null) {
7213                intent = intent.getSelector();
7214                comp = intent.getComponent();
7215            }
7216        }
7217        if (comp != null) {
7218            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
7219            final ProviderInfo pi = getProviderInfo(comp, flags, userId);
7220            if (pi != null) {
7221                // When specifying an explicit component, we prevent the provider from being
7222                // used when either 1) the provider is in an instant application and the
7223                // caller is not the same instant application or 2) the calling package is an
7224                // instant application and the provider is not visible to instant applications.
7225                final boolean matchInstantApp =
7226                        (flags & PackageManager.MATCH_INSTANT) != 0;
7227                final boolean matchVisibleToInstantAppOnly =
7228                        (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
7229                final boolean isCallerInstantApp =
7230                        instantAppPkgName != null;
7231                final boolean isTargetSameInstantApp =
7232                        comp.getPackageName().equals(instantAppPkgName);
7233                final boolean isTargetInstantApp =
7234                        (pi.applicationInfo.privateFlags
7235                                & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
7236                final boolean isTargetHiddenFromInstantApp =
7237                        (pi.flags & ProviderInfo.FLAG_VISIBLE_TO_EPHEMERAL) == 0;
7238                final boolean blockResolution =
7239                        !isTargetSameInstantApp
7240                        && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
7241                                || (matchVisibleToInstantAppOnly && isCallerInstantApp
7242                                        && isTargetHiddenFromInstantApp));
7243                if (!blockResolution) {
7244                    final ResolveInfo ri = new ResolveInfo();
7245                    ri.providerInfo = pi;
7246                    list.add(ri);
7247                }
7248            }
7249            return list;
7250        }
7251
7252        // reader
7253        synchronized (mPackages) {
7254            String pkgName = intent.getPackage();
7255            if (pkgName == null) {
7256                return applyPostContentProviderResolutionFilter(
7257                        mProviders.queryIntent(intent, resolvedType, flags, userId),
7258                        instantAppPkgName);
7259            }
7260            final PackageParser.Package pkg = mPackages.get(pkgName);
7261            if (pkg != null) {
7262                return applyPostContentProviderResolutionFilter(
7263                        mProviders.queryIntentForPackage(
7264                        intent, resolvedType, flags, pkg.providers, userId),
7265                        instantAppPkgName);
7266            }
7267            return Collections.emptyList();
7268        }
7269    }
7270
7271    private List<ResolveInfo> applyPostContentProviderResolutionFilter(
7272            List<ResolveInfo> resolveInfos, String instantAppPkgName) {
7273        // TODO: When adding on-demand split support for non-instant applications, remove
7274        // this check and always apply post filtering
7275        if (instantAppPkgName == null) {
7276            return resolveInfos;
7277        }
7278        for (int i = resolveInfos.size() - 1; i >= 0; i--) {
7279            final ResolveInfo info = resolveInfos.get(i);
7280            final boolean isEphemeralApp = info.providerInfo.applicationInfo.isInstantApp();
7281            // allow providers that are defined in the provided package
7282            if (isEphemeralApp && instantAppPkgName.equals(info.providerInfo.packageName)) {
7283                if (info.providerInfo.splitName != null
7284                        && !ArrayUtils.contains(info.providerInfo.applicationInfo.splitNames,
7285                                info.providerInfo.splitName)) {
7286                    // requested provider is defined in a split that hasn't been installed yet.
7287                    // add the installer to the resolve list
7288                    if (DEBUG_EPHEMERAL) {
7289                        Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
7290                    }
7291                    final ResolveInfo installerInfo = new ResolveInfo(mInstantAppInstallerInfo);
7292                    installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
7293                            info.providerInfo.packageName, info.providerInfo.splitName,
7294                            info.providerInfo.applicationInfo.versionCode);
7295                    // make sure this resolver is the default
7296                    installerInfo.isDefault = true;
7297                    installerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
7298                            | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
7299                    // add a non-generic filter
7300                    installerInfo.filter = new IntentFilter();
7301                    // load resources from the correct package
7302                    installerInfo.resolvePackageName = info.getComponentInfo().packageName;
7303                    resolveInfos.set(i, installerInfo);
7304                }
7305                continue;
7306            }
7307            // allow providers that have been explicitly exposed to instant applications
7308            if (!isEphemeralApp
7309                    && ((info.providerInfo.flags & ActivityInfo.FLAG_VISIBLE_TO_EPHEMERAL) != 0)) {
7310                continue;
7311            }
7312            resolveInfos.remove(i);
7313        }
7314        return resolveInfos;
7315    }
7316
7317    @Override
7318    public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) {
7319        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
7320        flags = updateFlagsForPackage(flags, userId, null);
7321        final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
7322        enforceCrossUserPermission(Binder.getCallingUid(), userId,
7323                true /* requireFullPermission */, false /* checkShell */,
7324                "get installed packages");
7325
7326        // writer
7327        synchronized (mPackages) {
7328            ArrayList<PackageInfo> list;
7329            if (listUninstalled) {
7330                list = new ArrayList<>(mSettings.mPackages.size());
7331                for (PackageSetting ps : mSettings.mPackages.values()) {
7332                    if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId)) {
7333                        continue;
7334                    }
7335                    final PackageInfo pi = generatePackageInfo(ps, flags, userId);
7336                    if (pi != null) {
7337                        list.add(pi);
7338                    }
7339                }
7340            } else {
7341                list = new ArrayList<>(mPackages.size());
7342                for (PackageParser.Package p : mPackages.values()) {
7343                    if (filterSharedLibPackageLPr((PackageSetting) p.mExtras,
7344                            Binder.getCallingUid(), userId)) {
7345                        continue;
7346                    }
7347                    final PackageInfo pi = generatePackageInfo((PackageSetting)
7348                            p.mExtras, flags, userId);
7349                    if (pi != null) {
7350                        list.add(pi);
7351                    }
7352                }
7353            }
7354
7355            return new ParceledListSlice<>(list);
7356        }
7357    }
7358
7359    private void addPackageHoldingPermissions(ArrayList<PackageInfo> list, PackageSetting ps,
7360            String[] permissions, boolean[] tmp, int flags, int userId) {
7361        int numMatch = 0;
7362        final PermissionsState permissionsState = ps.getPermissionsState();
7363        for (int i=0; i<permissions.length; i++) {
7364            final String permission = permissions[i];
7365            if (permissionsState.hasPermission(permission, userId)) {
7366                tmp[i] = true;
7367                numMatch++;
7368            } else {
7369                tmp[i] = false;
7370            }
7371        }
7372        if (numMatch == 0) {
7373            return;
7374        }
7375        final PackageInfo pi = generatePackageInfo(ps, flags, userId);
7376
7377        // The above might return null in cases of uninstalled apps or install-state
7378        // skew across users/profiles.
7379        if (pi != null) {
7380            if ((flags&PackageManager.GET_PERMISSIONS) == 0) {
7381                if (numMatch == permissions.length) {
7382                    pi.requestedPermissions = permissions;
7383                } else {
7384                    pi.requestedPermissions = new String[numMatch];
7385                    numMatch = 0;
7386                    for (int i=0; i<permissions.length; i++) {
7387                        if (tmp[i]) {
7388                            pi.requestedPermissions[numMatch] = permissions[i];
7389                            numMatch++;
7390                        }
7391                    }
7392                }
7393            }
7394            list.add(pi);
7395        }
7396    }
7397
7398    @Override
7399    public ParceledListSlice<PackageInfo> getPackagesHoldingPermissions(
7400            String[] permissions, int flags, int userId) {
7401        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
7402        flags = updateFlagsForPackage(flags, userId, permissions);
7403        enforceCrossUserPermission(Binder.getCallingUid(), userId,
7404                true /* requireFullPermission */, false /* checkShell */,
7405                "get packages holding permissions");
7406        final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
7407
7408        // writer
7409        synchronized (mPackages) {
7410            ArrayList<PackageInfo> list = new ArrayList<PackageInfo>();
7411            boolean[] tmpBools = new boolean[permissions.length];
7412            if (listUninstalled) {
7413                for (PackageSetting ps : mSettings.mPackages.values()) {
7414                    addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags,
7415                            userId);
7416                }
7417            } else {
7418                for (PackageParser.Package pkg : mPackages.values()) {
7419                    PackageSetting ps = (PackageSetting)pkg.mExtras;
7420                    if (ps != null) {
7421                        addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags,
7422                                userId);
7423                    }
7424                }
7425            }
7426
7427            return new ParceledListSlice<PackageInfo>(list);
7428        }
7429    }
7430
7431    @Override
7432    public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags, int userId) {
7433        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
7434        flags = updateFlagsForApplication(flags, userId, null);
7435        final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
7436
7437        // writer
7438        synchronized (mPackages) {
7439            ArrayList<ApplicationInfo> list;
7440            if (listUninstalled) {
7441                list = new ArrayList<>(mSettings.mPackages.size());
7442                for (PackageSetting ps : mSettings.mPackages.values()) {
7443                    ApplicationInfo ai;
7444                    int effectiveFlags = flags;
7445                    if (ps.isSystem()) {
7446                        effectiveFlags |= PackageManager.MATCH_ANY_USER;
7447                    }
7448                    if (ps.pkg != null) {
7449                        if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId)) {
7450                            continue;
7451                        }
7452                        ai = PackageParser.generateApplicationInfo(ps.pkg, effectiveFlags,
7453                                ps.readUserState(userId), userId);
7454                        if (ai != null) {
7455                            rebaseEnabledOverlays(ai, userId);
7456                            ai.packageName = resolveExternalPackageNameLPr(ps.pkg);
7457                        }
7458                    } else {
7459                        // Shared lib filtering done in generateApplicationInfoFromSettingsLPw
7460                        // and already converts to externally visible package name
7461                        ai = generateApplicationInfoFromSettingsLPw(ps.name,
7462                                Binder.getCallingUid(), effectiveFlags, userId);
7463                    }
7464                    if (ai != null) {
7465                        list.add(ai);
7466                    }
7467                }
7468            } else {
7469                list = new ArrayList<>(mPackages.size());
7470                for (PackageParser.Package p : mPackages.values()) {
7471                    if (p.mExtras != null) {
7472                        PackageSetting ps = (PackageSetting) p.mExtras;
7473                        if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId)) {
7474                            continue;
7475                        }
7476                        ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
7477                                ps.readUserState(userId), userId);
7478                        if (ai != null) {
7479                            rebaseEnabledOverlays(ai, userId);
7480                            ai.packageName = resolveExternalPackageNameLPr(p);
7481                            list.add(ai);
7482                        }
7483                    }
7484                }
7485            }
7486
7487            return new ParceledListSlice<>(list);
7488        }
7489    }
7490
7491    @Override
7492    public ParceledListSlice<InstantAppInfo> getInstantApps(int userId) {
7493        if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
7494            return null;
7495        }
7496
7497        mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_INSTANT_APPS,
7498                "getEphemeralApplications");
7499        enforceCrossUserPermission(Binder.getCallingUid(), userId,
7500                true /* requireFullPermission */, false /* checkShell */,
7501                "getEphemeralApplications");
7502        synchronized (mPackages) {
7503            List<InstantAppInfo> instantApps = mInstantAppRegistry
7504                    .getInstantAppsLPr(userId);
7505            if (instantApps != null) {
7506                return new ParceledListSlice<>(instantApps);
7507            }
7508        }
7509        return null;
7510    }
7511
7512    @Override
7513    public boolean isInstantApp(String packageName, int userId) {
7514        enforceCrossUserPermission(Binder.getCallingUid(), userId,
7515                true /* requireFullPermission */, false /* checkShell */,
7516                "isInstantApp");
7517        if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
7518            return false;
7519        }
7520        int uid = Binder.getCallingUid();
7521        if (Process.isIsolated(uid)) {
7522            uid = mIsolatedOwners.get(uid);
7523        }
7524
7525        synchronized (mPackages) {
7526            final PackageSetting ps = mSettings.mPackages.get(packageName);
7527            PackageParser.Package pkg = mPackages.get(packageName);
7528            final boolean returnAllowed =
7529                    ps != null
7530                    && (isCallerSameApp(packageName, uid)
7531                            || mContext.checkCallingOrSelfPermission(
7532                                    android.Manifest.permission.ACCESS_INSTANT_APPS)
7533                                            == PERMISSION_GRANTED
7534                            || mInstantAppRegistry.isInstantAccessGranted(
7535                                    userId, UserHandle.getAppId(uid), ps.appId));
7536            if (returnAllowed) {
7537                return ps.getInstantApp(userId);
7538            }
7539        }
7540        return false;
7541    }
7542
7543    @Override
7544    public byte[] getInstantAppCookie(String packageName, int userId) {
7545        if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
7546            return null;
7547        }
7548
7549        enforceCrossUserPermission(Binder.getCallingUid(), userId,
7550                true /* requireFullPermission */, false /* checkShell */,
7551                "getInstantAppCookie");
7552        if (!isCallerSameApp(packageName, Binder.getCallingUid())) {
7553            return null;
7554        }
7555        synchronized (mPackages) {
7556            return mInstantAppRegistry.getInstantAppCookieLPw(
7557                    packageName, userId);
7558        }
7559    }
7560
7561    @Override
7562    public boolean setInstantAppCookie(String packageName, byte[] cookie, int userId) {
7563        if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
7564            return true;
7565        }
7566
7567        enforceCrossUserPermission(Binder.getCallingUid(), userId,
7568                true /* requireFullPermission */, true /* checkShell */,
7569                "setInstantAppCookie");
7570        if (!isCallerSameApp(packageName, Binder.getCallingUid())) {
7571            return false;
7572        }
7573        synchronized (mPackages) {
7574            return mInstantAppRegistry.setInstantAppCookieLPw(
7575                    packageName, cookie, userId);
7576        }
7577    }
7578
7579    @Override
7580    public Bitmap getInstantAppIcon(String packageName, int userId) {
7581        if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
7582            return null;
7583        }
7584
7585        mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_INSTANT_APPS,
7586                "getInstantAppIcon");
7587
7588        enforceCrossUserPermission(Binder.getCallingUid(), userId,
7589                true /* requireFullPermission */, false /* checkShell */,
7590                "getInstantAppIcon");
7591
7592        synchronized (mPackages) {
7593            return mInstantAppRegistry.getInstantAppIconLPw(
7594                    packageName, userId);
7595        }
7596    }
7597
7598    private boolean isCallerSameApp(String packageName, int uid) {
7599        PackageParser.Package pkg = mPackages.get(packageName);
7600        return pkg != null
7601                && UserHandle.getAppId(uid) == pkg.applicationInfo.uid;
7602    }
7603
7604    @Override
7605    public @NonNull ParceledListSlice<ApplicationInfo> getPersistentApplications(int flags) {
7606        return new ParceledListSlice<>(getPersistentApplicationsInternal(flags));
7607    }
7608
7609    private @NonNull List<ApplicationInfo> getPersistentApplicationsInternal(int flags) {
7610        final ArrayList<ApplicationInfo> finalList = new ArrayList<ApplicationInfo>();
7611
7612        // reader
7613        synchronized (mPackages) {
7614            final Iterator<PackageParser.Package> i = mPackages.values().iterator();
7615            final int userId = UserHandle.getCallingUserId();
7616            while (i.hasNext()) {
7617                final PackageParser.Package p = i.next();
7618                if (p.applicationInfo == null) continue;
7619
7620                final boolean matchesUnaware = ((flags & MATCH_DIRECT_BOOT_UNAWARE) != 0)
7621                        && !p.applicationInfo.isDirectBootAware();
7622                final boolean matchesAware = ((flags & MATCH_DIRECT_BOOT_AWARE) != 0)
7623                        && p.applicationInfo.isDirectBootAware();
7624
7625                if ((p.applicationInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0
7626                        && (!mSafeMode || isSystemApp(p))
7627                        && (matchesUnaware || matchesAware)) {
7628                    PackageSetting ps = mSettings.mPackages.get(p.packageName);
7629                    if (ps != null) {
7630                        ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
7631                                ps.readUserState(userId), userId);
7632                        if (ai != null) {
7633                            rebaseEnabledOverlays(ai, userId);
7634                            finalList.add(ai);
7635                        }
7636                    }
7637                }
7638            }
7639        }
7640
7641        return finalList;
7642    }
7643
7644    @Override
7645    public ProviderInfo resolveContentProvider(String name, int flags, int userId) {
7646        if (!sUserManager.exists(userId)) return null;
7647        flags = updateFlagsForComponent(flags, userId, name);
7648        final String instantAppPkgName = getInstantAppPackageName(Binder.getCallingUid());
7649        // reader
7650        synchronized (mPackages) {
7651            final PackageParser.Provider provider = mProvidersByAuthority.get(name);
7652            PackageSetting ps = provider != null
7653                    ? mSettings.mPackages.get(provider.owner.packageName)
7654                    : null;
7655            if (ps != null) {
7656                final boolean isInstantApp = ps.getInstantApp(userId);
7657                // normal application; filter out instant application provider
7658                if (instantAppPkgName == null && isInstantApp) {
7659                    return null;
7660                }
7661                // instant application; filter out other instant applications
7662                if (instantAppPkgName != null
7663                        && isInstantApp
7664                        && !provider.owner.packageName.equals(instantAppPkgName)) {
7665                    return null;
7666                }
7667                // instant application; filter out non-exposed provider
7668                if (instantAppPkgName != null
7669                        && (provider.info.flags & ProviderInfo.FLAG_VISIBLE_TO_EPHEMERAL) == 0) {
7670                    return null;
7671                }
7672                // provider not enabled
7673                if (!mSettings.isEnabledAndMatchLPr(provider.info, flags, userId)) {
7674                    return null;
7675                }
7676                return PackageParser.generateProviderInfo(
7677                        provider, flags, ps.readUserState(userId), userId);
7678            }
7679            return null;
7680        }
7681    }
7682
7683    /**
7684     * @deprecated
7685     */
7686    @Deprecated
7687    public void querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo) {
7688        // reader
7689        synchronized (mPackages) {
7690            final Iterator<Map.Entry<String, PackageParser.Provider>> i = mProvidersByAuthority
7691                    .entrySet().iterator();
7692            final int userId = UserHandle.getCallingUserId();
7693            while (i.hasNext()) {
7694                Map.Entry<String, PackageParser.Provider> entry = i.next();
7695                PackageParser.Provider p = entry.getValue();
7696                PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
7697
7698                if (ps != null && p.syncable
7699                        && (!mSafeMode || (p.info.applicationInfo.flags
7700                                &ApplicationInfo.FLAG_SYSTEM) != 0)) {
7701                    ProviderInfo info = PackageParser.generateProviderInfo(p, 0,
7702                            ps.readUserState(userId), userId);
7703                    if (info != null) {
7704                        outNames.add(entry.getKey());
7705                        outInfo.add(info);
7706                    }
7707                }
7708            }
7709        }
7710    }
7711
7712    @Override
7713    public @NonNull ParceledListSlice<ProviderInfo> queryContentProviders(String processName,
7714            int uid, int flags, String metaDataKey) {
7715        final int userId = processName != null ? UserHandle.getUserId(uid)
7716                : UserHandle.getCallingUserId();
7717        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
7718        flags = updateFlagsForComponent(flags, userId, processName);
7719
7720        ArrayList<ProviderInfo> finalList = null;
7721        // reader
7722        synchronized (mPackages) {
7723            final Iterator<PackageParser.Provider> i = mProviders.mProviders.values().iterator();
7724            while (i.hasNext()) {
7725                final PackageParser.Provider p = i.next();
7726                PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
7727                if (ps != null && p.info.authority != null
7728                        && (processName == null
7729                                || (p.info.processName.equals(processName)
7730                                        && UserHandle.isSameApp(p.info.applicationInfo.uid, uid)))
7731                        && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) {
7732
7733                    // See PM.queryContentProviders()'s javadoc for why we have the metaData
7734                    // parameter.
7735                    if (metaDataKey != null
7736                            && (p.metaData == null || !p.metaData.containsKey(metaDataKey))) {
7737                        continue;
7738                    }
7739
7740                    if (finalList == null) {
7741                        finalList = new ArrayList<ProviderInfo>(3);
7742                    }
7743                    ProviderInfo info = PackageParser.generateProviderInfo(p, flags,
7744                            ps.readUserState(userId), userId);
7745                    if (info != null) {
7746                        finalList.add(info);
7747                    }
7748                }
7749            }
7750        }
7751
7752        if (finalList != null) {
7753            Collections.sort(finalList, mProviderInitOrderSorter);
7754            return new ParceledListSlice<ProviderInfo>(finalList);
7755        }
7756
7757        return ParceledListSlice.emptyList();
7758    }
7759
7760    @Override
7761    public InstrumentationInfo getInstrumentationInfo(ComponentName name, int flags) {
7762        // reader
7763        synchronized (mPackages) {
7764            final PackageParser.Instrumentation i = mInstrumentation.get(name);
7765            return PackageParser.generateInstrumentationInfo(i, flags);
7766        }
7767    }
7768
7769    @Override
7770    public @NonNull ParceledListSlice<InstrumentationInfo> queryInstrumentation(
7771            String targetPackage, int flags) {
7772        return new ParceledListSlice<>(queryInstrumentationInternal(targetPackage, flags));
7773    }
7774
7775    private @NonNull List<InstrumentationInfo> queryInstrumentationInternal(String targetPackage,
7776            int flags) {
7777        ArrayList<InstrumentationInfo> finalList = new ArrayList<InstrumentationInfo>();
7778
7779        // reader
7780        synchronized (mPackages) {
7781            final Iterator<PackageParser.Instrumentation> i = mInstrumentation.values().iterator();
7782            while (i.hasNext()) {
7783                final PackageParser.Instrumentation p = i.next();
7784                if (targetPackage == null
7785                        || targetPackage.equals(p.info.targetPackage)) {
7786                    InstrumentationInfo ii = PackageParser.generateInstrumentationInfo(p,
7787                            flags);
7788                    if (ii != null) {
7789                        finalList.add(ii);
7790                    }
7791                }
7792            }
7793        }
7794
7795        return finalList;
7796    }
7797
7798    private void scanDirTracedLI(File dir, final int parseFlags, int scanFlags, long currentTime) {
7799        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanDir [" + dir.getAbsolutePath() + "]");
7800        try {
7801            scanDirLI(dir, parseFlags, scanFlags, currentTime);
7802        } finally {
7803            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
7804        }
7805    }
7806
7807    private void scanDirLI(File dir, int parseFlags, int scanFlags, long currentTime) {
7808        final File[] files = dir.listFiles();
7809        if (ArrayUtils.isEmpty(files)) {
7810            Log.d(TAG, "No files in app dir " + dir);
7811            return;
7812        }
7813
7814        if (DEBUG_PACKAGE_SCANNING) {
7815            Log.d(TAG, "Scanning app dir " + dir + " scanFlags=" + scanFlags
7816                    + " flags=0x" + Integer.toHexString(parseFlags));
7817        }
7818        ParallelPackageParser parallelPackageParser = new ParallelPackageParser(
7819                mSeparateProcesses, mOnlyCore, mMetrics, mCacheDir, mPackageParserCallback);
7820
7821        // Submit files for parsing in parallel
7822        int fileCount = 0;
7823        for (File file : files) {
7824            final boolean isPackage = (isApkFile(file) || file.isDirectory())
7825                    && !PackageInstallerService.isStageName(file.getName());
7826            if (!isPackage) {
7827                // Ignore entries which are not packages
7828                continue;
7829            }
7830            parallelPackageParser.submit(file, parseFlags);
7831            fileCount++;
7832        }
7833
7834        // Process results one by one
7835        for (; fileCount > 0; fileCount--) {
7836            ParallelPackageParser.ParseResult parseResult = parallelPackageParser.take();
7837            Throwable throwable = parseResult.throwable;
7838            int errorCode = PackageManager.INSTALL_SUCCEEDED;
7839
7840            if (throwable == null) {
7841                // Static shared libraries have synthetic package names
7842                if (parseResult.pkg.applicationInfo.isStaticSharedLibrary()) {
7843                    renameStaticSharedLibraryPackage(parseResult.pkg);
7844                }
7845                try {
7846                    if (errorCode == PackageManager.INSTALL_SUCCEEDED) {
7847                        scanPackageLI(parseResult.pkg, parseResult.scanFile, parseFlags, scanFlags,
7848                                currentTime, null);
7849                    }
7850                } catch (PackageManagerException e) {
7851                    errorCode = e.error;
7852                    Slog.w(TAG, "Failed to scan " + parseResult.scanFile + ": " + e.getMessage());
7853                }
7854            } else if (throwable instanceof PackageParser.PackageParserException) {
7855                PackageParser.PackageParserException e = (PackageParser.PackageParserException)
7856                        throwable;
7857                errorCode = e.error;
7858                Slog.w(TAG, "Failed to parse " + parseResult.scanFile + ": " + e.getMessage());
7859            } else {
7860                throw new IllegalStateException("Unexpected exception occurred while parsing "
7861                        + parseResult.scanFile, throwable);
7862            }
7863
7864            // Delete invalid userdata apps
7865            if ((parseFlags & PackageParser.PARSE_IS_SYSTEM) == 0 &&
7866                    errorCode == PackageManager.INSTALL_FAILED_INVALID_APK) {
7867                logCriticalInfo(Log.WARN,
7868                        "Deleting invalid package at " + parseResult.scanFile);
7869                removeCodePathLI(parseResult.scanFile);
7870            }
7871        }
7872        parallelPackageParser.close();
7873    }
7874
7875    private static File getSettingsProblemFile() {
7876        File dataDir = Environment.getDataDirectory();
7877        File systemDir = new File(dataDir, "system");
7878        File fname = new File(systemDir, "uiderrors.txt");
7879        return fname;
7880    }
7881
7882    static void reportSettingsProblem(int priority, String msg) {
7883        logCriticalInfo(priority, msg);
7884    }
7885
7886    public static void logCriticalInfo(int priority, String msg) {
7887        Slog.println(priority, TAG, msg);
7888        EventLogTags.writePmCriticalInfo(msg);
7889        try {
7890            File fname = getSettingsProblemFile();
7891            FileOutputStream out = new FileOutputStream(fname, true);
7892            PrintWriter pw = new FastPrintWriter(out);
7893            SimpleDateFormat formatter = new SimpleDateFormat();
7894            String dateString = formatter.format(new Date(System.currentTimeMillis()));
7895            pw.println(dateString + ": " + msg);
7896            pw.close();
7897            FileUtils.setPermissions(
7898                    fname.toString(),
7899                    FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IROTH,
7900                    -1, -1);
7901        } catch (java.io.IOException e) {
7902        }
7903    }
7904
7905    private long getLastModifiedTime(PackageParser.Package pkg, File srcFile) {
7906        if (srcFile.isDirectory()) {
7907            final File baseFile = new File(pkg.baseCodePath);
7908            long maxModifiedTime = baseFile.lastModified();
7909            if (pkg.splitCodePaths != null) {
7910                for (int i = pkg.splitCodePaths.length - 1; i >=0; --i) {
7911                    final File splitFile = new File(pkg.splitCodePaths[i]);
7912                    maxModifiedTime = Math.max(maxModifiedTime, splitFile.lastModified());
7913                }
7914            }
7915            return maxModifiedTime;
7916        }
7917        return srcFile.lastModified();
7918    }
7919
7920    private void collectCertificatesLI(PackageSetting ps, PackageParser.Package pkg, File srcFile,
7921            final int policyFlags) throws PackageManagerException {
7922        // When upgrading from pre-N MR1, verify the package time stamp using the package
7923        // directory and not the APK file.
7924        final long lastModifiedTime = mIsPreNMR1Upgrade
7925                ? new File(pkg.codePath).lastModified() : getLastModifiedTime(pkg, srcFile);
7926        if (ps != null
7927                && ps.codePath.equals(srcFile)
7928                && ps.timeStamp == lastModifiedTime
7929                && !isCompatSignatureUpdateNeeded(pkg)
7930                && !isRecoverSignatureUpdateNeeded(pkg)) {
7931            long mSigningKeySetId = ps.keySetData.getProperSigningKeySet();
7932            KeySetManagerService ksms = mSettings.mKeySetManagerService;
7933            ArraySet<PublicKey> signingKs;
7934            synchronized (mPackages) {
7935                signingKs = ksms.getPublicKeysFromKeySetLPr(mSigningKeySetId);
7936            }
7937            if (ps.signatures.mSignatures != null
7938                    && ps.signatures.mSignatures.length != 0
7939                    && signingKs != null) {
7940                // Optimization: reuse the existing cached certificates
7941                // if the package appears to be unchanged.
7942                pkg.mSignatures = ps.signatures.mSignatures;
7943                pkg.mSigningKeys = signingKs;
7944                return;
7945            }
7946
7947            Slog.w(TAG, "PackageSetting for " + ps.name
7948                    + " is missing signatures.  Collecting certs again to recover them.");
7949        } else {
7950            Slog.i(TAG, srcFile.toString() + " changed; collecting certs");
7951        }
7952
7953        try {
7954            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "collectCertificates");
7955            PackageParser.collectCertificates(pkg, policyFlags);
7956        } catch (PackageParserException e) {
7957            throw PackageManagerException.from(e);
7958        } finally {
7959            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
7960        }
7961    }
7962
7963    /**
7964     *  Traces a package scan.
7965     *  @see #scanPackageLI(File, int, int, long, UserHandle)
7966     */
7967    private PackageParser.Package scanPackageTracedLI(File scanFile, final int parseFlags,
7968            int scanFlags, long currentTime, UserHandle user) throws PackageManagerException {
7969        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage [" + scanFile.toString() + "]");
7970        try {
7971            return scanPackageLI(scanFile, parseFlags, scanFlags, currentTime, user);
7972        } finally {
7973            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
7974        }
7975    }
7976
7977    /**
7978     *  Scans a package and returns the newly parsed package.
7979     *  Returns {@code null} in case of errors and the error code is stored in mLastScanError
7980     */
7981    private PackageParser.Package scanPackageLI(File scanFile, int parseFlags, int scanFlags,
7982            long currentTime, UserHandle user) throws PackageManagerException {
7983        if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanFile);
7984        PackageParser pp = new PackageParser();
7985        pp.setSeparateProcesses(mSeparateProcesses);
7986        pp.setOnlyCoreApps(mOnlyCore);
7987        pp.setDisplayMetrics(mMetrics);
7988        pp.setCallback(mPackageParserCallback);
7989
7990        if ((scanFlags & SCAN_TRUSTED_OVERLAY) != 0) {
7991            parseFlags |= PackageParser.PARSE_TRUSTED_OVERLAY;
7992        }
7993
7994        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
7995        final PackageParser.Package pkg;
7996        try {
7997            pkg = pp.parsePackage(scanFile, parseFlags);
7998        } catch (PackageParserException e) {
7999            throw PackageManagerException.from(e);
8000        } finally {
8001            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8002        }
8003
8004        // Static shared libraries have synthetic package names
8005        if (pkg.applicationInfo.isStaticSharedLibrary()) {
8006            renameStaticSharedLibraryPackage(pkg);
8007        }
8008
8009        return scanPackageLI(pkg, scanFile, parseFlags, scanFlags, currentTime, user);
8010    }
8011
8012    /**
8013     *  Scans a package and returns the newly parsed package.
8014     *  @throws PackageManagerException on a parse error.
8015     */
8016    private PackageParser.Package scanPackageLI(PackageParser.Package pkg, File scanFile,
8017            final int policyFlags, int scanFlags, long currentTime, @Nullable UserHandle user)
8018            throws PackageManagerException {
8019        // If the package has children and this is the first dive in the function
8020        // we scan the package with the SCAN_CHECK_ONLY flag set to see whether all
8021        // packages (parent and children) would be successfully scanned before the
8022        // actual scan since scanning mutates internal state and we want to atomically
8023        // install the package and its children.
8024        if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
8025            if (pkg.childPackages != null && pkg.childPackages.size() > 0) {
8026                scanFlags |= SCAN_CHECK_ONLY;
8027            }
8028        } else {
8029            scanFlags &= ~SCAN_CHECK_ONLY;
8030        }
8031
8032        // Scan the parent
8033        PackageParser.Package scannedPkg = scanPackageInternalLI(pkg, scanFile, policyFlags,
8034                scanFlags, currentTime, user);
8035
8036        // Scan the children
8037        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
8038        for (int i = 0; i < childCount; i++) {
8039            PackageParser.Package childPackage = pkg.childPackages.get(i);
8040            scanPackageInternalLI(childPackage, scanFile, policyFlags, scanFlags,
8041                    currentTime, user);
8042        }
8043
8044
8045        if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
8046            return scanPackageLI(pkg, scanFile, policyFlags, scanFlags, currentTime, user);
8047        }
8048
8049        return scannedPkg;
8050    }
8051
8052    /**
8053     *  Scans a package and returns the newly parsed package.
8054     *  @throws PackageManagerException on a parse error.
8055     */
8056    private PackageParser.Package scanPackageInternalLI(PackageParser.Package pkg, File scanFile,
8057            int policyFlags, int scanFlags, long currentTime, @Nullable UserHandle user)
8058            throws PackageManagerException {
8059        PackageSetting ps = null;
8060        PackageSetting updatedPkg;
8061        // reader
8062        synchronized (mPackages) {
8063            // Look to see if we already know about this package.
8064            String oldName = mSettings.getRenamedPackageLPr(pkg.packageName);
8065            if (pkg.mOriginalPackages != null && pkg.mOriginalPackages.contains(oldName)) {
8066                // This package has been renamed to its original name.  Let's
8067                // use that.
8068                ps = mSettings.getPackageLPr(oldName);
8069            }
8070            // If there was no original package, see one for the real package name.
8071            if (ps == null) {
8072                ps = mSettings.getPackageLPr(pkg.packageName);
8073            }
8074            // Check to see if this package could be hiding/updating a system
8075            // package.  Must look for it either under the original or real
8076            // package name depending on our state.
8077            updatedPkg = mSettings.getDisabledSystemPkgLPr(ps != null ? ps.name : pkg.packageName);
8078            if (DEBUG_INSTALL && updatedPkg != null) Slog.d(TAG, "updatedPkg = " + updatedPkg);
8079
8080            // If this is a package we don't know about on the system partition, we
8081            // may need to remove disabled child packages on the system partition
8082            // or may need to not add child packages if the parent apk is updated
8083            // on the data partition and no longer defines this child package.
8084            if ((policyFlags & PackageParser.PARSE_IS_SYSTEM) != 0) {
8085                // If this is a parent package for an updated system app and this system
8086                // app got an OTA update which no longer defines some of the child packages
8087                // we have to prune them from the disabled system packages.
8088                PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(pkg.packageName);
8089                if (disabledPs != null) {
8090                    final int scannedChildCount = (pkg.childPackages != null)
8091                            ? pkg.childPackages.size() : 0;
8092                    final int disabledChildCount = disabledPs.childPackageNames != null
8093                            ? disabledPs.childPackageNames.size() : 0;
8094                    for (int i = 0; i < disabledChildCount; i++) {
8095                        String disabledChildPackageName = disabledPs.childPackageNames.get(i);
8096                        boolean disabledPackageAvailable = false;
8097                        for (int j = 0; j < scannedChildCount; j++) {
8098                            PackageParser.Package childPkg = pkg.childPackages.get(j);
8099                            if (childPkg.packageName.equals(disabledChildPackageName)) {
8100                                disabledPackageAvailable = true;
8101                                break;
8102                            }
8103                         }
8104                         if (!disabledPackageAvailable) {
8105                             mSettings.removeDisabledSystemPackageLPw(disabledChildPackageName);
8106                         }
8107                    }
8108                }
8109            }
8110        }
8111
8112        boolean updatedPkgBetter = false;
8113        // First check if this is a system package that may involve an update
8114        if (updatedPkg != null && (policyFlags & PackageParser.PARSE_IS_SYSTEM) != 0) {
8115            // If new package is not located in "/system/priv-app" (e.g. due to an OTA),
8116            // it needs to drop FLAG_PRIVILEGED.
8117            if (locationIsPrivileged(scanFile)) {
8118                updatedPkg.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
8119            } else {
8120                updatedPkg.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
8121            }
8122
8123            if (ps != null && !ps.codePath.equals(scanFile)) {
8124                // The path has changed from what was last scanned...  check the
8125                // version of the new path against what we have stored to determine
8126                // what to do.
8127                if (DEBUG_INSTALL) Slog.d(TAG, "Path changing from " + ps.codePath);
8128                if (pkg.mVersionCode <= ps.versionCode) {
8129                    // The system package has been updated and the code path does not match
8130                    // Ignore entry. Skip it.
8131                    if (DEBUG_INSTALL) Slog.i(TAG, "Package " + ps.name + " at " + scanFile
8132                            + " ignored: updated version " + ps.versionCode
8133                            + " better than this " + pkg.mVersionCode);
8134                    if (!updatedPkg.codePath.equals(scanFile)) {
8135                        Slog.w(PackageManagerService.TAG, "Code path for hidden system pkg "
8136                                + ps.name + " changing from " + updatedPkg.codePathString
8137                                + " to " + scanFile);
8138                        updatedPkg.codePath = scanFile;
8139                        updatedPkg.codePathString = scanFile.toString();
8140                        updatedPkg.resourcePath = scanFile;
8141                        updatedPkg.resourcePathString = scanFile.toString();
8142                    }
8143                    updatedPkg.pkg = pkg;
8144                    updatedPkg.versionCode = pkg.mVersionCode;
8145
8146                    // Update the disabled system child packages to point to the package too.
8147                    final int childCount = updatedPkg.childPackageNames != null
8148                            ? updatedPkg.childPackageNames.size() : 0;
8149                    for (int i = 0; i < childCount; i++) {
8150                        String childPackageName = updatedPkg.childPackageNames.get(i);
8151                        PackageSetting updatedChildPkg = mSettings.getDisabledSystemPkgLPr(
8152                                childPackageName);
8153                        if (updatedChildPkg != null) {
8154                            updatedChildPkg.pkg = pkg;
8155                            updatedChildPkg.versionCode = pkg.mVersionCode;
8156                        }
8157                    }
8158
8159                    throw new PackageManagerException(Log.WARN, "Package " + ps.name + " at "
8160                            + scanFile + " ignored: updated version " + ps.versionCode
8161                            + " better than this " + pkg.mVersionCode);
8162                } else {
8163                    // The current app on the system partition is better than
8164                    // what we have updated to on the data partition; switch
8165                    // back to the system partition version.
8166                    // At this point, its safely assumed that package installation for
8167                    // apps in system partition will go through. If not there won't be a working
8168                    // version of the app
8169                    // writer
8170                    synchronized (mPackages) {
8171                        // Just remove the loaded entries from package lists.
8172                        mPackages.remove(ps.name);
8173                    }
8174
8175                    logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile
8176                            + " reverting from " + ps.codePathString
8177                            + ": new version " + pkg.mVersionCode
8178                            + " better than installed " + ps.versionCode);
8179
8180                    InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
8181                            ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
8182                    synchronized (mInstallLock) {
8183                        args.cleanUpResourcesLI();
8184                    }
8185                    synchronized (mPackages) {
8186                        mSettings.enableSystemPackageLPw(ps.name);
8187                    }
8188                    updatedPkgBetter = true;
8189                }
8190            }
8191        }
8192
8193        if (updatedPkg != null) {
8194            // An updated system app will not have the PARSE_IS_SYSTEM flag set
8195            // initially
8196            policyFlags |= PackageParser.PARSE_IS_SYSTEM;
8197
8198            // An updated privileged app will not have the PARSE_IS_PRIVILEGED
8199            // flag set initially
8200            if ((updatedPkg.pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0) {
8201                policyFlags |= PackageParser.PARSE_IS_PRIVILEGED;
8202            }
8203        }
8204
8205        // Verify certificates against what was last scanned
8206        collectCertificatesLI(ps, pkg, scanFile, policyFlags);
8207
8208        /*
8209         * A new system app appeared, but we already had a non-system one of the
8210         * same name installed earlier.
8211         */
8212        boolean shouldHideSystemApp = false;
8213        if (updatedPkg == null && ps != null
8214                && (policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0 && !isSystemApp(ps)) {
8215            /*
8216             * Check to make sure the signatures match first. If they don't,
8217             * wipe the installed application and its data.
8218             */
8219            if (compareSignatures(ps.signatures.mSignatures, pkg.mSignatures)
8220                    != PackageManager.SIGNATURE_MATCH) {
8221                logCriticalInfo(Log.WARN, "Package " + ps.name + " appeared on system, but"
8222                        + " signatures don't match existing userdata copy; removing");
8223                try (PackageFreezer freezer = freezePackage(pkg.packageName,
8224                        "scanPackageInternalLI")) {
8225                    deletePackageLIF(pkg.packageName, null, true, null, 0, null, false, null);
8226                }
8227                ps = null;
8228            } else {
8229                /*
8230                 * If the newly-added system app is an older version than the
8231                 * already installed version, hide it. It will be scanned later
8232                 * and re-added like an update.
8233                 */
8234                if (pkg.mVersionCode <= ps.versionCode) {
8235                    shouldHideSystemApp = true;
8236                    logCriticalInfo(Log.INFO, "Package " + ps.name + " appeared at " + scanFile
8237                            + " but new version " + pkg.mVersionCode + " better than installed "
8238                            + ps.versionCode + "; hiding system");
8239                } else {
8240                    /*
8241                     * The newly found system app is a newer version that the
8242                     * one previously installed. Simply remove the
8243                     * already-installed application and replace it with our own
8244                     * while keeping the application data.
8245                     */
8246                    logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile
8247                            + " reverting from " + ps.codePathString + ": new version "
8248                            + pkg.mVersionCode + " better than installed " + ps.versionCode);
8249                    InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
8250                            ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
8251                    synchronized (mInstallLock) {
8252                        args.cleanUpResourcesLI();
8253                    }
8254                }
8255            }
8256        }
8257
8258        // The apk is forward locked (not public) if its code and resources
8259        // are kept in different files. (except for app in either system or
8260        // vendor path).
8261        // TODO grab this value from PackageSettings
8262        if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
8263            if (ps != null && !ps.codePath.equals(ps.resourcePath)) {
8264                policyFlags |= PackageParser.PARSE_FORWARD_LOCK;
8265            }
8266        }
8267
8268        // TODO: extend to support forward-locked splits
8269        String resourcePath = null;
8270        String baseResourcePath = null;
8271        if ((policyFlags & PackageParser.PARSE_FORWARD_LOCK) != 0 && !updatedPkgBetter) {
8272            if (ps != null && ps.resourcePathString != null) {
8273                resourcePath = ps.resourcePathString;
8274                baseResourcePath = ps.resourcePathString;
8275            } else {
8276                // Should not happen at all. Just log an error.
8277                Slog.e(TAG, "Resource path not set for package " + pkg.packageName);
8278            }
8279        } else {
8280            resourcePath = pkg.codePath;
8281            baseResourcePath = pkg.baseCodePath;
8282        }
8283
8284        // Set application objects path explicitly.
8285        pkg.setApplicationVolumeUuid(pkg.volumeUuid);
8286        pkg.setApplicationInfoCodePath(pkg.codePath);
8287        pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
8288        pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
8289        pkg.setApplicationInfoResourcePath(resourcePath);
8290        pkg.setApplicationInfoBaseResourcePath(baseResourcePath);
8291        pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
8292
8293        final int userId = ((user == null) ? 0 : user.getIdentifier());
8294        if (ps != null && ps.getInstantApp(userId)) {
8295            scanFlags |= SCAN_AS_INSTANT_APP;
8296        }
8297
8298        // Note that we invoke the following method only if we are about to unpack an application
8299        PackageParser.Package scannedPkg = scanPackageLI(pkg, policyFlags, scanFlags
8300                | SCAN_UPDATE_SIGNATURE, currentTime, user);
8301
8302        /*
8303         * If the system app should be overridden by a previously installed
8304         * data, hide the system app now and let the /data/app scan pick it up
8305         * again.
8306         */
8307        if (shouldHideSystemApp) {
8308            synchronized (mPackages) {
8309                mSettings.disableSystemPackageLPw(pkg.packageName, true);
8310            }
8311        }
8312
8313        return scannedPkg;
8314    }
8315
8316    private void renameStaticSharedLibraryPackage(PackageParser.Package pkg) {
8317        // Derive the new package synthetic package name
8318        pkg.setPackageName(pkg.packageName + STATIC_SHARED_LIB_DELIMITER
8319                + pkg.staticSharedLibVersion);
8320    }
8321
8322    private static String fixProcessName(String defProcessName,
8323            String processName) {
8324        if (processName == null) {
8325            return defProcessName;
8326        }
8327        return processName;
8328    }
8329
8330    private void verifySignaturesLP(PackageSetting pkgSetting, PackageParser.Package pkg)
8331            throws PackageManagerException {
8332        if (pkgSetting.signatures.mSignatures != null) {
8333            // Already existing package. Make sure signatures match
8334            boolean match = compareSignatures(pkgSetting.signatures.mSignatures, pkg.mSignatures)
8335                    == PackageManager.SIGNATURE_MATCH;
8336            if (!match) {
8337                match = compareSignaturesCompat(pkgSetting.signatures, pkg)
8338                        == PackageManager.SIGNATURE_MATCH;
8339            }
8340            if (!match) {
8341                match = compareSignaturesRecover(pkgSetting.signatures, pkg)
8342                        == PackageManager.SIGNATURE_MATCH;
8343            }
8344            if (!match) {
8345                throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
8346                        + pkg.packageName + " signatures do not match the "
8347                        + "previously installed version; ignoring!");
8348            }
8349        }
8350
8351        // Check for shared user signatures
8352        if (pkgSetting.sharedUser != null && pkgSetting.sharedUser.signatures.mSignatures != null) {
8353            // Already existing package. Make sure signatures match
8354            boolean match = compareSignatures(pkgSetting.sharedUser.signatures.mSignatures,
8355                    pkg.mSignatures) == PackageManager.SIGNATURE_MATCH;
8356            if (!match) {
8357                match = compareSignaturesCompat(pkgSetting.sharedUser.signatures, pkg)
8358                        == PackageManager.SIGNATURE_MATCH;
8359            }
8360            if (!match) {
8361                match = compareSignaturesRecover(pkgSetting.sharedUser.signatures, pkg)
8362                        == PackageManager.SIGNATURE_MATCH;
8363            }
8364            if (!match) {
8365                throw new PackageManagerException(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
8366                        "Package " + pkg.packageName
8367                        + " has no signatures that match those in shared user "
8368                        + pkgSetting.sharedUser.name + "; ignoring!");
8369            }
8370        }
8371    }
8372
8373    /**
8374     * Enforces that only the system UID or root's UID can call a method exposed
8375     * via Binder.
8376     *
8377     * @param message used as message if SecurityException is thrown
8378     * @throws SecurityException if the caller is not system or root
8379     */
8380    private static final void enforceSystemOrRoot(String message) {
8381        final int uid = Binder.getCallingUid();
8382        if (uid != Process.SYSTEM_UID && uid != 0) {
8383            throw new SecurityException(message);
8384        }
8385    }
8386
8387    @Override
8388    public void performFstrimIfNeeded() {
8389        enforceSystemOrRoot("Only the system can request fstrim");
8390
8391        // Before everything else, see whether we need to fstrim.
8392        try {
8393            IStorageManager sm = PackageHelper.getStorageManager();
8394            if (sm != null) {
8395                boolean doTrim = false;
8396                final long interval = android.provider.Settings.Global.getLong(
8397                        mContext.getContentResolver(),
8398                        android.provider.Settings.Global.FSTRIM_MANDATORY_INTERVAL,
8399                        DEFAULT_MANDATORY_FSTRIM_INTERVAL);
8400                if (interval > 0) {
8401                    final long timeSinceLast = System.currentTimeMillis() - sm.lastMaintenance();
8402                    if (timeSinceLast > interval) {
8403                        doTrim = true;
8404                        Slog.w(TAG, "No disk maintenance in " + timeSinceLast
8405                                + "; running immediately");
8406                    }
8407                }
8408                if (doTrim) {
8409                    final boolean dexOptDialogShown;
8410                    synchronized (mPackages) {
8411                        dexOptDialogShown = mDexOptDialogShown;
8412                    }
8413                    if (!isFirstBoot() && dexOptDialogShown) {
8414                        try {
8415                            ActivityManager.getService().showBootMessage(
8416                                    mContext.getResources().getString(
8417                                            R.string.android_upgrading_fstrim), true);
8418                        } catch (RemoteException e) {
8419                        }
8420                    }
8421                    sm.runMaintenance();
8422                }
8423            } else {
8424                Slog.e(TAG, "storageManager service unavailable!");
8425            }
8426        } catch (RemoteException e) {
8427            // Can't happen; StorageManagerService is local
8428        }
8429    }
8430
8431    @Override
8432    public void updatePackagesIfNeeded() {
8433        enforceSystemOrRoot("Only the system can request package update");
8434
8435        // We need to re-extract after an OTA.
8436        boolean causeUpgrade = isUpgrade();
8437
8438        // First boot or factory reset.
8439        // Note: we also handle devices that are upgrading to N right now as if it is their
8440        //       first boot, as they do not have profile data.
8441        boolean causeFirstBoot = isFirstBoot() || mIsPreNUpgrade;
8442
8443        // We need to re-extract after a pruned cache, as AoT-ed files will be out of date.
8444        boolean causePrunedCache = VMRuntime.didPruneDalvikCache();
8445
8446        if (!causeUpgrade && !causeFirstBoot && !causePrunedCache) {
8447            return;
8448        }
8449
8450        List<PackageParser.Package> pkgs;
8451        synchronized (mPackages) {
8452            pkgs = PackageManagerServiceUtils.getPackagesForDexopt(mPackages.values(), this);
8453        }
8454
8455        final long startTime = System.nanoTime();
8456        final int[] stats = performDexOptUpgrade(pkgs, mIsPreNUpgrade /* showDialog */,
8457                    getCompilerFilterForReason(causeFirstBoot ? REASON_FIRST_BOOT : REASON_BOOT));
8458
8459        final int elapsedTimeSeconds =
8460                (int) TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - startTime);
8461
8462        MetricsLogger.histogram(mContext, "opt_dialog_num_dexopted", stats[0]);
8463        MetricsLogger.histogram(mContext, "opt_dialog_num_skipped", stats[1]);
8464        MetricsLogger.histogram(mContext, "opt_dialog_num_failed", stats[2]);
8465        MetricsLogger.histogram(mContext, "opt_dialog_num_total", getOptimizablePackages().size());
8466        MetricsLogger.histogram(mContext, "opt_dialog_time_s", elapsedTimeSeconds);
8467    }
8468
8469    /**
8470     * Performs dexopt on the set of packages in {@code packages} and returns an int array
8471     * containing statistics about the invocation. The array consists of three elements,
8472     * which are (in order) {@code numberOfPackagesOptimized}, {@code numberOfPackagesSkipped}
8473     * and {@code numberOfPackagesFailed}.
8474     */
8475    private int[] performDexOptUpgrade(List<PackageParser.Package> pkgs, boolean showDialog,
8476            String compilerFilter) {
8477
8478        int numberOfPackagesVisited = 0;
8479        int numberOfPackagesOptimized = 0;
8480        int numberOfPackagesSkipped = 0;
8481        int numberOfPackagesFailed = 0;
8482        final int numberOfPackagesToDexopt = pkgs.size();
8483
8484        for (PackageParser.Package pkg : pkgs) {
8485            numberOfPackagesVisited++;
8486
8487            if (!PackageDexOptimizer.canOptimizePackage(pkg)) {
8488                if (DEBUG_DEXOPT) {
8489                    Log.i(TAG, "Skipping update of of non-optimizable app " + pkg.packageName);
8490                }
8491                numberOfPackagesSkipped++;
8492                continue;
8493            }
8494
8495            if (DEBUG_DEXOPT) {
8496                Log.i(TAG, "Updating app " + numberOfPackagesVisited + " of " +
8497                        numberOfPackagesToDexopt + ": " + pkg.packageName);
8498            }
8499
8500            if (showDialog) {
8501                try {
8502                    ActivityManager.getService().showBootMessage(
8503                            mContext.getResources().getString(R.string.android_upgrading_apk,
8504                                    numberOfPackagesVisited, numberOfPackagesToDexopt), true);
8505                } catch (RemoteException e) {
8506                }
8507                synchronized (mPackages) {
8508                    mDexOptDialogShown = true;
8509                }
8510            }
8511
8512            // If the OTA updates a system app which was previously preopted to a non-preopted state
8513            // the app might end up being verified at runtime. That's because by default the apps
8514            // are verify-profile but for preopted apps there's no profile.
8515            // Do a hacky check to ensure that if we have no profiles (a reasonable indication
8516            // that before the OTA the app was preopted) the app gets compiled with a non-profile
8517            // filter (by default interpret-only).
8518            // Note that at this stage unused apps are already filtered.
8519            if (isSystemApp(pkg) &&
8520                    DexFile.isProfileGuidedCompilerFilter(compilerFilter) &&
8521                    !Environment.getReferenceProfile(pkg.packageName).exists()) {
8522                compilerFilter = getNonProfileGuidedCompilerFilter(compilerFilter);
8523            }
8524
8525            // checkProfiles is false to avoid merging profiles during boot which
8526            // might interfere with background compilation (b/28612421).
8527            // Unfortunately this will also means that "pm.dexopt.boot=speed-profile" will
8528            // behave differently than "pm.dexopt.bg-dexopt=speed-profile" but that's a
8529            // trade-off worth doing to save boot time work.
8530            int dexOptStatus = performDexOptTraced(pkg.packageName,
8531                    false /* checkProfiles */,
8532                    compilerFilter,
8533                    false /* force */);
8534            switch (dexOptStatus) {
8535                case PackageDexOptimizer.DEX_OPT_PERFORMED:
8536                    numberOfPackagesOptimized++;
8537                    break;
8538                case PackageDexOptimizer.DEX_OPT_SKIPPED:
8539                    numberOfPackagesSkipped++;
8540                    break;
8541                case PackageDexOptimizer.DEX_OPT_FAILED:
8542                    numberOfPackagesFailed++;
8543                    break;
8544                default:
8545                    Log.e(TAG, "Unexpected dexopt return code " + dexOptStatus);
8546                    break;
8547            }
8548        }
8549
8550        return new int[] { numberOfPackagesOptimized, numberOfPackagesSkipped,
8551                numberOfPackagesFailed };
8552    }
8553
8554    @Override
8555    public void notifyPackageUse(String packageName, int reason) {
8556        synchronized (mPackages) {
8557            PackageParser.Package p = mPackages.get(packageName);
8558            if (p == null) {
8559                return;
8560            }
8561            p.mLastPackageUsageTimeInMills[reason] = System.currentTimeMillis();
8562        }
8563    }
8564
8565    @Override
8566    public void notifyDexLoad(String loadingPackageName, List<String> dexPaths, String loaderIsa) {
8567        int userId = UserHandle.getCallingUserId();
8568        ApplicationInfo ai = getApplicationInfo(loadingPackageName, /*flags*/ 0, userId);
8569        if (ai == null) {
8570            Slog.w(TAG, "Loading a package that does not exist for the calling user. package="
8571                + loadingPackageName + ", user=" + userId);
8572            return;
8573        }
8574        mDexManager.notifyDexLoad(ai, dexPaths, loaderIsa, userId);
8575    }
8576
8577    // TODO: this is not used nor needed. Delete it.
8578    @Override
8579    public boolean performDexOptIfNeeded(String packageName) {
8580        int dexOptStatus = performDexOptTraced(packageName,
8581                false /* checkProfiles */, getFullCompilerFilter(), false /* force */);
8582        return dexOptStatus != PackageDexOptimizer.DEX_OPT_FAILED;
8583    }
8584
8585    @Override
8586    public boolean performDexOpt(String packageName,
8587            boolean checkProfiles, int compileReason, boolean force) {
8588        int dexOptStatus = performDexOptTraced(packageName, checkProfiles,
8589                getCompilerFilterForReason(compileReason), force);
8590        return dexOptStatus != PackageDexOptimizer.DEX_OPT_FAILED;
8591    }
8592
8593    @Override
8594    public boolean performDexOptMode(String packageName,
8595            boolean checkProfiles, String targetCompilerFilter, boolean force) {
8596        int dexOptStatus = performDexOptTraced(packageName, checkProfiles,
8597                targetCompilerFilter, force);
8598        return dexOptStatus != PackageDexOptimizer.DEX_OPT_FAILED;
8599    }
8600
8601    private int performDexOptTraced(String packageName,
8602                boolean checkProfiles, String targetCompilerFilter, boolean force) {
8603        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
8604        try {
8605            return performDexOptInternal(packageName, checkProfiles,
8606                    targetCompilerFilter, force);
8607        } finally {
8608            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8609        }
8610    }
8611
8612    // Run dexopt on a given package. Returns true if dexopt did not fail, i.e.
8613    // if the package can now be considered up to date for the given filter.
8614    private int performDexOptInternal(String packageName,
8615                boolean checkProfiles, String targetCompilerFilter, boolean force) {
8616        PackageParser.Package p;
8617        synchronized (mPackages) {
8618            p = mPackages.get(packageName);
8619            if (p == null) {
8620                // Package could not be found. Report failure.
8621                return PackageDexOptimizer.DEX_OPT_FAILED;
8622            }
8623            mPackageUsage.maybeWriteAsync(mPackages);
8624            mCompilerStats.maybeWriteAsync();
8625        }
8626        long callingId = Binder.clearCallingIdentity();
8627        try {
8628            synchronized (mInstallLock) {
8629                return performDexOptInternalWithDependenciesLI(p, checkProfiles,
8630                        targetCompilerFilter, force);
8631            }
8632        } finally {
8633            Binder.restoreCallingIdentity(callingId);
8634        }
8635    }
8636
8637    public ArraySet<String> getOptimizablePackages() {
8638        ArraySet<String> pkgs = new ArraySet<String>();
8639        synchronized (mPackages) {
8640            for (PackageParser.Package p : mPackages.values()) {
8641                if (PackageDexOptimizer.canOptimizePackage(p)) {
8642                    pkgs.add(p.packageName);
8643                }
8644            }
8645        }
8646        return pkgs;
8647    }
8648
8649    private int performDexOptInternalWithDependenciesLI(PackageParser.Package p,
8650            boolean checkProfiles, String targetCompilerFilter,
8651            boolean force) {
8652        // Select the dex optimizer based on the force parameter.
8653        // Note: The force option is rarely used (cmdline input for testing, mostly), so it's OK to
8654        //       allocate an object here.
8655        PackageDexOptimizer pdo = force
8656                ? new PackageDexOptimizer.ForcedUpdatePackageDexOptimizer(mPackageDexOptimizer)
8657                : mPackageDexOptimizer;
8658
8659        // Dexopt all dependencies first. Note: we ignore the return value and march on
8660        // on errors.
8661        // Note that we are going to call performDexOpt on those libraries as many times as
8662        // they are referenced in packages. When we do a batch of performDexOpt (for example
8663        // at boot, or background job), the passed 'targetCompilerFilter' stays the same,
8664        // and the first package that uses the library will dexopt it. The
8665        // others will see that the compiled code for the library is up to date.
8666        Collection<PackageParser.Package> deps = findSharedNonSystemLibraries(p);
8667        final String[] instructionSets = getAppDexInstructionSets(p.applicationInfo);
8668        if (!deps.isEmpty()) {
8669            for (PackageParser.Package depPackage : deps) {
8670                // TODO: Analyze and investigate if we (should) profile libraries.
8671                pdo.performDexOpt(depPackage, null /* sharedLibraries */, instructionSets,
8672                        false /* checkProfiles */,
8673                        targetCompilerFilter,
8674                        getOrCreateCompilerPackageStats(depPackage),
8675                        true /* isUsedByOtherApps */);
8676            }
8677        }
8678        return pdo.performDexOpt(p, p.usesLibraryFiles, instructionSets, checkProfiles,
8679                targetCompilerFilter, getOrCreateCompilerPackageStats(p),
8680                mDexManager.isUsedByOtherApps(p.packageName));
8681    }
8682
8683    // Performs dexopt on the used secondary dex files belonging to the given package.
8684    // Returns true if all dex files were process successfully (which could mean either dexopt or
8685    // skip). Returns false if any of the files caused errors.
8686    @Override
8687    public boolean performDexOptSecondary(String packageName, String compilerFilter,
8688            boolean force) {
8689        mDexManager.reconcileSecondaryDexFiles(packageName);
8690        return mDexManager.dexoptSecondaryDex(packageName, compilerFilter, force);
8691    }
8692
8693    public boolean performDexOptSecondary(String packageName, int compileReason,
8694            boolean force) {
8695        return mDexManager.dexoptSecondaryDex(packageName, compileReason, force);
8696    }
8697
8698    /**
8699     * Reconcile the information we have about the secondary dex files belonging to
8700     * {@code packagName} and the actual dex files. For all dex files that were
8701     * deleted, update the internal records and delete the generated oat files.
8702     */
8703    @Override
8704    public void reconcileSecondaryDexFiles(String packageName) {
8705        mDexManager.reconcileSecondaryDexFiles(packageName);
8706    }
8707
8708    // TODO(calin): this is only needed for BackgroundDexOptService. Find a cleaner way to inject
8709    // a reference there.
8710    /*package*/ DexManager getDexManager() {
8711        return mDexManager;
8712    }
8713
8714    /**
8715     * Execute the background dexopt job immediately.
8716     */
8717    @Override
8718    public boolean runBackgroundDexoptJob() {
8719        return BackgroundDexOptService.runIdleOptimizationsNow(this, mContext);
8720    }
8721
8722    List<PackageParser.Package> findSharedNonSystemLibraries(PackageParser.Package p) {
8723        if (p.usesLibraries != null || p.usesOptionalLibraries != null
8724                || p.usesStaticLibraries != null) {
8725            ArrayList<PackageParser.Package> retValue = new ArrayList<>();
8726            Set<String> collectedNames = new HashSet<>();
8727            findSharedNonSystemLibrariesRecursive(p, retValue, collectedNames);
8728
8729            retValue.remove(p);
8730
8731            return retValue;
8732        } else {
8733            return Collections.emptyList();
8734        }
8735    }
8736
8737    private void findSharedNonSystemLibrariesRecursive(PackageParser.Package p,
8738            ArrayList<PackageParser.Package> collected, Set<String> collectedNames) {
8739        if (!collectedNames.contains(p.packageName)) {
8740            collectedNames.add(p.packageName);
8741            collected.add(p);
8742
8743            if (p.usesLibraries != null) {
8744                findSharedNonSystemLibrariesRecursive(p.usesLibraries,
8745                        null, collected, collectedNames);
8746            }
8747            if (p.usesOptionalLibraries != null) {
8748                findSharedNonSystemLibrariesRecursive(p.usesOptionalLibraries,
8749                        null, collected, collectedNames);
8750            }
8751            if (p.usesStaticLibraries != null) {
8752                findSharedNonSystemLibrariesRecursive(p.usesStaticLibraries,
8753                        p.usesStaticLibrariesVersions, collected, collectedNames);
8754            }
8755        }
8756    }
8757
8758    private void findSharedNonSystemLibrariesRecursive(ArrayList<String> libs, int[] versions,
8759            ArrayList<PackageParser.Package> collected, Set<String> collectedNames) {
8760        final int libNameCount = libs.size();
8761        for (int i = 0; i < libNameCount; i++) {
8762            String libName = libs.get(i);
8763            int version = (versions != null && versions.length == libNameCount)
8764                    ? versions[i] : PackageManager.VERSION_CODE_HIGHEST;
8765            PackageParser.Package libPkg = findSharedNonSystemLibrary(libName, version);
8766            if (libPkg != null) {
8767                findSharedNonSystemLibrariesRecursive(libPkg, collected, collectedNames);
8768            }
8769        }
8770    }
8771
8772    private PackageParser.Package findSharedNonSystemLibrary(String name, int version) {
8773        synchronized (mPackages) {
8774            SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(name, version);
8775            if (libEntry != null) {
8776                return mPackages.get(libEntry.apk);
8777            }
8778            return null;
8779        }
8780    }
8781
8782    private SharedLibraryEntry getSharedLibraryEntryLPr(String name, int version) {
8783        SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(name);
8784        if (versionedLib == null) {
8785            return null;
8786        }
8787        return versionedLib.get(version);
8788    }
8789
8790    private SharedLibraryEntry getLatestSharedLibraVersionLPr(PackageParser.Package pkg) {
8791        SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(
8792                pkg.staticSharedLibName);
8793        if (versionedLib == null) {
8794            return null;
8795        }
8796        int previousLibVersion = -1;
8797        final int versionCount = versionedLib.size();
8798        for (int i = 0; i < versionCount; i++) {
8799            final int libVersion = versionedLib.keyAt(i);
8800            if (libVersion < pkg.staticSharedLibVersion) {
8801                previousLibVersion = Math.max(previousLibVersion, libVersion);
8802            }
8803        }
8804        if (previousLibVersion >= 0) {
8805            return versionedLib.get(previousLibVersion);
8806        }
8807        return null;
8808    }
8809
8810    public void shutdown() {
8811        mPackageUsage.writeNow(mPackages);
8812        mCompilerStats.writeNow();
8813    }
8814
8815    @Override
8816    public void dumpProfiles(String packageName) {
8817        PackageParser.Package pkg;
8818        synchronized (mPackages) {
8819            pkg = mPackages.get(packageName);
8820            if (pkg == null) {
8821                throw new IllegalArgumentException("Unknown package: " + packageName);
8822            }
8823        }
8824        /* Only the shell, root, or the app user should be able to dump profiles. */
8825        int callingUid = Binder.getCallingUid();
8826        if (callingUid != Process.SHELL_UID &&
8827            callingUid != Process.ROOT_UID &&
8828            callingUid != pkg.applicationInfo.uid) {
8829            throw new SecurityException("dumpProfiles");
8830        }
8831
8832        synchronized (mInstallLock) {
8833            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dump profiles");
8834            final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
8835            try {
8836                List<String> allCodePaths = pkg.getAllCodePathsExcludingResourceOnly();
8837                String codePaths = TextUtils.join(";", allCodePaths);
8838                mInstaller.dumpProfiles(sharedGid, packageName, codePaths);
8839            } catch (InstallerException e) {
8840                Slog.w(TAG, "Failed to dump profiles", e);
8841            }
8842            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8843        }
8844    }
8845
8846    @Override
8847    public void forceDexOpt(String packageName) {
8848        enforceSystemOrRoot("forceDexOpt");
8849
8850        PackageParser.Package pkg;
8851        synchronized (mPackages) {
8852            pkg = mPackages.get(packageName);
8853            if (pkg == null) {
8854                throw new IllegalArgumentException("Unknown package: " + packageName);
8855            }
8856        }
8857
8858        synchronized (mInstallLock) {
8859            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
8860
8861            // Whoever is calling forceDexOpt wants a fully compiled package.
8862            // Don't use profiles since that may cause compilation to be skipped.
8863            final int res = performDexOptInternalWithDependenciesLI(pkg,
8864                    false /* checkProfiles */, getCompilerFilterForReason(REASON_FORCED_DEXOPT),
8865                    true /* force */);
8866
8867            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8868            if (res != PackageDexOptimizer.DEX_OPT_PERFORMED) {
8869                throw new IllegalStateException("Failed to dexopt: " + res);
8870            }
8871        }
8872    }
8873
8874    private boolean verifyPackageUpdateLPr(PackageSetting oldPkg, PackageParser.Package newPkg) {
8875        if ((oldPkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8876            Slog.w(TAG, "Unable to update from " + oldPkg.name
8877                    + " to " + newPkg.packageName
8878                    + ": old package not in system partition");
8879            return false;
8880        } else if (mPackages.get(oldPkg.name) != null) {
8881            Slog.w(TAG, "Unable to update from " + oldPkg.name
8882                    + " to " + newPkg.packageName
8883                    + ": old package still exists");
8884            return false;
8885        }
8886        return true;
8887    }
8888
8889    void removeCodePathLI(File codePath) {
8890        if (codePath.isDirectory()) {
8891            try {
8892                mInstaller.rmPackageDir(codePath.getAbsolutePath());
8893            } catch (InstallerException e) {
8894                Slog.w(TAG, "Failed to remove code path", e);
8895            }
8896        } else {
8897            codePath.delete();
8898        }
8899    }
8900
8901    private int[] resolveUserIds(int userId) {
8902        return (userId == UserHandle.USER_ALL) ? sUserManager.getUserIds() : new int[] { userId };
8903    }
8904
8905    private void clearAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
8906        if (pkg == null) {
8907            Slog.wtf(TAG, "Package was null!", new Throwable());
8908            return;
8909        }
8910        clearAppDataLeafLIF(pkg, userId, flags);
8911        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
8912        for (int i = 0; i < childCount; i++) {
8913            clearAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
8914        }
8915    }
8916
8917    private void clearAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
8918        final PackageSetting ps;
8919        synchronized (mPackages) {
8920            ps = mSettings.mPackages.get(pkg.packageName);
8921        }
8922        for (int realUserId : resolveUserIds(userId)) {
8923            final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0;
8924            try {
8925                mInstaller.clearAppData(pkg.volumeUuid, pkg.packageName, realUserId, flags,
8926                        ceDataInode);
8927            } catch (InstallerException e) {
8928                Slog.w(TAG, String.valueOf(e));
8929            }
8930        }
8931    }
8932
8933    private void destroyAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
8934        if (pkg == null) {
8935            Slog.wtf(TAG, "Package was null!", new Throwable());
8936            return;
8937        }
8938        destroyAppDataLeafLIF(pkg, userId, flags);
8939        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
8940        for (int i = 0; i < childCount; i++) {
8941            destroyAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
8942        }
8943    }
8944
8945    private void destroyAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
8946        final PackageSetting ps;
8947        synchronized (mPackages) {
8948            ps = mSettings.mPackages.get(pkg.packageName);
8949        }
8950        for (int realUserId : resolveUserIds(userId)) {
8951            final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0;
8952            try {
8953                mInstaller.destroyAppData(pkg.volumeUuid, pkg.packageName, realUserId, flags,
8954                        ceDataInode);
8955            } catch (InstallerException e) {
8956                Slog.w(TAG, String.valueOf(e));
8957            }
8958            mDexManager.notifyPackageDataDestroyed(pkg.packageName, userId);
8959        }
8960    }
8961
8962    private void destroyAppProfilesLIF(PackageParser.Package pkg, int userId) {
8963        if (pkg == null) {
8964            Slog.wtf(TAG, "Package was null!", new Throwable());
8965            return;
8966        }
8967        destroyAppProfilesLeafLIF(pkg);
8968        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
8969        for (int i = 0; i < childCount; i++) {
8970            destroyAppProfilesLeafLIF(pkg.childPackages.get(i));
8971        }
8972    }
8973
8974    private void destroyAppProfilesLeafLIF(PackageParser.Package pkg) {
8975        try {
8976            mInstaller.destroyAppProfiles(pkg.packageName);
8977        } catch (InstallerException e) {
8978            Slog.w(TAG, String.valueOf(e));
8979        }
8980    }
8981
8982    private void clearAppProfilesLIF(PackageParser.Package pkg, int userId) {
8983        if (pkg == null) {
8984            Slog.wtf(TAG, "Package was null!", new Throwable());
8985            return;
8986        }
8987        clearAppProfilesLeafLIF(pkg);
8988        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
8989        for (int i = 0; i < childCount; i++) {
8990            clearAppProfilesLeafLIF(pkg.childPackages.get(i));
8991        }
8992    }
8993
8994    private void clearAppProfilesLeafLIF(PackageParser.Package pkg) {
8995        try {
8996            mInstaller.clearAppProfiles(pkg.packageName);
8997        } catch (InstallerException e) {
8998            Slog.w(TAG, String.valueOf(e));
8999        }
9000    }
9001
9002    private void setInstallAndUpdateTime(PackageParser.Package pkg, long firstInstallTime,
9003            long lastUpdateTime) {
9004        // Set parent install/update time
9005        PackageSetting ps = (PackageSetting) pkg.mExtras;
9006        if (ps != null) {
9007            ps.firstInstallTime = firstInstallTime;
9008            ps.lastUpdateTime = lastUpdateTime;
9009        }
9010        // Set children install/update time
9011        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9012        for (int i = 0; i < childCount; i++) {
9013            PackageParser.Package childPkg = pkg.childPackages.get(i);
9014            ps = (PackageSetting) childPkg.mExtras;
9015            if (ps != null) {
9016                ps.firstInstallTime = firstInstallTime;
9017                ps.lastUpdateTime = lastUpdateTime;
9018            }
9019        }
9020    }
9021
9022    private void addSharedLibraryLPr(ArraySet<String> usesLibraryFiles, SharedLibraryEntry file,
9023            PackageParser.Package changingLib) {
9024        if (file.path != null) {
9025            usesLibraryFiles.add(file.path);
9026            return;
9027        }
9028        PackageParser.Package p = mPackages.get(file.apk);
9029        if (changingLib != null && changingLib.packageName.equals(file.apk)) {
9030            // If we are doing this while in the middle of updating a library apk,
9031            // then we need to make sure to use that new apk for determining the
9032            // dependencies here.  (We haven't yet finished committing the new apk
9033            // to the package manager state.)
9034            if (p == null || p.packageName.equals(changingLib.packageName)) {
9035                p = changingLib;
9036            }
9037        }
9038        if (p != null) {
9039            usesLibraryFiles.addAll(p.getAllCodePaths());
9040        }
9041    }
9042
9043    private void updateSharedLibrariesLPr(PackageParser.Package pkg,
9044            PackageParser.Package changingLib) throws PackageManagerException {
9045        if (pkg == null) {
9046            return;
9047        }
9048        ArraySet<String> usesLibraryFiles = null;
9049        if (pkg.usesLibraries != null) {
9050            usesLibraryFiles = addSharedLibrariesLPw(pkg.usesLibraries,
9051                    null, null, pkg.packageName, changingLib, true, null);
9052        }
9053        if (pkg.usesStaticLibraries != null) {
9054            usesLibraryFiles = addSharedLibrariesLPw(pkg.usesStaticLibraries,
9055                    pkg.usesStaticLibrariesVersions, pkg.usesStaticLibrariesCertDigests,
9056                    pkg.packageName, changingLib, true, usesLibraryFiles);
9057        }
9058        if (pkg.usesOptionalLibraries != null) {
9059            usesLibraryFiles = addSharedLibrariesLPw(pkg.usesOptionalLibraries,
9060                    null, null, pkg.packageName, changingLib, false, usesLibraryFiles);
9061        }
9062        if (!ArrayUtils.isEmpty(usesLibraryFiles)) {
9063            pkg.usesLibraryFiles = usesLibraryFiles.toArray(new String[usesLibraryFiles.size()]);
9064        } else {
9065            pkg.usesLibraryFiles = null;
9066        }
9067    }
9068
9069    private ArraySet<String> addSharedLibrariesLPw(@NonNull List<String> requestedLibraries,
9070            @Nullable int[] requiredVersions, @Nullable String[] requiredCertDigests,
9071            @NonNull String packageName, @Nullable PackageParser.Package changingLib,
9072            boolean required, @Nullable ArraySet<String> outUsedLibraries)
9073            throws PackageManagerException {
9074        final int libCount = requestedLibraries.size();
9075        for (int i = 0; i < libCount; i++) {
9076            final String libName = requestedLibraries.get(i);
9077            final int libVersion = requiredVersions != null ? requiredVersions[i]
9078                    : SharedLibraryInfo.VERSION_UNDEFINED;
9079            final SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(libName, libVersion);
9080            if (libEntry == null) {
9081                if (required) {
9082                    throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
9083                            "Package " + packageName + " requires unavailable shared library "
9084                                    + libName + "; failing!");
9085                } else {
9086                    Slog.w(TAG, "Package " + packageName
9087                            + " desires unavailable shared library "
9088                            + libName + "; ignoring!");
9089                }
9090            } else {
9091                if (requiredVersions != null && requiredCertDigests != null) {
9092                    if (libEntry.info.getVersion() != requiredVersions[i]) {
9093                        throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
9094                            "Package " + packageName + " requires unavailable static shared"
9095                                    + " library " + libName + " version "
9096                                    + libEntry.info.getVersion() + "; failing!");
9097                    }
9098
9099                    PackageParser.Package libPkg = mPackages.get(libEntry.apk);
9100                    if (libPkg == null) {
9101                        throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
9102                                "Package " + packageName + " requires unavailable static shared"
9103                                        + " library; failing!");
9104                    }
9105
9106                    String expectedCertDigest = requiredCertDigests[i];
9107                    String libCertDigest = PackageUtils.computeCertSha256Digest(
9108                                libPkg.mSignatures[0]);
9109                    if (!libCertDigest.equalsIgnoreCase(expectedCertDigest)) {
9110                        throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
9111                                "Package " + packageName + " requires differently signed" +
9112                                        " static shared library; failing!");
9113                    }
9114                }
9115
9116                if (outUsedLibraries == null) {
9117                    outUsedLibraries = new ArraySet<>();
9118                }
9119                addSharedLibraryLPr(outUsedLibraries, libEntry, changingLib);
9120            }
9121        }
9122        return outUsedLibraries;
9123    }
9124
9125    private static boolean hasString(List<String> list, List<String> which) {
9126        if (list == null) {
9127            return false;
9128        }
9129        for (int i=list.size()-1; i>=0; i--) {
9130            for (int j=which.size()-1; j>=0; j--) {
9131                if (which.get(j).equals(list.get(i))) {
9132                    return true;
9133                }
9134            }
9135        }
9136        return false;
9137    }
9138
9139    private ArrayList<PackageParser.Package> updateAllSharedLibrariesLPw(
9140            PackageParser.Package changingPkg) {
9141        ArrayList<PackageParser.Package> res = null;
9142        for (PackageParser.Package pkg : mPackages.values()) {
9143            if (changingPkg != null
9144                    && !hasString(pkg.usesLibraries, changingPkg.libraryNames)
9145                    && !hasString(pkg.usesOptionalLibraries, changingPkg.libraryNames)
9146                    && !ArrayUtils.contains(pkg.usesStaticLibraries,
9147                            changingPkg.staticSharedLibName)) {
9148                return null;
9149            }
9150            if (res == null) {
9151                res = new ArrayList<>();
9152            }
9153            res.add(pkg);
9154            try {
9155                updateSharedLibrariesLPr(pkg, changingPkg);
9156            } catch (PackageManagerException e) {
9157                // If a system app update or an app and a required lib missing we
9158                // delete the package and for updated system apps keep the data as
9159                // it is better for the user to reinstall than to be in an limbo
9160                // state. Also libs disappearing under an app should never happen
9161                // - just in case.
9162                if (!pkg.isSystemApp() || pkg.isUpdatedSystemApp()) {
9163                    final int flags = pkg.isUpdatedSystemApp()
9164                            ? PackageManager.DELETE_KEEP_DATA : 0;
9165                    deletePackageLIF(pkg.packageName, null, true, sUserManager.getUserIds(),
9166                            flags , null, true, null);
9167                }
9168                Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
9169            }
9170        }
9171        return res;
9172    }
9173
9174    /**
9175     * Derive the value of the {@code cpuAbiOverride} based on the provided
9176     * value and an optional stored value from the package settings.
9177     */
9178    private static String deriveAbiOverride(String abiOverride, PackageSetting settings) {
9179        String cpuAbiOverride = null;
9180
9181        if (NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(abiOverride)) {
9182            cpuAbiOverride = null;
9183        } else if (abiOverride != null) {
9184            cpuAbiOverride = abiOverride;
9185        } else if (settings != null) {
9186            cpuAbiOverride = settings.cpuAbiOverrideString;
9187        }
9188
9189        return cpuAbiOverride;
9190    }
9191
9192    private PackageParser.Package scanPackageTracedLI(PackageParser.Package pkg,
9193            final int policyFlags, int scanFlags, long currentTime, @Nullable UserHandle user)
9194                    throws PackageManagerException {
9195        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage");
9196        // If the package has children and this is the first dive in the function
9197        // we recursively scan the package with the SCAN_CHECK_ONLY flag set to see
9198        // whether all packages (parent and children) would be successfully scanned
9199        // before the actual scan since scanning mutates internal state and we want
9200        // to atomically install the package and its children.
9201        if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
9202            if (pkg.childPackages != null && pkg.childPackages.size() > 0) {
9203                scanFlags |= SCAN_CHECK_ONLY;
9204            }
9205        } else {
9206            scanFlags &= ~SCAN_CHECK_ONLY;
9207        }
9208
9209        final PackageParser.Package scannedPkg;
9210        try {
9211            // Scan the parent
9212            scannedPkg = scanPackageLI(pkg, policyFlags, scanFlags, currentTime, user);
9213            // Scan the children
9214            final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9215            for (int i = 0; i < childCount; i++) {
9216                PackageParser.Package childPkg = pkg.childPackages.get(i);
9217                scanPackageLI(childPkg, policyFlags,
9218                        scanFlags, currentTime, user);
9219            }
9220        } finally {
9221            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9222        }
9223
9224        if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
9225            return scanPackageTracedLI(pkg, policyFlags, scanFlags, currentTime, user);
9226        }
9227
9228        return scannedPkg;
9229    }
9230
9231    private PackageParser.Package scanPackageLI(PackageParser.Package pkg, final int policyFlags,
9232            int scanFlags, long currentTime, @Nullable UserHandle user)
9233                    throws PackageManagerException {
9234        boolean success = false;
9235        try {
9236            final PackageParser.Package res = scanPackageDirtyLI(pkg, policyFlags, scanFlags,
9237                    currentTime, user);
9238            success = true;
9239            return res;
9240        } finally {
9241            if (!success && (scanFlags & SCAN_DELETE_DATA_ON_FAILURES) != 0) {
9242                // DELETE_DATA_ON_FAILURES is only used by frozen paths
9243                destroyAppDataLIF(pkg, UserHandle.USER_ALL,
9244                        StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
9245                destroyAppProfilesLIF(pkg, UserHandle.USER_ALL);
9246            }
9247        }
9248    }
9249
9250    /**
9251     * Returns {@code true} if the given file contains code. Otherwise {@code false}.
9252     */
9253    private static boolean apkHasCode(String fileName) {
9254        StrictJarFile jarFile = null;
9255        try {
9256            jarFile = new StrictJarFile(fileName,
9257                    false /*verify*/, false /*signatureSchemeRollbackProtectionsEnforced*/);
9258            return jarFile.findEntry("classes.dex") != null;
9259        } catch (IOException ignore) {
9260        } finally {
9261            try {
9262                if (jarFile != null) {
9263                    jarFile.close();
9264                }
9265            } catch (IOException ignore) {}
9266        }
9267        return false;
9268    }
9269
9270    /**
9271     * Enforces code policy for the package. This ensures that if an APK has
9272     * declared hasCode="true" in its manifest that the APK actually contains
9273     * code.
9274     *
9275     * @throws PackageManagerException If bytecode could not be found when it should exist
9276     */
9277    private static void assertCodePolicy(PackageParser.Package pkg)
9278            throws PackageManagerException {
9279        final boolean shouldHaveCode =
9280                (pkg.applicationInfo.flags & ApplicationInfo.FLAG_HAS_CODE) != 0;
9281        if (shouldHaveCode && !apkHasCode(pkg.baseCodePath)) {
9282            throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
9283                    "Package " + pkg.baseCodePath + " code is missing");
9284        }
9285
9286        if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) {
9287            for (int i = 0; i < pkg.splitCodePaths.length; i++) {
9288                final boolean splitShouldHaveCode =
9289                        (pkg.splitFlags[i] & ApplicationInfo.FLAG_HAS_CODE) != 0;
9290                if (splitShouldHaveCode && !apkHasCode(pkg.splitCodePaths[i])) {
9291                    throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
9292                            "Package " + pkg.splitCodePaths[i] + " code is missing");
9293                }
9294            }
9295        }
9296    }
9297
9298    private PackageParser.Package scanPackageDirtyLI(PackageParser.Package pkg,
9299            final int policyFlags, final int scanFlags, long currentTime, @Nullable UserHandle user)
9300                    throws PackageManagerException {
9301        if (DEBUG_PACKAGE_SCANNING) {
9302            if ((policyFlags & PackageParser.PARSE_CHATTY) != 0)
9303                Log.d(TAG, "Scanning package " + pkg.packageName);
9304        }
9305
9306        applyPolicy(pkg, policyFlags);
9307
9308        assertPackageIsValid(pkg, policyFlags, scanFlags);
9309
9310        // Initialize package source and resource directories
9311        final File scanFile = new File(pkg.codePath);
9312        final File destCodeFile = new File(pkg.applicationInfo.getCodePath());
9313        final File destResourceFile = new File(pkg.applicationInfo.getResourcePath());
9314
9315        SharedUserSetting suid = null;
9316        PackageSetting pkgSetting = null;
9317
9318        // Getting the package setting may have a side-effect, so if we
9319        // are only checking if scan would succeed, stash a copy of the
9320        // old setting to restore at the end.
9321        PackageSetting nonMutatedPs = null;
9322
9323        // We keep references to the derived CPU Abis from settings in oder to reuse
9324        // them in the case where we're not upgrading or booting for the first time.
9325        String primaryCpuAbiFromSettings = null;
9326        String secondaryCpuAbiFromSettings = null;
9327
9328        // writer
9329        synchronized (mPackages) {
9330            if (pkg.mSharedUserId != null) {
9331                // SIDE EFFECTS; may potentially allocate a new shared user
9332                suid = mSettings.getSharedUserLPw(
9333                        pkg.mSharedUserId, 0 /*pkgFlags*/, 0 /*pkgPrivateFlags*/, true /*create*/);
9334                if (DEBUG_PACKAGE_SCANNING) {
9335                    if ((policyFlags & PackageParser.PARSE_CHATTY) != 0)
9336                        Log.d(TAG, "Shared UserID " + pkg.mSharedUserId + " (uid=" + suid.userId
9337                                + "): packages=" + suid.packages);
9338                }
9339            }
9340
9341            // Check if we are renaming from an original package name.
9342            PackageSetting origPackage = null;
9343            String realName = null;
9344            if (pkg.mOriginalPackages != null) {
9345                // This package may need to be renamed to a previously
9346                // installed name.  Let's check on that...
9347                final String renamed = mSettings.getRenamedPackageLPr(pkg.mRealPackage);
9348                if (pkg.mOriginalPackages.contains(renamed)) {
9349                    // This package had originally been installed as the
9350                    // original name, and we have already taken care of
9351                    // transitioning to the new one.  Just update the new
9352                    // one to continue using the old name.
9353                    realName = pkg.mRealPackage;
9354                    if (!pkg.packageName.equals(renamed)) {
9355                        // Callers into this function may have already taken
9356                        // care of renaming the package; only do it here if
9357                        // it is not already done.
9358                        pkg.setPackageName(renamed);
9359                    }
9360                } else {
9361                    for (int i=pkg.mOriginalPackages.size()-1; i>=0; i--) {
9362                        if ((origPackage = mSettings.getPackageLPr(
9363                                pkg.mOriginalPackages.get(i))) != null) {
9364                            // We do have the package already installed under its
9365                            // original name...  should we use it?
9366                            if (!verifyPackageUpdateLPr(origPackage, pkg)) {
9367                                // New package is not compatible with original.
9368                                origPackage = null;
9369                                continue;
9370                            } else if (origPackage.sharedUser != null) {
9371                                // Make sure uid is compatible between packages.
9372                                if (!origPackage.sharedUser.name.equals(pkg.mSharedUserId)) {
9373                                    Slog.w(TAG, "Unable to migrate data from " + origPackage.name
9374                                            + " to " + pkg.packageName + ": old uid "
9375                                            + origPackage.sharedUser.name
9376                                            + " differs from " + pkg.mSharedUserId);
9377                                    origPackage = null;
9378                                    continue;
9379                                }
9380                                // TODO: Add case when shared user id is added [b/28144775]
9381                            } else {
9382                                if (DEBUG_UPGRADE) Log.v(TAG, "Renaming new package "
9383                                        + pkg.packageName + " to old name " + origPackage.name);
9384                            }
9385                            break;
9386                        }
9387                    }
9388                }
9389            }
9390
9391            if (mTransferedPackages.contains(pkg.packageName)) {
9392                Slog.w(TAG, "Package " + pkg.packageName
9393                        + " was transferred to another, but its .apk remains");
9394            }
9395
9396            // See comments in nonMutatedPs declaration
9397            if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
9398                PackageSetting foundPs = mSettings.getPackageLPr(pkg.packageName);
9399                if (foundPs != null) {
9400                    nonMutatedPs = new PackageSetting(foundPs);
9401                }
9402            }
9403
9404            if ((scanFlags & SCAN_FIRST_BOOT_OR_UPGRADE) == 0) {
9405                PackageSetting foundPs = mSettings.getPackageLPr(pkg.packageName);
9406                if (foundPs != null) {
9407                    primaryCpuAbiFromSettings = foundPs.primaryCpuAbiString;
9408                    secondaryCpuAbiFromSettings = foundPs.secondaryCpuAbiString;
9409                }
9410            }
9411
9412            pkgSetting = mSettings.getPackageLPr(pkg.packageName);
9413            if (pkgSetting != null && pkgSetting.sharedUser != suid) {
9414                PackageManagerService.reportSettingsProblem(Log.WARN,
9415                        "Package " + pkg.packageName + " shared user changed from "
9416                                + (pkgSetting.sharedUser != null
9417                                        ? pkgSetting.sharedUser.name : "<nothing>")
9418                                + " to "
9419                                + (suid != null ? suid.name : "<nothing>")
9420                                + "; replacing with new");
9421                pkgSetting = null;
9422            }
9423            final PackageSetting oldPkgSetting =
9424                    pkgSetting == null ? null : new PackageSetting(pkgSetting);
9425            final PackageSetting disabledPkgSetting =
9426                    mSettings.getDisabledSystemPkgLPr(pkg.packageName);
9427
9428            String[] usesStaticLibraries = null;
9429            if (pkg.usesStaticLibraries != null) {
9430                usesStaticLibraries = new String[pkg.usesStaticLibraries.size()];
9431                pkg.usesStaticLibraries.toArray(usesStaticLibraries);
9432            }
9433
9434            if (pkgSetting == null) {
9435                final String parentPackageName = (pkg.parentPackage != null)
9436                        ? pkg.parentPackage.packageName : null;
9437                final boolean instantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
9438                // REMOVE SharedUserSetting from method; update in a separate call
9439                pkgSetting = Settings.createNewSetting(pkg.packageName, origPackage,
9440                        disabledPkgSetting, realName, suid, destCodeFile, destResourceFile,
9441                        pkg.applicationInfo.nativeLibraryRootDir, pkg.applicationInfo.primaryCpuAbi,
9442                        pkg.applicationInfo.secondaryCpuAbi, pkg.mVersionCode,
9443                        pkg.applicationInfo.flags, pkg.applicationInfo.privateFlags, user,
9444                        true /*allowInstall*/, instantApp, parentPackageName,
9445                        pkg.getChildPackageNames(), UserManagerService.getInstance(),
9446                        usesStaticLibraries, pkg.usesStaticLibrariesVersions);
9447                // SIDE EFFECTS; updates system state; move elsewhere
9448                if (origPackage != null) {
9449                    mSettings.addRenamedPackageLPw(pkg.packageName, origPackage.name);
9450                }
9451                mSettings.addUserToSettingLPw(pkgSetting);
9452            } else {
9453                // REMOVE SharedUserSetting from method; update in a separate call.
9454                //
9455                // TODO(narayan): This update is bogus. nativeLibraryDir & primaryCpuAbi,
9456                // secondaryCpuAbi are not known at this point so we always update them
9457                // to null here, only to reset them at a later point.
9458                Settings.updatePackageSetting(pkgSetting, disabledPkgSetting, suid, destCodeFile,
9459                        pkg.applicationInfo.nativeLibraryDir, pkg.applicationInfo.primaryCpuAbi,
9460                        pkg.applicationInfo.secondaryCpuAbi, pkg.applicationInfo.flags,
9461                        pkg.applicationInfo.privateFlags, pkg.getChildPackageNames(),
9462                        UserManagerService.getInstance(), usesStaticLibraries,
9463                        pkg.usesStaticLibrariesVersions);
9464            }
9465            // SIDE EFFECTS; persists system state to files on disk; move elsewhere
9466            mSettings.writeUserRestrictionsLPw(pkgSetting, oldPkgSetting);
9467
9468            // SIDE EFFECTS; modifies system state; move elsewhere
9469            if (pkgSetting.origPackage != null) {
9470                // If we are first transitioning from an original package,
9471                // fix up the new package's name now.  We need to do this after
9472                // looking up the package under its new name, so getPackageLP
9473                // can take care of fiddling things correctly.
9474                pkg.setPackageName(origPackage.name);
9475
9476                // File a report about this.
9477                String msg = "New package " + pkgSetting.realName
9478                        + " renamed to replace old package " + pkgSetting.name;
9479                reportSettingsProblem(Log.WARN, msg);
9480
9481                // Make a note of it.
9482                if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
9483                    mTransferedPackages.add(origPackage.name);
9484                }
9485
9486                // No longer need to retain this.
9487                pkgSetting.origPackage = null;
9488            }
9489
9490            // SIDE EFFECTS; modifies system state; move elsewhere
9491            if ((scanFlags & SCAN_CHECK_ONLY) == 0 && realName != null) {
9492                // Make a note of it.
9493                mTransferedPackages.add(pkg.packageName);
9494            }
9495
9496            if (mSettings.isDisabledSystemPackageLPr(pkg.packageName)) {
9497                pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
9498            }
9499
9500            if ((scanFlags & SCAN_BOOTING) == 0
9501                    && (policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
9502                // Check all shared libraries and map to their actual file path.
9503                // We only do this here for apps not on a system dir, because those
9504                // are the only ones that can fail an install due to this.  We
9505                // will take care of the system apps by updating all of their
9506                // library paths after the scan is done. Also during the initial
9507                // scan don't update any libs as we do this wholesale after all
9508                // apps are scanned to avoid dependency based scanning.
9509                updateSharedLibrariesLPr(pkg, null);
9510            }
9511
9512            if (mFoundPolicyFile) {
9513                SELinuxMMAC.assignSeInfoValue(pkg);
9514            }
9515            pkg.applicationInfo.uid = pkgSetting.appId;
9516            pkg.mExtras = pkgSetting;
9517
9518
9519            // Static shared libs have same package with different versions where
9520            // we internally use a synthetic package name to allow multiple versions
9521            // of the same package, therefore we need to compare signatures against
9522            // the package setting for the latest library version.
9523            PackageSetting signatureCheckPs = pkgSetting;
9524            if (pkg.applicationInfo.isStaticSharedLibrary()) {
9525                SharedLibraryEntry libraryEntry = getLatestSharedLibraVersionLPr(pkg);
9526                if (libraryEntry != null) {
9527                    signatureCheckPs = mSettings.getPackageLPr(libraryEntry.apk);
9528                }
9529            }
9530
9531            if (shouldCheckUpgradeKeySetLP(signatureCheckPs, scanFlags)) {
9532                if (checkUpgradeKeySetLP(signatureCheckPs, pkg)) {
9533                    // We just determined the app is signed correctly, so bring
9534                    // over the latest parsed certs.
9535                    pkgSetting.signatures.mSignatures = pkg.mSignatures;
9536                } else {
9537                    if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
9538                        throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
9539                                "Package " + pkg.packageName + " upgrade keys do not match the "
9540                                + "previously installed version");
9541                    } else {
9542                        pkgSetting.signatures.mSignatures = pkg.mSignatures;
9543                        String msg = "System package " + pkg.packageName
9544                                + " signature changed; retaining data.";
9545                        reportSettingsProblem(Log.WARN, msg);
9546                    }
9547                }
9548            } else {
9549                try {
9550                    // SIDE EFFECTS; compareSignaturesCompat() changes KeysetManagerService
9551                    verifySignaturesLP(signatureCheckPs, pkg);
9552                    // We just determined the app is signed correctly, so bring
9553                    // over the latest parsed certs.
9554                    pkgSetting.signatures.mSignatures = pkg.mSignatures;
9555                } catch (PackageManagerException e) {
9556                    if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
9557                        throw e;
9558                    }
9559                    // The signature has changed, but this package is in the system
9560                    // image...  let's recover!
9561                    pkgSetting.signatures.mSignatures = pkg.mSignatures;
9562                    // However...  if this package is part of a shared user, but it
9563                    // doesn't match the signature of the shared user, let's fail.
9564                    // What this means is that you can't change the signatures
9565                    // associated with an overall shared user, which doesn't seem all
9566                    // that unreasonable.
9567                    if (signatureCheckPs.sharedUser != null) {
9568                        if (compareSignatures(signatureCheckPs.sharedUser.signatures.mSignatures,
9569                                pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) {
9570                            throw new PackageManagerException(
9571                                    INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES,
9572                                    "Signature mismatch for shared user: "
9573                                            + pkgSetting.sharedUser);
9574                        }
9575                    }
9576                    // File a report about this.
9577                    String msg = "System package " + pkg.packageName
9578                            + " signature changed; retaining data.";
9579                    reportSettingsProblem(Log.WARN, msg);
9580                }
9581            }
9582
9583            if ((scanFlags & SCAN_CHECK_ONLY) == 0 && pkg.mAdoptPermissions != null) {
9584                // This package wants to adopt ownership of permissions from
9585                // another package.
9586                for (int i = pkg.mAdoptPermissions.size() - 1; i >= 0; i--) {
9587                    final String origName = pkg.mAdoptPermissions.get(i);
9588                    final PackageSetting orig = mSettings.getPackageLPr(origName);
9589                    if (orig != null) {
9590                        if (verifyPackageUpdateLPr(orig, pkg)) {
9591                            Slog.i(TAG, "Adopting permissions from " + origName + " to "
9592                                    + pkg.packageName);
9593                            // SIDE EFFECTS; updates permissions system state; move elsewhere
9594                            mSettings.transferPermissionsLPw(origName, pkg.packageName);
9595                        }
9596                    }
9597                }
9598            }
9599        }
9600
9601        pkg.applicationInfo.processName = fixProcessName(
9602                pkg.applicationInfo.packageName,
9603                pkg.applicationInfo.processName);
9604
9605        if (pkg != mPlatformPackage) {
9606            // Get all of our default paths setup
9607            pkg.applicationInfo.initForUser(UserHandle.USER_SYSTEM);
9608        }
9609
9610        final String cpuAbiOverride = deriveAbiOverride(pkg.cpuAbiOverride, pkgSetting);
9611
9612        if ((scanFlags & SCAN_NEW_INSTALL) == 0) {
9613            if ((scanFlags & SCAN_FIRST_BOOT_OR_UPGRADE) != 0) {
9614                Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "derivePackageAbi");
9615                derivePackageAbi(
9616                        pkg, scanFile, cpuAbiOverride, true /*extractLibs*/, mAppLib32InstallDir);
9617                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9618
9619                // Some system apps still use directory structure for native libraries
9620                // in which case we might end up not detecting abi solely based on apk
9621                // structure. Try to detect abi based on directory structure.
9622                if (isSystemApp(pkg) && !pkg.isUpdatedSystemApp() &&
9623                        pkg.applicationInfo.primaryCpuAbi == null) {
9624                    setBundledAppAbisAndRoots(pkg, pkgSetting);
9625                    setNativeLibraryPaths(pkg, mAppLib32InstallDir);
9626                }
9627            } else {
9628                // This is not a first boot or an upgrade, don't bother deriving the
9629                // ABI during the scan. Instead, trust the value that was stored in the
9630                // package setting.
9631                pkg.applicationInfo.primaryCpuAbi = primaryCpuAbiFromSettings;
9632                pkg.applicationInfo.secondaryCpuAbi = secondaryCpuAbiFromSettings;
9633
9634                setNativeLibraryPaths(pkg, mAppLib32InstallDir);
9635
9636                if (DEBUG_ABI_SELECTION) {
9637                    Slog.i(TAG, "Using ABIS and native lib paths from settings : " +
9638                        pkg.packageName + " " + pkg.applicationInfo.primaryCpuAbi + ", " +
9639                        pkg.applicationInfo.secondaryCpuAbi);
9640                }
9641            }
9642        } else {
9643            if ((scanFlags & SCAN_MOVE) != 0) {
9644                // We haven't run dex-opt for this move (since we've moved the compiled output too)
9645                // but we already have this packages package info in the PackageSetting. We just
9646                // use that and derive the native library path based on the new codepath.
9647                pkg.applicationInfo.primaryCpuAbi = pkgSetting.primaryCpuAbiString;
9648                pkg.applicationInfo.secondaryCpuAbi = pkgSetting.secondaryCpuAbiString;
9649            }
9650
9651            // Set native library paths again. For moves, the path will be updated based on the
9652            // ABIs we've determined above. For non-moves, the path will be updated based on the
9653            // ABIs we determined during compilation, but the path will depend on the final
9654            // package path (after the rename away from the stage path).
9655            setNativeLibraryPaths(pkg, mAppLib32InstallDir);
9656        }
9657
9658        // This is a special case for the "system" package, where the ABI is
9659        // dictated by the zygote configuration (and init.rc). We should keep track
9660        // of this ABI so that we can deal with "normal" applications that run under
9661        // the same UID correctly.
9662        if (mPlatformPackage == pkg) {
9663            pkg.applicationInfo.primaryCpuAbi = VMRuntime.getRuntime().is64Bit() ?
9664                    Build.SUPPORTED_64_BIT_ABIS[0] : Build.SUPPORTED_32_BIT_ABIS[0];
9665        }
9666
9667        // If there's a mismatch between the abi-override in the package setting
9668        // and the abiOverride specified for the install. Warn about this because we
9669        // would've already compiled the app without taking the package setting into
9670        // account.
9671        if ((scanFlags & SCAN_NO_DEX) == 0 && (scanFlags & SCAN_NEW_INSTALL) != 0) {
9672            if (cpuAbiOverride == null && pkgSetting.cpuAbiOverrideString != null) {
9673                Slog.w(TAG, "Ignoring persisted ABI override " + cpuAbiOverride +
9674                        " for package " + pkg.packageName);
9675            }
9676        }
9677
9678        pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
9679        pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
9680        pkgSetting.cpuAbiOverrideString = cpuAbiOverride;
9681
9682        // Copy the derived override back to the parsed package, so that we can
9683        // update the package settings accordingly.
9684        pkg.cpuAbiOverride = cpuAbiOverride;
9685
9686        if (DEBUG_ABI_SELECTION) {
9687            Slog.d(TAG, "Resolved nativeLibraryRoot for " + pkg.applicationInfo.packageName
9688                    + " to root=" + pkg.applicationInfo.nativeLibraryRootDir + ", isa="
9689                    + pkg.applicationInfo.nativeLibraryRootRequiresIsa);
9690        }
9691
9692        // Push the derived path down into PackageSettings so we know what to
9693        // clean up at uninstall time.
9694        pkgSetting.legacyNativeLibraryPathString = pkg.applicationInfo.nativeLibraryRootDir;
9695
9696        if (DEBUG_ABI_SELECTION) {
9697            Log.d(TAG, "Abis for package[" + pkg.packageName + "] are" +
9698                    " primary=" + pkg.applicationInfo.primaryCpuAbi +
9699                    " secondary=" + pkg.applicationInfo.secondaryCpuAbi);
9700        }
9701
9702        // SIDE EFFECTS; removes DEX files from disk; move elsewhere
9703        if ((scanFlags & SCAN_BOOTING) == 0 && pkgSetting.sharedUser != null) {
9704            // We don't do this here during boot because we can do it all
9705            // at once after scanning all existing packages.
9706            //
9707            // We also do this *before* we perform dexopt on this package, so that
9708            // we can avoid redundant dexopts, and also to make sure we've got the
9709            // code and package path correct.
9710            adjustCpuAbisForSharedUserLPw(pkgSetting.sharedUser.packages, pkg);
9711        }
9712
9713        if (mFactoryTest && pkg.requestedPermissions.contains(
9714                android.Manifest.permission.FACTORY_TEST)) {
9715            pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST;
9716        }
9717
9718        if (isSystemApp(pkg)) {
9719            pkgSetting.isOrphaned = true;
9720        }
9721
9722        // Take care of first install / last update times.
9723        final long scanFileTime = getLastModifiedTime(pkg, scanFile);
9724        if (currentTime != 0) {
9725            if (pkgSetting.firstInstallTime == 0) {
9726                pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = currentTime;
9727            } else if ((scanFlags & SCAN_UPDATE_TIME) != 0) {
9728                pkgSetting.lastUpdateTime = currentTime;
9729            }
9730        } else if (pkgSetting.firstInstallTime == 0) {
9731            // We need *something*.  Take time time stamp of the file.
9732            pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = scanFileTime;
9733        } else if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0) {
9734            if (scanFileTime != pkgSetting.timeStamp) {
9735                // A package on the system image has changed; consider this
9736                // to be an update.
9737                pkgSetting.lastUpdateTime = scanFileTime;
9738            }
9739        }
9740        pkgSetting.setTimeStamp(scanFileTime);
9741
9742        if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
9743            if (nonMutatedPs != null) {
9744                synchronized (mPackages) {
9745                    mSettings.mPackages.put(nonMutatedPs.name, nonMutatedPs);
9746                }
9747            }
9748        } else {
9749            final int userId = user == null ? 0 : user.getIdentifier();
9750            // Modify state for the given package setting
9751            commitPackageSettings(pkg, pkgSetting, user, scanFlags,
9752                    (policyFlags & PackageParser.PARSE_CHATTY) != 0 /*chatty*/);
9753            if (pkgSetting.getInstantApp(userId)) {
9754                mInstantAppRegistry.addInstantAppLPw(userId, pkgSetting.appId);
9755            }
9756        }
9757        return pkg;
9758    }
9759
9760    /**
9761     * Applies policy to the parsed package based upon the given policy flags.
9762     * Ensures the package is in a good state.
9763     * <p>
9764     * Implementation detail: This method must NOT have any side effect. It would
9765     * ideally be static, but, it requires locks to read system state.
9766     */
9767    private void applyPolicy(PackageParser.Package pkg, int policyFlags) {
9768        if ((policyFlags&PackageParser.PARSE_IS_SYSTEM) != 0) {
9769            pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
9770            if (pkg.applicationInfo.isDirectBootAware()) {
9771                // we're direct boot aware; set for all components
9772                for (PackageParser.Service s : pkg.services) {
9773                    s.info.encryptionAware = s.info.directBootAware = true;
9774                }
9775                for (PackageParser.Provider p : pkg.providers) {
9776                    p.info.encryptionAware = p.info.directBootAware = true;
9777                }
9778                for (PackageParser.Activity a : pkg.activities) {
9779                    a.info.encryptionAware = a.info.directBootAware = true;
9780                }
9781                for (PackageParser.Activity r : pkg.receivers) {
9782                    r.info.encryptionAware = r.info.directBootAware = true;
9783                }
9784            }
9785        } else {
9786            // Only allow system apps to be flagged as core apps.
9787            pkg.coreApp = false;
9788            // clear flags not applicable to regular apps
9789            pkg.applicationInfo.privateFlags &=
9790                    ~ApplicationInfo.PRIVATE_FLAG_DEFAULT_TO_DEVICE_PROTECTED_STORAGE;
9791            pkg.applicationInfo.privateFlags &=
9792                    ~ApplicationInfo.PRIVATE_FLAG_DIRECT_BOOT_AWARE;
9793        }
9794        pkg.mTrustedOverlay = (policyFlags&PackageParser.PARSE_TRUSTED_OVERLAY) != 0;
9795
9796        if ((policyFlags&PackageParser.PARSE_IS_PRIVILEGED) != 0) {
9797            pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
9798        }
9799
9800        if (!isSystemApp(pkg)) {
9801            // Only system apps can use these features.
9802            pkg.mOriginalPackages = null;
9803            pkg.mRealPackage = null;
9804            pkg.mAdoptPermissions = null;
9805        }
9806    }
9807
9808    /**
9809     * Asserts the parsed package is valid according to the given policy. If the
9810     * package is invalid, for whatever reason, throws {@link PackageManagerException}.
9811     * <p>
9812     * Implementation detail: This method must NOT have any side effects. It would
9813     * ideally be static, but, it requires locks to read system state.
9814     *
9815     * @throws PackageManagerException If the package fails any of the validation checks
9816     */
9817    private void assertPackageIsValid(PackageParser.Package pkg, int policyFlags, int scanFlags)
9818            throws PackageManagerException {
9819        if ((policyFlags & PackageParser.PARSE_ENFORCE_CODE) != 0) {
9820            assertCodePolicy(pkg);
9821        }
9822
9823        if (pkg.applicationInfo.getCodePath() == null ||
9824                pkg.applicationInfo.getResourcePath() == null) {
9825            // Bail out. The resource and code paths haven't been set.
9826            throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
9827                    "Code and resource paths haven't been set correctly");
9828        }
9829
9830        // Make sure we're not adding any bogus keyset info
9831        KeySetManagerService ksms = mSettings.mKeySetManagerService;
9832        ksms.assertScannedPackageValid(pkg);
9833
9834        synchronized (mPackages) {
9835            // The special "android" package can only be defined once
9836            if (pkg.packageName.equals("android")) {
9837                if (mAndroidApplication != null) {
9838                    Slog.w(TAG, "*************************************************");
9839                    Slog.w(TAG, "Core android package being redefined.  Skipping.");
9840                    Slog.w(TAG, " codePath=" + pkg.codePath);
9841                    Slog.w(TAG, "*************************************************");
9842                    throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
9843                            "Core android package being redefined.  Skipping.");
9844                }
9845            }
9846
9847            // A package name must be unique; don't allow duplicates
9848            if (mPackages.containsKey(pkg.packageName)) {
9849                throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
9850                        "Application package " + pkg.packageName
9851                        + " already installed.  Skipping duplicate.");
9852            }
9853
9854            if (pkg.applicationInfo.isStaticSharedLibrary()) {
9855                // Static libs have a synthetic package name containing the version
9856                // but we still want the base name to be unique.
9857                if (mPackages.containsKey(pkg.manifestPackageName)) {
9858                    throw new PackageManagerException(
9859                            "Duplicate static shared lib provider package");
9860                }
9861
9862                // Static shared libraries should have at least O target SDK
9863                if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.O) {
9864                    throw new PackageManagerException(
9865                            "Packages declaring static-shared libs must target O SDK or higher");
9866                }
9867
9868                // Package declaring static a shared lib cannot be instant apps
9869                if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
9870                    throw new PackageManagerException(
9871                            "Packages declaring static-shared libs cannot be instant apps");
9872                }
9873
9874                // Package declaring static a shared lib cannot be renamed since the package
9875                // name is synthetic and apps can't code around package manager internals.
9876                if (!ArrayUtils.isEmpty(pkg.mOriginalPackages)) {
9877                    throw new PackageManagerException(
9878                            "Packages declaring static-shared libs cannot be renamed");
9879                }
9880
9881                // Package declaring static a shared lib cannot declare child packages
9882                if (!ArrayUtils.isEmpty(pkg.childPackages)) {
9883                    throw new PackageManagerException(
9884                            "Packages declaring static-shared libs cannot have child packages");
9885                }
9886
9887                // Package declaring static a shared lib cannot declare dynamic libs
9888                if (!ArrayUtils.isEmpty(pkg.libraryNames)) {
9889                    throw new PackageManagerException(
9890                            "Packages declaring static-shared libs cannot declare dynamic libs");
9891                }
9892
9893                // Package declaring static a shared lib cannot declare shared users
9894                if (pkg.mSharedUserId != null) {
9895                    throw new PackageManagerException(
9896                            "Packages declaring static-shared libs cannot declare shared users");
9897                }
9898
9899                // Static shared libs cannot declare activities
9900                if (!pkg.activities.isEmpty()) {
9901                    throw new PackageManagerException(
9902                            "Static shared libs cannot declare activities");
9903                }
9904
9905                // Static shared libs cannot declare services
9906                if (!pkg.services.isEmpty()) {
9907                    throw new PackageManagerException(
9908                            "Static shared libs cannot declare services");
9909                }
9910
9911                // Static shared libs cannot declare providers
9912                if (!pkg.providers.isEmpty()) {
9913                    throw new PackageManagerException(
9914                            "Static shared libs cannot declare content providers");
9915                }
9916
9917                // Static shared libs cannot declare receivers
9918                if (!pkg.receivers.isEmpty()) {
9919                    throw new PackageManagerException(
9920                            "Static shared libs cannot declare broadcast receivers");
9921                }
9922
9923                // Static shared libs cannot declare permission groups
9924                if (!pkg.permissionGroups.isEmpty()) {
9925                    throw new PackageManagerException(
9926                            "Static shared libs cannot declare permission groups");
9927                }
9928
9929                // Static shared libs cannot declare permissions
9930                if (!pkg.permissions.isEmpty()) {
9931                    throw new PackageManagerException(
9932                            "Static shared libs cannot declare permissions");
9933                }
9934
9935                // Static shared libs cannot declare protected broadcasts
9936                if (pkg.protectedBroadcasts != null) {
9937                    throw new PackageManagerException(
9938                            "Static shared libs cannot declare protected broadcasts");
9939                }
9940
9941                // Static shared libs cannot be overlay targets
9942                if (pkg.mOverlayTarget != null) {
9943                    throw new PackageManagerException(
9944                            "Static shared libs cannot be overlay targets");
9945                }
9946
9947                // The version codes must be ordered as lib versions
9948                int minVersionCode = Integer.MIN_VALUE;
9949                int maxVersionCode = Integer.MAX_VALUE;
9950
9951                SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(
9952                        pkg.staticSharedLibName);
9953                if (versionedLib != null) {
9954                    final int versionCount = versionedLib.size();
9955                    for (int i = 0; i < versionCount; i++) {
9956                        SharedLibraryInfo libInfo = versionedLib.valueAt(i).info;
9957                        // TODO: We will change version code to long, so in the new API it is long
9958                        final int libVersionCode = (int) libInfo.getDeclaringPackage()
9959                                .getVersionCode();
9960                        if (libInfo.getVersion() <  pkg.staticSharedLibVersion) {
9961                            minVersionCode = Math.max(minVersionCode, libVersionCode + 1);
9962                        } else if (libInfo.getVersion() >  pkg.staticSharedLibVersion) {
9963                            maxVersionCode = Math.min(maxVersionCode, libVersionCode - 1);
9964                        } else {
9965                            minVersionCode = maxVersionCode = libVersionCode;
9966                            break;
9967                        }
9968                    }
9969                }
9970                if (pkg.mVersionCode < minVersionCode || pkg.mVersionCode > maxVersionCode) {
9971                    throw new PackageManagerException("Static shared"
9972                            + " lib version codes must be ordered as lib versions");
9973                }
9974            }
9975
9976            // Only privileged apps and updated privileged apps can add child packages.
9977            if (pkg.childPackages != null && !pkg.childPackages.isEmpty()) {
9978                if ((policyFlags & PARSE_IS_PRIVILEGED) == 0) {
9979                    throw new PackageManagerException("Only privileged apps can add child "
9980                            + "packages. Ignoring package " + pkg.packageName);
9981                }
9982                final int childCount = pkg.childPackages.size();
9983                for (int i = 0; i < childCount; i++) {
9984                    PackageParser.Package childPkg = pkg.childPackages.get(i);
9985                    if (mSettings.hasOtherDisabledSystemPkgWithChildLPr(pkg.packageName,
9986                            childPkg.packageName)) {
9987                        throw new PackageManagerException("Can't override child of "
9988                                + "another disabled app. Ignoring package " + pkg.packageName);
9989                    }
9990                }
9991            }
9992
9993            // If we're only installing presumed-existing packages, require that the
9994            // scanned APK is both already known and at the path previously established
9995            // for it.  Previously unknown packages we pick up normally, but if we have an
9996            // a priori expectation about this package's install presence, enforce it.
9997            // With a singular exception for new system packages. When an OTA contains
9998            // a new system package, we allow the codepath to change from a system location
9999            // to the user-installed location. If we don't allow this change, any newer,
10000            // user-installed version of the application will be ignored.
10001            if ((scanFlags & SCAN_REQUIRE_KNOWN) != 0) {
10002                if (mExpectingBetter.containsKey(pkg.packageName)) {
10003                    logCriticalInfo(Log.WARN,
10004                            "Relax SCAN_REQUIRE_KNOWN requirement for package " + pkg.packageName);
10005                } else {
10006                    PackageSetting known = mSettings.getPackageLPr(pkg.packageName);
10007                    if (known != null) {
10008                        if (DEBUG_PACKAGE_SCANNING) {
10009                            Log.d(TAG, "Examining " + pkg.codePath
10010                                    + " and requiring known paths " + known.codePathString
10011                                    + " & " + known.resourcePathString);
10012                        }
10013                        if (!pkg.applicationInfo.getCodePath().equals(known.codePathString)
10014                                || !pkg.applicationInfo.getResourcePath().equals(
10015                                        known.resourcePathString)) {
10016                            throw new PackageManagerException(INSTALL_FAILED_PACKAGE_CHANGED,
10017                                    "Application package " + pkg.packageName
10018                                    + " found at " + pkg.applicationInfo.getCodePath()
10019                                    + " but expected at " + known.codePathString
10020                                    + "; ignoring.");
10021                        }
10022                    }
10023                }
10024            }
10025
10026            // Verify that this new package doesn't have any content providers
10027            // that conflict with existing packages.  Only do this if the
10028            // package isn't already installed, since we don't want to break
10029            // things that are installed.
10030            if ((scanFlags & SCAN_NEW_INSTALL) != 0) {
10031                final int N = pkg.providers.size();
10032                int i;
10033                for (i=0; i<N; i++) {
10034                    PackageParser.Provider p = pkg.providers.get(i);
10035                    if (p.info.authority != null) {
10036                        String names[] = p.info.authority.split(";");
10037                        for (int j = 0; j < names.length; j++) {
10038                            if (mProvidersByAuthority.containsKey(names[j])) {
10039                                PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
10040                                final String otherPackageName =
10041                                        ((other != null && other.getComponentName() != null) ?
10042                                                other.getComponentName().getPackageName() : "?");
10043                                throw new PackageManagerException(
10044                                        INSTALL_FAILED_CONFLICTING_PROVIDER,
10045                                        "Can't install because provider name " + names[j]
10046                                                + " (in package " + pkg.applicationInfo.packageName
10047                                                + ") is already used by " + otherPackageName);
10048                            }
10049                        }
10050                    }
10051                }
10052            }
10053        }
10054    }
10055
10056    private boolean addSharedLibraryLPw(String path, String apk, String name, int version,
10057            int type, String declaringPackageName, int declaringVersionCode) {
10058        SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(name);
10059        if (versionedLib == null) {
10060            versionedLib = new SparseArray<>();
10061            mSharedLibraries.put(name, versionedLib);
10062            if (type == SharedLibraryInfo.TYPE_STATIC) {
10063                mStaticLibsByDeclaringPackage.put(declaringPackageName, versionedLib);
10064            }
10065        } else if (versionedLib.indexOfKey(version) >= 0) {
10066            return false;
10067        }
10068        SharedLibraryEntry libEntry = new SharedLibraryEntry(path, apk, name,
10069                version, type, declaringPackageName, declaringVersionCode);
10070        versionedLib.put(version, libEntry);
10071        return true;
10072    }
10073
10074    private boolean removeSharedLibraryLPw(String name, int version) {
10075        SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(name);
10076        if (versionedLib == null) {
10077            return false;
10078        }
10079        final int libIdx = versionedLib.indexOfKey(version);
10080        if (libIdx < 0) {
10081            return false;
10082        }
10083        SharedLibraryEntry libEntry = versionedLib.valueAt(libIdx);
10084        versionedLib.remove(version);
10085        if (versionedLib.size() <= 0) {
10086            mSharedLibraries.remove(name);
10087            if (libEntry.info.getType() == SharedLibraryInfo.TYPE_STATIC) {
10088                mStaticLibsByDeclaringPackage.remove(libEntry.info.getDeclaringPackage()
10089                        .getPackageName());
10090            }
10091        }
10092        return true;
10093    }
10094
10095    /**
10096     * Adds a scanned package to the system. When this method is finished, the package will
10097     * be available for query, resolution, etc...
10098     */
10099    private void commitPackageSettings(PackageParser.Package pkg, PackageSetting pkgSetting,
10100            UserHandle user, int scanFlags, boolean chatty) throws PackageManagerException {
10101        final String pkgName = pkg.packageName;
10102        if (mCustomResolverComponentName != null &&
10103                mCustomResolverComponentName.getPackageName().equals(pkg.packageName)) {
10104            setUpCustomResolverActivity(pkg);
10105        }
10106
10107        if (pkg.packageName.equals("android")) {
10108            synchronized (mPackages) {
10109                if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
10110                    // Set up information for our fall-back user intent resolution activity.
10111                    mPlatformPackage = pkg;
10112                    pkg.mVersionCode = mSdkVersion;
10113                    mAndroidApplication = pkg.applicationInfo;
10114                    if (!mResolverReplaced) {
10115                        mResolveActivity.applicationInfo = mAndroidApplication;
10116                        mResolveActivity.name = ResolverActivity.class.getName();
10117                        mResolveActivity.packageName = mAndroidApplication.packageName;
10118                        mResolveActivity.processName = "system:ui";
10119                        mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
10120                        mResolveActivity.documentLaunchMode = ActivityInfo.DOCUMENT_LAUNCH_NEVER;
10121                        mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS;
10122                        mResolveActivity.theme = R.style.Theme_Material_Dialog_Alert;
10123                        mResolveActivity.exported = true;
10124                        mResolveActivity.enabled = true;
10125                        mResolveActivity.resizeMode = ActivityInfo.RESIZE_MODE_RESIZEABLE;
10126                        mResolveActivity.configChanges = ActivityInfo.CONFIG_SCREEN_SIZE
10127                                | ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE
10128                                | ActivityInfo.CONFIG_SCREEN_LAYOUT
10129                                | ActivityInfo.CONFIG_ORIENTATION
10130                                | ActivityInfo.CONFIG_KEYBOARD
10131                                | ActivityInfo.CONFIG_KEYBOARD_HIDDEN;
10132                        mResolveInfo.activityInfo = mResolveActivity;
10133                        mResolveInfo.priority = 0;
10134                        mResolveInfo.preferredOrder = 0;
10135                        mResolveInfo.match = 0;
10136                        mResolveComponentName = new ComponentName(
10137                                mAndroidApplication.packageName, mResolveActivity.name);
10138                    }
10139                }
10140            }
10141        }
10142
10143        ArrayList<PackageParser.Package> clientLibPkgs = null;
10144        // writer
10145        synchronized (mPackages) {
10146            boolean hasStaticSharedLibs = false;
10147
10148            // Any app can add new static shared libraries
10149            if (pkg.staticSharedLibName != null) {
10150                // Static shared libs don't allow renaming as they have synthetic package
10151                // names to allow install of multiple versions, so use name from manifest.
10152                if (addSharedLibraryLPw(null, pkg.packageName, pkg.staticSharedLibName,
10153                        pkg.staticSharedLibVersion, SharedLibraryInfo.TYPE_STATIC,
10154                        pkg.manifestPackageName, pkg.mVersionCode)) {
10155                    hasStaticSharedLibs = true;
10156                } else {
10157                    Slog.w(TAG, "Package " + pkg.packageName + " library "
10158                                + pkg.staticSharedLibName + " already exists; skipping");
10159                }
10160                // Static shared libs cannot be updated once installed since they
10161                // use synthetic package name which includes the version code, so
10162                // not need to update other packages's shared lib dependencies.
10163            }
10164
10165            if (!hasStaticSharedLibs
10166                    && (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10167                // Only system apps can add new dynamic shared libraries.
10168                if (pkg.libraryNames != null) {
10169                    for (int i = 0; i < pkg.libraryNames.size(); i++) {
10170                        String name = pkg.libraryNames.get(i);
10171                        boolean allowed = false;
10172                        if (pkg.isUpdatedSystemApp()) {
10173                            // New library entries can only be added through the
10174                            // system image.  This is important to get rid of a lot
10175                            // of nasty edge cases: for example if we allowed a non-
10176                            // system update of the app to add a library, then uninstalling
10177                            // the update would make the library go away, and assumptions
10178                            // we made such as through app install filtering would now
10179                            // have allowed apps on the device which aren't compatible
10180                            // with it.  Better to just have the restriction here, be
10181                            // conservative, and create many fewer cases that can negatively
10182                            // impact the user experience.
10183                            final PackageSetting sysPs = mSettings
10184                                    .getDisabledSystemPkgLPr(pkg.packageName);
10185                            if (sysPs.pkg != null && sysPs.pkg.libraryNames != null) {
10186                                for (int j = 0; j < sysPs.pkg.libraryNames.size(); j++) {
10187                                    if (name.equals(sysPs.pkg.libraryNames.get(j))) {
10188                                        allowed = true;
10189                                        break;
10190                                    }
10191                                }
10192                            }
10193                        } else {
10194                            allowed = true;
10195                        }
10196                        if (allowed) {
10197                            if (!addSharedLibraryLPw(null, pkg.packageName, name,
10198                                    SharedLibraryInfo.VERSION_UNDEFINED,
10199                                    SharedLibraryInfo.TYPE_DYNAMIC,
10200                                    pkg.packageName, pkg.mVersionCode)) {
10201                                Slog.w(TAG, "Package " + pkg.packageName + " library "
10202                                        + name + " already exists; skipping");
10203                            }
10204                        } else {
10205                            Slog.w(TAG, "Package " + pkg.packageName + " declares lib "
10206                                    + name + " that is not declared on system image; skipping");
10207                        }
10208                    }
10209
10210                    if ((scanFlags & SCAN_BOOTING) == 0) {
10211                        // If we are not booting, we need to update any applications
10212                        // that are clients of our shared library.  If we are booting,
10213                        // this will all be done once the scan is complete.
10214                        clientLibPkgs = updateAllSharedLibrariesLPw(pkg);
10215                    }
10216                }
10217            }
10218        }
10219
10220        if ((scanFlags & SCAN_BOOTING) != 0) {
10221            // No apps can run during boot scan, so they don't need to be frozen
10222        } else if ((scanFlags & SCAN_DONT_KILL_APP) != 0) {
10223            // Caller asked to not kill app, so it's probably not frozen
10224        } else if ((scanFlags & SCAN_IGNORE_FROZEN) != 0) {
10225            // Caller asked us to ignore frozen check for some reason; they
10226            // probably didn't know the package name
10227        } else {
10228            // We're doing major surgery on this package, so it better be frozen
10229            // right now to keep it from launching
10230            checkPackageFrozen(pkgName);
10231        }
10232
10233        // Also need to kill any apps that are dependent on the library.
10234        if (clientLibPkgs != null) {
10235            for (int i=0; i<clientLibPkgs.size(); i++) {
10236                PackageParser.Package clientPkg = clientLibPkgs.get(i);
10237                killApplication(clientPkg.applicationInfo.packageName,
10238                        clientPkg.applicationInfo.uid, "update lib");
10239            }
10240        }
10241
10242        // writer
10243        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");
10244
10245        synchronized (mPackages) {
10246            // We don't expect installation to fail beyond this point
10247
10248            // Add the new setting to mSettings
10249            mSettings.insertPackageSettingLPw(pkgSetting, pkg);
10250            // Add the new setting to mPackages
10251            mPackages.put(pkg.applicationInfo.packageName, pkg);
10252            // Make sure we don't accidentally delete its data.
10253            final Iterator<PackageCleanItem> iter = mSettings.mPackagesToBeCleaned.iterator();
10254            while (iter.hasNext()) {
10255                PackageCleanItem item = iter.next();
10256                if (pkgName.equals(item.packageName)) {
10257                    iter.remove();
10258                }
10259            }
10260
10261            // Add the package's KeySets to the global KeySetManagerService
10262            KeySetManagerService ksms = mSettings.mKeySetManagerService;
10263            ksms.addScannedPackageLPw(pkg);
10264
10265            int N = pkg.providers.size();
10266            StringBuilder r = null;
10267            int i;
10268            for (i=0; i<N; i++) {
10269                PackageParser.Provider p = pkg.providers.get(i);
10270                p.info.processName = fixProcessName(pkg.applicationInfo.processName,
10271                        p.info.processName);
10272                mProviders.addProvider(p);
10273                p.syncable = p.info.isSyncable;
10274                if (p.info.authority != null) {
10275                    String names[] = p.info.authority.split(";");
10276                    p.info.authority = null;
10277                    for (int j = 0; j < names.length; j++) {
10278                        if (j == 1 && p.syncable) {
10279                            // We only want the first authority for a provider to possibly be
10280                            // syncable, so if we already added this provider using a different
10281                            // authority clear the syncable flag. We copy the provider before
10282                            // changing it because the mProviders object contains a reference
10283                            // to a provider that we don't want to change.
10284                            // Only do this for the second authority since the resulting provider
10285                            // object can be the same for all future authorities for this provider.
10286                            p = new PackageParser.Provider(p);
10287                            p.syncable = false;
10288                        }
10289                        if (!mProvidersByAuthority.containsKey(names[j])) {
10290                            mProvidersByAuthority.put(names[j], p);
10291                            if (p.info.authority == null) {
10292                                p.info.authority = names[j];
10293                            } else {
10294                                p.info.authority = p.info.authority + ";" + names[j];
10295                            }
10296                            if (DEBUG_PACKAGE_SCANNING) {
10297                                if (chatty)
10298                                    Log.d(TAG, "Registered content provider: " + names[j]
10299                                            + ", className = " + p.info.name + ", isSyncable = "
10300                                            + p.info.isSyncable);
10301                            }
10302                        } else {
10303                            PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
10304                            Slog.w(TAG, "Skipping provider name " + names[j] +
10305                                    " (in package " + pkg.applicationInfo.packageName +
10306                                    "): name already used by "
10307                                    + ((other != null && other.getComponentName() != null)
10308                                            ? other.getComponentName().getPackageName() : "?"));
10309                        }
10310                    }
10311                }
10312                if (chatty) {
10313                    if (r == null) {
10314                        r = new StringBuilder(256);
10315                    } else {
10316                        r.append(' ');
10317                    }
10318                    r.append(p.info.name);
10319                }
10320            }
10321            if (r != null) {
10322                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Providers: " + r);
10323            }
10324
10325            N = pkg.services.size();
10326            r = null;
10327            for (i=0; i<N; i++) {
10328                PackageParser.Service s = pkg.services.get(i);
10329                s.info.processName = fixProcessName(pkg.applicationInfo.processName,
10330                        s.info.processName);
10331                mServices.addService(s);
10332                if (chatty) {
10333                    if (r == null) {
10334                        r = new StringBuilder(256);
10335                    } else {
10336                        r.append(' ');
10337                    }
10338                    r.append(s.info.name);
10339                }
10340            }
10341            if (r != null) {
10342                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Services: " + r);
10343            }
10344
10345            N = pkg.receivers.size();
10346            r = null;
10347            for (i=0; i<N; i++) {
10348                PackageParser.Activity a = pkg.receivers.get(i);
10349                a.info.processName = fixProcessName(pkg.applicationInfo.processName,
10350                        a.info.processName);
10351                mReceivers.addActivity(a, "receiver");
10352                if (chatty) {
10353                    if (r == null) {
10354                        r = new StringBuilder(256);
10355                    } else {
10356                        r.append(' ');
10357                    }
10358                    r.append(a.info.name);
10359                }
10360            }
10361            if (r != null) {
10362                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Receivers: " + r);
10363            }
10364
10365            N = pkg.activities.size();
10366            r = null;
10367            for (i=0; i<N; i++) {
10368                PackageParser.Activity a = pkg.activities.get(i);
10369                a.info.processName = fixProcessName(pkg.applicationInfo.processName,
10370                        a.info.processName);
10371                mActivities.addActivity(a, "activity");
10372                if (chatty) {
10373                    if (r == null) {
10374                        r = new StringBuilder(256);
10375                    } else {
10376                        r.append(' ');
10377                    }
10378                    r.append(a.info.name);
10379                }
10380            }
10381            if (r != null) {
10382                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Activities: " + r);
10383            }
10384
10385            N = pkg.permissionGroups.size();
10386            r = null;
10387            for (i=0; i<N; i++) {
10388                PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i);
10389                PackageParser.PermissionGroup cur = mPermissionGroups.get(pg.info.name);
10390                final String curPackageName = cur == null ? null : cur.info.packageName;
10391                // Dont allow ephemeral apps to define new permission groups.
10392                if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
10393                    Slog.w(TAG, "Permission group " + pg.info.name + " from package "
10394                            + pg.info.packageName
10395                            + " ignored: instant apps cannot define new permission groups.");
10396                    continue;
10397                }
10398                final boolean isPackageUpdate = pg.info.packageName.equals(curPackageName);
10399                if (cur == null || isPackageUpdate) {
10400                    mPermissionGroups.put(pg.info.name, pg);
10401                    if (chatty) {
10402                        if (r == null) {
10403                            r = new StringBuilder(256);
10404                        } else {
10405                            r.append(' ');
10406                        }
10407                        if (isPackageUpdate) {
10408                            r.append("UPD:");
10409                        }
10410                        r.append(pg.info.name);
10411                    }
10412                } else {
10413                    Slog.w(TAG, "Permission group " + pg.info.name + " from package "
10414                            + pg.info.packageName + " ignored: original from "
10415                            + cur.info.packageName);
10416                    if (chatty) {
10417                        if (r == null) {
10418                            r = new StringBuilder(256);
10419                        } else {
10420                            r.append(' ');
10421                        }
10422                        r.append("DUP:");
10423                        r.append(pg.info.name);
10424                    }
10425                }
10426            }
10427            if (r != null) {
10428                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Permission Groups: " + r);
10429            }
10430
10431            N = pkg.permissions.size();
10432            r = null;
10433            for (i=0; i<N; i++) {
10434                PackageParser.Permission p = pkg.permissions.get(i);
10435
10436                // Dont allow ephemeral apps to define new permissions.
10437                if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
10438                    Slog.w(TAG, "Permission " + p.info.name + " from package "
10439                            + p.info.packageName
10440                            + " ignored: instant apps cannot define new permissions.");
10441                    continue;
10442                }
10443
10444                // Assume by default that we did not install this permission into the system.
10445                p.info.flags &= ~PermissionInfo.FLAG_INSTALLED;
10446
10447                // Now that permission groups have a special meaning, we ignore permission
10448                // groups for legacy apps to prevent unexpected behavior. In particular,
10449                // permissions for one app being granted to someone just becase they happen
10450                // to be in a group defined by another app (before this had no implications).
10451                if (pkg.applicationInfo.targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1) {
10452                    p.group = mPermissionGroups.get(p.info.group);
10453                    // Warn for a permission in an unknown group.
10454                    if (p.info.group != null && p.group == null) {
10455                        Slog.w(TAG, "Permission " + p.info.name + " from package "
10456                                + p.info.packageName + " in an unknown group " + p.info.group);
10457                    }
10458                }
10459
10460                ArrayMap<String, BasePermission> permissionMap =
10461                        p.tree ? mSettings.mPermissionTrees
10462                                : mSettings.mPermissions;
10463                BasePermission bp = permissionMap.get(p.info.name);
10464
10465                // Allow system apps to redefine non-system permissions
10466                if (bp != null && !Objects.equals(bp.sourcePackage, p.info.packageName)) {
10467                    final boolean currentOwnerIsSystem = (bp.perm != null
10468                            && isSystemApp(bp.perm.owner));
10469                    if (isSystemApp(p.owner)) {
10470                        if (bp.type == BasePermission.TYPE_BUILTIN && bp.perm == null) {
10471                            // It's a built-in permission and no owner, take ownership now
10472                            bp.packageSetting = pkgSetting;
10473                            bp.perm = p;
10474                            bp.uid = pkg.applicationInfo.uid;
10475                            bp.sourcePackage = p.info.packageName;
10476                            p.info.flags |= PermissionInfo.FLAG_INSTALLED;
10477                        } else if (!currentOwnerIsSystem) {
10478                            String msg = "New decl " + p.owner + " of permission  "
10479                                    + p.info.name + " is system; overriding " + bp.sourcePackage;
10480                            reportSettingsProblem(Log.WARN, msg);
10481                            bp = null;
10482                        }
10483                    }
10484                }
10485
10486                if (bp == null) {
10487                    bp = new BasePermission(p.info.name, p.info.packageName,
10488                            BasePermission.TYPE_NORMAL);
10489                    permissionMap.put(p.info.name, bp);
10490                }
10491
10492                if (bp.perm == null) {
10493                    if (bp.sourcePackage == null
10494                            || bp.sourcePackage.equals(p.info.packageName)) {
10495                        BasePermission tree = findPermissionTreeLP(p.info.name);
10496                        if (tree == null
10497                                || tree.sourcePackage.equals(p.info.packageName)) {
10498                            bp.packageSetting = pkgSetting;
10499                            bp.perm = p;
10500                            bp.uid = pkg.applicationInfo.uid;
10501                            bp.sourcePackage = p.info.packageName;
10502                            p.info.flags |= PermissionInfo.FLAG_INSTALLED;
10503                            if (chatty) {
10504                                if (r == null) {
10505                                    r = new StringBuilder(256);
10506                                } else {
10507                                    r.append(' ');
10508                                }
10509                                r.append(p.info.name);
10510                            }
10511                        } else {
10512                            Slog.w(TAG, "Permission " + p.info.name + " from package "
10513                                    + p.info.packageName + " ignored: base tree "
10514                                    + tree.name + " is from package "
10515                                    + tree.sourcePackage);
10516                        }
10517                    } else {
10518                        Slog.w(TAG, "Permission " + p.info.name + " from package "
10519                                + p.info.packageName + " ignored: original from "
10520                                + bp.sourcePackage);
10521                    }
10522                } else if (chatty) {
10523                    if (r == null) {
10524                        r = new StringBuilder(256);
10525                    } else {
10526                        r.append(' ');
10527                    }
10528                    r.append("DUP:");
10529                    r.append(p.info.name);
10530                }
10531                if (bp.perm == p) {
10532                    bp.protectionLevel = p.info.protectionLevel;
10533                }
10534            }
10535
10536            if (r != null) {
10537                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Permissions: " + r);
10538            }
10539
10540            N = pkg.instrumentation.size();
10541            r = null;
10542            for (i=0; i<N; i++) {
10543                PackageParser.Instrumentation a = pkg.instrumentation.get(i);
10544                a.info.packageName = pkg.applicationInfo.packageName;
10545                a.info.sourceDir = pkg.applicationInfo.sourceDir;
10546                a.info.publicSourceDir = pkg.applicationInfo.publicSourceDir;
10547                a.info.splitNames = pkg.splitNames;
10548                a.info.splitSourceDirs = pkg.applicationInfo.splitSourceDirs;
10549                a.info.splitPublicSourceDirs = pkg.applicationInfo.splitPublicSourceDirs;
10550                a.info.splitDependencies = pkg.applicationInfo.splitDependencies;
10551                a.info.dataDir = pkg.applicationInfo.dataDir;
10552                a.info.deviceProtectedDataDir = pkg.applicationInfo.deviceProtectedDataDir;
10553                a.info.credentialProtectedDataDir = pkg.applicationInfo.credentialProtectedDataDir;
10554                a.info.nativeLibraryDir = pkg.applicationInfo.nativeLibraryDir;
10555                a.info.secondaryNativeLibraryDir = pkg.applicationInfo.secondaryNativeLibraryDir;
10556                mInstrumentation.put(a.getComponentName(), a);
10557                if (chatty) {
10558                    if (r == null) {
10559                        r = new StringBuilder(256);
10560                    } else {
10561                        r.append(' ');
10562                    }
10563                    r.append(a.info.name);
10564                }
10565            }
10566            if (r != null) {
10567                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Instrumentation: " + r);
10568            }
10569
10570            if (pkg.protectedBroadcasts != null) {
10571                N = pkg.protectedBroadcasts.size();
10572                for (i=0; i<N; i++) {
10573                    mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i));
10574                }
10575            }
10576        }
10577
10578        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
10579    }
10580
10581    /**
10582     * Derive the ABI of a non-system package located at {@code scanFile}. This information
10583     * is derived purely on the basis of the contents of {@code scanFile} and
10584     * {@code cpuAbiOverride}.
10585     *
10586     * If {@code extractLibs} is true, native libraries are extracted from the app if required.
10587     */
10588    private static void derivePackageAbi(PackageParser.Package pkg, File scanFile,
10589                                 String cpuAbiOverride, boolean extractLibs,
10590                                 File appLib32InstallDir)
10591            throws PackageManagerException {
10592        // Give ourselves some initial paths; we'll come back for another
10593        // pass once we've determined ABI below.
10594        setNativeLibraryPaths(pkg, appLib32InstallDir);
10595
10596        // We would never need to extract libs for forward-locked and external packages,
10597        // since the container service will do it for us. We shouldn't attempt to
10598        // extract libs from system app when it was not updated.
10599        if (pkg.isForwardLocked() || pkg.applicationInfo.isExternalAsec() ||
10600                (isSystemApp(pkg) && !pkg.isUpdatedSystemApp())) {
10601            extractLibs = false;
10602        }
10603
10604        final String nativeLibraryRootStr = pkg.applicationInfo.nativeLibraryRootDir;
10605        final boolean useIsaSpecificSubdirs = pkg.applicationInfo.nativeLibraryRootRequiresIsa;
10606
10607        NativeLibraryHelper.Handle handle = null;
10608        try {
10609            handle = NativeLibraryHelper.Handle.create(pkg);
10610            // TODO(multiArch): This can be null for apps that didn't go through the
10611            // usual installation process. We can calculate it again, like we
10612            // do during install time.
10613            //
10614            // TODO(multiArch): Why do we need to rescan ASEC apps again ? It seems totally
10615            // unnecessary.
10616            final File nativeLibraryRoot = new File(nativeLibraryRootStr);
10617
10618            // Null out the abis so that they can be recalculated.
10619            pkg.applicationInfo.primaryCpuAbi = null;
10620            pkg.applicationInfo.secondaryCpuAbi = null;
10621            if (isMultiArch(pkg.applicationInfo)) {
10622                // Warn if we've set an abiOverride for multi-lib packages..
10623                // By definition, we need to copy both 32 and 64 bit libraries for
10624                // such packages.
10625                if (pkg.cpuAbiOverride != null
10626                        && !NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(pkg.cpuAbiOverride)) {
10627                    Slog.w(TAG, "Ignoring abiOverride for multi arch application.");
10628                }
10629
10630                int abi32 = PackageManager.NO_NATIVE_LIBRARIES;
10631                int abi64 = PackageManager.NO_NATIVE_LIBRARIES;
10632                if (Build.SUPPORTED_32_BIT_ABIS.length > 0) {
10633                    if (extractLibs) {
10634                        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
10635                        abi32 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
10636                                nativeLibraryRoot, Build.SUPPORTED_32_BIT_ABIS,
10637                                useIsaSpecificSubdirs);
10638                    } else {
10639                        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
10640                        abi32 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_32_BIT_ABIS);
10641                    }
10642                    Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
10643                }
10644
10645                maybeThrowExceptionForMultiArchCopy(
10646                        "Error unpackaging 32 bit native libs for multiarch app.", abi32);
10647
10648                if (Build.SUPPORTED_64_BIT_ABIS.length > 0) {
10649                    if (extractLibs) {
10650                        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
10651                        abi64 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
10652                                nativeLibraryRoot, Build.SUPPORTED_64_BIT_ABIS,
10653                                useIsaSpecificSubdirs);
10654                    } else {
10655                        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
10656                        abi64 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_64_BIT_ABIS);
10657                    }
10658                    Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
10659                }
10660
10661                maybeThrowExceptionForMultiArchCopy(
10662                        "Error unpackaging 64 bit native libs for multiarch app.", abi64);
10663
10664                if (abi64 >= 0) {
10665                    pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[abi64];
10666                }
10667
10668                if (abi32 >= 0) {
10669                    final String abi = Build.SUPPORTED_32_BIT_ABIS[abi32];
10670                    if (abi64 >= 0) {
10671                        if (pkg.use32bitAbi) {
10672                            pkg.applicationInfo.secondaryCpuAbi = pkg.applicationInfo.primaryCpuAbi;
10673                            pkg.applicationInfo.primaryCpuAbi = abi;
10674                        } else {
10675                            pkg.applicationInfo.secondaryCpuAbi = abi;
10676                        }
10677                    } else {
10678                        pkg.applicationInfo.primaryCpuAbi = abi;
10679                    }
10680                }
10681
10682            } else {
10683                String[] abiList = (cpuAbiOverride != null) ?
10684                        new String[] { cpuAbiOverride } : Build.SUPPORTED_ABIS;
10685
10686                // Enable gross and lame hacks for apps that are built with old
10687                // SDK tools. We must scan their APKs for renderscript bitcode and
10688                // not launch them if it's present. Don't bother checking on devices
10689                // that don't have 64 bit support.
10690                boolean needsRenderScriptOverride = false;
10691                if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && cpuAbiOverride == null &&
10692                        NativeLibraryHelper.hasRenderscriptBitcode(handle)) {
10693                    abiList = Build.SUPPORTED_32_BIT_ABIS;
10694                    needsRenderScriptOverride = true;
10695                }
10696
10697                final int copyRet;
10698                if (extractLibs) {
10699                    Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
10700                    copyRet = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
10701                            nativeLibraryRoot, abiList, useIsaSpecificSubdirs);
10702                } else {
10703                    Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
10704                    copyRet = NativeLibraryHelper.findSupportedAbi(handle, abiList);
10705                }
10706                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
10707
10708                if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) {
10709                    throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
10710                            "Error unpackaging native libs for app, errorCode=" + copyRet);
10711                }
10712
10713                if (copyRet >= 0) {
10714                    pkg.applicationInfo.primaryCpuAbi = abiList[copyRet];
10715                } else if (copyRet == PackageManager.NO_NATIVE_LIBRARIES && cpuAbiOverride != null) {
10716                    pkg.applicationInfo.primaryCpuAbi = cpuAbiOverride;
10717                } else if (needsRenderScriptOverride) {
10718                    pkg.applicationInfo.primaryCpuAbi = abiList[0];
10719                }
10720            }
10721        } catch (IOException ioe) {
10722            Slog.e(TAG, "Unable to get canonical file " + ioe.toString());
10723        } finally {
10724            IoUtils.closeQuietly(handle);
10725        }
10726
10727        // Now that we've calculated the ABIs and determined if it's an internal app,
10728        // we will go ahead and populate the nativeLibraryPath.
10729        setNativeLibraryPaths(pkg, appLib32InstallDir);
10730    }
10731
10732    /**
10733     * Adjusts ABIs for a set of packages belonging to a shared user so that they all match.
10734     * i.e, so that all packages can be run inside a single process if required.
10735     *
10736     * Optionally, callers can pass in a parsed package via {@code newPackage} in which case
10737     * this function will either try and make the ABI for all packages in {@code packagesForUser}
10738     * match {@code scannedPackage} or will update the ABI of {@code scannedPackage} to match
10739     * the ABI selected for {@code packagesForUser}. This variant is used when installing or
10740     * updating a package that belongs to a shared user.
10741     *
10742     * NOTE: We currently only match for the primary CPU abi string. Matching the secondary
10743     * adds unnecessary complexity.
10744     */
10745    private void adjustCpuAbisForSharedUserLPw(Set<PackageSetting> packagesForUser,
10746            PackageParser.Package scannedPackage) {
10747        String requiredInstructionSet = null;
10748        if (scannedPackage != null && scannedPackage.applicationInfo.primaryCpuAbi != null) {
10749            requiredInstructionSet = VMRuntime.getInstructionSet(
10750                     scannedPackage.applicationInfo.primaryCpuAbi);
10751        }
10752
10753        PackageSetting requirer = null;
10754        for (PackageSetting ps : packagesForUser) {
10755            // If packagesForUser contains scannedPackage, we skip it. This will happen
10756            // when scannedPackage is an update of an existing package. Without this check,
10757            // we will never be able to change the ABI of any package belonging to a shared
10758            // user, even if it's compatible with other packages.
10759            if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
10760                if (ps.primaryCpuAbiString == null) {
10761                    continue;
10762                }
10763
10764                final String instructionSet = VMRuntime.getInstructionSet(ps.primaryCpuAbiString);
10765                if (requiredInstructionSet != null && !instructionSet.equals(requiredInstructionSet)) {
10766                    // We have a mismatch between instruction sets (say arm vs arm64) warn about
10767                    // this but there's not much we can do.
10768                    String errorMessage = "Instruction set mismatch, "
10769                            + ((requirer == null) ? "[caller]" : requirer)
10770                            + " requires " + requiredInstructionSet + " whereas " + ps
10771                            + " requires " + instructionSet;
10772                    Slog.w(TAG, errorMessage);
10773                }
10774
10775                if (requiredInstructionSet == null) {
10776                    requiredInstructionSet = instructionSet;
10777                    requirer = ps;
10778                }
10779            }
10780        }
10781
10782        if (requiredInstructionSet != null) {
10783            String adjustedAbi;
10784            if (requirer != null) {
10785                // requirer != null implies that either scannedPackage was null or that scannedPackage
10786                // did not require an ABI, in which case we have to adjust scannedPackage to match
10787                // the ABI of the set (which is the same as requirer's ABI)
10788                adjustedAbi = requirer.primaryCpuAbiString;
10789                if (scannedPackage != null) {
10790                    scannedPackage.applicationInfo.primaryCpuAbi = adjustedAbi;
10791                }
10792            } else {
10793                // requirer == null implies that we're updating all ABIs in the set to
10794                // match scannedPackage.
10795                adjustedAbi =  scannedPackage.applicationInfo.primaryCpuAbi;
10796            }
10797
10798            for (PackageSetting ps : packagesForUser) {
10799                if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
10800                    if (ps.primaryCpuAbiString != null) {
10801                        continue;
10802                    }
10803
10804                    ps.primaryCpuAbiString = adjustedAbi;
10805                    if (ps.pkg != null && ps.pkg.applicationInfo != null &&
10806                            !TextUtils.equals(adjustedAbi, ps.pkg.applicationInfo.primaryCpuAbi)) {
10807                        ps.pkg.applicationInfo.primaryCpuAbi = adjustedAbi;
10808                        Slog.i(TAG, "Adjusting ABI for " + ps.name + " to " + adjustedAbi
10809                                + " (requirer="
10810                                + (requirer != null ? requirer.pkg : "null")
10811                                + ", scannedPackage="
10812                                + (scannedPackage != null ? scannedPackage : "null")
10813                                + ")");
10814                        try {
10815                            mInstaller.rmdex(ps.codePathString,
10816                                    getDexCodeInstructionSet(getPreferredInstructionSet()));
10817                        } catch (InstallerException ignored) {
10818                        }
10819                    }
10820                }
10821            }
10822        }
10823    }
10824
10825    private void setUpCustomResolverActivity(PackageParser.Package pkg) {
10826        synchronized (mPackages) {
10827            mResolverReplaced = true;
10828            // Set up information for custom user intent resolution activity.
10829            mResolveActivity.applicationInfo = pkg.applicationInfo;
10830            mResolveActivity.name = mCustomResolverComponentName.getClassName();
10831            mResolveActivity.packageName = pkg.applicationInfo.packageName;
10832            mResolveActivity.processName = pkg.applicationInfo.packageName;
10833            mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
10834            mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS |
10835                    ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
10836            mResolveActivity.theme = 0;
10837            mResolveActivity.exported = true;
10838            mResolveActivity.enabled = true;
10839            mResolveInfo.activityInfo = mResolveActivity;
10840            mResolveInfo.priority = 0;
10841            mResolveInfo.preferredOrder = 0;
10842            mResolveInfo.match = 0;
10843            mResolveComponentName = mCustomResolverComponentName;
10844            Slog.i(TAG, "Replacing default ResolverActivity with custom activity: " +
10845                    mResolveComponentName);
10846        }
10847    }
10848
10849    private void setUpInstantAppInstallerActivityLP(ActivityInfo installerActivity) {
10850        if (installerActivity == null) {
10851            if (DEBUG_EPHEMERAL) {
10852                Slog.d(TAG, "Clear ephemeral installer activity");
10853            }
10854            mInstantAppInstallerActivity = null;
10855            return;
10856        }
10857
10858        if (DEBUG_EPHEMERAL) {
10859            Slog.d(TAG, "Set ephemeral installer activity: "
10860                    + installerActivity.getComponentName());
10861        }
10862        // Set up information for ephemeral installer activity
10863        mInstantAppInstallerActivity = installerActivity;
10864        mInstantAppInstallerActivity.flags |= ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS
10865                | ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
10866        mInstantAppInstallerActivity.exported = true;
10867        mInstantAppInstallerActivity.enabled = true;
10868        mInstantAppInstallerInfo.activityInfo = mInstantAppInstallerActivity;
10869        mInstantAppInstallerInfo.priority = 0;
10870        mInstantAppInstallerInfo.preferredOrder = 1;
10871        mInstantAppInstallerInfo.isDefault = true;
10872        mInstantAppInstallerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
10873                | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
10874    }
10875
10876    private static String calculateBundledApkRoot(final String codePathString) {
10877        final File codePath = new File(codePathString);
10878        final File codeRoot;
10879        if (FileUtils.contains(Environment.getRootDirectory(), codePath)) {
10880            codeRoot = Environment.getRootDirectory();
10881        } else if (FileUtils.contains(Environment.getOemDirectory(), codePath)) {
10882            codeRoot = Environment.getOemDirectory();
10883        } else if (FileUtils.contains(Environment.getVendorDirectory(), codePath)) {
10884            codeRoot = Environment.getVendorDirectory();
10885        } else {
10886            // Unrecognized code path; take its top real segment as the apk root:
10887            // e.g. /something/app/blah.apk => /something
10888            try {
10889                File f = codePath.getCanonicalFile();
10890                File parent = f.getParentFile();    // non-null because codePath is a file
10891                File tmp;
10892                while ((tmp = parent.getParentFile()) != null) {
10893                    f = parent;
10894                    parent = tmp;
10895                }
10896                codeRoot = f;
10897                Slog.w(TAG, "Unrecognized code path "
10898                        + codePath + " - using " + codeRoot);
10899            } catch (IOException e) {
10900                // Can't canonicalize the code path -- shenanigans?
10901                Slog.w(TAG, "Can't canonicalize code path " + codePath);
10902                return Environment.getRootDirectory().getPath();
10903            }
10904        }
10905        return codeRoot.getPath();
10906    }
10907
10908    /**
10909     * Derive and set the location of native libraries for the given package,
10910     * which varies depending on where and how the package was installed.
10911     */
10912    private static void setNativeLibraryPaths(PackageParser.Package pkg, File appLib32InstallDir) {
10913        final ApplicationInfo info = pkg.applicationInfo;
10914        final String codePath = pkg.codePath;
10915        final File codeFile = new File(codePath);
10916        final boolean bundledApp = info.isSystemApp() && !info.isUpdatedSystemApp();
10917        final boolean asecApp = info.isForwardLocked() || info.isExternalAsec();
10918
10919        info.nativeLibraryRootDir = null;
10920        info.nativeLibraryRootRequiresIsa = false;
10921        info.nativeLibraryDir = null;
10922        info.secondaryNativeLibraryDir = null;
10923
10924        if (isApkFile(codeFile)) {
10925            // Monolithic install
10926            if (bundledApp) {
10927                // If "/system/lib64/apkname" exists, assume that is the per-package
10928                // native library directory to use; otherwise use "/system/lib/apkname".
10929                final String apkRoot = calculateBundledApkRoot(info.sourceDir);
10930                final boolean is64Bit = VMRuntime.is64BitInstructionSet(
10931                        getPrimaryInstructionSet(info));
10932
10933                // This is a bundled system app so choose the path based on the ABI.
10934                // if it's a 64 bit abi, use lib64 otherwise use lib32. Note that this
10935                // is just the default path.
10936                final String apkName = deriveCodePathName(codePath);
10937                final String libDir = is64Bit ? LIB64_DIR_NAME : LIB_DIR_NAME;
10938                info.nativeLibraryRootDir = Environment.buildPath(new File(apkRoot), libDir,
10939                        apkName).getAbsolutePath();
10940
10941                if (info.secondaryCpuAbi != null) {
10942                    final String secondaryLibDir = is64Bit ? LIB_DIR_NAME : LIB64_DIR_NAME;
10943                    info.secondaryNativeLibraryDir = Environment.buildPath(new File(apkRoot),
10944                            secondaryLibDir, apkName).getAbsolutePath();
10945                }
10946            } else if (asecApp) {
10947                info.nativeLibraryRootDir = new File(codeFile.getParentFile(), LIB_DIR_NAME)
10948                        .getAbsolutePath();
10949            } else {
10950                final String apkName = deriveCodePathName(codePath);
10951                info.nativeLibraryRootDir = new File(appLib32InstallDir, apkName)
10952                        .getAbsolutePath();
10953            }
10954
10955            info.nativeLibraryRootRequiresIsa = false;
10956            info.nativeLibraryDir = info.nativeLibraryRootDir;
10957        } else {
10958            // Cluster install
10959            info.nativeLibraryRootDir = new File(codeFile, LIB_DIR_NAME).getAbsolutePath();
10960            info.nativeLibraryRootRequiresIsa = true;
10961
10962            info.nativeLibraryDir = new File(info.nativeLibraryRootDir,
10963                    getPrimaryInstructionSet(info)).getAbsolutePath();
10964
10965            if (info.secondaryCpuAbi != null) {
10966                info.secondaryNativeLibraryDir = new File(info.nativeLibraryRootDir,
10967                        VMRuntime.getInstructionSet(info.secondaryCpuAbi)).getAbsolutePath();
10968            }
10969        }
10970    }
10971
10972    /**
10973     * Calculate the abis and roots for a bundled app. These can uniquely
10974     * be determined from the contents of the system partition, i.e whether
10975     * it contains 64 or 32 bit shared libraries etc. We do not validate any
10976     * of this information, and instead assume that the system was built
10977     * sensibly.
10978     */
10979    private static void setBundledAppAbisAndRoots(PackageParser.Package pkg,
10980                                           PackageSetting pkgSetting) {
10981        final String apkName = deriveCodePathName(pkg.applicationInfo.getCodePath());
10982
10983        // If "/system/lib64/apkname" exists, assume that is the per-package
10984        // native library directory to use; otherwise use "/system/lib/apkname".
10985        final String apkRoot = calculateBundledApkRoot(pkg.applicationInfo.sourceDir);
10986        setBundledAppAbi(pkg, apkRoot, apkName);
10987        // pkgSetting might be null during rescan following uninstall of updates
10988        // to a bundled app, so accommodate that possibility.  The settings in
10989        // that case will be established later from the parsed package.
10990        //
10991        // If the settings aren't null, sync them up with what we've just derived.
10992        // note that apkRoot isn't stored in the package settings.
10993        if (pkgSetting != null) {
10994            pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
10995            pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
10996        }
10997    }
10998
10999    /**
11000     * Deduces the ABI of a bundled app and sets the relevant fields on the
11001     * parsed pkg object.
11002     *
11003     * @param apkRoot the root of the installed apk, something like {@code /system} or {@code /oem}
11004     *        under which system libraries are installed.
11005     * @param apkName the name of the installed package.
11006     */
11007    private static void setBundledAppAbi(PackageParser.Package pkg, String apkRoot, String apkName) {
11008        final File codeFile = new File(pkg.codePath);
11009
11010        final boolean has64BitLibs;
11011        final boolean has32BitLibs;
11012        if (isApkFile(codeFile)) {
11013            // Monolithic install
11014            has64BitLibs = (new File(apkRoot, new File(LIB64_DIR_NAME, apkName).getPath())).exists();
11015            has32BitLibs = (new File(apkRoot, new File(LIB_DIR_NAME, apkName).getPath())).exists();
11016        } else {
11017            // Cluster install
11018            final File rootDir = new File(codeFile, LIB_DIR_NAME);
11019            if (!ArrayUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS)
11020                    && !TextUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS[0])) {
11021                final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_64_BIT_ABIS[0]);
11022                has64BitLibs = (new File(rootDir, isa)).exists();
11023            } else {
11024                has64BitLibs = false;
11025            }
11026            if (!ArrayUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS)
11027                    && !TextUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS[0])) {
11028                final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_32_BIT_ABIS[0]);
11029                has32BitLibs = (new File(rootDir, isa)).exists();
11030            } else {
11031                has32BitLibs = false;
11032            }
11033        }
11034
11035        if (has64BitLibs && !has32BitLibs) {
11036            // The package has 64 bit libs, but not 32 bit libs. Its primary
11037            // ABI should be 64 bit. We can safely assume here that the bundled
11038            // native libraries correspond to the most preferred ABI in the list.
11039
11040            pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
11041            pkg.applicationInfo.secondaryCpuAbi = null;
11042        } else if (has32BitLibs && !has64BitLibs) {
11043            // The package has 32 bit libs but not 64 bit libs. Its primary
11044            // ABI should be 32 bit.
11045
11046            pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
11047            pkg.applicationInfo.secondaryCpuAbi = null;
11048        } else if (has32BitLibs && has64BitLibs) {
11049            // The application has both 64 and 32 bit bundled libraries. We check
11050            // here that the app declares multiArch support, and warn if it doesn't.
11051            //
11052            // We will be lenient here and record both ABIs. The primary will be the
11053            // ABI that's higher on the list, i.e, a device that's configured to prefer
11054            // 64 bit apps will see a 64 bit primary ABI,
11055
11056            if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) == 0) {
11057                Slog.e(TAG, "Package " + pkg + " has multiple bundled libs, but is not multiarch.");
11058            }
11059
11060            if (VMRuntime.is64BitInstructionSet(getPreferredInstructionSet())) {
11061                pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
11062                pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
11063            } else {
11064                pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
11065                pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
11066            }
11067        } else {
11068            pkg.applicationInfo.primaryCpuAbi = null;
11069            pkg.applicationInfo.secondaryCpuAbi = null;
11070        }
11071    }
11072
11073    private void killApplication(String pkgName, int appId, String reason) {
11074        killApplication(pkgName, appId, UserHandle.USER_ALL, reason);
11075    }
11076
11077    private void killApplication(String pkgName, int appId, int userId, String reason) {
11078        // Request the ActivityManager to kill the process(only for existing packages)
11079        // so that we do not end up in a confused state while the user is still using the older
11080        // version of the application while the new one gets installed.
11081        final long token = Binder.clearCallingIdentity();
11082        try {
11083            IActivityManager am = ActivityManager.getService();
11084            if (am != null) {
11085                try {
11086                    am.killApplication(pkgName, appId, userId, reason);
11087                } catch (RemoteException e) {
11088                }
11089            }
11090        } finally {
11091            Binder.restoreCallingIdentity(token);
11092        }
11093    }
11094
11095    private void removePackageLI(PackageParser.Package pkg, boolean chatty) {
11096        // Remove the parent package setting
11097        PackageSetting ps = (PackageSetting) pkg.mExtras;
11098        if (ps != null) {
11099            removePackageLI(ps, chatty);
11100        }
11101        // Remove the child package setting
11102        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
11103        for (int i = 0; i < childCount; i++) {
11104            PackageParser.Package childPkg = pkg.childPackages.get(i);
11105            ps = (PackageSetting) childPkg.mExtras;
11106            if (ps != null) {
11107                removePackageLI(ps, chatty);
11108            }
11109        }
11110    }
11111
11112    void removePackageLI(PackageSetting ps, boolean chatty) {
11113        if (DEBUG_INSTALL) {
11114            if (chatty)
11115                Log.d(TAG, "Removing package " + ps.name);
11116        }
11117
11118        // writer
11119        synchronized (mPackages) {
11120            mPackages.remove(ps.name);
11121            final PackageParser.Package pkg = ps.pkg;
11122            if (pkg != null) {
11123                cleanPackageDataStructuresLILPw(pkg, chatty);
11124            }
11125        }
11126    }
11127
11128    void removeInstalledPackageLI(PackageParser.Package pkg, boolean chatty) {
11129        if (DEBUG_INSTALL) {
11130            if (chatty)
11131                Log.d(TAG, "Removing package " + pkg.applicationInfo.packageName);
11132        }
11133
11134        // writer
11135        synchronized (mPackages) {
11136            // Remove the parent package
11137            mPackages.remove(pkg.applicationInfo.packageName);
11138            cleanPackageDataStructuresLILPw(pkg, chatty);
11139
11140            // Remove the child packages
11141            final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
11142            for (int i = 0; i < childCount; i++) {
11143                PackageParser.Package childPkg = pkg.childPackages.get(i);
11144                mPackages.remove(childPkg.applicationInfo.packageName);
11145                cleanPackageDataStructuresLILPw(childPkg, chatty);
11146            }
11147        }
11148    }
11149
11150    void cleanPackageDataStructuresLILPw(PackageParser.Package pkg, boolean chatty) {
11151        int N = pkg.providers.size();
11152        StringBuilder r = null;
11153        int i;
11154        for (i=0; i<N; i++) {
11155            PackageParser.Provider p = pkg.providers.get(i);
11156            mProviders.removeProvider(p);
11157            if (p.info.authority == null) {
11158
11159                /* There was another ContentProvider with this authority when
11160                 * this app was installed so this authority is null,
11161                 * Ignore it as we don't have to unregister the provider.
11162                 */
11163                continue;
11164            }
11165            String names[] = p.info.authority.split(";");
11166            for (int j = 0; j < names.length; j++) {
11167                if (mProvidersByAuthority.get(names[j]) == p) {
11168                    mProvidersByAuthority.remove(names[j]);
11169                    if (DEBUG_REMOVE) {
11170                        if (chatty)
11171                            Log.d(TAG, "Unregistered content provider: " + names[j]
11172                                    + ", className = " + p.info.name + ", isSyncable = "
11173                                    + p.info.isSyncable);
11174                    }
11175                }
11176            }
11177            if (DEBUG_REMOVE && chatty) {
11178                if (r == null) {
11179                    r = new StringBuilder(256);
11180                } else {
11181                    r.append(' ');
11182                }
11183                r.append(p.info.name);
11184            }
11185        }
11186        if (r != null) {
11187            if (DEBUG_REMOVE) Log.d(TAG, "  Providers: " + r);
11188        }
11189
11190        N = pkg.services.size();
11191        r = null;
11192        for (i=0; i<N; i++) {
11193            PackageParser.Service s = pkg.services.get(i);
11194            mServices.removeService(s);
11195            if (chatty) {
11196                if (r == null) {
11197                    r = new StringBuilder(256);
11198                } else {
11199                    r.append(' ');
11200                }
11201                r.append(s.info.name);
11202            }
11203        }
11204        if (r != null) {
11205            if (DEBUG_REMOVE) Log.d(TAG, "  Services: " + r);
11206        }
11207
11208        N = pkg.receivers.size();
11209        r = null;
11210        for (i=0; i<N; i++) {
11211            PackageParser.Activity a = pkg.receivers.get(i);
11212            mReceivers.removeActivity(a, "receiver");
11213            if (DEBUG_REMOVE && chatty) {
11214                if (r == null) {
11215                    r = new StringBuilder(256);
11216                } else {
11217                    r.append(' ');
11218                }
11219                r.append(a.info.name);
11220            }
11221        }
11222        if (r != null) {
11223            if (DEBUG_REMOVE) Log.d(TAG, "  Receivers: " + r);
11224        }
11225
11226        N = pkg.activities.size();
11227        r = null;
11228        for (i=0; i<N; i++) {
11229            PackageParser.Activity a = pkg.activities.get(i);
11230            mActivities.removeActivity(a, "activity");
11231            if (DEBUG_REMOVE && chatty) {
11232                if (r == null) {
11233                    r = new StringBuilder(256);
11234                } else {
11235                    r.append(' ');
11236                }
11237                r.append(a.info.name);
11238            }
11239        }
11240        if (r != null) {
11241            if (DEBUG_REMOVE) Log.d(TAG, "  Activities: " + r);
11242        }
11243
11244        N = pkg.permissions.size();
11245        r = null;
11246        for (i=0; i<N; i++) {
11247            PackageParser.Permission p = pkg.permissions.get(i);
11248            BasePermission bp = mSettings.mPermissions.get(p.info.name);
11249            if (bp == null) {
11250                bp = mSettings.mPermissionTrees.get(p.info.name);
11251            }
11252            if (bp != null && bp.perm == p) {
11253                bp.perm = null;
11254                if (DEBUG_REMOVE && chatty) {
11255                    if (r == null) {
11256                        r = new StringBuilder(256);
11257                    } else {
11258                        r.append(' ');
11259                    }
11260                    r.append(p.info.name);
11261                }
11262            }
11263            if ((p.info.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
11264                ArraySet<String> appOpPkgs = mAppOpPermissionPackages.get(p.info.name);
11265                if (appOpPkgs != null) {
11266                    appOpPkgs.remove(pkg.packageName);
11267                }
11268            }
11269        }
11270        if (r != null) {
11271            if (DEBUG_REMOVE) Log.d(TAG, "  Permissions: " + r);
11272        }
11273
11274        N = pkg.requestedPermissions.size();
11275        r = null;
11276        for (i=0; i<N; i++) {
11277            String perm = pkg.requestedPermissions.get(i);
11278            BasePermission bp = mSettings.mPermissions.get(perm);
11279            if (bp != null && (bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
11280                ArraySet<String> appOpPkgs = mAppOpPermissionPackages.get(perm);
11281                if (appOpPkgs != null) {
11282                    appOpPkgs.remove(pkg.packageName);
11283                    if (appOpPkgs.isEmpty()) {
11284                        mAppOpPermissionPackages.remove(perm);
11285                    }
11286                }
11287            }
11288        }
11289        if (r != null) {
11290            if (DEBUG_REMOVE) Log.d(TAG, "  Permissions: " + r);
11291        }
11292
11293        N = pkg.instrumentation.size();
11294        r = null;
11295        for (i=0; i<N; i++) {
11296            PackageParser.Instrumentation a = pkg.instrumentation.get(i);
11297            mInstrumentation.remove(a.getComponentName());
11298            if (DEBUG_REMOVE && chatty) {
11299                if (r == null) {
11300                    r = new StringBuilder(256);
11301                } else {
11302                    r.append(' ');
11303                }
11304                r.append(a.info.name);
11305            }
11306        }
11307        if (r != null) {
11308            if (DEBUG_REMOVE) Log.d(TAG, "  Instrumentation: " + r);
11309        }
11310
11311        r = null;
11312        if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11313            // Only system apps can hold shared libraries.
11314            if (pkg.libraryNames != null) {
11315                for (i = 0; i < pkg.libraryNames.size(); i++) {
11316                    String name = pkg.libraryNames.get(i);
11317                    if (removeSharedLibraryLPw(name, 0)) {
11318                        if (DEBUG_REMOVE && chatty) {
11319                            if (r == null) {
11320                                r = new StringBuilder(256);
11321                            } else {
11322                                r.append(' ');
11323                            }
11324                            r.append(name);
11325                        }
11326                    }
11327                }
11328            }
11329        }
11330
11331        r = null;
11332
11333        // Any package can hold static shared libraries.
11334        if (pkg.staticSharedLibName != null) {
11335            if (removeSharedLibraryLPw(pkg.staticSharedLibName, pkg.staticSharedLibVersion)) {
11336                if (DEBUG_REMOVE && chatty) {
11337                    if (r == null) {
11338                        r = new StringBuilder(256);
11339                    } else {
11340                        r.append(' ');
11341                    }
11342                    r.append(pkg.staticSharedLibName);
11343                }
11344            }
11345        }
11346
11347        if (r != null) {
11348            if (DEBUG_REMOVE) Log.d(TAG, "  Libraries: " + r);
11349        }
11350    }
11351
11352    private static boolean hasPermission(PackageParser.Package pkgInfo, String perm) {
11353        for (int i=pkgInfo.permissions.size()-1; i>=0; i--) {
11354            if (pkgInfo.permissions.get(i).info.name.equals(perm)) {
11355                return true;
11356            }
11357        }
11358        return false;
11359    }
11360
11361    static final int UPDATE_PERMISSIONS_ALL = 1<<0;
11362    static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1<<1;
11363    static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1<<2;
11364
11365    private void updatePermissionsLPw(PackageParser.Package pkg, int flags) {
11366        // Update the parent permissions
11367        updatePermissionsLPw(pkg.packageName, pkg, flags);
11368        // Update the child permissions
11369        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
11370        for (int i = 0; i < childCount; i++) {
11371            PackageParser.Package childPkg = pkg.childPackages.get(i);
11372            updatePermissionsLPw(childPkg.packageName, childPkg, flags);
11373        }
11374    }
11375
11376    private void updatePermissionsLPw(String changingPkg, PackageParser.Package pkgInfo,
11377            int flags) {
11378        final String volumeUuid = (pkgInfo != null) ? getVolumeUuidForPackage(pkgInfo) : null;
11379        updatePermissionsLPw(changingPkg, pkgInfo, volumeUuid, flags);
11380    }
11381
11382    private void updatePermissionsLPw(String changingPkg,
11383            PackageParser.Package pkgInfo, String replaceVolumeUuid, int flags) {
11384        // Make sure there are no dangling permission trees.
11385        Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator();
11386        while (it.hasNext()) {
11387            final BasePermission bp = it.next();
11388            if (bp.packageSetting == null) {
11389                // We may not yet have parsed the package, so just see if
11390                // we still know about its settings.
11391                bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage);
11392            }
11393            if (bp.packageSetting == null) {
11394                Slog.w(TAG, "Removing dangling permission tree: " + bp.name
11395                        + " from package " + bp.sourcePackage);
11396                it.remove();
11397            } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) {
11398                if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
11399                    Slog.i(TAG, "Removing old permission tree: " + bp.name
11400                            + " from package " + bp.sourcePackage);
11401                    flags |= UPDATE_PERMISSIONS_ALL;
11402                    it.remove();
11403                }
11404            }
11405        }
11406
11407        // Make sure all dynamic permissions have been assigned to a package,
11408        // and make sure there are no dangling permissions.
11409        it = mSettings.mPermissions.values().iterator();
11410        while (it.hasNext()) {
11411            final BasePermission bp = it.next();
11412            if (bp.type == BasePermission.TYPE_DYNAMIC) {
11413                if (DEBUG_SETTINGS) Log.v(TAG, "Dynamic permission: name="
11414                        + bp.name + " pkg=" + bp.sourcePackage
11415                        + " info=" + bp.pendingInfo);
11416                if (bp.packageSetting == null && bp.pendingInfo != null) {
11417                    final BasePermission tree = findPermissionTreeLP(bp.name);
11418                    if (tree != null && tree.perm != null) {
11419                        bp.packageSetting = tree.packageSetting;
11420                        bp.perm = new PackageParser.Permission(tree.perm.owner,
11421                                new PermissionInfo(bp.pendingInfo));
11422                        bp.perm.info.packageName = tree.perm.info.packageName;
11423                        bp.perm.info.name = bp.name;
11424                        bp.uid = tree.uid;
11425                    }
11426                }
11427            }
11428            if (bp.packageSetting == null) {
11429                // We may not yet have parsed the package, so just see if
11430                // we still know about its settings.
11431                bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage);
11432            }
11433            if (bp.packageSetting == null) {
11434                Slog.w(TAG, "Removing dangling permission: " + bp.name
11435                        + " from package " + bp.sourcePackage);
11436                it.remove();
11437            } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) {
11438                if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
11439                    Slog.i(TAG, "Removing old permission: " + bp.name
11440                            + " from package " + bp.sourcePackage);
11441                    flags |= UPDATE_PERMISSIONS_ALL;
11442                    it.remove();
11443                }
11444            }
11445        }
11446
11447        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "grantPermissions");
11448        // Now update the permissions for all packages, in particular
11449        // replace the granted permissions of the system packages.
11450        if ((flags&UPDATE_PERMISSIONS_ALL) != 0) {
11451            for (PackageParser.Package pkg : mPackages.values()) {
11452                if (pkg != pkgInfo) {
11453                    // Only replace for packages on requested volume
11454                    final String volumeUuid = getVolumeUuidForPackage(pkg);
11455                    final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_ALL) != 0)
11456                            && Objects.equals(replaceVolumeUuid, volumeUuid);
11457                    grantPermissionsLPw(pkg, replace, changingPkg);
11458                }
11459            }
11460        }
11461
11462        if (pkgInfo != null) {
11463            // Only replace for packages on requested volume
11464            final String volumeUuid = getVolumeUuidForPackage(pkgInfo);
11465            final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_PKG) != 0)
11466                    && Objects.equals(replaceVolumeUuid, volumeUuid);
11467            grantPermissionsLPw(pkgInfo, replace, changingPkg);
11468        }
11469        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
11470    }
11471
11472    private void grantPermissionsLPw(PackageParser.Package pkg, boolean replace,
11473            String packageOfInterest) {
11474        // IMPORTANT: There are two types of permissions: install and runtime.
11475        // Install time permissions are granted when the app is installed to
11476        // all device users and users added in the future. Runtime permissions
11477        // are granted at runtime explicitly to specific users. Normal and signature
11478        // protected permissions are install time permissions. Dangerous permissions
11479        // are install permissions if the app's target SDK is Lollipop MR1 or older,
11480        // otherwise they are runtime permissions. This function does not manage
11481        // runtime permissions except for the case an app targeting Lollipop MR1
11482        // being upgraded to target a newer SDK, in which case dangerous permissions
11483        // are transformed from install time to runtime ones.
11484
11485        final PackageSetting ps = (PackageSetting) pkg.mExtras;
11486        if (ps == null) {
11487            return;
11488        }
11489
11490        PermissionsState permissionsState = ps.getPermissionsState();
11491        PermissionsState origPermissions = permissionsState;
11492
11493        final int[] currentUserIds = UserManagerService.getInstance().getUserIds();
11494
11495        boolean runtimePermissionsRevoked = false;
11496        int[] changedRuntimePermissionUserIds = EMPTY_INT_ARRAY;
11497
11498        boolean changedInstallPermission = false;
11499
11500        if (replace) {
11501            ps.installPermissionsFixed = false;
11502            if (!ps.isSharedUser()) {
11503                origPermissions = new PermissionsState(permissionsState);
11504                permissionsState.reset();
11505            } else {
11506                // We need to know only about runtime permission changes since the
11507                // calling code always writes the install permissions state but
11508                // the runtime ones are written only if changed. The only cases of
11509                // changed runtime permissions here are promotion of an install to
11510                // runtime and revocation of a runtime from a shared user.
11511                changedRuntimePermissionUserIds = revokeUnusedSharedUserPermissionsLPw(
11512                        ps.sharedUser, UserManagerService.getInstance().getUserIds());
11513                if (!ArrayUtils.isEmpty(changedRuntimePermissionUserIds)) {
11514                    runtimePermissionsRevoked = true;
11515                }
11516            }
11517        }
11518
11519        permissionsState.setGlobalGids(mGlobalGids);
11520
11521        final int N = pkg.requestedPermissions.size();
11522        for (int i=0; i<N; i++) {
11523            final String name = pkg.requestedPermissions.get(i);
11524            final BasePermission bp = mSettings.mPermissions.get(name);
11525            final boolean appSupportsRuntimePermissions = pkg.applicationInfo.targetSdkVersion
11526                    >= Build.VERSION_CODES.M;
11527
11528            if (DEBUG_INSTALL) {
11529                Log.i(TAG, "Package " + pkg.packageName + " checking " + name + ": " + bp);
11530            }
11531
11532            if (bp == null || bp.packageSetting == null) {
11533                if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) {
11534                    Slog.w(TAG, "Unknown permission " + name
11535                            + " in package " + pkg.packageName);
11536                }
11537                continue;
11538            }
11539
11540
11541            // Limit ephemeral apps to ephemeral allowed permissions.
11542            if (pkg.applicationInfo.isInstantApp() && !bp.isInstant()) {
11543                Log.i(TAG, "Denying non-ephemeral permission " + bp.name + " for package "
11544                        + pkg.packageName);
11545                continue;
11546            }
11547
11548            if (bp.isRuntimeOnly() && !appSupportsRuntimePermissions) {
11549                Log.i(TAG, "Denying runtime-only permission " + bp.name + " for package "
11550                        + pkg.packageName);
11551                continue;
11552            }
11553
11554            final String perm = bp.name;
11555            boolean allowedSig = false;
11556            int grant = GRANT_DENIED;
11557
11558            // Keep track of app op permissions.
11559            if ((bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
11560                ArraySet<String> pkgs = mAppOpPermissionPackages.get(bp.name);
11561                if (pkgs == null) {
11562                    pkgs = new ArraySet<>();
11563                    mAppOpPermissionPackages.put(bp.name, pkgs);
11564                }
11565                pkgs.add(pkg.packageName);
11566            }
11567
11568            final int level = bp.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE;
11569            switch (level) {
11570                case PermissionInfo.PROTECTION_NORMAL: {
11571                    // For all apps normal permissions are install time ones.
11572                    grant = GRANT_INSTALL;
11573                } break;
11574
11575                case PermissionInfo.PROTECTION_DANGEROUS: {
11576                    // If a permission review is required for legacy apps we represent
11577                    // their permissions as always granted runtime ones since we need
11578                    // to keep the review required permission flag per user while an
11579                    // install permission's state is shared across all users.
11580                    if (!appSupportsRuntimePermissions && !mPermissionReviewRequired) {
11581                        // For legacy apps dangerous permissions are install time ones.
11582                        grant = GRANT_INSTALL;
11583                    } else if (origPermissions.hasInstallPermission(bp.name)) {
11584                        // For legacy apps that became modern, install becomes runtime.
11585                        grant = GRANT_UPGRADE;
11586                    } else if (mPromoteSystemApps
11587                            && isSystemApp(ps)
11588                            && mExistingSystemPackages.contains(ps.name)) {
11589                        // For legacy system apps, install becomes runtime.
11590                        // We cannot check hasInstallPermission() for system apps since those
11591                        // permissions were granted implicitly and not persisted pre-M.
11592                        grant = GRANT_UPGRADE;
11593                    } else {
11594                        // For modern apps keep runtime permissions unchanged.
11595                        grant = GRANT_RUNTIME;
11596                    }
11597                } break;
11598
11599                case PermissionInfo.PROTECTION_SIGNATURE: {
11600                    // For all apps signature permissions are install time ones.
11601                    allowedSig = grantSignaturePermission(perm, pkg, bp, origPermissions);
11602                    if (allowedSig) {
11603                        grant = GRANT_INSTALL;
11604                    }
11605                } break;
11606            }
11607
11608            if (DEBUG_INSTALL) {
11609                Log.i(TAG, "Package " + pkg.packageName + " granting " + perm);
11610            }
11611
11612            if (grant != GRANT_DENIED) {
11613                if (!isSystemApp(ps) && ps.installPermissionsFixed) {
11614                    // If this is an existing, non-system package, then
11615                    // we can't add any new permissions to it.
11616                    if (!allowedSig && !origPermissions.hasInstallPermission(perm)) {
11617                        // Except...  if this is a permission that was added
11618                        // to the platform (note: need to only do this when
11619                        // updating the platform).
11620                        if (!isNewPlatformPermissionForPackage(perm, pkg)) {
11621                            grant = GRANT_DENIED;
11622                        }
11623                    }
11624                }
11625
11626                switch (grant) {
11627                    case GRANT_INSTALL: {
11628                        // Revoke this as runtime permission to handle the case of
11629                        // a runtime permission being downgraded to an install one.
11630                        // Also in permission review mode we keep dangerous permissions
11631                        // for legacy apps
11632                        for (int userId : UserManagerService.getInstance().getUserIds()) {
11633                            if (origPermissions.getRuntimePermissionState(
11634                                    bp.name, userId) != null) {
11635                                // Revoke the runtime permission and clear the flags.
11636                                origPermissions.revokeRuntimePermission(bp, userId);
11637                                origPermissions.updatePermissionFlags(bp, userId,
11638                                      PackageManager.MASK_PERMISSION_FLAGS, 0);
11639                                // If we revoked a permission permission, we have to write.
11640                                changedRuntimePermissionUserIds = ArrayUtils.appendInt(
11641                                        changedRuntimePermissionUserIds, userId);
11642                            }
11643                        }
11644                        // Grant an install permission.
11645                        if (permissionsState.grantInstallPermission(bp) !=
11646                                PermissionsState.PERMISSION_OPERATION_FAILURE) {
11647                            changedInstallPermission = true;
11648                        }
11649                    } break;
11650
11651                    case GRANT_RUNTIME: {
11652                        // Grant previously granted runtime permissions.
11653                        for (int userId : UserManagerService.getInstance().getUserIds()) {
11654                            PermissionState permissionState = origPermissions
11655                                    .getRuntimePermissionState(bp.name, userId);
11656                            int flags = permissionState != null
11657                                    ? permissionState.getFlags() : 0;
11658                            if (origPermissions.hasRuntimePermission(bp.name, userId)) {
11659                                // Don't propagate the permission in a permission review mode if
11660                                // the former was revoked, i.e. marked to not propagate on upgrade.
11661                                // Note that in a permission review mode install permissions are
11662                                // represented as constantly granted runtime ones since we need to
11663                                // keep a per user state associated with the permission. Also the
11664                                // revoke on upgrade flag is no longer applicable and is reset.
11665                                final boolean revokeOnUpgrade = (flags & PackageManager
11666                                        .FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0;
11667                                if (revokeOnUpgrade) {
11668                                    flags &= ~PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE;
11669                                    // Since we changed the flags, we have to write.
11670                                    changedRuntimePermissionUserIds = ArrayUtils.appendInt(
11671                                            changedRuntimePermissionUserIds, userId);
11672                                }
11673                                if (!mPermissionReviewRequired || !revokeOnUpgrade) {
11674                                    if (permissionsState.grantRuntimePermission(bp, userId) ==
11675                                            PermissionsState.PERMISSION_OPERATION_FAILURE) {
11676                                        // If we cannot put the permission as it was,
11677                                        // we have to write.
11678                                        changedRuntimePermissionUserIds = ArrayUtils.appendInt(
11679                                                changedRuntimePermissionUserIds, userId);
11680                                    }
11681                                }
11682
11683                                // If the app supports runtime permissions no need for a review.
11684                                if (mPermissionReviewRequired
11685                                        && appSupportsRuntimePermissions
11686                                        && (flags & PackageManager
11687                                                .FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
11688                                    flags &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
11689                                    // Since we changed the flags, we have to write.
11690                                    changedRuntimePermissionUserIds = ArrayUtils.appendInt(
11691                                            changedRuntimePermissionUserIds, userId);
11692                                }
11693                            } else if (mPermissionReviewRequired
11694                                    && !appSupportsRuntimePermissions) {
11695                                // For legacy apps that need a permission review, every new
11696                                // runtime permission is granted but it is pending a review.
11697                                // We also need to review only platform defined runtime
11698                                // permissions as these are the only ones the platform knows
11699                                // how to disable the API to simulate revocation as legacy
11700                                // apps don't expect to run with revoked permissions.
11701                                if (PLATFORM_PACKAGE_NAME.equals(bp.sourcePackage)) {
11702                                    if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) {
11703                                        flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
11704                                        // We changed the flags, hence have to write.
11705                                        changedRuntimePermissionUserIds = ArrayUtils.appendInt(
11706                                                changedRuntimePermissionUserIds, userId);
11707                                    }
11708                                }
11709                                if (permissionsState.grantRuntimePermission(bp, userId)
11710                                        != PermissionsState.PERMISSION_OPERATION_FAILURE) {
11711                                    // We changed the permission, hence have to write.
11712                                    changedRuntimePermissionUserIds = ArrayUtils.appendInt(
11713                                            changedRuntimePermissionUserIds, userId);
11714                                }
11715                            }
11716                            // Propagate the permission flags.
11717                            permissionsState.updatePermissionFlags(bp, userId, flags, flags);
11718                        }
11719                    } break;
11720
11721                    case GRANT_UPGRADE: {
11722                        // Grant runtime permissions for a previously held install permission.
11723                        PermissionState permissionState = origPermissions
11724                                .getInstallPermissionState(bp.name);
11725                        final int flags = permissionState != null ? permissionState.getFlags() : 0;
11726
11727                        if (origPermissions.revokeInstallPermission(bp)
11728                                != PermissionsState.PERMISSION_OPERATION_FAILURE) {
11729                            // We will be transferring the permission flags, so clear them.
11730                            origPermissions.updatePermissionFlags(bp, UserHandle.USER_ALL,
11731                                    PackageManager.MASK_PERMISSION_FLAGS, 0);
11732                            changedInstallPermission = true;
11733                        }
11734
11735                        // If the permission is not to be promoted to runtime we ignore it and
11736                        // also its other flags as they are not applicable to install permissions.
11737                        if ((flags & PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE) == 0) {
11738                            for (int userId : currentUserIds) {
11739                                if (permissionsState.grantRuntimePermission(bp, userId) !=
11740                                        PermissionsState.PERMISSION_OPERATION_FAILURE) {
11741                                    // Transfer the permission flags.
11742                                    permissionsState.updatePermissionFlags(bp, userId,
11743                                            flags, flags);
11744                                    // If we granted the permission, we have to write.
11745                                    changedRuntimePermissionUserIds = ArrayUtils.appendInt(
11746                                            changedRuntimePermissionUserIds, userId);
11747                                }
11748                            }
11749                        }
11750                    } break;
11751
11752                    default: {
11753                        if (packageOfInterest == null
11754                                || packageOfInterest.equals(pkg.packageName)) {
11755                            Slog.w(TAG, "Not granting permission " + perm
11756                                    + " to package " + pkg.packageName
11757                                    + " because it was previously installed without");
11758                        }
11759                    } break;
11760                }
11761            } else {
11762                if (permissionsState.revokeInstallPermission(bp) !=
11763                        PermissionsState.PERMISSION_OPERATION_FAILURE) {
11764                    // Also drop the permission flags.
11765                    permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
11766                            PackageManager.MASK_PERMISSION_FLAGS, 0);
11767                    changedInstallPermission = true;
11768                    Slog.i(TAG, "Un-granting permission " + perm
11769                            + " from package " + pkg.packageName
11770                            + " (protectionLevel=" + bp.protectionLevel
11771                            + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
11772                            + ")");
11773                } else if ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) == 0) {
11774                    // Don't print warning for app op permissions, since it is fine for them
11775                    // not to be granted, there is a UI for the user to decide.
11776                    if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) {
11777                        Slog.w(TAG, "Not granting permission " + perm
11778                                + " to package " + pkg.packageName
11779                                + " (protectionLevel=" + bp.protectionLevel
11780                                + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
11781                                + ")");
11782                    }
11783                }
11784            }
11785        }
11786
11787        if ((changedInstallPermission || replace) && !ps.installPermissionsFixed &&
11788                !isSystemApp(ps) || isUpdatedSystemApp(ps)){
11789            // This is the first that we have heard about this package, so the
11790            // permissions we have now selected are fixed until explicitly
11791            // changed.
11792            ps.installPermissionsFixed = true;
11793        }
11794
11795        // Persist the runtime permissions state for users with changes. If permissions
11796        // were revoked because no app in the shared user declares them we have to
11797        // write synchronously to avoid losing runtime permissions state.
11798        for (int userId : changedRuntimePermissionUserIds) {
11799            mSettings.writeRuntimePermissionsForUserLPr(userId, runtimePermissionsRevoked);
11800        }
11801    }
11802
11803    private boolean isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg) {
11804        boolean allowed = false;
11805        final int NP = PackageParser.NEW_PERMISSIONS.length;
11806        for (int ip=0; ip<NP; ip++) {
11807            final PackageParser.NewPermissionInfo npi
11808                    = PackageParser.NEW_PERMISSIONS[ip];
11809            if (npi.name.equals(perm)
11810                    && pkg.applicationInfo.targetSdkVersion < npi.sdkVersion) {
11811                allowed = true;
11812                Log.i(TAG, "Auto-granting " + perm + " to old pkg "
11813                        + pkg.packageName);
11814                break;
11815            }
11816        }
11817        return allowed;
11818    }
11819
11820    private boolean grantSignaturePermission(String perm, PackageParser.Package pkg,
11821            BasePermission bp, PermissionsState origPermissions) {
11822        boolean privilegedPermission = (bp.protectionLevel
11823                & PermissionInfo.PROTECTION_FLAG_PRIVILEGED) != 0;
11824        boolean privappPermissionsDisable =
11825                RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_DISABLE;
11826        boolean platformPermission = PLATFORM_PACKAGE_NAME.equals(bp.sourcePackage);
11827        boolean platformPackage = PLATFORM_PACKAGE_NAME.equals(pkg.packageName);
11828        if (!privappPermissionsDisable && privilegedPermission && pkg.isPrivilegedApp()
11829                && !platformPackage && platformPermission) {
11830            ArraySet<String> wlPermissions = SystemConfig.getInstance()
11831                    .getPrivAppPermissions(pkg.packageName);
11832            boolean whitelisted = wlPermissions != null && wlPermissions.contains(perm);
11833            if (!whitelisted) {
11834                Slog.w(TAG, "Privileged permission " + perm + " for package "
11835                        + pkg.packageName + " - not in privapp-permissions whitelist");
11836                // Only report violations for apps on system image
11837                if (!mSystemReady && !pkg.isUpdatedSystemApp()) {
11838                    if (mPrivappPermissionsViolations == null) {
11839                        mPrivappPermissionsViolations = new ArraySet<>();
11840                    }
11841                    mPrivappPermissionsViolations.add(pkg.packageName + ": " + perm);
11842                }
11843                if (RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_ENFORCE) {
11844                    return false;
11845                }
11846            }
11847        }
11848        boolean allowed = (compareSignatures(
11849                bp.packageSetting.signatures.mSignatures, pkg.mSignatures)
11850                        == PackageManager.SIGNATURE_MATCH)
11851                || (compareSignatures(mPlatformPackage.mSignatures, pkg.mSignatures)
11852                        == PackageManager.SIGNATURE_MATCH);
11853        if (!allowed && privilegedPermission) {
11854            if (isSystemApp(pkg)) {
11855                // For updated system applications, a system permission
11856                // is granted only if it had been defined by the original application.
11857                if (pkg.isUpdatedSystemApp()) {
11858                    final PackageSetting sysPs = mSettings
11859                            .getDisabledSystemPkgLPr(pkg.packageName);
11860                    if (sysPs != null && sysPs.getPermissionsState().hasInstallPermission(perm)) {
11861                        // If the original was granted this permission, we take
11862                        // that grant decision as read and propagate it to the
11863                        // update.
11864                        if (sysPs.isPrivileged()) {
11865                            allowed = true;
11866                        }
11867                    } else {
11868                        // The system apk may have been updated with an older
11869                        // version of the one on the data partition, but which
11870                        // granted a new system permission that it didn't have
11871                        // before.  In this case we do want to allow the app to
11872                        // now get the new permission if the ancestral apk is
11873                        // privileged to get it.
11874                        if (sysPs != null && sysPs.pkg != null && sysPs.isPrivileged()) {
11875                            for (int j = 0; j < sysPs.pkg.requestedPermissions.size(); j++) {
11876                                if (perm.equals(sysPs.pkg.requestedPermissions.get(j))) {
11877                                    allowed = true;
11878                                    break;
11879                                }
11880                            }
11881                        }
11882                        // Also if a privileged parent package on the system image or any of
11883                        // its children requested a privileged permission, the updated child
11884                        // packages can also get the permission.
11885                        if (pkg.parentPackage != null) {
11886                            final PackageSetting disabledSysParentPs = mSettings
11887                                    .getDisabledSystemPkgLPr(pkg.parentPackage.packageName);
11888                            if (disabledSysParentPs != null && disabledSysParentPs.pkg != null
11889                                    && disabledSysParentPs.isPrivileged()) {
11890                                if (isPackageRequestingPermission(disabledSysParentPs.pkg, perm)) {
11891                                    allowed = true;
11892                                } else if (disabledSysParentPs.pkg.childPackages != null) {
11893                                    final int count = disabledSysParentPs.pkg.childPackages.size();
11894                                    for (int i = 0; i < count; i++) {
11895                                        PackageParser.Package disabledSysChildPkg =
11896                                                disabledSysParentPs.pkg.childPackages.get(i);
11897                                        if (isPackageRequestingPermission(disabledSysChildPkg,
11898                                                perm)) {
11899                                            allowed = true;
11900                                            break;
11901                                        }
11902                                    }
11903                                }
11904                            }
11905                        }
11906                    }
11907                } else {
11908                    allowed = isPrivilegedApp(pkg);
11909                }
11910            }
11911        }
11912        if (!allowed) {
11913            if (!allowed && (bp.protectionLevel
11914                    & PermissionInfo.PROTECTION_FLAG_PRE23) != 0
11915                    && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
11916                // If this was a previously normal/dangerous permission that got moved
11917                // to a system permission as part of the runtime permission redesign, then
11918                // we still want to blindly grant it to old apps.
11919                allowed = true;
11920            }
11921            if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_INSTALLER) != 0
11922                    && pkg.packageName.equals(mRequiredInstallerPackage)) {
11923                // If this permission is to be granted to the system installer and
11924                // this app is an installer, then it gets the permission.
11925                allowed = true;
11926            }
11927            if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_VERIFIER) != 0
11928                    && pkg.packageName.equals(mRequiredVerifierPackage)) {
11929                // If this permission is to be granted to the system verifier and
11930                // this app is a verifier, then it gets the permission.
11931                allowed = true;
11932            }
11933            if (!allowed && (bp.protectionLevel
11934                    & PermissionInfo.PROTECTION_FLAG_PREINSTALLED) != 0
11935                    && isSystemApp(pkg)) {
11936                // Any pre-installed system app is allowed to get this permission.
11937                allowed = true;
11938            }
11939            if (!allowed && (bp.protectionLevel
11940                    & PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0) {
11941                // For development permissions, a development permission
11942                // is granted only if it was already granted.
11943                allowed = origPermissions.hasInstallPermission(perm);
11944            }
11945            if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_SETUP) != 0
11946                    && pkg.packageName.equals(mSetupWizardPackage)) {
11947                // If this permission is to be granted to the system setup wizard and
11948                // this app is a setup wizard, then it gets the permission.
11949                allowed = true;
11950            }
11951        }
11952        return allowed;
11953    }
11954
11955    private boolean isPackageRequestingPermission(PackageParser.Package pkg, String permission) {
11956        final int permCount = pkg.requestedPermissions.size();
11957        for (int j = 0; j < permCount; j++) {
11958            String requestedPermission = pkg.requestedPermissions.get(j);
11959            if (permission.equals(requestedPermission)) {
11960                return true;
11961            }
11962        }
11963        return false;
11964    }
11965
11966    final class ActivityIntentResolver
11967            extends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo> {
11968        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
11969                boolean defaultOnly, int userId) {
11970            if (!sUserManager.exists(userId)) return null;
11971            mFlags = (defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0);
11972            return super.queryIntent(intent, resolvedType, defaultOnly, userId);
11973        }
11974
11975        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
11976                int userId) {
11977            if (!sUserManager.exists(userId)) return null;
11978            mFlags = flags;
11979            return super.queryIntent(intent, resolvedType,
11980                    (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
11981                    userId);
11982        }
11983
11984        public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
11985                int flags, ArrayList<PackageParser.Activity> packageActivities, int userId) {
11986            if (!sUserManager.exists(userId)) return null;
11987            if (packageActivities == null) {
11988                return null;
11989            }
11990            mFlags = flags;
11991            final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0;
11992            final int N = packageActivities.size();
11993            ArrayList<PackageParser.ActivityIntentInfo[]> listCut =
11994                new ArrayList<PackageParser.ActivityIntentInfo[]>(N);
11995
11996            ArrayList<PackageParser.ActivityIntentInfo> intentFilters;
11997            for (int i = 0; i < N; ++i) {
11998                intentFilters = packageActivities.get(i).intents;
11999                if (intentFilters != null && intentFilters.size() > 0) {
12000                    PackageParser.ActivityIntentInfo[] array =
12001                            new PackageParser.ActivityIntentInfo[intentFilters.size()];
12002                    intentFilters.toArray(array);
12003                    listCut.add(array);
12004                }
12005            }
12006            return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
12007        }
12008
12009        /**
12010         * Finds a privileged activity that matches the specified activity names.
12011         */
12012        private PackageParser.Activity findMatchingActivity(
12013                List<PackageParser.Activity> activityList, ActivityInfo activityInfo) {
12014            for (PackageParser.Activity sysActivity : activityList) {
12015                if (sysActivity.info.name.equals(activityInfo.name)) {
12016                    return sysActivity;
12017                }
12018                if (sysActivity.info.name.equals(activityInfo.targetActivity)) {
12019                    return sysActivity;
12020                }
12021                if (sysActivity.info.targetActivity != null) {
12022                    if (sysActivity.info.targetActivity.equals(activityInfo.name)) {
12023                        return sysActivity;
12024                    }
12025                    if (sysActivity.info.targetActivity.equals(activityInfo.targetActivity)) {
12026                        return sysActivity;
12027                    }
12028                }
12029            }
12030            return null;
12031        }
12032
12033        public class IterGenerator<E> {
12034            public Iterator<E> generate(ActivityIntentInfo info) {
12035                return null;
12036            }
12037        }
12038
12039        public class ActionIterGenerator extends IterGenerator<String> {
12040            @Override
12041            public Iterator<String> generate(ActivityIntentInfo info) {
12042                return info.actionsIterator();
12043            }
12044        }
12045
12046        public class CategoriesIterGenerator extends IterGenerator<String> {
12047            @Override
12048            public Iterator<String> generate(ActivityIntentInfo info) {
12049                return info.categoriesIterator();
12050            }
12051        }
12052
12053        public class SchemesIterGenerator extends IterGenerator<String> {
12054            @Override
12055            public Iterator<String> generate(ActivityIntentInfo info) {
12056                return info.schemesIterator();
12057            }
12058        }
12059
12060        public class AuthoritiesIterGenerator extends IterGenerator<IntentFilter.AuthorityEntry> {
12061            @Override
12062            public Iterator<IntentFilter.AuthorityEntry> generate(ActivityIntentInfo info) {
12063                return info.authoritiesIterator();
12064            }
12065        }
12066
12067        /**
12068         * <em>WARNING</em> for performance reasons, the passed in intentList WILL BE
12069         * MODIFIED. Do not pass in a list that should not be changed.
12070         */
12071        private <T> void getIntentListSubset(List<ActivityIntentInfo> intentList,
12072                IterGenerator<T> generator, Iterator<T> searchIterator) {
12073            // loop through the set of actions; every one must be found in the intent filter
12074            while (searchIterator.hasNext()) {
12075                // we must have at least one filter in the list to consider a match
12076                if (intentList.size() == 0) {
12077                    break;
12078                }
12079
12080                final T searchAction = searchIterator.next();
12081
12082                // loop through the set of intent filters
12083                final Iterator<ActivityIntentInfo> intentIter = intentList.iterator();
12084                while (intentIter.hasNext()) {
12085                    final ActivityIntentInfo intentInfo = intentIter.next();
12086                    boolean selectionFound = false;
12087
12088                    // loop through the intent filter's selection criteria; at least one
12089                    // of them must match the searched criteria
12090                    final Iterator<T> intentSelectionIter = generator.generate(intentInfo);
12091                    while (intentSelectionIter != null && intentSelectionIter.hasNext()) {
12092                        final T intentSelection = intentSelectionIter.next();
12093                        if (intentSelection != null && intentSelection.equals(searchAction)) {
12094                            selectionFound = true;
12095                            break;
12096                        }
12097                    }
12098
12099                    // the selection criteria wasn't found in this filter's set; this filter
12100                    // is not a potential match
12101                    if (!selectionFound) {
12102                        intentIter.remove();
12103                    }
12104                }
12105            }
12106        }
12107
12108        private boolean isProtectedAction(ActivityIntentInfo filter) {
12109            final Iterator<String> actionsIter = filter.actionsIterator();
12110            while (actionsIter != null && actionsIter.hasNext()) {
12111                final String filterAction = actionsIter.next();
12112                if (PROTECTED_ACTIONS.contains(filterAction)) {
12113                    return true;
12114                }
12115            }
12116            return false;
12117        }
12118
12119        /**
12120         * Adjusts the priority of the given intent filter according to policy.
12121         * <p>
12122         * <ul>
12123         * <li>The priority for non privileged applications is capped to '0'</li>
12124         * <li>The priority for protected actions on privileged applications is capped to '0'</li>
12125         * <li>The priority for unbundled updates to privileged applications is capped to the
12126         *      priority defined on the system partition</li>
12127         * </ul>
12128         * <p>
12129         * <em>NOTE:</em> There is one exception. For security reasons, the setup wizard is
12130         * allowed to obtain any priority on any action.
12131         */
12132        private void adjustPriority(
12133                List<PackageParser.Activity> systemActivities, ActivityIntentInfo intent) {
12134            // nothing to do; priority is fine as-is
12135            if (intent.getPriority() <= 0) {
12136                return;
12137            }
12138
12139            final ActivityInfo activityInfo = intent.activity.info;
12140            final ApplicationInfo applicationInfo = activityInfo.applicationInfo;
12141
12142            final boolean privilegedApp =
12143                    ((applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0);
12144            if (!privilegedApp) {
12145                // non-privileged applications can never define a priority >0
12146                Slog.w(TAG, "Non-privileged app; cap priority to 0;"
12147                        + " package: " + applicationInfo.packageName
12148                        + " activity: " + intent.activity.className
12149                        + " origPrio: " + intent.getPriority());
12150                intent.setPriority(0);
12151                return;
12152            }
12153
12154            if (systemActivities == null) {
12155                // the system package is not disabled; we're parsing the system partition
12156                if (isProtectedAction(intent)) {
12157                    if (mDeferProtectedFilters) {
12158                        // We can't deal with these just yet. No component should ever obtain a
12159                        // >0 priority for a protected actions, with ONE exception -- the setup
12160                        // wizard. The setup wizard, however, cannot be known until we're able to
12161                        // query it for the category CATEGORY_SETUP_WIZARD. Which we can't do
12162                        // until all intent filters have been processed. Chicken, meet egg.
12163                        // Let the filter temporarily have a high priority and rectify the
12164                        // priorities after all system packages have been scanned.
12165                        mProtectedFilters.add(intent);
12166                        if (DEBUG_FILTERS) {
12167                            Slog.i(TAG, "Protected action; save for later;"
12168                                    + " package: " + applicationInfo.packageName
12169                                    + " activity: " + intent.activity.className
12170                                    + " origPrio: " + intent.getPriority());
12171                        }
12172                        return;
12173                    } else {
12174                        if (DEBUG_FILTERS && mSetupWizardPackage == null) {
12175                            Slog.i(TAG, "No setup wizard;"
12176                                + " All protected intents capped to priority 0");
12177                        }
12178                        if (intent.activity.info.packageName.equals(mSetupWizardPackage)) {
12179                            if (DEBUG_FILTERS) {
12180                                Slog.i(TAG, "Found setup wizard;"
12181                                    + " allow priority " + intent.getPriority() + ";"
12182                                    + " package: " + intent.activity.info.packageName
12183                                    + " activity: " + intent.activity.className
12184                                    + " priority: " + intent.getPriority());
12185                            }
12186                            // setup wizard gets whatever it wants
12187                            return;
12188                        }
12189                        Slog.w(TAG, "Protected action; cap priority to 0;"
12190                                + " package: " + intent.activity.info.packageName
12191                                + " activity: " + intent.activity.className
12192                                + " origPrio: " + intent.getPriority());
12193                        intent.setPriority(0);
12194                        return;
12195                    }
12196                }
12197                // privileged apps on the system image get whatever priority they request
12198                return;
12199            }
12200
12201            // privileged app unbundled update ... try to find the same activity
12202            final PackageParser.Activity foundActivity =
12203                    findMatchingActivity(systemActivities, activityInfo);
12204            if (foundActivity == null) {
12205                // this is a new activity; it cannot obtain >0 priority
12206                if (DEBUG_FILTERS) {
12207                    Slog.i(TAG, "New activity; cap priority to 0;"
12208                            + " package: " + applicationInfo.packageName
12209                            + " activity: " + intent.activity.className
12210                            + " origPrio: " + intent.getPriority());
12211                }
12212                intent.setPriority(0);
12213                return;
12214            }
12215
12216            // found activity, now check for filter equivalence
12217
12218            // a shallow copy is enough; we modify the list, not its contents
12219            final List<ActivityIntentInfo> intentListCopy =
12220                    new ArrayList<>(foundActivity.intents);
12221            final List<ActivityIntentInfo> foundFilters = findFilters(intent);
12222
12223            // find matching action subsets
12224            final Iterator<String> actionsIterator = intent.actionsIterator();
12225            if (actionsIterator != null) {
12226                getIntentListSubset(
12227                        intentListCopy, new ActionIterGenerator(), actionsIterator);
12228                if (intentListCopy.size() == 0) {
12229                    // no more intents to match; we're not equivalent
12230                    if (DEBUG_FILTERS) {
12231                        Slog.i(TAG, "Mismatched action; cap priority to 0;"
12232                                + " package: " + applicationInfo.packageName
12233                                + " activity: " + intent.activity.className
12234                                + " origPrio: " + intent.getPriority());
12235                    }
12236                    intent.setPriority(0);
12237                    return;
12238                }
12239            }
12240
12241            // find matching category subsets
12242            final Iterator<String> categoriesIterator = intent.categoriesIterator();
12243            if (categoriesIterator != null) {
12244                getIntentListSubset(intentListCopy, new CategoriesIterGenerator(),
12245                        categoriesIterator);
12246                if (intentListCopy.size() == 0) {
12247                    // no more intents to match; we're not equivalent
12248                    if (DEBUG_FILTERS) {
12249                        Slog.i(TAG, "Mismatched category; cap priority to 0;"
12250                                + " package: " + applicationInfo.packageName
12251                                + " activity: " + intent.activity.className
12252                                + " origPrio: " + intent.getPriority());
12253                    }
12254                    intent.setPriority(0);
12255                    return;
12256                }
12257            }
12258
12259            // find matching schemes subsets
12260            final Iterator<String> schemesIterator = intent.schemesIterator();
12261            if (schemesIterator != null) {
12262                getIntentListSubset(intentListCopy, new SchemesIterGenerator(),
12263                        schemesIterator);
12264                if (intentListCopy.size() == 0) {
12265                    // no more intents to match; we're not equivalent
12266                    if (DEBUG_FILTERS) {
12267                        Slog.i(TAG, "Mismatched scheme; cap priority to 0;"
12268                                + " package: " + applicationInfo.packageName
12269                                + " activity: " + intent.activity.className
12270                                + " origPrio: " + intent.getPriority());
12271                    }
12272                    intent.setPriority(0);
12273                    return;
12274                }
12275            }
12276
12277            // find matching authorities subsets
12278            final Iterator<IntentFilter.AuthorityEntry>
12279                    authoritiesIterator = intent.authoritiesIterator();
12280            if (authoritiesIterator != null) {
12281                getIntentListSubset(intentListCopy,
12282                        new AuthoritiesIterGenerator(),
12283                        authoritiesIterator);
12284                if (intentListCopy.size() == 0) {
12285                    // no more intents to match; we're not equivalent
12286                    if (DEBUG_FILTERS) {
12287                        Slog.i(TAG, "Mismatched authority; cap priority to 0;"
12288                                + " package: " + applicationInfo.packageName
12289                                + " activity: " + intent.activity.className
12290                                + " origPrio: " + intent.getPriority());
12291                    }
12292                    intent.setPriority(0);
12293                    return;
12294                }
12295            }
12296
12297            // we found matching filter(s); app gets the max priority of all intents
12298            int cappedPriority = 0;
12299            for (int i = intentListCopy.size() - 1; i >= 0; --i) {
12300                cappedPriority = Math.max(cappedPriority, intentListCopy.get(i).getPriority());
12301            }
12302            if (intent.getPriority() > cappedPriority) {
12303                if (DEBUG_FILTERS) {
12304                    Slog.i(TAG, "Found matching filter(s);"
12305                            + " cap priority to " + cappedPriority + ";"
12306                            + " package: " + applicationInfo.packageName
12307                            + " activity: " + intent.activity.className
12308                            + " origPrio: " + intent.getPriority());
12309                }
12310                intent.setPriority(cappedPriority);
12311                return;
12312            }
12313            // all this for nothing; the requested priority was <= what was on the system
12314        }
12315
12316        public final void addActivity(PackageParser.Activity a, String type) {
12317            mActivities.put(a.getComponentName(), a);
12318            if (DEBUG_SHOW_INFO)
12319                Log.v(
12320                TAG, "  " + type + " " +
12321                (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel : a.info.name) + ":");
12322            if (DEBUG_SHOW_INFO)
12323                Log.v(TAG, "    Class=" + a.info.name);
12324            final int NI = a.intents.size();
12325            for (int j=0; j<NI; j++) {
12326                PackageParser.ActivityIntentInfo intent = a.intents.get(j);
12327                if ("activity".equals(type)) {
12328                    final PackageSetting ps =
12329                            mSettings.getDisabledSystemPkgLPr(intent.activity.info.packageName);
12330                    final List<PackageParser.Activity> systemActivities =
12331                            ps != null && ps.pkg != null ? ps.pkg.activities : null;
12332                    adjustPriority(systemActivities, intent);
12333                }
12334                if (DEBUG_SHOW_INFO) {
12335                    Log.v(TAG, "    IntentFilter:");
12336                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
12337                }
12338                if (!intent.debugCheck()) {
12339                    Log.w(TAG, "==> For Activity " + a.info.name);
12340                }
12341                addFilter(intent);
12342            }
12343        }
12344
12345        public final void removeActivity(PackageParser.Activity a, String type) {
12346            mActivities.remove(a.getComponentName());
12347            if (DEBUG_SHOW_INFO) {
12348                Log.v(TAG, "  " + type + " "
12349                        + (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel
12350                                : a.info.name) + ":");
12351                Log.v(TAG, "    Class=" + a.info.name);
12352            }
12353            final int NI = a.intents.size();
12354            for (int j=0; j<NI; j++) {
12355                PackageParser.ActivityIntentInfo intent = a.intents.get(j);
12356                if (DEBUG_SHOW_INFO) {
12357                    Log.v(TAG, "    IntentFilter:");
12358                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
12359                }
12360                removeFilter(intent);
12361            }
12362        }
12363
12364        @Override
12365        protected boolean allowFilterResult(
12366                PackageParser.ActivityIntentInfo filter, List<ResolveInfo> dest) {
12367            ActivityInfo filterAi = filter.activity.info;
12368            for (int i=dest.size()-1; i>=0; i--) {
12369                ActivityInfo destAi = dest.get(i).activityInfo;
12370                if (destAi.name == filterAi.name
12371                        && destAi.packageName == filterAi.packageName) {
12372                    return false;
12373                }
12374            }
12375            return true;
12376        }
12377
12378        @Override
12379        protected ActivityIntentInfo[] newArray(int size) {
12380            return new ActivityIntentInfo[size];
12381        }
12382
12383        @Override
12384        protected boolean isFilterStopped(PackageParser.ActivityIntentInfo filter, int userId) {
12385            if (!sUserManager.exists(userId)) return true;
12386            PackageParser.Package p = filter.activity.owner;
12387            if (p != null) {
12388                PackageSetting ps = (PackageSetting)p.mExtras;
12389                if (ps != null) {
12390                    // System apps are never considered stopped for purposes of
12391                    // filtering, because there may be no way for the user to
12392                    // actually re-launch them.
12393                    return (ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0
12394                            && ps.getStopped(userId);
12395                }
12396            }
12397            return false;
12398        }
12399
12400        @Override
12401        protected boolean isPackageForFilter(String packageName,
12402                PackageParser.ActivityIntentInfo info) {
12403            return packageName.equals(info.activity.owner.packageName);
12404        }
12405
12406        @Override
12407        protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info,
12408                int match, int userId) {
12409            if (!sUserManager.exists(userId)) return null;
12410            if (!mSettings.isEnabledAndMatchLPr(info.activity.info, mFlags, userId)) {
12411                return null;
12412            }
12413            final PackageParser.Activity activity = info.activity;
12414            PackageSetting ps = (PackageSetting) activity.owner.mExtras;
12415            if (ps == null) {
12416                return null;
12417            }
12418            final PackageUserState userState = ps.readUserState(userId);
12419            ActivityInfo ai = generateActivityInfo(activity, mFlags, userState, userId);
12420            if (ai == null) {
12421                return null;
12422            }
12423            final boolean matchVisibleToInstantApp =
12424                    (mFlags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
12425            final boolean isInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0;
12426            // throw out filters that aren't visible to ephemeral apps
12427            if (matchVisibleToInstantApp
12428                    && !(info.isVisibleToInstantApp() || userState.instantApp)) {
12429                return null;
12430            }
12431            // throw out ephemeral filters if we're not explicitly requesting them
12432            if (!isInstantApp && userState.instantApp) {
12433                return null;
12434            }
12435            // throw out instant app filters if updates are available; will trigger
12436            // instant app resolution
12437            if (userState.instantApp && ps.isUpdateAvailable()) {
12438                return null;
12439            }
12440            final ResolveInfo res = new ResolveInfo();
12441            res.activityInfo = ai;
12442            if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
12443                res.filter = info;
12444            }
12445            if (info != null) {
12446                res.handleAllWebDataURI = info.handleAllWebDataURI();
12447            }
12448            res.priority = info.getPriority();
12449            res.preferredOrder = activity.owner.mPreferredOrder;
12450            //System.out.println("Result: " + res.activityInfo.className +
12451            //                   " = " + res.priority);
12452            res.match = match;
12453            res.isDefault = info.hasDefault;
12454            res.labelRes = info.labelRes;
12455            res.nonLocalizedLabel = info.nonLocalizedLabel;
12456            if (userNeedsBadging(userId)) {
12457                res.noResourceId = true;
12458            } else {
12459                res.icon = info.icon;
12460            }
12461            res.iconResourceId = info.icon;
12462            res.system = res.activityInfo.applicationInfo.isSystemApp();
12463            res.instantAppAvailable = userState.instantApp;
12464            return res;
12465        }
12466
12467        @Override
12468        protected void sortResults(List<ResolveInfo> results) {
12469            Collections.sort(results, mResolvePrioritySorter);
12470        }
12471
12472        @Override
12473        protected void dumpFilter(PrintWriter out, String prefix,
12474                PackageParser.ActivityIntentInfo filter) {
12475            out.print(prefix); out.print(
12476                    Integer.toHexString(System.identityHashCode(filter.activity)));
12477                    out.print(' ');
12478                    filter.activity.printComponentShortName(out);
12479                    out.print(" filter ");
12480                    out.println(Integer.toHexString(System.identityHashCode(filter)));
12481        }
12482
12483        @Override
12484        protected Object filterToLabel(PackageParser.ActivityIntentInfo filter) {
12485            return filter.activity;
12486        }
12487
12488        protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
12489            PackageParser.Activity activity = (PackageParser.Activity)label;
12490            out.print(prefix); out.print(
12491                    Integer.toHexString(System.identityHashCode(activity)));
12492                    out.print(' ');
12493                    activity.printComponentShortName(out);
12494            if (count > 1) {
12495                out.print(" ("); out.print(count); out.print(" filters)");
12496            }
12497            out.println();
12498        }
12499
12500        // Keys are String (activity class name), values are Activity.
12501        private final ArrayMap<ComponentName, PackageParser.Activity> mActivities
12502                = new ArrayMap<ComponentName, PackageParser.Activity>();
12503        private int mFlags;
12504    }
12505
12506    private final class ServiceIntentResolver
12507            extends IntentResolver<PackageParser.ServiceIntentInfo, ResolveInfo> {
12508        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
12509                boolean defaultOnly, int userId) {
12510            mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
12511            return super.queryIntent(intent, resolvedType, defaultOnly, userId);
12512        }
12513
12514        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
12515                int userId) {
12516            if (!sUserManager.exists(userId)) return null;
12517            mFlags = flags;
12518            return super.queryIntent(intent, resolvedType,
12519                    (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
12520                    userId);
12521        }
12522
12523        public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
12524                int flags, ArrayList<PackageParser.Service> packageServices, int userId) {
12525            if (!sUserManager.exists(userId)) return null;
12526            if (packageServices == null) {
12527                return null;
12528            }
12529            mFlags = flags;
12530            final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0;
12531            final int N = packageServices.size();
12532            ArrayList<PackageParser.ServiceIntentInfo[]> listCut =
12533                new ArrayList<PackageParser.ServiceIntentInfo[]>(N);
12534
12535            ArrayList<PackageParser.ServiceIntentInfo> intentFilters;
12536            for (int i = 0; i < N; ++i) {
12537                intentFilters = packageServices.get(i).intents;
12538                if (intentFilters != null && intentFilters.size() > 0) {
12539                    PackageParser.ServiceIntentInfo[] array =
12540                            new PackageParser.ServiceIntentInfo[intentFilters.size()];
12541                    intentFilters.toArray(array);
12542                    listCut.add(array);
12543                }
12544            }
12545            return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
12546        }
12547
12548        public final void addService(PackageParser.Service s) {
12549            mServices.put(s.getComponentName(), s);
12550            if (DEBUG_SHOW_INFO) {
12551                Log.v(TAG, "  "
12552                        + (s.info.nonLocalizedLabel != null
12553                        ? s.info.nonLocalizedLabel : s.info.name) + ":");
12554                Log.v(TAG, "    Class=" + s.info.name);
12555            }
12556            final int NI = s.intents.size();
12557            int j;
12558            for (j=0; j<NI; j++) {
12559                PackageParser.ServiceIntentInfo intent = s.intents.get(j);
12560                if (DEBUG_SHOW_INFO) {
12561                    Log.v(TAG, "    IntentFilter:");
12562                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
12563                }
12564                if (!intent.debugCheck()) {
12565                    Log.w(TAG, "==> For Service " + s.info.name);
12566                }
12567                addFilter(intent);
12568            }
12569        }
12570
12571        public final void removeService(PackageParser.Service s) {
12572            mServices.remove(s.getComponentName());
12573            if (DEBUG_SHOW_INFO) {
12574                Log.v(TAG, "  " + (s.info.nonLocalizedLabel != null
12575                        ? s.info.nonLocalizedLabel : s.info.name) + ":");
12576                Log.v(TAG, "    Class=" + s.info.name);
12577            }
12578            final int NI = s.intents.size();
12579            int j;
12580            for (j=0; j<NI; j++) {
12581                PackageParser.ServiceIntentInfo intent = s.intents.get(j);
12582                if (DEBUG_SHOW_INFO) {
12583                    Log.v(TAG, "    IntentFilter:");
12584                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
12585                }
12586                removeFilter(intent);
12587            }
12588        }
12589
12590        @Override
12591        protected boolean allowFilterResult(
12592                PackageParser.ServiceIntentInfo filter, List<ResolveInfo> dest) {
12593            ServiceInfo filterSi = filter.service.info;
12594            for (int i=dest.size()-1; i>=0; i--) {
12595                ServiceInfo destAi = dest.get(i).serviceInfo;
12596                if (destAi.name == filterSi.name
12597                        && destAi.packageName == filterSi.packageName) {
12598                    return false;
12599                }
12600            }
12601            return true;
12602        }
12603
12604        @Override
12605        protected PackageParser.ServiceIntentInfo[] newArray(int size) {
12606            return new PackageParser.ServiceIntentInfo[size];
12607        }
12608
12609        @Override
12610        protected boolean isFilterStopped(PackageParser.ServiceIntentInfo filter, int userId) {
12611            if (!sUserManager.exists(userId)) return true;
12612            PackageParser.Package p = filter.service.owner;
12613            if (p != null) {
12614                PackageSetting ps = (PackageSetting)p.mExtras;
12615                if (ps != null) {
12616                    // System apps are never considered stopped for purposes of
12617                    // filtering, because there may be no way for the user to
12618                    // actually re-launch them.
12619                    return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
12620                            && ps.getStopped(userId);
12621                }
12622            }
12623            return false;
12624        }
12625
12626        @Override
12627        protected boolean isPackageForFilter(String packageName,
12628                PackageParser.ServiceIntentInfo info) {
12629            return packageName.equals(info.service.owner.packageName);
12630        }
12631
12632        @Override
12633        protected ResolveInfo newResult(PackageParser.ServiceIntentInfo filter,
12634                int match, int userId) {
12635            if (!sUserManager.exists(userId)) return null;
12636            final PackageParser.ServiceIntentInfo info = (PackageParser.ServiceIntentInfo)filter;
12637            if (!mSettings.isEnabledAndMatchLPr(info.service.info, mFlags, userId)) {
12638                return null;
12639            }
12640            final PackageParser.Service service = info.service;
12641            PackageSetting ps = (PackageSetting) service.owner.mExtras;
12642            if (ps == null) {
12643                return null;
12644            }
12645            final PackageUserState userState = ps.readUserState(userId);
12646            ServiceInfo si = PackageParser.generateServiceInfo(service, mFlags,
12647                    userState, userId);
12648            if (si == null) {
12649                return null;
12650            }
12651            final boolean matchVisibleToInstantApp =
12652                    (mFlags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
12653            final boolean isInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0;
12654            // throw out filters that aren't visible to ephemeral apps
12655            if (matchVisibleToInstantApp
12656                    && !(info.isVisibleToInstantApp() || userState.instantApp)) {
12657                return null;
12658            }
12659            // throw out ephemeral filters if we're not explicitly requesting them
12660            if (!isInstantApp && userState.instantApp) {
12661                return null;
12662            }
12663            // throw out instant app filters if updates are available; will trigger
12664            // instant app resolution
12665            if (userState.instantApp && ps.isUpdateAvailable()) {
12666                return null;
12667            }
12668            final ResolveInfo res = new ResolveInfo();
12669            res.serviceInfo = si;
12670            if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
12671                res.filter = filter;
12672            }
12673            res.priority = info.getPriority();
12674            res.preferredOrder = service.owner.mPreferredOrder;
12675            res.match = match;
12676            res.isDefault = info.hasDefault;
12677            res.labelRes = info.labelRes;
12678            res.nonLocalizedLabel = info.nonLocalizedLabel;
12679            res.icon = info.icon;
12680            res.system = res.serviceInfo.applicationInfo.isSystemApp();
12681            return res;
12682        }
12683
12684        @Override
12685        protected void sortResults(List<ResolveInfo> results) {
12686            Collections.sort(results, mResolvePrioritySorter);
12687        }
12688
12689        @Override
12690        protected void dumpFilter(PrintWriter out, String prefix,
12691                PackageParser.ServiceIntentInfo filter) {
12692            out.print(prefix); out.print(
12693                    Integer.toHexString(System.identityHashCode(filter.service)));
12694                    out.print(' ');
12695                    filter.service.printComponentShortName(out);
12696                    out.print(" filter ");
12697                    out.println(Integer.toHexString(System.identityHashCode(filter)));
12698        }
12699
12700        @Override
12701        protected Object filterToLabel(PackageParser.ServiceIntentInfo filter) {
12702            return filter.service;
12703        }
12704
12705        protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
12706            PackageParser.Service service = (PackageParser.Service)label;
12707            out.print(prefix); out.print(
12708                    Integer.toHexString(System.identityHashCode(service)));
12709                    out.print(' ');
12710                    service.printComponentShortName(out);
12711            if (count > 1) {
12712                out.print(" ("); out.print(count); out.print(" filters)");
12713            }
12714            out.println();
12715        }
12716
12717//        List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) {
12718//            final Iterator<ResolveInfo> i = resolveInfoList.iterator();
12719//            final List<ResolveInfo> retList = Lists.newArrayList();
12720//            while (i.hasNext()) {
12721//                final ResolveInfo resolveInfo = (ResolveInfo) i;
12722//                if (isEnabledLP(resolveInfo.serviceInfo)) {
12723//                    retList.add(resolveInfo);
12724//                }
12725//            }
12726//            return retList;
12727//        }
12728
12729        // Keys are String (activity class name), values are Activity.
12730        private final ArrayMap<ComponentName, PackageParser.Service> mServices
12731                = new ArrayMap<ComponentName, PackageParser.Service>();
12732        private int mFlags;
12733    }
12734
12735    private final class ProviderIntentResolver
12736            extends IntentResolver<PackageParser.ProviderIntentInfo, ResolveInfo> {
12737        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
12738                boolean defaultOnly, int userId) {
12739            mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
12740            return super.queryIntent(intent, resolvedType, defaultOnly, userId);
12741        }
12742
12743        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
12744                int userId) {
12745            if (!sUserManager.exists(userId))
12746                return null;
12747            mFlags = flags;
12748            return super.queryIntent(intent, resolvedType,
12749                    (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
12750                    userId);
12751        }
12752
12753        public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
12754                int flags, ArrayList<PackageParser.Provider> packageProviders, int userId) {
12755            if (!sUserManager.exists(userId))
12756                return null;
12757            if (packageProviders == null) {
12758                return null;
12759            }
12760            mFlags = flags;
12761            final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0;
12762            final int N = packageProviders.size();
12763            ArrayList<PackageParser.ProviderIntentInfo[]> listCut =
12764                    new ArrayList<PackageParser.ProviderIntentInfo[]>(N);
12765
12766            ArrayList<PackageParser.ProviderIntentInfo> intentFilters;
12767            for (int i = 0; i < N; ++i) {
12768                intentFilters = packageProviders.get(i).intents;
12769                if (intentFilters != null && intentFilters.size() > 0) {
12770                    PackageParser.ProviderIntentInfo[] array =
12771                            new PackageParser.ProviderIntentInfo[intentFilters.size()];
12772                    intentFilters.toArray(array);
12773                    listCut.add(array);
12774                }
12775            }
12776            return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
12777        }
12778
12779        public final void addProvider(PackageParser.Provider p) {
12780            if (mProviders.containsKey(p.getComponentName())) {
12781                Slog.w(TAG, "Provider " + p.getComponentName() + " already defined; ignoring");
12782                return;
12783            }
12784
12785            mProviders.put(p.getComponentName(), p);
12786            if (DEBUG_SHOW_INFO) {
12787                Log.v(TAG, "  "
12788                        + (p.info.nonLocalizedLabel != null
12789                                ? p.info.nonLocalizedLabel : p.info.name) + ":");
12790                Log.v(TAG, "    Class=" + p.info.name);
12791            }
12792            final int NI = p.intents.size();
12793            int j;
12794            for (j = 0; j < NI; j++) {
12795                PackageParser.ProviderIntentInfo intent = p.intents.get(j);
12796                if (DEBUG_SHOW_INFO) {
12797                    Log.v(TAG, "    IntentFilter:");
12798                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
12799                }
12800                if (!intent.debugCheck()) {
12801                    Log.w(TAG, "==> For Provider " + p.info.name);
12802                }
12803                addFilter(intent);
12804            }
12805        }
12806
12807        public final void removeProvider(PackageParser.Provider p) {
12808            mProviders.remove(p.getComponentName());
12809            if (DEBUG_SHOW_INFO) {
12810                Log.v(TAG, "  " + (p.info.nonLocalizedLabel != null
12811                        ? p.info.nonLocalizedLabel : p.info.name) + ":");
12812                Log.v(TAG, "    Class=" + p.info.name);
12813            }
12814            final int NI = p.intents.size();
12815            int j;
12816            for (j = 0; j < NI; j++) {
12817                PackageParser.ProviderIntentInfo intent = p.intents.get(j);
12818                if (DEBUG_SHOW_INFO) {
12819                    Log.v(TAG, "    IntentFilter:");
12820                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
12821                }
12822                removeFilter(intent);
12823            }
12824        }
12825
12826        @Override
12827        protected boolean allowFilterResult(
12828                PackageParser.ProviderIntentInfo filter, List<ResolveInfo> dest) {
12829            ProviderInfo filterPi = filter.provider.info;
12830            for (int i = dest.size() - 1; i >= 0; i--) {
12831                ProviderInfo destPi = dest.get(i).providerInfo;
12832                if (destPi.name == filterPi.name
12833                        && destPi.packageName == filterPi.packageName) {
12834                    return false;
12835                }
12836            }
12837            return true;
12838        }
12839
12840        @Override
12841        protected PackageParser.ProviderIntentInfo[] newArray(int size) {
12842            return new PackageParser.ProviderIntentInfo[size];
12843        }
12844
12845        @Override
12846        protected boolean isFilterStopped(PackageParser.ProviderIntentInfo filter, int userId) {
12847            if (!sUserManager.exists(userId))
12848                return true;
12849            PackageParser.Package p = filter.provider.owner;
12850            if (p != null) {
12851                PackageSetting ps = (PackageSetting) p.mExtras;
12852                if (ps != null) {
12853                    // System apps are never considered stopped for purposes of
12854                    // filtering, because there may be no way for the user to
12855                    // actually re-launch them.
12856                    return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
12857                            && ps.getStopped(userId);
12858                }
12859            }
12860            return false;
12861        }
12862
12863        @Override
12864        protected boolean isPackageForFilter(String packageName,
12865                PackageParser.ProviderIntentInfo info) {
12866            return packageName.equals(info.provider.owner.packageName);
12867        }
12868
12869        @Override
12870        protected ResolveInfo newResult(PackageParser.ProviderIntentInfo filter,
12871                int match, int userId) {
12872            if (!sUserManager.exists(userId))
12873                return null;
12874            final PackageParser.ProviderIntentInfo info = filter;
12875            if (!mSettings.isEnabledAndMatchLPr(info.provider.info, mFlags, userId)) {
12876                return null;
12877            }
12878            final PackageParser.Provider provider = info.provider;
12879            PackageSetting ps = (PackageSetting) provider.owner.mExtras;
12880            if (ps == null) {
12881                return null;
12882            }
12883            final PackageUserState userState = ps.readUserState(userId);
12884            final boolean matchVisibleToInstantApp =
12885                    (mFlags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
12886            final boolean isInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0;
12887            // throw out filters that aren't visible to instant applications
12888            if (matchVisibleToInstantApp
12889                    && !(info.isVisibleToInstantApp() || userState.instantApp)) {
12890                return null;
12891            }
12892            // throw out instant application filters if we're not explicitly requesting them
12893            if (!isInstantApp && userState.instantApp) {
12894                return null;
12895            }
12896            // throw out instant application filters if updates are available; will trigger
12897            // instant application resolution
12898            if (userState.instantApp && ps.isUpdateAvailable()) {
12899                return null;
12900            }
12901            ProviderInfo pi = PackageParser.generateProviderInfo(provider, mFlags,
12902                    userState, userId);
12903            if (pi == null) {
12904                return null;
12905            }
12906            final ResolveInfo res = new ResolveInfo();
12907            res.providerInfo = pi;
12908            if ((mFlags & PackageManager.GET_RESOLVED_FILTER) != 0) {
12909                res.filter = filter;
12910            }
12911            res.priority = info.getPriority();
12912            res.preferredOrder = provider.owner.mPreferredOrder;
12913            res.match = match;
12914            res.isDefault = info.hasDefault;
12915            res.labelRes = info.labelRes;
12916            res.nonLocalizedLabel = info.nonLocalizedLabel;
12917            res.icon = info.icon;
12918            res.system = res.providerInfo.applicationInfo.isSystemApp();
12919            return res;
12920        }
12921
12922        @Override
12923        protected void sortResults(List<ResolveInfo> results) {
12924            Collections.sort(results, mResolvePrioritySorter);
12925        }
12926
12927        @Override
12928        protected void dumpFilter(PrintWriter out, String prefix,
12929                PackageParser.ProviderIntentInfo filter) {
12930            out.print(prefix);
12931            out.print(
12932                    Integer.toHexString(System.identityHashCode(filter.provider)));
12933            out.print(' ');
12934            filter.provider.printComponentShortName(out);
12935            out.print(" filter ");
12936            out.println(Integer.toHexString(System.identityHashCode(filter)));
12937        }
12938
12939        @Override
12940        protected Object filterToLabel(PackageParser.ProviderIntentInfo filter) {
12941            return filter.provider;
12942        }
12943
12944        protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
12945            PackageParser.Provider provider = (PackageParser.Provider)label;
12946            out.print(prefix); out.print(
12947                    Integer.toHexString(System.identityHashCode(provider)));
12948                    out.print(' ');
12949                    provider.printComponentShortName(out);
12950            if (count > 1) {
12951                out.print(" ("); out.print(count); out.print(" filters)");
12952            }
12953            out.println();
12954        }
12955
12956        private final ArrayMap<ComponentName, PackageParser.Provider> mProviders
12957                = new ArrayMap<ComponentName, PackageParser.Provider>();
12958        private int mFlags;
12959    }
12960
12961    static final class EphemeralIntentResolver
12962            extends IntentResolver<AuxiliaryResolveInfo, AuxiliaryResolveInfo> {
12963        /**
12964         * The result that has the highest defined order. Ordering applies on a
12965         * per-package basis. Mapping is from package name to Pair of order and
12966         * EphemeralResolveInfo.
12967         * <p>
12968         * NOTE: This is implemented as a field variable for convenience and efficiency.
12969         * By having a field variable, we're able to track filter ordering as soon as
12970         * a non-zero order is defined. Otherwise, multiple loops across the result set
12971         * would be needed to apply ordering. If the intent resolver becomes re-entrant,
12972         * this needs to be contained entirely within {@link #filterResults}.
12973         */
12974        final ArrayMap<String, Pair<Integer, InstantAppResolveInfo>> mOrderResult = new ArrayMap<>();
12975
12976        @Override
12977        protected AuxiliaryResolveInfo[] newArray(int size) {
12978            return new AuxiliaryResolveInfo[size];
12979        }
12980
12981        @Override
12982        protected boolean isPackageForFilter(String packageName, AuxiliaryResolveInfo responseObj) {
12983            return true;
12984        }
12985
12986        @Override
12987        protected AuxiliaryResolveInfo newResult(AuxiliaryResolveInfo responseObj, int match,
12988                int userId) {
12989            if (!sUserManager.exists(userId)) {
12990                return null;
12991            }
12992            final String packageName = responseObj.resolveInfo.getPackageName();
12993            final Integer order = responseObj.getOrder();
12994            final Pair<Integer, InstantAppResolveInfo> lastOrderResult =
12995                    mOrderResult.get(packageName);
12996            // ordering is enabled and this item's order isn't high enough
12997            if (lastOrderResult != null && lastOrderResult.first >= order) {
12998                return null;
12999            }
13000            final InstantAppResolveInfo res = responseObj.resolveInfo;
13001            if (order > 0) {
13002                // non-zero order, enable ordering
13003                mOrderResult.put(packageName, new Pair<>(order, res));
13004            }
13005            return responseObj;
13006        }
13007
13008        @Override
13009        protected void filterResults(List<AuxiliaryResolveInfo> results) {
13010            // only do work if ordering is enabled [most of the time it won't be]
13011            if (mOrderResult.size() == 0) {
13012                return;
13013            }
13014            int resultSize = results.size();
13015            for (int i = 0; i < resultSize; i++) {
13016                final InstantAppResolveInfo info = results.get(i).resolveInfo;
13017                final String packageName = info.getPackageName();
13018                final Pair<Integer, InstantAppResolveInfo> savedInfo = mOrderResult.get(packageName);
13019                if (savedInfo == null) {
13020                    // package doesn't having ordering
13021                    continue;
13022                }
13023                if (savedInfo.second == info) {
13024                    // circled back to the highest ordered item; remove from order list
13025                    mOrderResult.remove(savedInfo);
13026                    if (mOrderResult.size() == 0) {
13027                        // no more ordered items
13028                        break;
13029                    }
13030                    continue;
13031                }
13032                // item has a worse order, remove it from the result list
13033                results.remove(i);
13034                resultSize--;
13035                i--;
13036            }
13037        }
13038    }
13039
13040    private static final Comparator<ResolveInfo> mResolvePrioritySorter =
13041            new Comparator<ResolveInfo>() {
13042        public int compare(ResolveInfo r1, ResolveInfo r2) {
13043            int v1 = r1.priority;
13044            int v2 = r2.priority;
13045            //System.out.println("Comparing: q1=" + q1 + " q2=" + q2);
13046            if (v1 != v2) {
13047                return (v1 > v2) ? -1 : 1;
13048            }
13049            v1 = r1.preferredOrder;
13050            v2 = r2.preferredOrder;
13051            if (v1 != v2) {
13052                return (v1 > v2) ? -1 : 1;
13053            }
13054            if (r1.isDefault != r2.isDefault) {
13055                return r1.isDefault ? -1 : 1;
13056            }
13057            v1 = r1.match;
13058            v2 = r2.match;
13059            //System.out.println("Comparing: m1=" + m1 + " m2=" + m2);
13060            if (v1 != v2) {
13061                return (v1 > v2) ? -1 : 1;
13062            }
13063            if (r1.system != r2.system) {
13064                return r1.system ? -1 : 1;
13065            }
13066            if (r1.activityInfo != null) {
13067                return r1.activityInfo.packageName.compareTo(r2.activityInfo.packageName);
13068            }
13069            if (r1.serviceInfo != null) {
13070                return r1.serviceInfo.packageName.compareTo(r2.serviceInfo.packageName);
13071            }
13072            if (r1.providerInfo != null) {
13073                return r1.providerInfo.packageName.compareTo(r2.providerInfo.packageName);
13074            }
13075            return 0;
13076        }
13077    };
13078
13079    private static final Comparator<ProviderInfo> mProviderInitOrderSorter =
13080            new Comparator<ProviderInfo>() {
13081        public int compare(ProviderInfo p1, ProviderInfo p2) {
13082            final int v1 = p1.initOrder;
13083            final int v2 = p2.initOrder;
13084            return (v1 > v2) ? -1 : ((v1 < v2) ? 1 : 0);
13085        }
13086    };
13087
13088    final void sendPackageBroadcast(final String action, final String pkg, final Bundle extras,
13089            final int flags, final String targetPkg, final IIntentReceiver finishedReceiver,
13090            final int[] userIds) {
13091        mHandler.post(new Runnable() {
13092            @Override
13093            public void run() {
13094                try {
13095                    final IActivityManager am = ActivityManager.getService();
13096                    if (am == null) return;
13097                    final int[] resolvedUserIds;
13098                    if (userIds == null) {
13099                        resolvedUserIds = am.getRunningUserIds();
13100                    } else {
13101                        resolvedUserIds = userIds;
13102                    }
13103                    for (int id : resolvedUserIds) {
13104                        final Intent intent = new Intent(action,
13105                                pkg != null ? Uri.fromParts(PACKAGE_SCHEME, pkg, null) : null);
13106                        if (extras != null) {
13107                            intent.putExtras(extras);
13108                        }
13109                        if (targetPkg != null) {
13110                            intent.setPackage(targetPkg);
13111                        }
13112                        // Modify the UID when posting to other users
13113                        int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
13114                        if (uid > 0 && UserHandle.getUserId(uid) != id) {
13115                            uid = UserHandle.getUid(id, UserHandle.getAppId(uid));
13116                            intent.putExtra(Intent.EXTRA_UID, uid);
13117                        }
13118                        intent.putExtra(Intent.EXTRA_USER_HANDLE, id);
13119                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT | flags);
13120                        if (DEBUG_BROADCASTS) {
13121                            RuntimeException here = new RuntimeException("here");
13122                            here.fillInStackTrace();
13123                            Slog.d(TAG, "Sending to user " + id + ": "
13124                                    + intent.toShortString(false, true, false, false)
13125                                    + " " + intent.getExtras(), here);
13126                        }
13127                        am.broadcastIntent(null, intent, null, finishedReceiver,
13128                                0, null, null, null, android.app.AppOpsManager.OP_NONE,
13129                                null, finishedReceiver != null, false, id);
13130                    }
13131                } catch (RemoteException ex) {
13132                }
13133            }
13134        });
13135    }
13136
13137    /**
13138     * Check if the external storage media is available. This is true if there
13139     * is a mounted external storage medium or if the external storage is
13140     * emulated.
13141     */
13142    private boolean isExternalMediaAvailable() {
13143        return mMediaMounted || Environment.isExternalStorageEmulated();
13144    }
13145
13146    @Override
13147    public PackageCleanItem nextPackageToClean(PackageCleanItem lastPackage) {
13148        // writer
13149        synchronized (mPackages) {
13150            if (!isExternalMediaAvailable()) {
13151                // If the external storage is no longer mounted at this point,
13152                // the caller may not have been able to delete all of this
13153                // packages files and can not delete any more.  Bail.
13154                return null;
13155            }
13156            final ArrayList<PackageCleanItem> pkgs = mSettings.mPackagesToBeCleaned;
13157            if (lastPackage != null) {
13158                pkgs.remove(lastPackage);
13159            }
13160            if (pkgs.size() > 0) {
13161                return pkgs.get(0);
13162            }
13163        }
13164        return null;
13165    }
13166
13167    void schedulePackageCleaning(String packageName, int userId, boolean andCode) {
13168        final Message msg = mHandler.obtainMessage(START_CLEANING_PACKAGE,
13169                userId, andCode ? 1 : 0, packageName);
13170        if (mSystemReady) {
13171            msg.sendToTarget();
13172        } else {
13173            if (mPostSystemReadyMessages == null) {
13174                mPostSystemReadyMessages = new ArrayList<>();
13175            }
13176            mPostSystemReadyMessages.add(msg);
13177        }
13178    }
13179
13180    void startCleaningPackages() {
13181        // reader
13182        if (!isExternalMediaAvailable()) {
13183            return;
13184        }
13185        synchronized (mPackages) {
13186            if (mSettings.mPackagesToBeCleaned.isEmpty()) {
13187                return;
13188            }
13189        }
13190        Intent intent = new Intent(PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE);
13191        intent.setComponent(DEFAULT_CONTAINER_COMPONENT);
13192        IActivityManager am = ActivityManager.getService();
13193        if (am != null) {
13194            int dcsUid = -1;
13195            synchronized (mPackages) {
13196                if (!mDefaultContainerWhitelisted) {
13197                    mDefaultContainerWhitelisted = true;
13198                    PackageSetting ps = mSettings.mPackages.get(DEFAULT_CONTAINER_PACKAGE);
13199                    dcsUid = UserHandle.getUid(UserHandle.USER_SYSTEM, ps.appId);
13200                }
13201            }
13202            try {
13203                if (dcsUid > 0) {
13204                    am.backgroundWhitelistUid(dcsUid);
13205                }
13206                am.startService(null, intent, null, -1, null, false, mContext.getOpPackageName(),
13207                        UserHandle.USER_SYSTEM);
13208            } catch (RemoteException e) {
13209            }
13210        }
13211    }
13212
13213    @Override
13214    public void installPackageAsUser(String originPath, IPackageInstallObserver2 observer,
13215            int installFlags, String installerPackageName, int userId) {
13216        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null);
13217
13218        final int callingUid = Binder.getCallingUid();
13219        enforceCrossUserPermission(callingUid, userId,
13220                true /* requireFullPermission */, true /* checkShell */, "installPackageAsUser");
13221
13222        if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
13223            try {
13224                if (observer != null) {
13225                    observer.onPackageInstalled("", INSTALL_FAILED_USER_RESTRICTED, null, null);
13226                }
13227            } catch (RemoteException re) {
13228            }
13229            return;
13230        }
13231
13232        if ((callingUid == Process.SHELL_UID) || (callingUid == Process.ROOT_UID)) {
13233            installFlags |= PackageManager.INSTALL_FROM_ADB;
13234
13235        } else {
13236            // Caller holds INSTALL_PACKAGES permission, so we're less strict
13237            // about installerPackageName.
13238
13239            installFlags &= ~PackageManager.INSTALL_FROM_ADB;
13240            installFlags &= ~PackageManager.INSTALL_ALL_USERS;
13241        }
13242
13243        UserHandle user;
13244        if ((installFlags & PackageManager.INSTALL_ALL_USERS) != 0) {
13245            user = UserHandle.ALL;
13246        } else {
13247            user = new UserHandle(userId);
13248        }
13249
13250        // Only system components can circumvent runtime permissions when installing.
13251        if ((installFlags & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0
13252                && mContext.checkCallingOrSelfPermission(Manifest.permission
13253                .INSTALL_GRANT_RUNTIME_PERMISSIONS) == PackageManager.PERMISSION_DENIED) {
13254            throw new SecurityException("You need the "
13255                    + "android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS permission "
13256                    + "to use the PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS flag");
13257        }
13258
13259        if ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0
13260                || (installFlags & PackageManager.INSTALL_EXTERNAL) != 0) {
13261            throw new IllegalArgumentException(
13262                    "New installs into ASEC containers no longer supported");
13263        }
13264
13265        final File originFile = new File(originPath);
13266        final OriginInfo origin = OriginInfo.fromUntrustedFile(originFile);
13267
13268        final Message msg = mHandler.obtainMessage(INIT_COPY);
13269        final VerificationInfo verificationInfo = new VerificationInfo(
13270                null /*originatingUri*/, null /*referrer*/, -1 /*originatingUid*/, callingUid);
13271        final InstallParams params = new InstallParams(origin, null /*moveInfo*/, observer,
13272                installFlags, installerPackageName, null /*volumeUuid*/, verificationInfo, user,
13273                null /*packageAbiOverride*/, null /*grantedPermissions*/,
13274                null /*certificates*/, PackageManager.INSTALL_REASON_UNKNOWN);
13275        params.setTraceMethod("installAsUser").setTraceCookie(System.identityHashCode(params));
13276        msg.obj = params;
13277
13278        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installAsUser",
13279                System.identityHashCode(msg.obj));
13280        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
13281                System.identityHashCode(msg.obj));
13282
13283        mHandler.sendMessage(msg);
13284    }
13285
13286
13287    /**
13288     * Ensure that the install reason matches what we know about the package installer (e.g. whether
13289     * it is acting on behalf on an enterprise or the user).
13290     *
13291     * Note that the ordering of the conditionals in this method is important. The checks we perform
13292     * are as follows, in this order:
13293     *
13294     * 1) If the install is being performed by a system app, we can trust the app to have set the
13295     *    install reason correctly. Thus, we pass through the install reason unchanged, no matter
13296     *    what it is.
13297     * 2) If the install is being performed by a device or profile owner app, the install reason
13298     *    should be enterprise policy. However, we cannot be sure that the device or profile owner
13299     *    set the install reason correctly. If the app targets an older SDK version where install
13300     *    reasons did not exist yet, or if the app author simply forgot, the install reason may be
13301     *    unset or wrong. Thus, we force the install reason to be enterprise policy.
13302     * 3) In all other cases, the install is being performed by a regular app that is neither part
13303     *    of the system nor a device or profile owner. We have no reason to believe that this app is
13304     *    acting on behalf of the enterprise admin. Thus, we check whether the install reason was
13305     *    set to enterprise policy and if so, change it to unknown instead.
13306     */
13307    private int fixUpInstallReason(String installerPackageName, int installerUid,
13308            int installReason) {
13309        if (checkUidPermission(android.Manifest.permission.INSTALL_PACKAGES, installerUid)
13310                == PERMISSION_GRANTED) {
13311            // If the install is being performed by a system app, we trust that app to have set the
13312            // install reason correctly.
13313            return installReason;
13314        }
13315
13316        final IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
13317            ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
13318        if (dpm != null) {
13319            ComponentName owner = null;
13320            try {
13321                owner = dpm.getDeviceOwnerComponent(true /* callingUserOnly */);
13322                if (owner == null) {
13323                    owner = dpm.getProfileOwner(UserHandle.getUserId(installerUid));
13324                }
13325            } catch (RemoteException e) {
13326            }
13327            if (owner != null && owner.getPackageName().equals(installerPackageName)) {
13328                // If the install is being performed by a device or profile owner, the install
13329                // reason should be enterprise policy.
13330                return PackageManager.INSTALL_REASON_POLICY;
13331            }
13332        }
13333
13334        if (installReason == PackageManager.INSTALL_REASON_POLICY) {
13335            // If the install is being performed by a regular app (i.e. neither system app nor
13336            // device or profile owner), we have no reason to believe that the app is acting on
13337            // behalf of an enterprise. If the app set the install reason to enterprise policy,
13338            // change it to unknown instead.
13339            return PackageManager.INSTALL_REASON_UNKNOWN;
13340        }
13341
13342        // If the install is being performed by a regular app and the install reason was set to any
13343        // value but enterprise policy, leave the install reason unchanged.
13344        return installReason;
13345    }
13346
13347    void installStage(String packageName, File stagedDir, String stagedCid,
13348            IPackageInstallObserver2 observer, PackageInstaller.SessionParams sessionParams,
13349            String installerPackageName, int installerUid, UserHandle user,
13350            Certificate[][] certificates) {
13351        if (DEBUG_EPHEMERAL) {
13352            if ((sessionParams.installFlags & PackageManager.INSTALL_INSTANT_APP) != 0) {
13353                Slog.d(TAG, "Ephemeral install of " + packageName);
13354            }
13355        }
13356        final VerificationInfo verificationInfo = new VerificationInfo(
13357                sessionParams.originatingUri, sessionParams.referrerUri,
13358                sessionParams.originatingUid, installerUid);
13359
13360        final OriginInfo origin;
13361        if (stagedDir != null) {
13362            origin = OriginInfo.fromStagedFile(stagedDir);
13363        } else {
13364            origin = OriginInfo.fromStagedContainer(stagedCid);
13365        }
13366
13367        final Message msg = mHandler.obtainMessage(INIT_COPY);
13368        final int installReason = fixUpInstallReason(installerPackageName, installerUid,
13369                sessionParams.installReason);
13370        final InstallParams params = new InstallParams(origin, null, observer,
13371                sessionParams.installFlags, installerPackageName, sessionParams.volumeUuid,
13372                verificationInfo, user, sessionParams.abiOverride,
13373                sessionParams.grantedRuntimePermissions, certificates, installReason);
13374        params.setTraceMethod("installStage").setTraceCookie(System.identityHashCode(params));
13375        msg.obj = params;
13376
13377        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installStage",
13378                System.identityHashCode(msg.obj));
13379        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
13380                System.identityHashCode(msg.obj));
13381
13382        mHandler.sendMessage(msg);
13383    }
13384
13385    private void sendPackageAddedForUser(String packageName, PackageSetting pkgSetting,
13386            int userId) {
13387        final boolean isSystem = isSystemApp(pkgSetting) || isUpdatedSystemApp(pkgSetting);
13388        sendPackageAddedForNewUsers(packageName, isSystem, pkgSetting.appId, userId);
13389    }
13390
13391    private void sendPackageAddedForNewUsers(String packageName, boolean isSystem,
13392            int appId, int... userIds) {
13393        if (ArrayUtils.isEmpty(userIds)) {
13394            return;
13395        }
13396        Bundle extras = new Bundle(1);
13397        // Set to UID of the first user, EXTRA_UID is automatically updated in sendPackageBroadcast
13398        extras.putInt(Intent.EXTRA_UID, UserHandle.getUid(userIds[0], appId));
13399
13400        sendPackageBroadcast(Intent.ACTION_PACKAGE_FIRST_ADDED, packageName,
13401                extras, Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND, null, null, userIds);
13402        sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
13403                extras, 0, null, null, userIds);
13404        if (isSystem) {
13405            mHandler.post(() -> {
13406                        for (int userId : userIds) {
13407                            sendBootCompletedBroadcastToSystemApp(packageName, userId);
13408                        }
13409                    }
13410            );
13411        }
13412    }
13413
13414    /**
13415     * The just-installed/enabled app is bundled on the system, so presumed to be able to run
13416     * automatically without needing an explicit launch.
13417     * Send it a LOCKED_BOOT_COMPLETED/BOOT_COMPLETED if it would ordinarily have gotten ones.
13418     */
13419    private void sendBootCompletedBroadcastToSystemApp(String packageName, int userId) {
13420        // If user is not running, the app didn't miss any broadcast
13421        if (!mUserManagerInternal.isUserRunning(userId)) {
13422            return;
13423        }
13424        final IActivityManager am = ActivityManager.getService();
13425        try {
13426            // Deliver LOCKED_BOOT_COMPLETED first
13427            Intent lockedBcIntent = new Intent(Intent.ACTION_LOCKED_BOOT_COMPLETED)
13428                    .setPackage(packageName);
13429            final String[] requiredPermissions = {Manifest.permission.RECEIVE_BOOT_COMPLETED};
13430            am.broadcastIntent(null, lockedBcIntent, null, null, 0, null, null, requiredPermissions,
13431                    android.app.AppOpsManager.OP_NONE, null, false, false, userId);
13432
13433            // Deliver BOOT_COMPLETED only if user is unlocked
13434            if (mUserManagerInternal.isUserUnlockingOrUnlocked(userId)) {
13435                Intent bcIntent = new Intent(Intent.ACTION_BOOT_COMPLETED).setPackage(packageName);
13436                am.broadcastIntent(null, bcIntent, null, null, 0, null, null, requiredPermissions,
13437                        android.app.AppOpsManager.OP_NONE, null, false, false, userId);
13438            }
13439        } catch (RemoteException e) {
13440            throw e.rethrowFromSystemServer();
13441        }
13442    }
13443
13444    @Override
13445    public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden,
13446            int userId) {
13447        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
13448        PackageSetting pkgSetting;
13449        final int uid = Binder.getCallingUid();
13450        enforceCrossUserPermission(uid, userId,
13451                true /* requireFullPermission */, true /* checkShell */,
13452                "setApplicationHiddenSetting for user " + userId);
13453
13454        if (hidden && isPackageDeviceAdmin(packageName, userId)) {
13455            Slog.w(TAG, "Not hiding package " + packageName + ": has active device admin");
13456            return false;
13457        }
13458
13459        long callingId = Binder.clearCallingIdentity();
13460        try {
13461            boolean sendAdded = false;
13462            boolean sendRemoved = false;
13463            // writer
13464            synchronized (mPackages) {
13465                pkgSetting = mSettings.mPackages.get(packageName);
13466                if (pkgSetting == null) {
13467                    return false;
13468                }
13469                // Do not allow "android" is being disabled
13470                if ("android".equals(packageName)) {
13471                    Slog.w(TAG, "Cannot hide package: android");
13472                    return false;
13473                }
13474                // Cannot hide static shared libs as they are considered
13475                // a part of the using app (emulating static linking). Also
13476                // static libs are installed always on internal storage.
13477                PackageParser.Package pkg = mPackages.get(packageName);
13478                if (pkg != null && pkg.staticSharedLibName != null) {
13479                    Slog.w(TAG, "Cannot hide package: " + packageName
13480                            + " providing static shared library: "
13481                            + pkg.staticSharedLibName);
13482                    return false;
13483                }
13484                // Only allow protected packages to hide themselves.
13485                if (hidden && !UserHandle.isSameApp(uid, pkgSetting.appId)
13486                        && mProtectedPackages.isPackageStateProtected(userId, packageName)) {
13487                    Slog.w(TAG, "Not hiding protected package: " + packageName);
13488                    return false;
13489                }
13490
13491                if (pkgSetting.getHidden(userId) != hidden) {
13492                    pkgSetting.setHidden(hidden, userId);
13493                    mSettings.writePackageRestrictionsLPr(userId);
13494                    if (hidden) {
13495                        sendRemoved = true;
13496                    } else {
13497                        sendAdded = true;
13498                    }
13499                }
13500            }
13501            if (sendAdded) {
13502                sendPackageAddedForUser(packageName, pkgSetting, userId);
13503                return true;
13504            }
13505            if (sendRemoved) {
13506                killApplication(packageName, UserHandle.getUid(userId, pkgSetting.appId),
13507                        "hiding pkg");
13508                sendApplicationHiddenForUser(packageName, pkgSetting, userId);
13509                return true;
13510            }
13511        } finally {
13512            Binder.restoreCallingIdentity(callingId);
13513        }
13514        return false;
13515    }
13516
13517    private void sendApplicationHiddenForUser(String packageName, PackageSetting pkgSetting,
13518            int userId) {
13519        final PackageRemovedInfo info = new PackageRemovedInfo();
13520        info.removedPackage = packageName;
13521        info.removedUsers = new int[] {userId};
13522        info.broadcastUsers = new int[] {userId};
13523        info.uid = UserHandle.getUid(userId, pkgSetting.appId);
13524        info.sendPackageRemovedBroadcasts(true /*killApp*/);
13525    }
13526
13527    private void sendPackagesSuspendedForUser(String[] pkgList, int userId, boolean suspended) {
13528        if (pkgList.length > 0) {
13529            Bundle extras = new Bundle(1);
13530            extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
13531
13532            sendPackageBroadcast(
13533                    suspended ? Intent.ACTION_PACKAGES_SUSPENDED
13534                            : Intent.ACTION_PACKAGES_UNSUSPENDED,
13535                    null, extras, Intent.FLAG_RECEIVER_REGISTERED_ONLY, null, null,
13536                    new int[] {userId});
13537        }
13538    }
13539
13540    /**
13541     * Returns true if application is not found or there was an error. Otherwise it returns
13542     * the hidden state of the package for the given user.
13543     */
13544    @Override
13545    public boolean getApplicationHiddenSettingAsUser(String packageName, int userId) {
13546        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
13547        enforceCrossUserPermission(Binder.getCallingUid(), userId,
13548                true /* requireFullPermission */, false /* checkShell */,
13549                "getApplicationHidden for user " + userId);
13550        PackageSetting pkgSetting;
13551        long callingId = Binder.clearCallingIdentity();
13552        try {
13553            // writer
13554            synchronized (mPackages) {
13555                pkgSetting = mSettings.mPackages.get(packageName);
13556                if (pkgSetting == null) {
13557                    return true;
13558                }
13559                return pkgSetting.getHidden(userId);
13560            }
13561        } finally {
13562            Binder.restoreCallingIdentity(callingId);
13563        }
13564    }
13565
13566    /**
13567     * @hide
13568     */
13569    @Override
13570    public int installExistingPackageAsUser(String packageName, int userId, int installFlags,
13571            int installReason) {
13572        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES,
13573                null);
13574        PackageSetting pkgSetting;
13575        final int uid = Binder.getCallingUid();
13576        enforceCrossUserPermission(uid, userId,
13577                true /* requireFullPermission */, true /* checkShell */,
13578                "installExistingPackage for user " + userId);
13579        if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
13580            return PackageManager.INSTALL_FAILED_USER_RESTRICTED;
13581        }
13582
13583        long callingId = Binder.clearCallingIdentity();
13584        try {
13585            boolean installed = false;
13586            final boolean instantApp =
13587                    (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
13588            final boolean fullApp =
13589                    (installFlags & PackageManager.INSTALL_FULL_APP) != 0;
13590
13591            // writer
13592            synchronized (mPackages) {
13593                pkgSetting = mSettings.mPackages.get(packageName);
13594                if (pkgSetting == null) {
13595                    return PackageManager.INSTALL_FAILED_INVALID_URI;
13596                }
13597                if (!pkgSetting.getInstalled(userId)) {
13598                    pkgSetting.setInstalled(true, userId);
13599                    pkgSetting.setHidden(false, userId);
13600                    pkgSetting.setInstallReason(installReason, userId);
13601                    mSettings.writePackageRestrictionsLPr(userId);
13602                    mSettings.writeKernelMappingLPr(pkgSetting);
13603                    installed = true;
13604                } else if (fullApp && pkgSetting.getInstantApp(userId)) {
13605                    // upgrade app from instant to full; we don't allow app downgrade
13606                    installed = true;
13607                }
13608                setInstantAppForUser(pkgSetting, userId, instantApp, fullApp);
13609            }
13610
13611            if (installed) {
13612                if (pkgSetting.pkg != null) {
13613                    synchronized (mInstallLock) {
13614                        // We don't need to freeze for a brand new install
13615                        prepareAppDataAfterInstallLIF(pkgSetting.pkg);
13616                    }
13617                }
13618                sendPackageAddedForUser(packageName, pkgSetting, userId);
13619                synchronized (mPackages) {
13620                    updateSequenceNumberLP(packageName, new int[]{ userId });
13621                }
13622            }
13623        } finally {
13624            Binder.restoreCallingIdentity(callingId);
13625        }
13626
13627        return PackageManager.INSTALL_SUCCEEDED;
13628    }
13629
13630    void setInstantAppForUser(PackageSetting pkgSetting, int userId,
13631            boolean instantApp, boolean fullApp) {
13632        // no state specified; do nothing
13633        if (!instantApp && !fullApp) {
13634            return;
13635        }
13636        if (userId != UserHandle.USER_ALL) {
13637            if (instantApp && !pkgSetting.getInstantApp(userId)) {
13638                pkgSetting.setInstantApp(true /*instantApp*/, userId);
13639            } else if (fullApp && pkgSetting.getInstantApp(userId)) {
13640                pkgSetting.setInstantApp(false /*instantApp*/, userId);
13641            }
13642        } else {
13643            for (int currentUserId : sUserManager.getUserIds()) {
13644                if (instantApp && !pkgSetting.getInstantApp(currentUserId)) {
13645                    pkgSetting.setInstantApp(true /*instantApp*/, currentUserId);
13646                } else if (fullApp && pkgSetting.getInstantApp(currentUserId)) {
13647                    pkgSetting.setInstantApp(false /*instantApp*/, currentUserId);
13648                }
13649            }
13650        }
13651    }
13652
13653    boolean isUserRestricted(int userId, String restrictionKey) {
13654        Bundle restrictions = sUserManager.getUserRestrictions(userId);
13655        if (restrictions.getBoolean(restrictionKey, false)) {
13656            Log.w(TAG, "User is restricted: " + restrictionKey);
13657            return true;
13658        }
13659        return false;
13660    }
13661
13662    @Override
13663    public String[] setPackagesSuspendedAsUser(String[] packageNames, boolean suspended,
13664            int userId) {
13665        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
13666        enforceCrossUserPermission(Binder.getCallingUid(), userId,
13667                true /* requireFullPermission */, true /* checkShell */,
13668                "setPackagesSuspended for user " + userId);
13669
13670        if (ArrayUtils.isEmpty(packageNames)) {
13671            return packageNames;
13672        }
13673
13674        // List of package names for whom the suspended state has changed.
13675        List<String> changedPackages = new ArrayList<>(packageNames.length);
13676        // List of package names for whom the suspended state is not set as requested in this
13677        // method.
13678        List<String> unactionedPackages = new ArrayList<>(packageNames.length);
13679        long callingId = Binder.clearCallingIdentity();
13680        try {
13681            for (int i = 0; i < packageNames.length; i++) {
13682                String packageName = packageNames[i];
13683                boolean changed = false;
13684                final int appId;
13685                synchronized (mPackages) {
13686                    final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
13687                    if (pkgSetting == null) {
13688                        Slog.w(TAG, "Could not find package setting for package \"" + packageName
13689                                + "\". Skipping suspending/un-suspending.");
13690                        unactionedPackages.add(packageName);
13691                        continue;
13692                    }
13693                    appId = pkgSetting.appId;
13694                    if (pkgSetting.getSuspended(userId) != suspended) {
13695                        if (!canSuspendPackageForUserLocked(packageName, userId)) {
13696                            unactionedPackages.add(packageName);
13697                            continue;
13698                        }
13699                        pkgSetting.setSuspended(suspended, userId);
13700                        mSettings.writePackageRestrictionsLPr(userId);
13701                        changed = true;
13702                        changedPackages.add(packageName);
13703                    }
13704                }
13705
13706                if (changed && suspended) {
13707                    killApplication(packageName, UserHandle.getUid(userId, appId),
13708                            "suspending package");
13709                }
13710            }
13711        } finally {
13712            Binder.restoreCallingIdentity(callingId);
13713        }
13714
13715        if (!changedPackages.isEmpty()) {
13716            sendPackagesSuspendedForUser(changedPackages.toArray(
13717                    new String[changedPackages.size()]), userId, suspended);
13718        }
13719
13720        return unactionedPackages.toArray(new String[unactionedPackages.size()]);
13721    }
13722
13723    @Override
13724    public boolean isPackageSuspendedForUser(String packageName, int userId) {
13725        enforceCrossUserPermission(Binder.getCallingUid(), userId,
13726                true /* requireFullPermission */, false /* checkShell */,
13727                "isPackageSuspendedForUser for user " + userId);
13728        synchronized (mPackages) {
13729            final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
13730            if (pkgSetting == null) {
13731                throw new IllegalArgumentException("Unknown target package: " + packageName);
13732            }
13733            return pkgSetting.getSuspended(userId);
13734        }
13735    }
13736
13737    private boolean canSuspendPackageForUserLocked(String packageName, int userId) {
13738        if (isPackageDeviceAdmin(packageName, userId)) {
13739            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
13740                    + "\": has an active device admin");
13741            return false;
13742        }
13743
13744        String activeLauncherPackageName = getActiveLauncherPackageName(userId);
13745        if (packageName.equals(activeLauncherPackageName)) {
13746            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
13747                    + "\": contains the active launcher");
13748            return false;
13749        }
13750
13751        if (packageName.equals(mRequiredInstallerPackage)) {
13752            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
13753                    + "\": required for package installation");
13754            return false;
13755        }
13756
13757        if (packageName.equals(mRequiredUninstallerPackage)) {
13758            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
13759                    + "\": required for package uninstallation");
13760            return false;
13761        }
13762
13763        if (packageName.equals(mRequiredVerifierPackage)) {
13764            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
13765                    + "\": required for package verification");
13766            return false;
13767        }
13768
13769        if (packageName.equals(getDefaultDialerPackageName(userId))) {
13770            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
13771                    + "\": is the default dialer");
13772            return false;
13773        }
13774
13775        if (mProtectedPackages.isPackageStateProtected(userId, packageName)) {
13776            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
13777                    + "\": protected package");
13778            return false;
13779        }
13780
13781        // Cannot suspend static shared libs as they are considered
13782        // a part of the using app (emulating static linking). Also
13783        // static libs are installed always on internal storage.
13784        PackageParser.Package pkg = mPackages.get(packageName);
13785        if (pkg != null && pkg.applicationInfo.isStaticSharedLibrary()) {
13786            Slog.w(TAG, "Cannot suspend package: " + packageName
13787                    + " providing static shared library: "
13788                    + pkg.staticSharedLibName);
13789            return false;
13790        }
13791
13792        return true;
13793    }
13794
13795    private String getActiveLauncherPackageName(int userId) {
13796        Intent intent = new Intent(Intent.ACTION_MAIN);
13797        intent.addCategory(Intent.CATEGORY_HOME);
13798        ResolveInfo resolveInfo = resolveIntent(
13799                intent,
13800                intent.resolveTypeIfNeeded(mContext.getContentResolver()),
13801                PackageManager.MATCH_DEFAULT_ONLY,
13802                userId);
13803
13804        return resolveInfo == null ? null : resolveInfo.activityInfo.packageName;
13805    }
13806
13807    private String getDefaultDialerPackageName(int userId) {
13808        synchronized (mPackages) {
13809            return mSettings.getDefaultDialerPackageNameLPw(userId);
13810        }
13811    }
13812
13813    @Override
13814    public void verifyPendingInstall(int id, int verificationCode) throws RemoteException {
13815        mContext.enforceCallingOrSelfPermission(
13816                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
13817                "Only package verification agents can verify applications");
13818
13819        final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
13820        final PackageVerificationResponse response = new PackageVerificationResponse(
13821                verificationCode, Binder.getCallingUid());
13822        msg.arg1 = id;
13823        msg.obj = response;
13824        mHandler.sendMessage(msg);
13825    }
13826
13827    @Override
13828    public void extendVerificationTimeout(int id, int verificationCodeAtTimeout,
13829            long millisecondsToDelay) {
13830        mContext.enforceCallingOrSelfPermission(
13831                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
13832                "Only package verification agents can extend verification timeouts");
13833
13834        final PackageVerificationState state = mPendingVerification.get(id);
13835        final PackageVerificationResponse response = new PackageVerificationResponse(
13836                verificationCodeAtTimeout, Binder.getCallingUid());
13837
13838        if (millisecondsToDelay > PackageManager.MAXIMUM_VERIFICATION_TIMEOUT) {
13839            millisecondsToDelay = PackageManager.MAXIMUM_VERIFICATION_TIMEOUT;
13840        }
13841        if (millisecondsToDelay < 0) {
13842            millisecondsToDelay = 0;
13843        }
13844        if ((verificationCodeAtTimeout != PackageManager.VERIFICATION_ALLOW)
13845                && (verificationCodeAtTimeout != PackageManager.VERIFICATION_REJECT)) {
13846            verificationCodeAtTimeout = PackageManager.VERIFICATION_REJECT;
13847        }
13848
13849        if ((state != null) && !state.timeoutExtended()) {
13850            state.extendTimeout();
13851
13852            final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
13853            msg.arg1 = id;
13854            msg.obj = response;
13855            mHandler.sendMessageDelayed(msg, millisecondsToDelay);
13856        }
13857    }
13858
13859    private void broadcastPackageVerified(int verificationId, Uri packageUri,
13860            int verificationCode, UserHandle user) {
13861        final Intent intent = new Intent(Intent.ACTION_PACKAGE_VERIFIED);
13862        intent.setDataAndType(packageUri, PACKAGE_MIME_TYPE);
13863        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
13864        intent.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
13865        intent.putExtra(PackageManager.EXTRA_VERIFICATION_RESULT, verificationCode);
13866
13867        mContext.sendBroadcastAsUser(intent, user,
13868                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT);
13869    }
13870
13871    private ComponentName matchComponentForVerifier(String packageName,
13872            List<ResolveInfo> receivers) {
13873        ActivityInfo targetReceiver = null;
13874
13875        final int NR = receivers.size();
13876        for (int i = 0; i < NR; i++) {
13877            final ResolveInfo info = receivers.get(i);
13878            if (info.activityInfo == null) {
13879                continue;
13880            }
13881
13882            if (packageName.equals(info.activityInfo.packageName)) {
13883                targetReceiver = info.activityInfo;
13884                break;
13885            }
13886        }
13887
13888        if (targetReceiver == null) {
13889            return null;
13890        }
13891
13892        return new ComponentName(targetReceiver.packageName, targetReceiver.name);
13893    }
13894
13895    private List<ComponentName> matchVerifiers(PackageInfoLite pkgInfo,
13896            List<ResolveInfo> receivers, final PackageVerificationState verificationState) {
13897        if (pkgInfo.verifiers.length == 0) {
13898            return null;
13899        }
13900
13901        final int N = pkgInfo.verifiers.length;
13902        final List<ComponentName> sufficientVerifiers = new ArrayList<ComponentName>(N + 1);
13903        for (int i = 0; i < N; i++) {
13904            final VerifierInfo verifierInfo = pkgInfo.verifiers[i];
13905
13906            final ComponentName comp = matchComponentForVerifier(verifierInfo.packageName,
13907                    receivers);
13908            if (comp == null) {
13909                continue;
13910            }
13911
13912            final int verifierUid = getUidForVerifier(verifierInfo);
13913            if (verifierUid == -1) {
13914                continue;
13915            }
13916
13917            if (DEBUG_VERIFY) {
13918                Slog.d(TAG, "Added sufficient verifier " + verifierInfo.packageName
13919                        + " with the correct signature");
13920            }
13921            sufficientVerifiers.add(comp);
13922            verificationState.addSufficientVerifier(verifierUid);
13923        }
13924
13925        return sufficientVerifiers;
13926    }
13927
13928    private int getUidForVerifier(VerifierInfo verifierInfo) {
13929        synchronized (mPackages) {
13930            final PackageParser.Package pkg = mPackages.get(verifierInfo.packageName);
13931            if (pkg == null) {
13932                return -1;
13933            } else if (pkg.mSignatures.length != 1) {
13934                Slog.i(TAG, "Verifier package " + verifierInfo.packageName
13935                        + " has more than one signature; ignoring");
13936                return -1;
13937            }
13938
13939            /*
13940             * If the public key of the package's signature does not match
13941             * our expected public key, then this is a different package and
13942             * we should skip.
13943             */
13944
13945            final byte[] expectedPublicKey;
13946            try {
13947                final Signature verifierSig = pkg.mSignatures[0];
13948                final PublicKey publicKey = verifierSig.getPublicKey();
13949                expectedPublicKey = publicKey.getEncoded();
13950            } catch (CertificateException e) {
13951                return -1;
13952            }
13953
13954            final byte[] actualPublicKey = verifierInfo.publicKey.getEncoded();
13955
13956            if (!Arrays.equals(actualPublicKey, expectedPublicKey)) {
13957                Slog.i(TAG, "Verifier package " + verifierInfo.packageName
13958                        + " does not have the expected public key; ignoring");
13959                return -1;
13960            }
13961
13962            return pkg.applicationInfo.uid;
13963        }
13964    }
13965
13966    @Override
13967    public void finishPackageInstall(int token, boolean didLaunch) {
13968        enforceSystemOrRoot("Only the system is allowed to finish installs");
13969
13970        if (DEBUG_INSTALL) {
13971            Slog.v(TAG, "BM finishing package install for " + token);
13972        }
13973        Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "restore", token);
13974
13975        final Message msg = mHandler.obtainMessage(POST_INSTALL, token, didLaunch ? 1 : 0);
13976        mHandler.sendMessage(msg);
13977    }
13978
13979    /**
13980     * Get the verification agent timeout.
13981     *
13982     * @return verification timeout in milliseconds
13983     */
13984    private long getVerificationTimeout() {
13985        return android.provider.Settings.Global.getLong(mContext.getContentResolver(),
13986                android.provider.Settings.Global.PACKAGE_VERIFIER_TIMEOUT,
13987                DEFAULT_VERIFICATION_TIMEOUT);
13988    }
13989
13990    /**
13991     * Get the default verification agent response code.
13992     *
13993     * @return default verification response code
13994     */
13995    private int getDefaultVerificationResponse() {
13996        return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
13997                android.provider.Settings.Global.PACKAGE_VERIFIER_DEFAULT_RESPONSE,
13998                DEFAULT_VERIFICATION_RESPONSE);
13999    }
14000
14001    /**
14002     * Check whether or not package verification has been enabled.
14003     *
14004     * @return true if verification should be performed
14005     */
14006    private boolean isVerificationEnabled(int userId, int installFlags) {
14007        if (!DEFAULT_VERIFY_ENABLE) {
14008            return false;
14009        }
14010
14011        boolean ensureVerifyAppsEnabled = isUserRestricted(userId, UserManager.ENSURE_VERIFY_APPS);
14012
14013        // Check if installing from ADB
14014        if ((installFlags & PackageManager.INSTALL_FROM_ADB) != 0) {
14015            // Do not run verification in a test harness environment
14016            if (ActivityManager.isRunningInTestHarness()) {
14017                return false;
14018            }
14019            if (ensureVerifyAppsEnabled) {
14020                return true;
14021            }
14022            // Check if the developer does not want package verification for ADB installs
14023            if (android.provider.Settings.Global.getInt(mContext.getContentResolver(),
14024                    android.provider.Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, 1) == 0) {
14025                return false;
14026            }
14027        }
14028
14029        if (ensureVerifyAppsEnabled) {
14030            return true;
14031        }
14032
14033        return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
14034                android.provider.Settings.Global.PACKAGE_VERIFIER_ENABLE, 1) == 1;
14035    }
14036
14037    @Override
14038    public void verifyIntentFilter(int id, int verificationCode, List<String> failedDomains)
14039            throws RemoteException {
14040        mContext.enforceCallingOrSelfPermission(
14041                Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT,
14042                "Only intentfilter verification agents can verify applications");
14043
14044        final Message msg = mHandler.obtainMessage(INTENT_FILTER_VERIFIED);
14045        final IntentFilterVerificationResponse response = new IntentFilterVerificationResponse(
14046                Binder.getCallingUid(), verificationCode, failedDomains);
14047        msg.arg1 = id;
14048        msg.obj = response;
14049        mHandler.sendMessage(msg);
14050    }
14051
14052    @Override
14053    public int getIntentVerificationStatus(String packageName, int userId) {
14054        synchronized (mPackages) {
14055            return mSettings.getIntentFilterVerificationStatusLPr(packageName, userId);
14056        }
14057    }
14058
14059    @Override
14060    public boolean updateIntentVerificationStatus(String packageName, int status, int userId) {
14061        mContext.enforceCallingOrSelfPermission(
14062                android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
14063
14064        boolean result = false;
14065        synchronized (mPackages) {
14066            result = mSettings.updateIntentFilterVerificationStatusLPw(packageName, status, userId);
14067        }
14068        if (result) {
14069            scheduleWritePackageRestrictionsLocked(userId);
14070        }
14071        return result;
14072    }
14073
14074    @Override
14075    public @NonNull ParceledListSlice<IntentFilterVerificationInfo> getIntentFilterVerifications(
14076            String packageName) {
14077        synchronized (mPackages) {
14078            return new ParceledListSlice<>(mSettings.getIntentFilterVerificationsLPr(packageName));
14079        }
14080    }
14081
14082    @Override
14083    public @NonNull ParceledListSlice<IntentFilter> getAllIntentFilters(String packageName) {
14084        if (TextUtils.isEmpty(packageName)) {
14085            return ParceledListSlice.emptyList();
14086        }
14087        synchronized (mPackages) {
14088            PackageParser.Package pkg = mPackages.get(packageName);
14089            if (pkg == null || pkg.activities == null) {
14090                return ParceledListSlice.emptyList();
14091            }
14092            final int count = pkg.activities.size();
14093            ArrayList<IntentFilter> result = new ArrayList<>();
14094            for (int n=0; n<count; n++) {
14095                PackageParser.Activity activity = pkg.activities.get(n);
14096                if (activity.intents != null && activity.intents.size() > 0) {
14097                    result.addAll(activity.intents);
14098                }
14099            }
14100            return new ParceledListSlice<>(result);
14101        }
14102    }
14103
14104    @Override
14105    public boolean setDefaultBrowserPackageName(String packageName, int userId) {
14106        mContext.enforceCallingOrSelfPermission(
14107                android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
14108
14109        synchronized (mPackages) {
14110            boolean result = mSettings.setDefaultBrowserPackageNameLPw(packageName, userId);
14111            if (packageName != null) {
14112                result |= updateIntentVerificationStatus(packageName,
14113                        PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS,
14114                        userId);
14115                mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultBrowserLPr(
14116                        packageName, userId);
14117            }
14118            return result;
14119        }
14120    }
14121
14122    @Override
14123    public String getDefaultBrowserPackageName(int userId) {
14124        synchronized (mPackages) {
14125            return mSettings.getDefaultBrowserPackageNameLPw(userId);
14126        }
14127    }
14128
14129    /**
14130     * Get the "allow unknown sources" setting.
14131     *
14132     * @return the current "allow unknown sources" setting
14133     */
14134    private int getUnknownSourcesSettings() {
14135        return android.provider.Settings.Secure.getInt(mContext.getContentResolver(),
14136                android.provider.Settings.Secure.INSTALL_NON_MARKET_APPS,
14137                -1);
14138    }
14139
14140    @Override
14141    public void setInstallerPackageName(String targetPackage, String installerPackageName) {
14142        final int uid = Binder.getCallingUid();
14143        // writer
14144        synchronized (mPackages) {
14145            PackageSetting targetPackageSetting = mSettings.mPackages.get(targetPackage);
14146            if (targetPackageSetting == null) {
14147                throw new IllegalArgumentException("Unknown target package: " + targetPackage);
14148            }
14149
14150            PackageSetting installerPackageSetting;
14151            if (installerPackageName != null) {
14152                installerPackageSetting = mSettings.mPackages.get(installerPackageName);
14153                if (installerPackageSetting == null) {
14154                    throw new IllegalArgumentException("Unknown installer package: "
14155                            + installerPackageName);
14156                }
14157            } else {
14158                installerPackageSetting = null;
14159            }
14160
14161            Signature[] callerSignature;
14162            Object obj = mSettings.getUserIdLPr(uid);
14163            if (obj != null) {
14164                if (obj instanceof SharedUserSetting) {
14165                    callerSignature = ((SharedUserSetting)obj).signatures.mSignatures;
14166                } else if (obj instanceof PackageSetting) {
14167                    callerSignature = ((PackageSetting)obj).signatures.mSignatures;
14168                } else {
14169                    throw new SecurityException("Bad object " + obj + " for uid " + uid);
14170                }
14171            } else {
14172                throw new SecurityException("Unknown calling UID: " + uid);
14173            }
14174
14175            // Verify: can't set installerPackageName to a package that is
14176            // not signed with the same cert as the caller.
14177            if (installerPackageSetting != null) {
14178                if (compareSignatures(callerSignature,
14179                        installerPackageSetting.signatures.mSignatures)
14180                        != PackageManager.SIGNATURE_MATCH) {
14181                    throw new SecurityException(
14182                            "Caller does not have same cert as new installer package "
14183                            + installerPackageName);
14184                }
14185            }
14186
14187            // Verify: if target already has an installer package, it must
14188            // be signed with the same cert as the caller.
14189            if (targetPackageSetting.installerPackageName != null) {
14190                PackageSetting setting = mSettings.mPackages.get(
14191                        targetPackageSetting.installerPackageName);
14192                // If the currently set package isn't valid, then it's always
14193                // okay to change it.
14194                if (setting != null) {
14195                    if (compareSignatures(callerSignature,
14196                            setting.signatures.mSignatures)
14197                            != PackageManager.SIGNATURE_MATCH) {
14198                        throw new SecurityException(
14199                                "Caller does not have same cert as old installer package "
14200                                + targetPackageSetting.installerPackageName);
14201                    }
14202                }
14203            }
14204
14205            // Okay!
14206            targetPackageSetting.installerPackageName = installerPackageName;
14207            if (installerPackageName != null) {
14208                mSettings.mInstallerPackages.add(installerPackageName);
14209            }
14210            scheduleWriteSettingsLocked();
14211        }
14212    }
14213
14214    @Override
14215    public void setApplicationCategoryHint(String packageName, int categoryHint,
14216            String callerPackageName) {
14217        mContext.getSystemService(AppOpsManager.class).checkPackage(Binder.getCallingUid(),
14218                callerPackageName);
14219        synchronized (mPackages) {
14220            PackageSetting ps = mSettings.mPackages.get(packageName);
14221            if (ps == null) {
14222                throw new IllegalArgumentException("Unknown target package " + packageName);
14223            }
14224
14225            if (!Objects.equals(callerPackageName, ps.installerPackageName)) {
14226                throw new IllegalArgumentException("Calling package " + callerPackageName
14227                        + " is not installer for " + packageName);
14228            }
14229
14230            if (ps.categoryHint != categoryHint) {
14231                ps.categoryHint = categoryHint;
14232                scheduleWriteSettingsLocked();
14233            }
14234        }
14235    }
14236
14237    private void processPendingInstall(final InstallArgs args, final int currentStatus) {
14238        // Queue up an async operation since the package installation may take a little while.
14239        mHandler.post(new Runnable() {
14240            public void run() {
14241                mHandler.removeCallbacks(this);
14242                 // Result object to be returned
14243                PackageInstalledInfo res = new PackageInstalledInfo();
14244                res.setReturnCode(currentStatus);
14245                res.uid = -1;
14246                res.pkg = null;
14247                res.removedInfo = null;
14248                if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
14249                    args.doPreInstall(res.returnCode);
14250                    synchronized (mInstallLock) {
14251                        installPackageTracedLI(args, res);
14252                    }
14253                    args.doPostInstall(res.returnCode, res.uid);
14254                }
14255
14256                // A restore should be performed at this point if (a) the install
14257                // succeeded, (b) the operation is not an update, and (c) the new
14258                // package has not opted out of backup participation.
14259                final boolean update = res.removedInfo != null
14260                        && res.removedInfo.removedPackage != null;
14261                final int flags = (res.pkg == null) ? 0 : res.pkg.applicationInfo.flags;
14262                boolean doRestore = !update
14263                        && ((flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0);
14264
14265                // Set up the post-install work request bookkeeping.  This will be used
14266                // and cleaned up by the post-install event handling regardless of whether
14267                // there's a restore pass performed.  Token values are >= 1.
14268                int token;
14269                if (mNextInstallToken < 0) mNextInstallToken = 1;
14270                token = mNextInstallToken++;
14271
14272                PostInstallData data = new PostInstallData(args, res);
14273                mRunningInstalls.put(token, data);
14274                if (DEBUG_INSTALL) Log.v(TAG, "+ starting restore round-trip " + token);
14275
14276                if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && doRestore) {
14277                    // Pass responsibility to the Backup Manager.  It will perform a
14278                    // restore if appropriate, then pass responsibility back to the
14279                    // Package Manager to run the post-install observer callbacks
14280                    // and broadcasts.
14281                    IBackupManager bm = IBackupManager.Stub.asInterface(
14282                            ServiceManager.getService(Context.BACKUP_SERVICE));
14283                    if (bm != null) {
14284                        if (DEBUG_INSTALL) Log.v(TAG, "token " + token
14285                                + " to BM for possible restore");
14286                        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "restore", token);
14287                        try {
14288                            // TODO: http://b/22388012
14289                            if (bm.isBackupServiceActive(UserHandle.USER_SYSTEM)) {
14290                                bm.restoreAtInstall(res.pkg.applicationInfo.packageName, token);
14291                            } else {
14292                                doRestore = false;
14293                            }
14294                        } catch (RemoteException e) {
14295                            // can't happen; the backup manager is local
14296                        } catch (Exception e) {
14297                            Slog.e(TAG, "Exception trying to enqueue restore", e);
14298                            doRestore = false;
14299                        }
14300                    } else {
14301                        Slog.e(TAG, "Backup Manager not found!");
14302                        doRestore = false;
14303                    }
14304                }
14305
14306                if (!doRestore) {
14307                    // No restore possible, or the Backup Manager was mysteriously not
14308                    // available -- just fire the post-install work request directly.
14309                    if (DEBUG_INSTALL) Log.v(TAG, "No restore - queue post-install for " + token);
14310
14311                    Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "postInstall", token);
14312
14313                    Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0);
14314                    mHandler.sendMessage(msg);
14315                }
14316            }
14317        });
14318    }
14319
14320    /**
14321     * Callback from PackageSettings whenever an app is first transitioned out of the
14322     * 'stopped' state.  Normally we just issue the broadcast, but we can't do that if
14323     * the app was "launched" for a restoreAtInstall operation.  Therefore we check
14324     * here whether the app is the target of an ongoing install, and only send the
14325     * broadcast immediately if it is not in that state.  If it *is* undergoing a restore,
14326     * the first-launch broadcast will be sent implicitly on that basis in POST_INSTALL
14327     * handling.
14328     */
14329    void notifyFirstLaunch(final String pkgName, final String installerPackage, final int userId) {
14330        // Serialize this with the rest of the install-process message chain.  In the
14331        // restore-at-install case, this Runnable will necessarily run before the
14332        // POST_INSTALL message is processed, so the contents of mRunningInstalls
14333        // are coherent.  In the non-restore case, the app has already completed install
14334        // and been launched through some other means, so it is not in a problematic
14335        // state for observers to see the FIRST_LAUNCH signal.
14336        mHandler.post(new Runnable() {
14337            @Override
14338            public void run() {
14339                for (int i = 0; i < mRunningInstalls.size(); i++) {
14340                    final PostInstallData data = mRunningInstalls.valueAt(i);
14341                    if (data.res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
14342                        continue;
14343                    }
14344                    if (pkgName.equals(data.res.pkg.applicationInfo.packageName)) {
14345                        // right package; but is it for the right user?
14346                        for (int uIndex = 0; uIndex < data.res.newUsers.length; uIndex++) {
14347                            if (userId == data.res.newUsers[uIndex]) {
14348                                if (DEBUG_BACKUP) {
14349                                    Slog.i(TAG, "Package " + pkgName
14350                                            + " being restored so deferring FIRST_LAUNCH");
14351                                }
14352                                return;
14353                            }
14354                        }
14355                    }
14356                }
14357                // didn't find it, so not being restored
14358                if (DEBUG_BACKUP) {
14359                    Slog.i(TAG, "Package " + pkgName + " sending normal FIRST_LAUNCH");
14360                }
14361                sendFirstLaunchBroadcast(pkgName, installerPackage, new int[] {userId});
14362            }
14363        });
14364    }
14365
14366    private void sendFirstLaunchBroadcast(String pkgName, String installerPkg, int[] userIds) {
14367        sendPackageBroadcast(Intent.ACTION_PACKAGE_FIRST_LAUNCH, pkgName, null, 0,
14368                installerPkg, null, userIds);
14369    }
14370
14371    private abstract class HandlerParams {
14372        private static final int MAX_RETRIES = 4;
14373
14374        /**
14375         * Number of times startCopy() has been attempted and had a non-fatal
14376         * error.
14377         */
14378        private int mRetries = 0;
14379
14380        /** User handle for the user requesting the information or installation. */
14381        private final UserHandle mUser;
14382        String traceMethod;
14383        int traceCookie;
14384
14385        HandlerParams(UserHandle user) {
14386            mUser = user;
14387        }
14388
14389        UserHandle getUser() {
14390            return mUser;
14391        }
14392
14393        HandlerParams setTraceMethod(String traceMethod) {
14394            this.traceMethod = traceMethod;
14395            return this;
14396        }
14397
14398        HandlerParams setTraceCookie(int traceCookie) {
14399            this.traceCookie = traceCookie;
14400            return this;
14401        }
14402
14403        final boolean startCopy() {
14404            boolean res;
14405            try {
14406                if (DEBUG_INSTALL) Slog.i(TAG, "startCopy " + mUser + ": " + this);
14407
14408                if (++mRetries > MAX_RETRIES) {
14409                    Slog.w(TAG, "Failed to invoke remote methods on default container service. Giving up");
14410                    mHandler.sendEmptyMessage(MCS_GIVE_UP);
14411                    handleServiceError();
14412                    return false;
14413                } else {
14414                    handleStartCopy();
14415                    res = true;
14416                }
14417            } catch (RemoteException e) {
14418                if (DEBUG_INSTALL) Slog.i(TAG, "Posting install MCS_RECONNECT");
14419                mHandler.sendEmptyMessage(MCS_RECONNECT);
14420                res = false;
14421            }
14422            handleReturnCode();
14423            return res;
14424        }
14425
14426        final void serviceError() {
14427            if (DEBUG_INSTALL) Slog.i(TAG, "serviceError");
14428            handleServiceError();
14429            handleReturnCode();
14430        }
14431
14432        abstract void handleStartCopy() throws RemoteException;
14433        abstract void handleServiceError();
14434        abstract void handleReturnCode();
14435    }
14436
14437    private static void clearDirectory(IMediaContainerService mcs, File[] paths) {
14438        for (File path : paths) {
14439            try {
14440                mcs.clearDirectory(path.getAbsolutePath());
14441            } catch (RemoteException e) {
14442            }
14443        }
14444    }
14445
14446    static class OriginInfo {
14447        /**
14448         * Location where install is coming from, before it has been
14449         * copied/renamed into place. This could be a single monolithic APK
14450         * file, or a cluster directory. This location may be untrusted.
14451         */
14452        final File file;
14453        final String cid;
14454
14455        /**
14456         * Flag indicating that {@link #file} or {@link #cid} has already been
14457         * staged, meaning downstream users don't need to defensively copy the
14458         * contents.
14459         */
14460        final boolean staged;
14461
14462        /**
14463         * Flag indicating that {@link #file} or {@link #cid} is an already
14464         * installed app that is being moved.
14465         */
14466        final boolean existing;
14467
14468        final String resolvedPath;
14469        final File resolvedFile;
14470
14471        static OriginInfo fromNothing() {
14472            return new OriginInfo(null, null, false, false);
14473        }
14474
14475        static OriginInfo fromUntrustedFile(File file) {
14476            return new OriginInfo(file, null, false, false);
14477        }
14478
14479        static OriginInfo fromExistingFile(File file) {
14480            return new OriginInfo(file, null, false, true);
14481        }
14482
14483        static OriginInfo fromStagedFile(File file) {
14484            return new OriginInfo(file, null, true, false);
14485        }
14486
14487        static OriginInfo fromStagedContainer(String cid) {
14488            return new OriginInfo(null, cid, true, false);
14489        }
14490
14491        private OriginInfo(File file, String cid, boolean staged, boolean existing) {
14492            this.file = file;
14493            this.cid = cid;
14494            this.staged = staged;
14495            this.existing = existing;
14496
14497            if (cid != null) {
14498                resolvedPath = PackageHelper.getSdDir(cid);
14499                resolvedFile = new File(resolvedPath);
14500            } else if (file != null) {
14501                resolvedPath = file.getAbsolutePath();
14502                resolvedFile = file;
14503            } else {
14504                resolvedPath = null;
14505                resolvedFile = null;
14506            }
14507        }
14508    }
14509
14510    static class MoveInfo {
14511        final int moveId;
14512        final String fromUuid;
14513        final String toUuid;
14514        final String packageName;
14515        final String dataAppName;
14516        final int appId;
14517        final String seinfo;
14518        final int targetSdkVersion;
14519
14520        public MoveInfo(int moveId, String fromUuid, String toUuid, String packageName,
14521                String dataAppName, int appId, String seinfo, int targetSdkVersion) {
14522            this.moveId = moveId;
14523            this.fromUuid = fromUuid;
14524            this.toUuid = toUuid;
14525            this.packageName = packageName;
14526            this.dataAppName = dataAppName;
14527            this.appId = appId;
14528            this.seinfo = seinfo;
14529            this.targetSdkVersion = targetSdkVersion;
14530        }
14531    }
14532
14533    static class VerificationInfo {
14534        /** A constant used to indicate that a uid value is not present. */
14535        public static final int NO_UID = -1;
14536
14537        /** URI referencing where the package was downloaded from. */
14538        final Uri originatingUri;
14539
14540        /** HTTP referrer URI associated with the originatingURI. */
14541        final Uri referrer;
14542
14543        /** UID of the application that the install request originated from. */
14544        final int originatingUid;
14545
14546        /** UID of application requesting the install */
14547        final int installerUid;
14548
14549        VerificationInfo(Uri originatingUri, Uri referrer, int originatingUid, int installerUid) {
14550            this.originatingUri = originatingUri;
14551            this.referrer = referrer;
14552            this.originatingUid = originatingUid;
14553            this.installerUid = installerUid;
14554        }
14555    }
14556
14557    class InstallParams extends HandlerParams {
14558        final OriginInfo origin;
14559        final MoveInfo move;
14560        final IPackageInstallObserver2 observer;
14561        int installFlags;
14562        final String installerPackageName;
14563        final String volumeUuid;
14564        private InstallArgs mArgs;
14565        private int mRet;
14566        final String packageAbiOverride;
14567        final String[] grantedRuntimePermissions;
14568        final VerificationInfo verificationInfo;
14569        final Certificate[][] certificates;
14570        final int installReason;
14571
14572        InstallParams(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
14573                int installFlags, String installerPackageName, String volumeUuid,
14574                VerificationInfo verificationInfo, UserHandle user, String packageAbiOverride,
14575                String[] grantedPermissions, Certificate[][] certificates, int installReason) {
14576            super(user);
14577            this.origin = origin;
14578            this.move = move;
14579            this.observer = observer;
14580            this.installFlags = installFlags;
14581            this.installerPackageName = installerPackageName;
14582            this.volumeUuid = volumeUuid;
14583            this.verificationInfo = verificationInfo;
14584            this.packageAbiOverride = packageAbiOverride;
14585            this.grantedRuntimePermissions = grantedPermissions;
14586            this.certificates = certificates;
14587            this.installReason = installReason;
14588        }
14589
14590        @Override
14591        public String toString() {
14592            return "InstallParams{" + Integer.toHexString(System.identityHashCode(this))
14593                    + " file=" + origin.file + " cid=" + origin.cid + "}";
14594        }
14595
14596        private int installLocationPolicy(PackageInfoLite pkgLite) {
14597            String packageName = pkgLite.packageName;
14598            int installLocation = pkgLite.installLocation;
14599            boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
14600            // reader
14601            synchronized (mPackages) {
14602                // Currently installed package which the new package is attempting to replace or
14603                // null if no such package is installed.
14604                PackageParser.Package installedPkg = mPackages.get(packageName);
14605                // Package which currently owns the data which the new package will own if installed.
14606                // If an app is unstalled while keeping data (e.g., adb uninstall -k), installedPkg
14607                // will be null whereas dataOwnerPkg will contain information about the package
14608                // which was uninstalled while keeping its data.
14609                PackageParser.Package dataOwnerPkg = installedPkg;
14610                if (dataOwnerPkg  == null) {
14611                    PackageSetting ps = mSettings.mPackages.get(packageName);
14612                    if (ps != null) {
14613                        dataOwnerPkg = ps.pkg;
14614                    }
14615                }
14616
14617                if (dataOwnerPkg != null) {
14618                    // If installed, the package will get access to data left on the device by its
14619                    // predecessor. As a security measure, this is permited only if this is not a
14620                    // version downgrade or if the predecessor package is marked as debuggable and
14621                    // a downgrade is explicitly requested.
14622                    //
14623                    // On debuggable platform builds, downgrades are permitted even for
14624                    // non-debuggable packages to make testing easier. Debuggable platform builds do
14625                    // not offer security guarantees and thus it's OK to disable some security
14626                    // mechanisms to make debugging/testing easier on those builds. However, even on
14627                    // debuggable builds downgrades of packages are permitted only if requested via
14628                    // installFlags. This is because we aim to keep the behavior of debuggable
14629                    // platform builds as close as possible to the behavior of non-debuggable
14630                    // platform builds.
14631                    final boolean downgradeRequested =
14632                            (installFlags & PackageManager.INSTALL_ALLOW_DOWNGRADE) != 0;
14633                    final boolean packageDebuggable =
14634                                (dataOwnerPkg.applicationInfo.flags
14635                                        & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
14636                    final boolean downgradePermitted =
14637                            (downgradeRequested) && ((Build.IS_DEBUGGABLE) || (packageDebuggable));
14638                    if (!downgradePermitted) {
14639                        try {
14640                            checkDowngrade(dataOwnerPkg, pkgLite);
14641                        } catch (PackageManagerException e) {
14642                            Slog.w(TAG, "Downgrade detected: " + e.getMessage());
14643                            return PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE;
14644                        }
14645                    }
14646                }
14647
14648                if (installedPkg != null) {
14649                    if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
14650                        // Check for updated system application.
14651                        if ((installedPkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
14652                            if (onSd) {
14653                                Slog.w(TAG, "Cannot install update to system app on sdcard");
14654                                return PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION;
14655                            }
14656                            return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
14657                        } else {
14658                            if (onSd) {
14659                                // Install flag overrides everything.
14660                                return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
14661                            }
14662                            // If current upgrade specifies particular preference
14663                            if (installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) {
14664                                // Application explicitly specified internal.
14665                                return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
14666                            } else if (installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) {
14667                                // App explictly prefers external. Let policy decide
14668                            } else {
14669                                // Prefer previous location
14670                                if (isExternal(installedPkg)) {
14671                                    return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
14672                                }
14673                                return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
14674                            }
14675                        }
14676                    } else {
14677                        // Invalid install. Return error code
14678                        return PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS;
14679                    }
14680                }
14681            }
14682            // All the special cases have been taken care of.
14683            // Return result based on recommended install location.
14684            if (onSd) {
14685                return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
14686            }
14687            return pkgLite.recommendedInstallLocation;
14688        }
14689
14690        /*
14691         * Invoke remote method to get package information and install
14692         * location values. Override install location based on default
14693         * policy if needed and then create install arguments based
14694         * on the install location.
14695         */
14696        public void handleStartCopy() throws RemoteException {
14697            int ret = PackageManager.INSTALL_SUCCEEDED;
14698
14699            // If we're already staged, we've firmly committed to an install location
14700            if (origin.staged) {
14701                if (origin.file != null) {
14702                    installFlags |= PackageManager.INSTALL_INTERNAL;
14703                    installFlags &= ~PackageManager.INSTALL_EXTERNAL;
14704                } else if (origin.cid != null) {
14705                    installFlags |= PackageManager.INSTALL_EXTERNAL;
14706                    installFlags &= ~PackageManager.INSTALL_INTERNAL;
14707                } else {
14708                    throw new IllegalStateException("Invalid stage location");
14709                }
14710            }
14711
14712            final boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
14713            final boolean onInt = (installFlags & PackageManager.INSTALL_INTERNAL) != 0;
14714            final boolean ephemeral = (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
14715            PackageInfoLite pkgLite = null;
14716
14717            if (onInt && onSd) {
14718                // Check if both bits are set.
14719                Slog.w(TAG, "Conflicting flags specified for installing on both internal and external");
14720                ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
14721            } else if (onSd && ephemeral) {
14722                Slog.w(TAG,  "Conflicting flags specified for installing ephemeral on external");
14723                ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
14724            } else {
14725                pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, installFlags,
14726                        packageAbiOverride);
14727
14728                if (DEBUG_EPHEMERAL && ephemeral) {
14729                    Slog.v(TAG, "pkgLite for install: " + pkgLite);
14730                }
14731
14732                /*
14733                 * If we have too little free space, try to free cache
14734                 * before giving up.
14735                 */
14736                if (!origin.staged && pkgLite.recommendedInstallLocation
14737                        == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
14738                    // TODO: focus freeing disk space on the target device
14739                    final StorageManager storage = StorageManager.from(mContext);
14740                    final long lowThreshold = storage.getStorageLowBytes(
14741                            Environment.getDataDirectory());
14742
14743                    final long sizeBytes = mContainerService.calculateInstalledSize(
14744                            origin.resolvedPath, isForwardLocked(), packageAbiOverride);
14745
14746                    try {
14747                        mInstaller.freeCache(null, sizeBytes + lowThreshold, 0);
14748                        pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath,
14749                                installFlags, packageAbiOverride);
14750                    } catch (InstallerException e) {
14751                        Slog.w(TAG, "Failed to free cache", e);
14752                    }
14753
14754                    /*
14755                     * The cache free must have deleted the file we
14756                     * downloaded to install.
14757                     *
14758                     * TODO: fix the "freeCache" call to not delete
14759                     *       the file we care about.
14760                     */
14761                    if (pkgLite.recommendedInstallLocation
14762                            == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
14763                        pkgLite.recommendedInstallLocation
14764                            = PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE;
14765                    }
14766                }
14767            }
14768
14769            if (ret == PackageManager.INSTALL_SUCCEEDED) {
14770                int loc = pkgLite.recommendedInstallLocation;
14771                if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION) {
14772                    ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
14773                } else if (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS) {
14774                    ret = PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
14775                } else if (loc == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
14776                    ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
14777                } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_APK) {
14778                    ret = PackageManager.INSTALL_FAILED_INVALID_APK;
14779                } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
14780                    ret = PackageManager.INSTALL_FAILED_INVALID_URI;
14781                } else if (loc == PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE) {
14782                    ret = PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE;
14783                } else {
14784                    // Override with defaults if needed.
14785                    loc = installLocationPolicy(pkgLite);
14786                    if (loc == PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE) {
14787                        ret = PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
14788                    } else if (!onSd && !onInt) {
14789                        // Override install location with flags
14790                        if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) {
14791                            // Set the flag to install on external media.
14792                            installFlags |= PackageManager.INSTALL_EXTERNAL;
14793                            installFlags &= ~PackageManager.INSTALL_INTERNAL;
14794                        } else if (loc == PackageHelper.RECOMMEND_INSTALL_EPHEMERAL) {
14795                            if (DEBUG_EPHEMERAL) {
14796                                Slog.v(TAG, "...setting INSTALL_EPHEMERAL install flag");
14797                            }
14798                            installFlags |= PackageManager.INSTALL_INSTANT_APP;
14799                            installFlags &= ~(PackageManager.INSTALL_EXTERNAL
14800                                    |PackageManager.INSTALL_INTERNAL);
14801                        } else {
14802                            // Make sure the flag for installing on external
14803                            // media is unset
14804                            installFlags |= PackageManager.INSTALL_INTERNAL;
14805                            installFlags &= ~PackageManager.INSTALL_EXTERNAL;
14806                        }
14807                    }
14808                }
14809            }
14810
14811            final InstallArgs args = createInstallArgs(this);
14812            mArgs = args;
14813
14814            if (ret == PackageManager.INSTALL_SUCCEEDED) {
14815                // TODO: http://b/22976637
14816                // Apps installed for "all" users use the device owner to verify the app
14817                UserHandle verifierUser = getUser();
14818                if (verifierUser == UserHandle.ALL) {
14819                    verifierUser = UserHandle.SYSTEM;
14820                }
14821
14822                /*
14823                 * Determine if we have any installed package verifiers. If we
14824                 * do, then we'll defer to them to verify the packages.
14825                 */
14826                final int requiredUid = mRequiredVerifierPackage == null ? -1
14827                        : getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
14828                                verifierUser.getIdentifier());
14829                if (!origin.existing && requiredUid != -1
14830                        && isVerificationEnabled(verifierUser.getIdentifier(), installFlags)) {
14831                    final Intent verification = new Intent(
14832                            Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
14833                    verification.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14834                    verification.setDataAndType(Uri.fromFile(new File(origin.resolvedPath)),
14835                            PACKAGE_MIME_TYPE);
14836                    verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
14837
14838                    // Query all live verifiers based on current user state
14839                    final List<ResolveInfo> receivers = queryIntentReceiversInternal(verification,
14840                            PACKAGE_MIME_TYPE, 0, verifierUser.getIdentifier());
14841
14842                    if (DEBUG_VERIFY) {
14843                        Slog.d(TAG, "Found " + receivers.size() + " verifiers for intent "
14844                                + verification.toString() + " with " + pkgLite.verifiers.length
14845                                + " optional verifiers");
14846                    }
14847
14848                    final int verificationId = mPendingVerificationToken++;
14849
14850                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
14851
14852                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_PACKAGE,
14853                            installerPackageName);
14854
14855                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALL_FLAGS,
14856                            installFlags);
14857
14858                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_PACKAGE_NAME,
14859                            pkgLite.packageName);
14860
14861                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_VERSION_CODE,
14862                            pkgLite.versionCode);
14863
14864                    if (verificationInfo != null) {
14865                        if (verificationInfo.originatingUri != null) {
14866                            verification.putExtra(Intent.EXTRA_ORIGINATING_URI,
14867                                    verificationInfo.originatingUri);
14868                        }
14869                        if (verificationInfo.referrer != null) {
14870                            verification.putExtra(Intent.EXTRA_REFERRER,
14871                                    verificationInfo.referrer);
14872                        }
14873                        if (verificationInfo.originatingUid >= 0) {
14874                            verification.putExtra(Intent.EXTRA_ORIGINATING_UID,
14875                                    verificationInfo.originatingUid);
14876                        }
14877                        if (verificationInfo.installerUid >= 0) {
14878                            verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_UID,
14879                                    verificationInfo.installerUid);
14880                        }
14881                    }
14882
14883                    final PackageVerificationState verificationState = new PackageVerificationState(
14884                            requiredUid, args);
14885
14886                    mPendingVerification.append(verificationId, verificationState);
14887
14888                    final List<ComponentName> sufficientVerifiers = matchVerifiers(pkgLite,
14889                            receivers, verificationState);
14890
14891                    DeviceIdleController.LocalService idleController = getDeviceIdleController();
14892                    final long idleDuration = getVerificationTimeout();
14893
14894                    /*
14895                     * If any sufficient verifiers were listed in the package
14896                     * manifest, attempt to ask them.
14897                     */
14898                    if (sufficientVerifiers != null) {
14899                        final int N = sufficientVerifiers.size();
14900                        if (N == 0) {
14901                            Slog.i(TAG, "Additional verifiers required, but none installed.");
14902                            ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
14903                        } else {
14904                            for (int i = 0; i < N; i++) {
14905                                final ComponentName verifierComponent = sufficientVerifiers.get(i);
14906                                idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
14907                                        verifierComponent.getPackageName(), idleDuration,
14908                                        verifierUser.getIdentifier(), false, "package verifier");
14909
14910                                final Intent sufficientIntent = new Intent(verification);
14911                                sufficientIntent.setComponent(verifierComponent);
14912                                mContext.sendBroadcastAsUser(sufficientIntent, verifierUser);
14913                            }
14914                        }
14915                    }
14916
14917                    final ComponentName requiredVerifierComponent = matchComponentForVerifier(
14918                            mRequiredVerifierPackage, receivers);
14919                    if (ret == PackageManager.INSTALL_SUCCEEDED
14920                            && mRequiredVerifierPackage != null) {
14921                        Trace.asyncTraceBegin(
14922                                TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
14923                        /*
14924                         * Send the intent to the required verification agent,
14925                         * but only start the verification timeout after the
14926                         * target BroadcastReceivers have run.
14927                         */
14928                        verification.setComponent(requiredVerifierComponent);
14929                        idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
14930                                mRequiredVerifierPackage, idleDuration,
14931                                verifierUser.getIdentifier(), false, "package verifier");
14932                        mContext.sendOrderedBroadcastAsUser(verification, verifierUser,
14933                                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
14934                                new BroadcastReceiver() {
14935                                    @Override
14936                                    public void onReceive(Context context, Intent intent) {
14937                                        final Message msg = mHandler
14938                                                .obtainMessage(CHECK_PENDING_VERIFICATION);
14939                                        msg.arg1 = verificationId;
14940                                        mHandler.sendMessageDelayed(msg, getVerificationTimeout());
14941                                    }
14942                                }, null, 0, null, null);
14943
14944                        /*
14945                         * We don't want the copy to proceed until verification
14946                         * succeeds, so null out this field.
14947                         */
14948                        mArgs = null;
14949                    }
14950                } else {
14951                    /*
14952                     * No package verification is enabled, so immediately start
14953                     * the remote call to initiate copy using temporary file.
14954                     */
14955                    ret = args.copyApk(mContainerService, true);
14956                }
14957            }
14958
14959            mRet = ret;
14960        }
14961
14962        @Override
14963        void handleReturnCode() {
14964            // If mArgs is null, then MCS couldn't be reached. When it
14965            // reconnects, it will try again to install. At that point, this
14966            // will succeed.
14967            if (mArgs != null) {
14968                processPendingInstall(mArgs, mRet);
14969            }
14970        }
14971
14972        @Override
14973        void handleServiceError() {
14974            mArgs = createInstallArgs(this);
14975            mRet = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
14976        }
14977
14978        public boolean isForwardLocked() {
14979            return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
14980        }
14981    }
14982
14983    /**
14984     * Used during creation of InstallArgs
14985     *
14986     * @param installFlags package installation flags
14987     * @return true if should be installed on external storage
14988     */
14989    private static boolean installOnExternalAsec(int installFlags) {
14990        if ((installFlags & PackageManager.INSTALL_INTERNAL) != 0) {
14991            return false;
14992        }
14993        if ((installFlags & PackageManager.INSTALL_EXTERNAL) != 0) {
14994            return true;
14995        }
14996        return false;
14997    }
14998
14999    /**
15000     * Used during creation of InstallArgs
15001     *
15002     * @param installFlags package installation flags
15003     * @return true if should be installed as forward locked
15004     */
15005    private static boolean installForwardLocked(int installFlags) {
15006        return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
15007    }
15008
15009    private InstallArgs createInstallArgs(InstallParams params) {
15010        if (params.move != null) {
15011            return new MoveInstallArgs(params);
15012        } else if (installOnExternalAsec(params.installFlags) || params.isForwardLocked()) {
15013            return new AsecInstallArgs(params);
15014        } else {
15015            return new FileInstallArgs(params);
15016        }
15017    }
15018
15019    /**
15020     * Create args that describe an existing installed package. Typically used
15021     * when cleaning up old installs, or used as a move source.
15022     */
15023    private InstallArgs createInstallArgsForExisting(int installFlags, String codePath,
15024            String resourcePath, String[] instructionSets) {
15025        final boolean isInAsec;
15026        if (installOnExternalAsec(installFlags)) {
15027            /* Apps on SD card are always in ASEC containers. */
15028            isInAsec = true;
15029        } else if (installForwardLocked(installFlags)
15030                && !codePath.startsWith(mDrmAppPrivateInstallDir.getAbsolutePath())) {
15031            /*
15032             * Forward-locked apps are only in ASEC containers if they're the
15033             * new style
15034             */
15035            isInAsec = true;
15036        } else {
15037            isInAsec = false;
15038        }
15039
15040        if (isInAsec) {
15041            return new AsecInstallArgs(codePath, instructionSets,
15042                    installOnExternalAsec(installFlags), installForwardLocked(installFlags));
15043        } else {
15044            return new FileInstallArgs(codePath, resourcePath, instructionSets);
15045        }
15046    }
15047
15048    static abstract class InstallArgs {
15049        /** @see InstallParams#origin */
15050        final OriginInfo origin;
15051        /** @see InstallParams#move */
15052        final MoveInfo move;
15053
15054        final IPackageInstallObserver2 observer;
15055        // Always refers to PackageManager flags only
15056        final int installFlags;
15057        final String installerPackageName;
15058        final String volumeUuid;
15059        final UserHandle user;
15060        final String abiOverride;
15061        final String[] installGrantPermissions;
15062        /** If non-null, drop an async trace when the install completes */
15063        final String traceMethod;
15064        final int traceCookie;
15065        final Certificate[][] certificates;
15066        final int installReason;
15067
15068        // The list of instruction sets supported by this app. This is currently
15069        // only used during the rmdex() phase to clean up resources. We can get rid of this
15070        // if we move dex files under the common app path.
15071        /* nullable */ String[] instructionSets;
15072
15073        InstallArgs(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
15074                int installFlags, String installerPackageName, String volumeUuid,
15075                UserHandle user, String[] instructionSets,
15076                String abiOverride, String[] installGrantPermissions,
15077                String traceMethod, int traceCookie, Certificate[][] certificates,
15078                int installReason) {
15079            this.origin = origin;
15080            this.move = move;
15081            this.installFlags = installFlags;
15082            this.observer = observer;
15083            this.installerPackageName = installerPackageName;
15084            this.volumeUuid = volumeUuid;
15085            this.user = user;
15086            this.instructionSets = instructionSets;
15087            this.abiOverride = abiOverride;
15088            this.installGrantPermissions = installGrantPermissions;
15089            this.traceMethod = traceMethod;
15090            this.traceCookie = traceCookie;
15091            this.certificates = certificates;
15092            this.installReason = installReason;
15093        }
15094
15095        abstract int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException;
15096        abstract int doPreInstall(int status);
15097
15098        /**
15099         * Rename package into final resting place. All paths on the given
15100         * scanned package should be updated to reflect the rename.
15101         */
15102        abstract boolean doRename(int status, PackageParser.Package pkg, String oldCodePath);
15103        abstract int doPostInstall(int status, int uid);
15104
15105        /** @see PackageSettingBase#codePathString */
15106        abstract String getCodePath();
15107        /** @see PackageSettingBase#resourcePathString */
15108        abstract String getResourcePath();
15109
15110        // Need installer lock especially for dex file removal.
15111        abstract void cleanUpResourcesLI();
15112        abstract boolean doPostDeleteLI(boolean delete);
15113
15114        /**
15115         * Called before the source arguments are copied. This is used mostly
15116         * for MoveParams when it needs to read the source file to put it in the
15117         * destination.
15118         */
15119        int doPreCopy() {
15120            return PackageManager.INSTALL_SUCCEEDED;
15121        }
15122
15123        /**
15124         * Called after the source arguments are copied. This is used mostly for
15125         * MoveParams when it needs to read the source file to put it in the
15126         * destination.
15127         */
15128        int doPostCopy(int uid) {
15129            return PackageManager.INSTALL_SUCCEEDED;
15130        }
15131
15132        protected boolean isFwdLocked() {
15133            return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
15134        }
15135
15136        protected boolean isExternalAsec() {
15137            return (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
15138        }
15139
15140        protected boolean isEphemeral() {
15141            return (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
15142        }
15143
15144        UserHandle getUser() {
15145            return user;
15146        }
15147    }
15148
15149    private void removeDexFiles(List<String> allCodePaths, String[] instructionSets) {
15150        if (!allCodePaths.isEmpty()) {
15151            if (instructionSets == null) {
15152                throw new IllegalStateException("instructionSet == null");
15153            }
15154            String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
15155            for (String codePath : allCodePaths) {
15156                for (String dexCodeInstructionSet : dexCodeInstructionSets) {
15157                    try {
15158                        mInstaller.rmdex(codePath, dexCodeInstructionSet);
15159                    } catch (InstallerException ignored) {
15160                    }
15161                }
15162            }
15163        }
15164    }
15165
15166    /**
15167     * Logic to handle installation of non-ASEC applications, including copying
15168     * and renaming logic.
15169     */
15170    class FileInstallArgs extends InstallArgs {
15171        private File codeFile;
15172        private File resourceFile;
15173
15174        // Example topology:
15175        // /data/app/com.example/base.apk
15176        // /data/app/com.example/split_foo.apk
15177        // /data/app/com.example/lib/arm/libfoo.so
15178        // /data/app/com.example/lib/arm64/libfoo.so
15179        // /data/app/com.example/dalvik/arm/base.apk@classes.dex
15180
15181        /** New install */
15182        FileInstallArgs(InstallParams params) {
15183            super(params.origin, params.move, params.observer, params.installFlags,
15184                    params.installerPackageName, params.volumeUuid,
15185                    params.getUser(), null /*instructionSets*/, params.packageAbiOverride,
15186                    params.grantedRuntimePermissions,
15187                    params.traceMethod, params.traceCookie, params.certificates,
15188                    params.installReason);
15189            if (isFwdLocked()) {
15190                throw new IllegalArgumentException("Forward locking only supported in ASEC");
15191            }
15192        }
15193
15194        /** Existing install */
15195        FileInstallArgs(String codePath, String resourcePath, String[] instructionSets) {
15196            super(OriginInfo.fromNothing(), null, null, 0, null, null, null, instructionSets,
15197                    null, null, null, 0, null /*certificates*/,
15198                    PackageManager.INSTALL_REASON_UNKNOWN);
15199            this.codeFile = (codePath != null) ? new File(codePath) : null;
15200            this.resourceFile = (resourcePath != null) ? new File(resourcePath) : null;
15201        }
15202
15203        int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
15204            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyApk");
15205            try {
15206                return doCopyApk(imcs, temp);
15207            } finally {
15208                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
15209            }
15210        }
15211
15212        private int doCopyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
15213            if (origin.staged) {
15214                if (DEBUG_INSTALL) Slog.d(TAG, origin.file + " already staged; skipping copy");
15215                codeFile = origin.file;
15216                resourceFile = origin.file;
15217                return PackageManager.INSTALL_SUCCEEDED;
15218            }
15219
15220            try {
15221                final boolean isEphemeral = (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
15222                final File tempDir =
15223                        mInstallerService.allocateStageDirLegacy(volumeUuid, isEphemeral);
15224                codeFile = tempDir;
15225                resourceFile = tempDir;
15226            } catch (IOException e) {
15227                Slog.w(TAG, "Failed to create copy file: " + e);
15228                return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
15229            }
15230
15231            final IParcelFileDescriptorFactory target = new IParcelFileDescriptorFactory.Stub() {
15232                @Override
15233                public ParcelFileDescriptor open(String name, int mode) throws RemoteException {
15234                    if (!FileUtils.isValidExtFilename(name)) {
15235                        throw new IllegalArgumentException("Invalid filename: " + name);
15236                    }
15237                    try {
15238                        final File file = new File(codeFile, name);
15239                        final FileDescriptor fd = Os.open(file.getAbsolutePath(),
15240                                O_RDWR | O_CREAT, 0644);
15241                        Os.chmod(file.getAbsolutePath(), 0644);
15242                        return new ParcelFileDescriptor(fd);
15243                    } catch (ErrnoException e) {
15244                        throw new RemoteException("Failed to open: " + e.getMessage());
15245                    }
15246                }
15247            };
15248
15249            int ret = PackageManager.INSTALL_SUCCEEDED;
15250            ret = imcs.copyPackage(origin.file.getAbsolutePath(), target);
15251            if (ret != PackageManager.INSTALL_SUCCEEDED) {
15252                Slog.e(TAG, "Failed to copy package");
15253                return ret;
15254            }
15255
15256            final File libraryRoot = new File(codeFile, LIB_DIR_NAME);
15257            NativeLibraryHelper.Handle handle = null;
15258            try {
15259                handle = NativeLibraryHelper.Handle.create(codeFile);
15260                ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot,
15261                        abiOverride);
15262            } catch (IOException e) {
15263                Slog.e(TAG, "Copying native libraries failed", e);
15264                ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
15265            } finally {
15266                IoUtils.closeQuietly(handle);
15267            }
15268
15269            return ret;
15270        }
15271
15272        int doPreInstall(int status) {
15273            if (status != PackageManager.INSTALL_SUCCEEDED) {
15274                cleanUp();
15275            }
15276            return status;
15277        }
15278
15279        boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
15280            if (status != PackageManager.INSTALL_SUCCEEDED) {
15281                cleanUp();
15282                return false;
15283            }
15284
15285            final File targetDir = codeFile.getParentFile();
15286            final File beforeCodeFile = codeFile;
15287            final File afterCodeFile = getNextCodePath(targetDir, pkg.packageName);
15288
15289            if (DEBUG_INSTALL) Slog.d(TAG, "Renaming " + beforeCodeFile + " to " + afterCodeFile);
15290            try {
15291                Os.rename(beforeCodeFile.getAbsolutePath(), afterCodeFile.getAbsolutePath());
15292            } catch (ErrnoException e) {
15293                Slog.w(TAG, "Failed to rename", e);
15294                return false;
15295            }
15296
15297            if (!SELinux.restoreconRecursive(afterCodeFile)) {
15298                Slog.w(TAG, "Failed to restorecon");
15299                return false;
15300            }
15301
15302            // Reflect the rename internally
15303            codeFile = afterCodeFile;
15304            resourceFile = afterCodeFile;
15305
15306            // Reflect the rename in scanned details
15307            pkg.setCodePath(afterCodeFile.getAbsolutePath());
15308            pkg.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile,
15309                    afterCodeFile, pkg.baseCodePath));
15310            pkg.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile,
15311                    afterCodeFile, pkg.splitCodePaths));
15312
15313            // Reflect the rename in app info
15314            pkg.setApplicationVolumeUuid(pkg.volumeUuid);
15315            pkg.setApplicationInfoCodePath(pkg.codePath);
15316            pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
15317            pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
15318            pkg.setApplicationInfoResourcePath(pkg.codePath);
15319            pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
15320            pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
15321
15322            return true;
15323        }
15324
15325        int doPostInstall(int status, int uid) {
15326            if (status != PackageManager.INSTALL_SUCCEEDED) {
15327                cleanUp();
15328            }
15329            return status;
15330        }
15331
15332        @Override
15333        String getCodePath() {
15334            return (codeFile != null) ? codeFile.getAbsolutePath() : null;
15335        }
15336
15337        @Override
15338        String getResourcePath() {
15339            return (resourceFile != null) ? resourceFile.getAbsolutePath() : null;
15340        }
15341
15342        private boolean cleanUp() {
15343            if (codeFile == null || !codeFile.exists()) {
15344                return false;
15345            }
15346
15347            removeCodePathLI(codeFile);
15348
15349            if (resourceFile != null && !FileUtils.contains(codeFile, resourceFile)) {
15350                resourceFile.delete();
15351            }
15352
15353            return true;
15354        }
15355
15356        void cleanUpResourcesLI() {
15357            // Try enumerating all code paths before deleting
15358            List<String> allCodePaths = Collections.EMPTY_LIST;
15359            if (codeFile != null && codeFile.exists()) {
15360                try {
15361                    final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0);
15362                    allCodePaths = pkg.getAllCodePaths();
15363                } catch (PackageParserException e) {
15364                    // Ignored; we tried our best
15365                }
15366            }
15367
15368            cleanUp();
15369            removeDexFiles(allCodePaths, instructionSets);
15370        }
15371
15372        boolean doPostDeleteLI(boolean delete) {
15373            // XXX err, shouldn't we respect the delete flag?
15374            cleanUpResourcesLI();
15375            return true;
15376        }
15377    }
15378
15379    private boolean isAsecExternal(String cid) {
15380        final String asecPath = PackageHelper.getSdFilesystem(cid);
15381        return !asecPath.startsWith(mAsecInternalPath);
15382    }
15383
15384    private static void maybeThrowExceptionForMultiArchCopy(String message, int copyRet) throws
15385            PackageManagerException {
15386        if (copyRet < 0) {
15387            if (copyRet != PackageManager.NO_NATIVE_LIBRARIES &&
15388                    copyRet != PackageManager.INSTALL_FAILED_NO_MATCHING_ABIS) {
15389                throw new PackageManagerException(copyRet, message);
15390            }
15391        }
15392    }
15393
15394    /**
15395     * Extract the StorageManagerService "container ID" from the full code path of an
15396     * .apk.
15397     */
15398    static String cidFromCodePath(String fullCodePath) {
15399        int eidx = fullCodePath.lastIndexOf("/");
15400        String subStr1 = fullCodePath.substring(0, eidx);
15401        int sidx = subStr1.lastIndexOf("/");
15402        return subStr1.substring(sidx+1, eidx);
15403    }
15404
15405    /**
15406     * Logic to handle installation of ASEC applications, including copying and
15407     * renaming logic.
15408     */
15409    class AsecInstallArgs extends InstallArgs {
15410        static final String RES_FILE_NAME = "pkg.apk";
15411        static final String PUBLIC_RES_FILE_NAME = "res.zip";
15412
15413        String cid;
15414        String packagePath;
15415        String resourcePath;
15416
15417        /** New install */
15418        AsecInstallArgs(InstallParams params) {
15419            super(params.origin, params.move, params.observer, params.installFlags,
15420                    params.installerPackageName, params.volumeUuid,
15421                    params.getUser(), null /* instruction sets */, params.packageAbiOverride,
15422                    params.grantedRuntimePermissions,
15423                    params.traceMethod, params.traceCookie, params.certificates,
15424                    params.installReason);
15425        }
15426
15427        /** Existing install */
15428        AsecInstallArgs(String fullCodePath, String[] instructionSets,
15429                        boolean isExternal, boolean isForwardLocked) {
15430            super(OriginInfo.fromNothing(), null, null, (isExternal ? INSTALL_EXTERNAL : 0)
15431                    | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null,
15432                    instructionSets, null, null, null, 0, null /*certificates*/,
15433                    PackageManager.INSTALL_REASON_UNKNOWN);
15434            // Hackily pretend we're still looking at a full code path
15435            if (!fullCodePath.endsWith(RES_FILE_NAME)) {
15436                fullCodePath = new File(fullCodePath, RES_FILE_NAME).getAbsolutePath();
15437            }
15438
15439            // Extract cid from fullCodePath
15440            int eidx = fullCodePath.lastIndexOf("/");
15441            String subStr1 = fullCodePath.substring(0, eidx);
15442            int sidx = subStr1.lastIndexOf("/");
15443            cid = subStr1.substring(sidx+1, eidx);
15444            setMountPath(subStr1);
15445        }
15446
15447        AsecInstallArgs(String cid, String[] instructionSets, boolean isForwardLocked) {
15448            super(OriginInfo.fromNothing(), null, null, (isAsecExternal(cid) ? INSTALL_EXTERNAL : 0)
15449                    | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null,
15450                    instructionSets, null, null, null, 0, null /*certificates*/,
15451                    PackageManager.INSTALL_REASON_UNKNOWN);
15452            this.cid = cid;
15453            setMountPath(PackageHelper.getSdDir(cid));
15454        }
15455
15456        void createCopyFile() {
15457            cid = mInstallerService.allocateExternalStageCidLegacy();
15458        }
15459
15460        int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
15461            if (origin.staged && origin.cid != null) {
15462                if (DEBUG_INSTALL) Slog.d(TAG, origin.cid + " already staged; skipping copy");
15463                cid = origin.cid;
15464                setMountPath(PackageHelper.getSdDir(cid));
15465                return PackageManager.INSTALL_SUCCEEDED;
15466            }
15467
15468            if (temp) {
15469                createCopyFile();
15470            } else {
15471                /*
15472                 * Pre-emptively destroy the container since it's destroyed if
15473                 * copying fails due to it existing anyway.
15474                 */
15475                PackageHelper.destroySdDir(cid);
15476            }
15477
15478            final String newMountPath = imcs.copyPackageToContainer(
15479                    origin.file.getAbsolutePath(), cid, getEncryptKey(), isExternalAsec(),
15480                    isFwdLocked(), deriveAbiOverride(abiOverride, null /* settings */));
15481
15482            if (newMountPath != null) {
15483                setMountPath(newMountPath);
15484                return PackageManager.INSTALL_SUCCEEDED;
15485            } else {
15486                return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
15487            }
15488        }
15489
15490        @Override
15491        String getCodePath() {
15492            return packagePath;
15493        }
15494
15495        @Override
15496        String getResourcePath() {
15497            return resourcePath;
15498        }
15499
15500        int doPreInstall(int status) {
15501            if (status != PackageManager.INSTALL_SUCCEEDED) {
15502                // Destroy container
15503                PackageHelper.destroySdDir(cid);
15504            } else {
15505                boolean mounted = PackageHelper.isContainerMounted(cid);
15506                if (!mounted) {
15507                    String newMountPath = PackageHelper.mountSdDir(cid, getEncryptKey(),
15508                            Process.SYSTEM_UID);
15509                    if (newMountPath != null) {
15510                        setMountPath(newMountPath);
15511                    } else {
15512                        return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
15513                    }
15514                }
15515            }
15516            return status;
15517        }
15518
15519        boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
15520            String newCacheId = getNextCodePath(oldCodePath, pkg.packageName, "/" + RES_FILE_NAME);
15521            String newMountPath = null;
15522            if (PackageHelper.isContainerMounted(cid)) {
15523                // Unmount the container
15524                if (!PackageHelper.unMountSdDir(cid)) {
15525                    Slog.i(TAG, "Failed to unmount " + cid + " before renaming");
15526                    return false;
15527                }
15528            }
15529            if (!PackageHelper.renameSdDir(cid, newCacheId)) {
15530                Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId +
15531                        " which might be stale. Will try to clean up.");
15532                // Clean up the stale container and proceed to recreate.
15533                if (!PackageHelper.destroySdDir(newCacheId)) {
15534                    Slog.e(TAG, "Very strange. Cannot clean up stale container " + newCacheId);
15535                    return false;
15536                }
15537                // Successfully cleaned up stale container. Try to rename again.
15538                if (!PackageHelper.renameSdDir(cid, newCacheId)) {
15539                    Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId
15540                            + " inspite of cleaning it up.");
15541                    return false;
15542                }
15543            }
15544            if (!PackageHelper.isContainerMounted(newCacheId)) {
15545                Slog.w(TAG, "Mounting container " + newCacheId);
15546                newMountPath = PackageHelper.mountSdDir(newCacheId,
15547                        getEncryptKey(), Process.SYSTEM_UID);
15548            } else {
15549                newMountPath = PackageHelper.getSdDir(newCacheId);
15550            }
15551            if (newMountPath == null) {
15552                Slog.w(TAG, "Failed to get cache path for  " + newCacheId);
15553                return false;
15554            }
15555            Log.i(TAG, "Succesfully renamed " + cid +
15556                    " to " + newCacheId +
15557                    " at new path: " + newMountPath);
15558            cid = newCacheId;
15559
15560            final File beforeCodeFile = new File(packagePath);
15561            setMountPath(newMountPath);
15562            final File afterCodeFile = new File(packagePath);
15563
15564            // Reflect the rename in scanned details
15565            pkg.setCodePath(afterCodeFile.getAbsolutePath());
15566            pkg.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile,
15567                    afterCodeFile, pkg.baseCodePath));
15568            pkg.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile,
15569                    afterCodeFile, pkg.splitCodePaths));
15570
15571            // Reflect the rename in app info
15572            pkg.setApplicationVolumeUuid(pkg.volumeUuid);
15573            pkg.setApplicationInfoCodePath(pkg.codePath);
15574            pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
15575            pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
15576            pkg.setApplicationInfoResourcePath(pkg.codePath);
15577            pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
15578            pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
15579
15580            return true;
15581        }
15582
15583        private void setMountPath(String mountPath) {
15584            final File mountFile = new File(mountPath);
15585
15586            final File monolithicFile = new File(mountFile, RES_FILE_NAME);
15587            if (monolithicFile.exists()) {
15588                packagePath = monolithicFile.getAbsolutePath();
15589                if (isFwdLocked()) {
15590                    resourcePath = new File(mountFile, PUBLIC_RES_FILE_NAME).getAbsolutePath();
15591                } else {
15592                    resourcePath = packagePath;
15593                }
15594            } else {
15595                packagePath = mountFile.getAbsolutePath();
15596                resourcePath = packagePath;
15597            }
15598        }
15599
15600        int doPostInstall(int status, int uid) {
15601            if (status != PackageManager.INSTALL_SUCCEEDED) {
15602                cleanUp();
15603            } else {
15604                final int groupOwner;
15605                final String protectedFile;
15606                if (isFwdLocked()) {
15607                    groupOwner = UserHandle.getSharedAppGid(uid);
15608                    protectedFile = RES_FILE_NAME;
15609                } else {
15610                    groupOwner = -1;
15611                    protectedFile = null;
15612                }
15613
15614                if (uid < Process.FIRST_APPLICATION_UID
15615                        || !PackageHelper.fixSdPermissions(cid, groupOwner, protectedFile)) {
15616                    Slog.e(TAG, "Failed to finalize " + cid);
15617                    PackageHelper.destroySdDir(cid);
15618                    return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
15619                }
15620
15621                boolean mounted = PackageHelper.isContainerMounted(cid);
15622                if (!mounted) {
15623                    PackageHelper.mountSdDir(cid, getEncryptKey(), Process.myUid());
15624                }
15625            }
15626            return status;
15627        }
15628
15629        private void cleanUp() {
15630            if (DEBUG_SD_INSTALL) Slog.i(TAG, "cleanUp");
15631
15632            // Destroy secure container
15633            PackageHelper.destroySdDir(cid);
15634        }
15635
15636        private List<String> getAllCodePaths() {
15637            final File codeFile = new File(getCodePath());
15638            if (codeFile != null && codeFile.exists()) {
15639                try {
15640                    final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0);
15641                    return pkg.getAllCodePaths();
15642                } catch (PackageParserException e) {
15643                    // Ignored; we tried our best
15644                }
15645            }
15646            return Collections.EMPTY_LIST;
15647        }
15648
15649        void cleanUpResourcesLI() {
15650            // Enumerate all code paths before deleting
15651            cleanUpResourcesLI(getAllCodePaths());
15652        }
15653
15654        private void cleanUpResourcesLI(List<String> allCodePaths) {
15655            cleanUp();
15656            removeDexFiles(allCodePaths, instructionSets);
15657        }
15658
15659        String getPackageName() {
15660            return getAsecPackageName(cid);
15661        }
15662
15663        boolean doPostDeleteLI(boolean delete) {
15664            if (DEBUG_SD_INSTALL) Slog.i(TAG, "doPostDeleteLI() del=" + delete);
15665            final List<String> allCodePaths = getAllCodePaths();
15666            boolean mounted = PackageHelper.isContainerMounted(cid);
15667            if (mounted) {
15668                // Unmount first
15669                if (PackageHelper.unMountSdDir(cid)) {
15670                    mounted = false;
15671                }
15672            }
15673            if (!mounted && delete) {
15674                cleanUpResourcesLI(allCodePaths);
15675            }
15676            return !mounted;
15677        }
15678
15679        @Override
15680        int doPreCopy() {
15681            if (isFwdLocked()) {
15682                if (!PackageHelper.fixSdPermissions(cid, getPackageUid(DEFAULT_CONTAINER_PACKAGE,
15683                        MATCH_SYSTEM_ONLY, UserHandle.USER_SYSTEM), RES_FILE_NAME)) {
15684                    return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
15685                }
15686            }
15687
15688            return PackageManager.INSTALL_SUCCEEDED;
15689        }
15690
15691        @Override
15692        int doPostCopy(int uid) {
15693            if (isFwdLocked()) {
15694                if (uid < Process.FIRST_APPLICATION_UID
15695                        || !PackageHelper.fixSdPermissions(cid, UserHandle.getSharedAppGid(uid),
15696                                RES_FILE_NAME)) {
15697                    Slog.e(TAG, "Failed to finalize " + cid);
15698                    PackageHelper.destroySdDir(cid);
15699                    return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
15700                }
15701            }
15702
15703            return PackageManager.INSTALL_SUCCEEDED;
15704        }
15705    }
15706
15707    /**
15708     * Logic to handle movement of existing installed applications.
15709     */
15710    class MoveInstallArgs extends InstallArgs {
15711        private File codeFile;
15712        private File resourceFile;
15713
15714        /** New install */
15715        MoveInstallArgs(InstallParams params) {
15716            super(params.origin, params.move, params.observer, params.installFlags,
15717                    params.installerPackageName, params.volumeUuid,
15718                    params.getUser(), null /* instruction sets */, params.packageAbiOverride,
15719                    params.grantedRuntimePermissions,
15720                    params.traceMethod, params.traceCookie, params.certificates,
15721                    params.installReason);
15722        }
15723
15724        int copyApk(IMediaContainerService imcs, boolean temp) {
15725            if (DEBUG_INSTALL) Slog.d(TAG, "Moving " + move.packageName + " from "
15726                    + move.fromUuid + " to " + move.toUuid);
15727            synchronized (mInstaller) {
15728                try {
15729                    mInstaller.moveCompleteApp(move.fromUuid, move.toUuid, move.packageName,
15730                            move.dataAppName, move.appId, move.seinfo, move.targetSdkVersion);
15731                } catch (InstallerException e) {
15732                    Slog.w(TAG, "Failed to move app", e);
15733                    return PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
15734                }
15735            }
15736
15737            codeFile = new File(Environment.getDataAppDirectory(move.toUuid), move.dataAppName);
15738            resourceFile = codeFile;
15739            if (DEBUG_INSTALL) Slog.d(TAG, "codeFile after move is " + codeFile);
15740
15741            return PackageManager.INSTALL_SUCCEEDED;
15742        }
15743
15744        int doPreInstall(int status) {
15745            if (status != PackageManager.INSTALL_SUCCEEDED) {
15746                cleanUp(move.toUuid);
15747            }
15748            return status;
15749        }
15750
15751        boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
15752            if (status != PackageManager.INSTALL_SUCCEEDED) {
15753                cleanUp(move.toUuid);
15754                return false;
15755            }
15756
15757            // Reflect the move in app info
15758            pkg.setApplicationVolumeUuid(pkg.volumeUuid);
15759            pkg.setApplicationInfoCodePath(pkg.codePath);
15760            pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
15761            pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
15762            pkg.setApplicationInfoResourcePath(pkg.codePath);
15763            pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
15764            pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
15765
15766            return true;
15767        }
15768
15769        int doPostInstall(int status, int uid) {
15770            if (status == PackageManager.INSTALL_SUCCEEDED) {
15771                cleanUp(move.fromUuid);
15772            } else {
15773                cleanUp(move.toUuid);
15774            }
15775            return status;
15776        }
15777
15778        @Override
15779        String getCodePath() {
15780            return (codeFile != null) ? codeFile.getAbsolutePath() : null;
15781        }
15782
15783        @Override
15784        String getResourcePath() {
15785            return (resourceFile != null) ? resourceFile.getAbsolutePath() : null;
15786        }
15787
15788        private boolean cleanUp(String volumeUuid) {
15789            final File codeFile = new File(Environment.getDataAppDirectory(volumeUuid),
15790                    move.dataAppName);
15791            Slog.d(TAG, "Cleaning up " + move.packageName + " on " + volumeUuid);
15792            final int[] userIds = sUserManager.getUserIds();
15793            synchronized (mInstallLock) {
15794                // Clean up both app data and code
15795                // All package moves are frozen until finished
15796                for (int userId : userIds) {
15797                    try {
15798                        mInstaller.destroyAppData(volumeUuid, move.packageName, userId,
15799                                StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE, 0);
15800                    } catch (InstallerException e) {
15801                        Slog.w(TAG, String.valueOf(e));
15802                    }
15803                }
15804                removeCodePathLI(codeFile);
15805            }
15806            return true;
15807        }
15808
15809        void cleanUpResourcesLI() {
15810            throw new UnsupportedOperationException();
15811        }
15812
15813        boolean doPostDeleteLI(boolean delete) {
15814            throw new UnsupportedOperationException();
15815        }
15816    }
15817
15818    static String getAsecPackageName(String packageCid) {
15819        int idx = packageCid.lastIndexOf("-");
15820        if (idx == -1) {
15821            return packageCid;
15822        }
15823        return packageCid.substring(0, idx);
15824    }
15825
15826    // Utility method used to create code paths based on package name and available index.
15827    private static String getNextCodePath(String oldCodePath, String prefix, String suffix) {
15828        String idxStr = "";
15829        int idx = 1;
15830        // Fall back to default value of idx=1 if prefix is not
15831        // part of oldCodePath
15832        if (oldCodePath != null) {
15833            String subStr = oldCodePath;
15834            // Drop the suffix right away
15835            if (suffix != null && subStr.endsWith(suffix)) {
15836                subStr = subStr.substring(0, subStr.length() - suffix.length());
15837            }
15838            // If oldCodePath already contains prefix find out the
15839            // ending index to either increment or decrement.
15840            int sidx = subStr.lastIndexOf(prefix);
15841            if (sidx != -1) {
15842                subStr = subStr.substring(sidx + prefix.length());
15843                if (subStr != null) {
15844                    if (subStr.startsWith(INSTALL_PACKAGE_SUFFIX)) {
15845                        subStr = subStr.substring(INSTALL_PACKAGE_SUFFIX.length());
15846                    }
15847                    try {
15848                        idx = Integer.parseInt(subStr);
15849                        if (idx <= 1) {
15850                            idx++;
15851                        } else {
15852                            idx--;
15853                        }
15854                    } catch(NumberFormatException e) {
15855                    }
15856                }
15857            }
15858        }
15859        idxStr = INSTALL_PACKAGE_SUFFIX + Integer.toString(idx);
15860        return prefix + idxStr;
15861    }
15862
15863    private File getNextCodePath(File targetDir, String packageName) {
15864        File result;
15865        SecureRandom random = new SecureRandom();
15866        byte[] bytes = new byte[16];
15867        do {
15868            random.nextBytes(bytes);
15869            String suffix = Base64.encodeToString(bytes, Base64.URL_SAFE | Base64.NO_WRAP);
15870            result = new File(targetDir, packageName + "-" + suffix);
15871        } while (result.exists());
15872        return result;
15873    }
15874
15875    // Utility method that returns the relative package path with respect
15876    // to the installation directory. Like say for /data/data/com.test-1.apk
15877    // string com.test-1 is returned.
15878    static String deriveCodePathName(String codePath) {
15879        if (codePath == null) {
15880            return null;
15881        }
15882        final File codeFile = new File(codePath);
15883        final String name = codeFile.getName();
15884        if (codeFile.isDirectory()) {
15885            return name;
15886        } else if (name.endsWith(".apk") || name.endsWith(".tmp")) {
15887            final int lastDot = name.lastIndexOf('.');
15888            return name.substring(0, lastDot);
15889        } else {
15890            Slog.w(TAG, "Odd, " + codePath + " doesn't look like an APK");
15891            return null;
15892        }
15893    }
15894
15895    static class PackageInstalledInfo {
15896        String name;
15897        int uid;
15898        // The set of users that originally had this package installed.
15899        int[] origUsers;
15900        // The set of users that now have this package installed.
15901        int[] newUsers;
15902        PackageParser.Package pkg;
15903        int returnCode;
15904        String returnMsg;
15905        PackageRemovedInfo removedInfo;
15906        ArrayMap<String, PackageInstalledInfo> addedChildPackages;
15907
15908        public void setError(int code, String msg) {
15909            setReturnCode(code);
15910            setReturnMessage(msg);
15911            Slog.w(TAG, msg);
15912        }
15913
15914        public void setError(String msg, PackageParserException e) {
15915            setReturnCode(e.error);
15916            setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e));
15917            Slog.w(TAG, msg, e);
15918        }
15919
15920        public void setError(String msg, PackageManagerException e) {
15921            returnCode = e.error;
15922            setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e));
15923            Slog.w(TAG, msg, e);
15924        }
15925
15926        public void setReturnCode(int returnCode) {
15927            this.returnCode = returnCode;
15928            final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
15929            for (int i = 0; i < childCount; i++) {
15930                addedChildPackages.valueAt(i).returnCode = returnCode;
15931            }
15932        }
15933
15934        private void setReturnMessage(String returnMsg) {
15935            this.returnMsg = returnMsg;
15936            final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
15937            for (int i = 0; i < childCount; i++) {
15938                addedChildPackages.valueAt(i).returnMsg = returnMsg;
15939            }
15940        }
15941
15942        // In some error cases we want to convey more info back to the observer
15943        String origPackage;
15944        String origPermission;
15945    }
15946
15947    /*
15948     * Install a non-existing package.
15949     */
15950    private void installNewPackageLIF(PackageParser.Package pkg, final int policyFlags,
15951            int scanFlags, UserHandle user, String installerPackageName, String volumeUuid,
15952            PackageInstalledInfo res, int installReason) {
15953        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installNewPackage");
15954
15955        // Remember this for later, in case we need to rollback this install
15956        String pkgName = pkg.packageName;
15957
15958        if (DEBUG_INSTALL) Slog.d(TAG, "installNewPackageLI: " + pkg);
15959
15960        synchronized(mPackages) {
15961            final String renamedPackage = mSettings.getRenamedPackageLPr(pkgName);
15962            if (renamedPackage != null) {
15963                // A package with the same name is already installed, though
15964                // it has been renamed to an older name.  The package we
15965                // are trying to install should be installed as an update to
15966                // the existing one, but that has not been requested, so bail.
15967                res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName
15968                        + " without first uninstalling package running as "
15969                        + renamedPackage);
15970                return;
15971            }
15972            if (mPackages.containsKey(pkgName)) {
15973                // Don't allow installation over an existing package with the same name.
15974                res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName
15975                        + " without first uninstalling.");
15976                return;
15977            }
15978        }
15979
15980        try {
15981            PackageParser.Package newPackage = scanPackageTracedLI(pkg, policyFlags, scanFlags,
15982                    System.currentTimeMillis(), user);
15983
15984            updateSettingsLI(newPackage, installerPackageName, null, res, user, installReason);
15985
15986            if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
15987                prepareAppDataAfterInstallLIF(newPackage);
15988
15989            } else {
15990                // Remove package from internal structures, but keep around any
15991                // data that might have already existed
15992                deletePackageLIF(pkgName, UserHandle.ALL, false, null,
15993                        PackageManager.DELETE_KEEP_DATA, res.removedInfo, true, null);
15994            }
15995        } catch (PackageManagerException e) {
15996            res.setError("Package couldn't be installed in " + pkg.codePath, e);
15997        }
15998
15999        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16000    }
16001
16002    private boolean shouldCheckUpgradeKeySetLP(PackageSetting oldPs, int scanFlags) {
16003        // Can't rotate keys during boot or if sharedUser.
16004        if (oldPs == null || (scanFlags&SCAN_INITIAL) != 0 || oldPs.sharedUser != null
16005                || !oldPs.keySetData.isUsingUpgradeKeySets()) {
16006            return false;
16007        }
16008        // app is using upgradeKeySets; make sure all are valid
16009        KeySetManagerService ksms = mSettings.mKeySetManagerService;
16010        long[] upgradeKeySets = oldPs.keySetData.getUpgradeKeySets();
16011        for (int i = 0; i < upgradeKeySets.length; i++) {
16012            if (!ksms.isIdValidKeySetId(upgradeKeySets[i])) {
16013                Slog.wtf(TAG, "Package "
16014                         + (oldPs.name != null ? oldPs.name : "<null>")
16015                         + " contains upgrade-key-set reference to unknown key-set: "
16016                         + upgradeKeySets[i]
16017                         + " reverting to signatures check.");
16018                return false;
16019            }
16020        }
16021        return true;
16022    }
16023
16024    private boolean checkUpgradeKeySetLP(PackageSetting oldPS, PackageParser.Package newPkg) {
16025        // Upgrade keysets are being used.  Determine if new package has a superset of the
16026        // required keys.
16027        long[] upgradeKeySets = oldPS.keySetData.getUpgradeKeySets();
16028        KeySetManagerService ksms = mSettings.mKeySetManagerService;
16029        for (int i = 0; i < upgradeKeySets.length; i++) {
16030            Set<PublicKey> upgradeSet = ksms.getPublicKeysFromKeySetLPr(upgradeKeySets[i]);
16031            if (upgradeSet != null && newPkg.mSigningKeys.containsAll(upgradeSet)) {
16032                return true;
16033            }
16034        }
16035        return false;
16036    }
16037
16038    private static void updateDigest(MessageDigest digest, File file) throws IOException {
16039        try (DigestInputStream digestStream =
16040                new DigestInputStream(new FileInputStream(file), digest)) {
16041            while (digestStream.read() != -1) {} // nothing to do; just plow through the file
16042        }
16043    }
16044
16045    private void replacePackageLIF(PackageParser.Package pkg, final int policyFlags, int scanFlags,
16046            UserHandle user, String installerPackageName, PackageInstalledInfo res,
16047            int installReason) {
16048        final boolean isInstantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
16049
16050        final PackageParser.Package oldPackage;
16051        final String pkgName = pkg.packageName;
16052        final int[] allUsers;
16053        final int[] installedUsers;
16054
16055        synchronized(mPackages) {
16056            oldPackage = mPackages.get(pkgName);
16057            if (DEBUG_INSTALL) Slog.d(TAG, "replacePackageLI: new=" + pkg + ", old=" + oldPackage);
16058
16059            // don't allow upgrade to target a release SDK from a pre-release SDK
16060            final boolean oldTargetsPreRelease = oldPackage.applicationInfo.targetSdkVersion
16061                    == android.os.Build.VERSION_CODES.CUR_DEVELOPMENT;
16062            final boolean newTargetsPreRelease = pkg.applicationInfo.targetSdkVersion
16063                    == android.os.Build.VERSION_CODES.CUR_DEVELOPMENT;
16064            if (oldTargetsPreRelease
16065                    && !newTargetsPreRelease
16066                    && ((policyFlags & PackageParser.PARSE_FORCE_SDK) == 0)) {
16067                Slog.w(TAG, "Can't install package targeting released sdk");
16068                res.setReturnCode(PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE);
16069                return;
16070            }
16071
16072            final PackageSetting ps = mSettings.mPackages.get(pkgName);
16073
16074            // verify signatures are valid
16075            if (shouldCheckUpgradeKeySetLP(ps, scanFlags)) {
16076                if (!checkUpgradeKeySetLP(ps, pkg)) {
16077                    res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
16078                            "New package not signed by keys specified by upgrade-keysets: "
16079                                    + pkgName);
16080                    return;
16081                }
16082            } else {
16083                // default to original signature matching
16084                if (compareSignatures(oldPackage.mSignatures, pkg.mSignatures)
16085                        != PackageManager.SIGNATURE_MATCH) {
16086                    res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
16087                            "New package has a different signature: " + pkgName);
16088                    return;
16089                }
16090            }
16091
16092            // don't allow a system upgrade unless the upgrade hash matches
16093            if (oldPackage.restrictUpdateHash != null && oldPackage.isSystemApp()) {
16094                byte[] digestBytes = null;
16095                try {
16096                    final MessageDigest digest = MessageDigest.getInstance("SHA-512");
16097                    updateDigest(digest, new File(pkg.baseCodePath));
16098                    if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) {
16099                        for (String path : pkg.splitCodePaths) {
16100                            updateDigest(digest, new File(path));
16101                        }
16102                    }
16103                    digestBytes = digest.digest();
16104                } catch (NoSuchAlgorithmException | IOException e) {
16105                    res.setError(INSTALL_FAILED_INVALID_APK,
16106                            "Could not compute hash: " + pkgName);
16107                    return;
16108                }
16109                if (!Arrays.equals(oldPackage.restrictUpdateHash, digestBytes)) {
16110                    res.setError(INSTALL_FAILED_INVALID_APK,
16111                            "New package fails restrict-update check: " + pkgName);
16112                    return;
16113                }
16114                // retain upgrade restriction
16115                pkg.restrictUpdateHash = oldPackage.restrictUpdateHash;
16116            }
16117
16118            // Check for shared user id changes
16119            String invalidPackageName =
16120                    getParentOrChildPackageChangedSharedUser(oldPackage, pkg);
16121            if (invalidPackageName != null) {
16122                res.setError(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
16123                        "Package " + invalidPackageName + " tried to change user "
16124                                + oldPackage.mSharedUserId);
16125                return;
16126            }
16127
16128            // In case of rollback, remember per-user/profile install state
16129            allUsers = sUserManager.getUserIds();
16130            installedUsers = ps.queryInstalledUsers(allUsers, true);
16131
16132            // don't allow an upgrade from full to ephemeral
16133            if (isInstantApp) {
16134                if (user == null || user.getIdentifier() == UserHandle.USER_ALL) {
16135                    for (int currentUser : allUsers) {
16136                        if (!ps.getInstantApp(currentUser)) {
16137                            // can't downgrade from full to instant
16138                            Slog.w(TAG, "Can't replace full app with instant app: " + pkgName
16139                                    + " for user: " + currentUser);
16140                            res.setReturnCode(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
16141                            return;
16142                        }
16143                    }
16144                } else if (!ps.getInstantApp(user.getIdentifier())) {
16145                    // can't downgrade from full to instant
16146                    Slog.w(TAG, "Can't replace full app with instant app: " + pkgName
16147                            + " for user: " + user.getIdentifier());
16148                    res.setReturnCode(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
16149                    return;
16150                }
16151            }
16152        }
16153
16154        // Update what is removed
16155        res.removedInfo = new PackageRemovedInfo();
16156        res.removedInfo.uid = oldPackage.applicationInfo.uid;
16157        res.removedInfo.removedPackage = oldPackage.packageName;
16158        res.removedInfo.isStaticSharedLib = pkg.staticSharedLibName != null;
16159        res.removedInfo.isUpdate = true;
16160        res.removedInfo.origUsers = installedUsers;
16161        final PackageSetting ps = mSettings.getPackageLPr(pkgName);
16162        res.removedInfo.installReasons = new SparseArray<>(installedUsers.length);
16163        for (int i = 0; i < installedUsers.length; i++) {
16164            final int userId = installedUsers[i];
16165            res.removedInfo.installReasons.put(userId, ps.getInstallReason(userId));
16166        }
16167
16168        final int childCount = (oldPackage.childPackages != null)
16169                ? oldPackage.childPackages.size() : 0;
16170        for (int i = 0; i < childCount; i++) {
16171            boolean childPackageUpdated = false;
16172            PackageParser.Package childPkg = oldPackage.childPackages.get(i);
16173            final PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName);
16174            if (res.addedChildPackages != null) {
16175                PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName);
16176                if (childRes != null) {
16177                    childRes.removedInfo.uid = childPkg.applicationInfo.uid;
16178                    childRes.removedInfo.removedPackage = childPkg.packageName;
16179                    childRes.removedInfo.isUpdate = true;
16180                    childRes.removedInfo.installReasons = res.removedInfo.installReasons;
16181                    childPackageUpdated = true;
16182                }
16183            }
16184            if (!childPackageUpdated) {
16185                PackageRemovedInfo childRemovedRes = new PackageRemovedInfo();
16186                childRemovedRes.removedPackage = childPkg.packageName;
16187                childRemovedRes.isUpdate = false;
16188                childRemovedRes.dataRemoved = true;
16189                synchronized (mPackages) {
16190                    if (childPs != null) {
16191                        childRemovedRes.origUsers = childPs.queryInstalledUsers(allUsers, true);
16192                    }
16193                }
16194                if (res.removedInfo.removedChildPackages == null) {
16195                    res.removedInfo.removedChildPackages = new ArrayMap<>();
16196                }
16197                res.removedInfo.removedChildPackages.put(childPkg.packageName, childRemovedRes);
16198            }
16199        }
16200
16201        boolean sysPkg = (isSystemApp(oldPackage));
16202        if (sysPkg) {
16203            // Set the system/privileged flags as needed
16204            final boolean privileged =
16205                    (oldPackage.applicationInfo.privateFlags
16206                            & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0;
16207            final int systemPolicyFlags = policyFlags
16208                    | PackageParser.PARSE_IS_SYSTEM
16209                    | (privileged ? PackageParser.PARSE_IS_PRIVILEGED : 0);
16210
16211            replaceSystemPackageLIF(oldPackage, pkg, systemPolicyFlags, scanFlags,
16212                    user, allUsers, installerPackageName, res, installReason);
16213        } else {
16214            replaceNonSystemPackageLIF(oldPackage, pkg, policyFlags, scanFlags,
16215                    user, allUsers, installerPackageName, res, installReason);
16216        }
16217    }
16218
16219    public List<String> getPreviousCodePaths(String packageName) {
16220        final PackageSetting ps = mSettings.mPackages.get(packageName);
16221        final List<String> result = new ArrayList<String>();
16222        if (ps != null && ps.oldCodePaths != null) {
16223            result.addAll(ps.oldCodePaths);
16224        }
16225        return result;
16226    }
16227
16228    private void replaceNonSystemPackageLIF(PackageParser.Package deletedPackage,
16229            PackageParser.Package pkg, final int policyFlags, int scanFlags, UserHandle user,
16230            int[] allUsers, String installerPackageName, PackageInstalledInfo res,
16231            int installReason) {
16232        if (DEBUG_INSTALL) Slog.d(TAG, "replaceNonSystemPackageLI: new=" + pkg + ", old="
16233                + deletedPackage);
16234
16235        String pkgName = deletedPackage.packageName;
16236        boolean deletedPkg = true;
16237        boolean addedPkg = false;
16238        boolean updatedSettings = false;
16239        final boolean killApp = (scanFlags & SCAN_DONT_KILL_APP) == 0;
16240        final int deleteFlags = PackageManager.DELETE_KEEP_DATA
16241                | (killApp ? 0 : PackageManager.DELETE_DONT_KILL_APP);
16242
16243        final long origUpdateTime = (pkg.mExtras != null)
16244                ? ((PackageSetting)pkg.mExtras).lastUpdateTime : 0;
16245
16246        // First delete the existing package while retaining the data directory
16247        if (!deletePackageLIF(pkgName, null, true, allUsers, deleteFlags,
16248                res.removedInfo, true, pkg)) {
16249            // If the existing package wasn't successfully deleted
16250            res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE, "replaceNonSystemPackageLI");
16251            deletedPkg = false;
16252        } else {
16253            // Successfully deleted the old package; proceed with replace.
16254
16255            // If deleted package lived in a container, give users a chance to
16256            // relinquish resources before killing.
16257            if (deletedPackage.isForwardLocked() || isExternal(deletedPackage)) {
16258                if (DEBUG_INSTALL) {
16259                    Slog.i(TAG, "upgrading pkg " + deletedPackage + " is ASEC-hosted -> UNAVAILABLE");
16260                }
16261                final int[] uidArray = new int[] { deletedPackage.applicationInfo.uid };
16262                final ArrayList<String> pkgList = new ArrayList<String>(1);
16263                pkgList.add(deletedPackage.applicationInfo.packageName);
16264                sendResourcesChangedBroadcast(false, true, pkgList, uidArray, null);
16265            }
16266
16267            clearAppDataLIF(pkg, UserHandle.USER_ALL, StorageManager.FLAG_STORAGE_DE
16268                    | StorageManager.FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
16269            clearAppProfilesLIF(deletedPackage, UserHandle.USER_ALL);
16270
16271            try {
16272                final PackageParser.Package newPackage = scanPackageTracedLI(pkg, policyFlags,
16273                        scanFlags | SCAN_UPDATE_TIME, System.currentTimeMillis(), user);
16274                updateSettingsLI(newPackage, installerPackageName, allUsers, res, user,
16275                        installReason);
16276
16277                // Update the in-memory copy of the previous code paths.
16278                PackageSetting ps = mSettings.mPackages.get(pkgName);
16279                if (!killApp) {
16280                    if (ps.oldCodePaths == null) {
16281                        ps.oldCodePaths = new ArraySet<>();
16282                    }
16283                    Collections.addAll(ps.oldCodePaths, deletedPackage.baseCodePath);
16284                    if (deletedPackage.splitCodePaths != null) {
16285                        Collections.addAll(ps.oldCodePaths, deletedPackage.splitCodePaths);
16286                    }
16287                } else {
16288                    ps.oldCodePaths = null;
16289                }
16290                if (ps.childPackageNames != null) {
16291                    for (int i = ps.childPackageNames.size() - 1; i >= 0; --i) {
16292                        final String childPkgName = ps.childPackageNames.get(i);
16293                        final PackageSetting childPs = mSettings.mPackages.get(childPkgName);
16294                        childPs.oldCodePaths = ps.oldCodePaths;
16295                    }
16296                }
16297                // set instant app status, but, only if it's explicitly specified
16298                final boolean instantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
16299                final boolean fullApp = (scanFlags & SCAN_AS_FULL_APP) != 0;
16300                setInstantAppForUser(ps, user.getIdentifier(), instantApp, fullApp);
16301                prepareAppDataAfterInstallLIF(newPackage);
16302                addedPkg = true;
16303                mDexManager.notifyPackageUpdated(newPackage.packageName,
16304                        newPackage.baseCodePath, newPackage.splitCodePaths);
16305            } catch (PackageManagerException e) {
16306                res.setError("Package couldn't be installed in " + pkg.codePath, e);
16307            }
16308        }
16309
16310        if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
16311            if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, rolling pack: " + pkgName);
16312
16313            // Revert all internal state mutations and added folders for the failed install
16314            if (addedPkg) {
16315                deletePackageLIF(pkgName, null, true, allUsers, deleteFlags,
16316                        res.removedInfo, true, null);
16317            }
16318
16319            // Restore the old package
16320            if (deletedPkg) {
16321                if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, reinstalling: " + deletedPackage);
16322                File restoreFile = new File(deletedPackage.codePath);
16323                // Parse old package
16324                boolean oldExternal = isExternal(deletedPackage);
16325                int oldParseFlags  = mDefParseFlags | PackageParser.PARSE_CHATTY |
16326                        (deletedPackage.isForwardLocked() ? PackageParser.PARSE_FORWARD_LOCK : 0) |
16327                        (oldExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0);
16328                int oldScanFlags = SCAN_UPDATE_SIGNATURE | SCAN_UPDATE_TIME;
16329                try {
16330                    scanPackageTracedLI(restoreFile, oldParseFlags, oldScanFlags, origUpdateTime,
16331                            null);
16332                } catch (PackageManagerException e) {
16333                    Slog.e(TAG, "Failed to restore package : " + pkgName + " after failed upgrade: "
16334                            + e.getMessage());
16335                    return;
16336                }
16337
16338                synchronized (mPackages) {
16339                    // Ensure the installer package name up to date
16340                    setInstallerPackageNameLPw(deletedPackage, installerPackageName);
16341
16342                    // Update permissions for restored package
16343                    updatePermissionsLPw(deletedPackage, UPDATE_PERMISSIONS_ALL);
16344
16345                    mSettings.writeLPr();
16346                }
16347
16348                Slog.i(TAG, "Successfully restored package : " + pkgName + " after failed upgrade");
16349            }
16350        } else {
16351            synchronized (mPackages) {
16352                PackageSetting ps = mSettings.getPackageLPr(pkg.packageName);
16353                if (ps != null) {
16354                    res.removedInfo.removedForAllUsers = mPackages.get(ps.name) == null;
16355                    if (res.removedInfo.removedChildPackages != null) {
16356                        final int childCount = res.removedInfo.removedChildPackages.size();
16357                        // Iterate in reverse as we may modify the collection
16358                        for (int i = childCount - 1; i >= 0; i--) {
16359                            String childPackageName = res.removedInfo.removedChildPackages.keyAt(i);
16360                            if (res.addedChildPackages.containsKey(childPackageName)) {
16361                                res.removedInfo.removedChildPackages.removeAt(i);
16362                            } else {
16363                                PackageRemovedInfo childInfo = res.removedInfo
16364                                        .removedChildPackages.valueAt(i);
16365                                childInfo.removedForAllUsers = mPackages.get(
16366                                        childInfo.removedPackage) == null;
16367                            }
16368                        }
16369                    }
16370                }
16371            }
16372        }
16373    }
16374
16375    private void replaceSystemPackageLIF(PackageParser.Package deletedPackage,
16376            PackageParser.Package pkg, final int policyFlags, int scanFlags, UserHandle user,
16377            int[] allUsers, String installerPackageName, PackageInstalledInfo res,
16378            int installReason) {
16379        if (DEBUG_INSTALL) Slog.d(TAG, "replaceSystemPackageLI: new=" + pkg
16380                + ", old=" + deletedPackage);
16381
16382        final boolean disabledSystem;
16383
16384        // Remove existing system package
16385        removePackageLI(deletedPackage, true);
16386
16387        synchronized (mPackages) {
16388            disabledSystem = disableSystemPackageLPw(deletedPackage, pkg);
16389        }
16390        if (!disabledSystem) {
16391            // We didn't need to disable the .apk as a current system package,
16392            // which means we are replacing another update that is already
16393            // installed.  We need to make sure to delete the older one's .apk.
16394            res.removedInfo.args = createInstallArgsForExisting(0,
16395                    deletedPackage.applicationInfo.getCodePath(),
16396                    deletedPackage.applicationInfo.getResourcePath(),
16397                    getAppDexInstructionSets(deletedPackage.applicationInfo));
16398        } else {
16399            res.removedInfo.args = null;
16400        }
16401
16402        // Successfully disabled the old package. Now proceed with re-installation
16403        clearAppDataLIF(pkg, UserHandle.USER_ALL, StorageManager.FLAG_STORAGE_DE
16404                | StorageManager.FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
16405        clearAppProfilesLIF(deletedPackage, UserHandle.USER_ALL);
16406
16407        res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
16408        pkg.setApplicationInfoFlags(ApplicationInfo.FLAG_UPDATED_SYSTEM_APP,
16409                ApplicationInfo.FLAG_UPDATED_SYSTEM_APP);
16410
16411        PackageParser.Package newPackage = null;
16412        try {
16413            // Add the package to the internal data structures
16414            newPackage = scanPackageTracedLI(pkg, policyFlags, scanFlags, 0, user);
16415
16416            // Set the update and install times
16417            PackageSetting deletedPkgSetting = (PackageSetting) deletedPackage.mExtras;
16418            setInstallAndUpdateTime(newPackage, deletedPkgSetting.firstInstallTime,
16419                    System.currentTimeMillis());
16420
16421            // Update the package dynamic state if succeeded
16422            if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
16423                // Now that the install succeeded make sure we remove data
16424                // directories for any child package the update removed.
16425                final int deletedChildCount = (deletedPackage.childPackages != null)
16426                        ? deletedPackage.childPackages.size() : 0;
16427                final int newChildCount = (newPackage.childPackages != null)
16428                        ? newPackage.childPackages.size() : 0;
16429                for (int i = 0; i < deletedChildCount; i++) {
16430                    PackageParser.Package deletedChildPkg = deletedPackage.childPackages.get(i);
16431                    boolean childPackageDeleted = true;
16432                    for (int j = 0; j < newChildCount; j++) {
16433                        PackageParser.Package newChildPkg = newPackage.childPackages.get(j);
16434                        if (deletedChildPkg.packageName.equals(newChildPkg.packageName)) {
16435                            childPackageDeleted = false;
16436                            break;
16437                        }
16438                    }
16439                    if (childPackageDeleted) {
16440                        PackageSetting ps = mSettings.getDisabledSystemPkgLPr(
16441                                deletedChildPkg.packageName);
16442                        if (ps != null && res.removedInfo.removedChildPackages != null) {
16443                            PackageRemovedInfo removedChildRes = res.removedInfo
16444                                    .removedChildPackages.get(deletedChildPkg.packageName);
16445                            removePackageDataLIF(ps, allUsers, removedChildRes, 0, false);
16446                            removedChildRes.removedForAllUsers = mPackages.get(ps.name) == null;
16447                        }
16448                    }
16449                }
16450
16451                updateSettingsLI(newPackage, installerPackageName, allUsers, res, user,
16452                        installReason);
16453                prepareAppDataAfterInstallLIF(newPackage);
16454
16455                mDexManager.notifyPackageUpdated(newPackage.packageName,
16456                            newPackage.baseCodePath, newPackage.splitCodePaths);
16457            }
16458        } catch (PackageManagerException e) {
16459            res.setReturnCode(INSTALL_FAILED_INTERNAL_ERROR);
16460            res.setError("Package couldn't be installed in " + pkg.codePath, e);
16461        }
16462
16463        if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
16464            // Re installation failed. Restore old information
16465            // Remove new pkg information
16466            if (newPackage != null) {
16467                removeInstalledPackageLI(newPackage, true);
16468            }
16469            // Add back the old system package
16470            try {
16471                scanPackageTracedLI(deletedPackage, policyFlags, SCAN_UPDATE_SIGNATURE, 0, user);
16472            } catch (PackageManagerException e) {
16473                Slog.e(TAG, "Failed to restore original package: " + e.getMessage());
16474            }
16475
16476            synchronized (mPackages) {
16477                if (disabledSystem) {
16478                    enableSystemPackageLPw(deletedPackage);
16479                }
16480
16481                // Ensure the installer package name up to date
16482                setInstallerPackageNameLPw(deletedPackage, installerPackageName);
16483
16484                // Update permissions for restored package
16485                updatePermissionsLPw(deletedPackage, UPDATE_PERMISSIONS_ALL);
16486
16487                mSettings.writeLPr();
16488            }
16489
16490            Slog.i(TAG, "Successfully restored package : " + deletedPackage.packageName
16491                    + " after failed upgrade");
16492        }
16493    }
16494
16495    /**
16496     * Checks whether the parent or any of the child packages have a change shared
16497     * user. For a package to be a valid update the shred users of the parent and
16498     * the children should match. We may later support changing child shared users.
16499     * @param oldPkg The updated package.
16500     * @param newPkg The update package.
16501     * @return The shared user that change between the versions.
16502     */
16503    private String getParentOrChildPackageChangedSharedUser(PackageParser.Package oldPkg,
16504            PackageParser.Package newPkg) {
16505        // Check parent shared user
16506        if (!Objects.equals(oldPkg.mSharedUserId, newPkg.mSharedUserId)) {
16507            return newPkg.packageName;
16508        }
16509        // Check child shared users
16510        final int oldChildCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0;
16511        final int newChildCount = (newPkg.childPackages != null) ? newPkg.childPackages.size() : 0;
16512        for (int i = 0; i < newChildCount; i++) {
16513            PackageParser.Package newChildPkg = newPkg.childPackages.get(i);
16514            // If this child was present, did it have the same shared user?
16515            for (int j = 0; j < oldChildCount; j++) {
16516                PackageParser.Package oldChildPkg = oldPkg.childPackages.get(j);
16517                if (newChildPkg.packageName.equals(oldChildPkg.packageName)
16518                        && !Objects.equals(newChildPkg.mSharedUserId, oldChildPkg.mSharedUserId)) {
16519                    return newChildPkg.packageName;
16520                }
16521            }
16522        }
16523        return null;
16524    }
16525
16526    private void removeNativeBinariesLI(PackageSetting ps) {
16527        // Remove the lib path for the parent package
16528        if (ps != null) {
16529            NativeLibraryHelper.removeNativeBinariesLI(ps.legacyNativeLibraryPathString);
16530            // Remove the lib path for the child packages
16531            final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0;
16532            for (int i = 0; i < childCount; i++) {
16533                PackageSetting childPs = null;
16534                synchronized (mPackages) {
16535                    childPs = mSettings.getPackageLPr(ps.childPackageNames.get(i));
16536                }
16537                if (childPs != null) {
16538                    NativeLibraryHelper.removeNativeBinariesLI(childPs
16539                            .legacyNativeLibraryPathString);
16540                }
16541            }
16542        }
16543    }
16544
16545    private void enableSystemPackageLPw(PackageParser.Package pkg) {
16546        // Enable the parent package
16547        mSettings.enableSystemPackageLPw(pkg.packageName);
16548        // Enable the child packages
16549        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
16550        for (int i = 0; i < childCount; i++) {
16551            PackageParser.Package childPkg = pkg.childPackages.get(i);
16552            mSettings.enableSystemPackageLPw(childPkg.packageName);
16553        }
16554    }
16555
16556    private boolean disableSystemPackageLPw(PackageParser.Package oldPkg,
16557            PackageParser.Package newPkg) {
16558        // Disable the parent package (parent always replaced)
16559        boolean disabled = mSettings.disableSystemPackageLPw(oldPkg.packageName, true);
16560        // Disable the child packages
16561        final int childCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0;
16562        for (int i = 0; i < childCount; i++) {
16563            PackageParser.Package childPkg = oldPkg.childPackages.get(i);
16564            final boolean replace = newPkg.hasChildPackage(childPkg.packageName);
16565            disabled |= mSettings.disableSystemPackageLPw(childPkg.packageName, replace);
16566        }
16567        return disabled;
16568    }
16569
16570    private void setInstallerPackageNameLPw(PackageParser.Package pkg,
16571            String installerPackageName) {
16572        // Enable the parent package
16573        mSettings.setInstallerPackageName(pkg.packageName, installerPackageName);
16574        // Enable the child packages
16575        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
16576        for (int i = 0; i < childCount; i++) {
16577            PackageParser.Package childPkg = pkg.childPackages.get(i);
16578            mSettings.setInstallerPackageName(childPkg.packageName, installerPackageName);
16579        }
16580    }
16581
16582    private int[] revokeUnusedSharedUserPermissionsLPw(SharedUserSetting su, int[] allUserIds) {
16583        // Collect all used permissions in the UID
16584        ArraySet<String> usedPermissions = new ArraySet<>();
16585        final int packageCount = su.packages.size();
16586        for (int i = 0; i < packageCount; i++) {
16587            PackageSetting ps = su.packages.valueAt(i);
16588            if (ps.pkg == null) {
16589                continue;
16590            }
16591            final int requestedPermCount = ps.pkg.requestedPermissions.size();
16592            for (int j = 0; j < requestedPermCount; j++) {
16593                String permission = ps.pkg.requestedPermissions.get(j);
16594                BasePermission bp = mSettings.mPermissions.get(permission);
16595                if (bp != null) {
16596                    usedPermissions.add(permission);
16597                }
16598            }
16599        }
16600
16601        PermissionsState permissionsState = su.getPermissionsState();
16602        // Prune install permissions
16603        List<PermissionState> installPermStates = permissionsState.getInstallPermissionStates();
16604        final int installPermCount = installPermStates.size();
16605        for (int i = installPermCount - 1; i >= 0;  i--) {
16606            PermissionState permissionState = installPermStates.get(i);
16607            if (!usedPermissions.contains(permissionState.getName())) {
16608                BasePermission bp = mSettings.mPermissions.get(permissionState.getName());
16609                if (bp != null) {
16610                    permissionsState.revokeInstallPermission(bp);
16611                    permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
16612                            PackageManager.MASK_PERMISSION_FLAGS, 0);
16613                }
16614            }
16615        }
16616
16617        int[] runtimePermissionChangedUserIds = EmptyArray.INT;
16618
16619        // Prune runtime permissions
16620        for (int userId : allUserIds) {
16621            List<PermissionState> runtimePermStates = permissionsState
16622                    .getRuntimePermissionStates(userId);
16623            final int runtimePermCount = runtimePermStates.size();
16624            for (int i = runtimePermCount - 1; i >= 0; i--) {
16625                PermissionState permissionState = runtimePermStates.get(i);
16626                if (!usedPermissions.contains(permissionState.getName())) {
16627                    BasePermission bp = mSettings.mPermissions.get(permissionState.getName());
16628                    if (bp != null) {
16629                        permissionsState.revokeRuntimePermission(bp, userId);
16630                        permissionsState.updatePermissionFlags(bp, userId,
16631                                PackageManager.MASK_PERMISSION_FLAGS, 0);
16632                        runtimePermissionChangedUserIds = ArrayUtils.appendInt(
16633                                runtimePermissionChangedUserIds, userId);
16634                    }
16635                }
16636            }
16637        }
16638
16639        return runtimePermissionChangedUserIds;
16640    }
16641
16642    private void updateSettingsLI(PackageParser.Package newPackage, String installerPackageName,
16643            int[] allUsers, PackageInstalledInfo res, UserHandle user, int installReason) {
16644        // Update the parent package setting
16645        updateSettingsInternalLI(newPackage, installerPackageName, allUsers, res.origUsers,
16646                res, user, installReason);
16647        // Update the child packages setting
16648        final int childCount = (newPackage.childPackages != null)
16649                ? newPackage.childPackages.size() : 0;
16650        for (int i = 0; i < childCount; i++) {
16651            PackageParser.Package childPackage = newPackage.childPackages.get(i);
16652            PackageInstalledInfo childRes = res.addedChildPackages.get(childPackage.packageName);
16653            updateSettingsInternalLI(childPackage, installerPackageName, allUsers,
16654                    childRes.origUsers, childRes, user, installReason);
16655        }
16656    }
16657
16658    private void updateSettingsInternalLI(PackageParser.Package newPackage,
16659            String installerPackageName, int[] allUsers, int[] installedForUsers,
16660            PackageInstalledInfo res, UserHandle user, int installReason) {
16661        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");
16662
16663        String pkgName = newPackage.packageName;
16664        synchronized (mPackages) {
16665            //write settings. the installStatus will be incomplete at this stage.
16666            //note that the new package setting would have already been
16667            //added to mPackages. It hasn't been persisted yet.
16668            mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_INCOMPLETE);
16669            // TODO: Remove this write? It's also written at the end of this method
16670            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings");
16671            mSettings.writeLPr();
16672            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16673        }
16674
16675        if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + newPackage.codePath);
16676        synchronized (mPackages) {
16677            updatePermissionsLPw(newPackage.packageName, newPackage,
16678                    UPDATE_PERMISSIONS_REPLACE_PKG | (newPackage.permissions.size() > 0
16679                            ? UPDATE_PERMISSIONS_ALL : 0));
16680            // For system-bundled packages, we assume that installing an upgraded version
16681            // of the package implies that the user actually wants to run that new code,
16682            // so we enable the package.
16683            PackageSetting ps = mSettings.mPackages.get(pkgName);
16684            final int userId = user.getIdentifier();
16685            if (ps != null) {
16686                if (isSystemApp(newPackage)) {
16687                    if (DEBUG_INSTALL) {
16688                        Slog.d(TAG, "Implicitly enabling system package on upgrade: " + pkgName);
16689                    }
16690                    // Enable system package for requested users
16691                    if (res.origUsers != null) {
16692                        for (int origUserId : res.origUsers) {
16693                            if (userId == UserHandle.USER_ALL || userId == origUserId) {
16694                                ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT,
16695                                        origUserId, installerPackageName);
16696                            }
16697                        }
16698                    }
16699                    // Also convey the prior install/uninstall state
16700                    if (allUsers != null && installedForUsers != null) {
16701                        for (int currentUserId : allUsers) {
16702                            final boolean installed = ArrayUtils.contains(
16703                                    installedForUsers, currentUserId);
16704                            if (DEBUG_INSTALL) {
16705                                Slog.d(TAG, "    user " + currentUserId + " => " + installed);
16706                            }
16707                            ps.setInstalled(installed, currentUserId);
16708                        }
16709                        // these install state changes will be persisted in the
16710                        // upcoming call to mSettings.writeLPr().
16711                    }
16712                }
16713                // It's implied that when a user requests installation, they want the app to be
16714                // installed and enabled.
16715                if (userId != UserHandle.USER_ALL) {
16716                    ps.setInstalled(true, userId);
16717                    ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, userId, installerPackageName);
16718                }
16719
16720                // When replacing an existing package, preserve the original install reason for all
16721                // users that had the package installed before.
16722                final Set<Integer> previousUserIds = new ArraySet<>();
16723                if (res.removedInfo != null && res.removedInfo.installReasons != null) {
16724                    final int installReasonCount = res.removedInfo.installReasons.size();
16725                    for (int i = 0; i < installReasonCount; i++) {
16726                        final int previousUserId = res.removedInfo.installReasons.keyAt(i);
16727                        final int previousInstallReason = res.removedInfo.installReasons.valueAt(i);
16728                        ps.setInstallReason(previousInstallReason, previousUserId);
16729                        previousUserIds.add(previousUserId);
16730                    }
16731                }
16732
16733                // Set install reason for users that are having the package newly installed.
16734                if (userId == UserHandle.USER_ALL) {
16735                    for (int currentUserId : sUserManager.getUserIds()) {
16736                        if (!previousUserIds.contains(currentUserId)) {
16737                            ps.setInstallReason(installReason, currentUserId);
16738                        }
16739                    }
16740                } else if (!previousUserIds.contains(userId)) {
16741                    ps.setInstallReason(installReason, userId);
16742                }
16743                mSettings.writeKernelMappingLPr(ps);
16744            }
16745            res.name = pkgName;
16746            res.uid = newPackage.applicationInfo.uid;
16747            res.pkg = newPackage;
16748            mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_COMPLETE);
16749            mSettings.setInstallerPackageName(pkgName, installerPackageName);
16750            res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
16751            //to update install status
16752            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings");
16753            mSettings.writeLPr();
16754            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16755        }
16756
16757        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16758    }
16759
16760    private void installPackageTracedLI(InstallArgs args, PackageInstalledInfo res) {
16761        try {
16762            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installPackage");
16763            installPackageLI(args, res);
16764        } finally {
16765            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16766        }
16767    }
16768
16769    private void installPackageLI(InstallArgs args, PackageInstalledInfo res) {
16770        final int installFlags = args.installFlags;
16771        final String installerPackageName = args.installerPackageName;
16772        final String volumeUuid = args.volumeUuid;
16773        final File tmpPackageFile = new File(args.getCodePath());
16774        final boolean forwardLocked = ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0);
16775        final boolean onExternal = (((installFlags & PackageManager.INSTALL_EXTERNAL) != 0)
16776                || (args.volumeUuid != null));
16777        final boolean instantApp = ((installFlags & PackageManager.INSTALL_INSTANT_APP) != 0);
16778        final boolean fullApp = ((installFlags & PackageManager.INSTALL_FULL_APP) != 0);
16779        final boolean forceSdk = ((installFlags & PackageManager.INSTALL_FORCE_SDK) != 0);
16780        boolean replace = false;
16781        int scanFlags = SCAN_NEW_INSTALL | SCAN_UPDATE_SIGNATURE;
16782        if (args.move != null) {
16783            // moving a complete application; perform an initial scan on the new install location
16784            scanFlags |= SCAN_INITIAL;
16785        }
16786        if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) {
16787            scanFlags |= SCAN_DONT_KILL_APP;
16788        }
16789        if (instantApp) {
16790            scanFlags |= SCAN_AS_INSTANT_APP;
16791        }
16792        if (fullApp) {
16793            scanFlags |= SCAN_AS_FULL_APP;
16794        }
16795
16796        // Result object to be returned
16797        res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
16798
16799        if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile);
16800
16801        // Sanity check
16802        if (instantApp && (forwardLocked || onExternal)) {
16803            Slog.i(TAG, "Incompatible ephemeral install; fwdLocked=" + forwardLocked
16804                    + " external=" + onExternal);
16805            res.setReturnCode(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
16806            return;
16807        }
16808
16809        // Retrieve PackageSettings and parse package
16810        final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY
16811                | PackageParser.PARSE_ENFORCE_CODE
16812                | (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0)
16813                | (onExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0)
16814                | (instantApp ? PackageParser.PARSE_IS_EPHEMERAL : 0)
16815                | (forceSdk ? PackageParser.PARSE_FORCE_SDK : 0);
16816        PackageParser pp = new PackageParser();
16817        pp.setSeparateProcesses(mSeparateProcesses);
16818        pp.setDisplayMetrics(mMetrics);
16819        pp.setCallback(mPackageParserCallback);
16820
16821        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
16822        final PackageParser.Package pkg;
16823        try {
16824            pkg = pp.parsePackage(tmpPackageFile, parseFlags);
16825        } catch (PackageParserException e) {
16826            res.setError("Failed parse during installPackageLI", e);
16827            return;
16828        } finally {
16829            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16830        }
16831
16832        // Instant apps must have target SDK >= O and have targetSanboxVersion >= 2
16833        if (instantApp && pkg.applicationInfo.targetSdkVersion <= Build.VERSION_CODES.N_MR1) {
16834            Slog.w(TAG, "Instant app package " + pkg.packageName
16835                    + " does not target O, this will be a fatal error.");
16836            // STOPSHIP: Make this a fatal error
16837            pkg.applicationInfo.targetSdkVersion = Build.VERSION_CODES.O;
16838        }
16839        if (instantApp && pkg.applicationInfo.targetSandboxVersion != 2) {
16840            Slog.w(TAG, "Instant app package " + pkg.packageName
16841                    + " does not target targetSandboxVersion 2, this will be a fatal error.");
16842            // STOPSHIP: Make this a fatal error
16843            pkg.applicationInfo.targetSandboxVersion = 2;
16844        }
16845
16846        if (pkg.applicationInfo.isStaticSharedLibrary()) {
16847            // Static shared libraries have synthetic package names
16848            renameStaticSharedLibraryPackage(pkg);
16849
16850            // No static shared libs on external storage
16851            if (onExternal) {
16852                Slog.i(TAG, "Static shared libs can only be installed on internal storage.");
16853                res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
16854                        "Packages declaring static-shared libs cannot be updated");
16855                return;
16856            }
16857        }
16858
16859        // If we are installing a clustered package add results for the children
16860        if (pkg.childPackages != null) {
16861            synchronized (mPackages) {
16862                final int childCount = pkg.childPackages.size();
16863                for (int i = 0; i < childCount; i++) {
16864                    PackageParser.Package childPkg = pkg.childPackages.get(i);
16865                    PackageInstalledInfo childRes = new PackageInstalledInfo();
16866                    childRes.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
16867                    childRes.pkg = childPkg;
16868                    childRes.name = childPkg.packageName;
16869                    PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName);
16870                    if (childPs != null) {
16871                        childRes.origUsers = childPs.queryInstalledUsers(
16872                                sUserManager.getUserIds(), true);
16873                    }
16874                    if ((mPackages.containsKey(childPkg.packageName))) {
16875                        childRes.removedInfo = new PackageRemovedInfo();
16876                        childRes.removedInfo.removedPackage = childPkg.packageName;
16877                    }
16878                    if (res.addedChildPackages == null) {
16879                        res.addedChildPackages = new ArrayMap<>();
16880                    }
16881                    res.addedChildPackages.put(childPkg.packageName, childRes);
16882                }
16883            }
16884        }
16885
16886        // If package doesn't declare API override, mark that we have an install
16887        // time CPU ABI override.
16888        if (TextUtils.isEmpty(pkg.cpuAbiOverride)) {
16889            pkg.cpuAbiOverride = args.abiOverride;
16890        }
16891
16892        String pkgName = res.name = pkg.packageName;
16893        if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_TEST_ONLY) != 0) {
16894            if ((installFlags & PackageManager.INSTALL_ALLOW_TEST) == 0) {
16895                res.setError(INSTALL_FAILED_TEST_ONLY, "installPackageLI");
16896                return;
16897            }
16898        }
16899
16900        try {
16901            // either use what we've been given or parse directly from the APK
16902            if (args.certificates != null) {
16903                try {
16904                    PackageParser.populateCertificates(pkg, args.certificates);
16905                } catch (PackageParserException e) {
16906                    // there was something wrong with the certificates we were given;
16907                    // try to pull them from the APK
16908                    PackageParser.collectCertificates(pkg, parseFlags);
16909                }
16910            } else {
16911                PackageParser.collectCertificates(pkg, parseFlags);
16912            }
16913        } catch (PackageParserException e) {
16914            res.setError("Failed collect during installPackageLI", e);
16915            return;
16916        }
16917
16918        // Get rid of all references to package scan path via parser.
16919        pp = null;
16920        String oldCodePath = null;
16921        boolean systemApp = false;
16922        synchronized (mPackages) {
16923            // Check if installing already existing package
16924            if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
16925                String oldName = mSettings.getRenamedPackageLPr(pkgName);
16926                if (pkg.mOriginalPackages != null
16927                        && pkg.mOriginalPackages.contains(oldName)
16928                        && mPackages.containsKey(oldName)) {
16929                    // This package is derived from an original package,
16930                    // and this device has been updating from that original
16931                    // name.  We must continue using the original name, so
16932                    // rename the new package here.
16933                    pkg.setPackageName(oldName);
16934                    pkgName = pkg.packageName;
16935                    replace = true;
16936                    if (DEBUG_INSTALL) Slog.d(TAG, "Replacing existing renamed package: oldName="
16937                            + oldName + " pkgName=" + pkgName);
16938                } else if (mPackages.containsKey(pkgName)) {
16939                    // This package, under its official name, already exists
16940                    // on the device; we should replace it.
16941                    replace = true;
16942                    if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing pacakge: " + pkgName);
16943                }
16944
16945                // Child packages are installed through the parent package
16946                if (pkg.parentPackage != null) {
16947                    res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME,
16948                            "Package " + pkg.packageName + " is child of package "
16949                                    + pkg.parentPackage.parentPackage + ". Child packages "
16950                                    + "can be updated only through the parent package.");
16951                    return;
16952                }
16953
16954                if (replace) {
16955                    // Prevent apps opting out from runtime permissions
16956                    PackageParser.Package oldPackage = mPackages.get(pkgName);
16957                    final int oldTargetSdk = oldPackage.applicationInfo.targetSdkVersion;
16958                    final int newTargetSdk = pkg.applicationInfo.targetSdkVersion;
16959                    if (oldTargetSdk > Build.VERSION_CODES.LOLLIPOP_MR1
16960                            && newTargetSdk <= Build.VERSION_CODES.LOLLIPOP_MR1) {
16961                        res.setError(PackageManager.INSTALL_FAILED_PERMISSION_MODEL_DOWNGRADE,
16962                                "Package " + pkg.packageName + " new target SDK " + newTargetSdk
16963                                        + " doesn't support runtime permissions but the old"
16964                                        + " target SDK " + oldTargetSdk + " does.");
16965                        return;
16966                    }
16967                    // Prevent apps from downgrading their targetSandbox.
16968                    final int oldTargetSandbox = oldPackage.applicationInfo.targetSandboxVersion;
16969                    final int newTargetSandbox = pkg.applicationInfo.targetSandboxVersion;
16970                    if (oldTargetSandbox == 2 && newTargetSandbox != 2) {
16971                        res.setError(PackageManager.INSTALL_FAILED_SANDBOX_VERSION_DOWNGRADE,
16972                                "Package " + pkg.packageName + " new target sandbox "
16973                                + newTargetSandbox + " is incompatible with the previous value of"
16974                                + oldTargetSandbox + ".");
16975                        return;
16976                    }
16977
16978                    // Prevent installing of child packages
16979                    if (oldPackage.parentPackage != null) {
16980                        res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME,
16981                                "Package " + pkg.packageName + " is child of package "
16982                                        + oldPackage.parentPackage + ". Child packages "
16983                                        + "can be updated only through the parent package.");
16984                        return;
16985                    }
16986                }
16987            }
16988
16989            PackageSetting ps = mSettings.mPackages.get(pkgName);
16990            if (ps != null) {
16991                if (DEBUG_INSTALL) Slog.d(TAG, "Existing package: " + ps);
16992
16993                // Static shared libs have same package with different versions where
16994                // we internally use a synthetic package name to allow multiple versions
16995                // of the same package, therefore we need to compare signatures against
16996                // the package setting for the latest library version.
16997                PackageSetting signatureCheckPs = ps;
16998                if (pkg.applicationInfo.isStaticSharedLibrary()) {
16999                    SharedLibraryEntry libraryEntry = getLatestSharedLibraVersionLPr(pkg);
17000                    if (libraryEntry != null) {
17001                        signatureCheckPs = mSettings.getPackageLPr(libraryEntry.apk);
17002                    }
17003                }
17004
17005                // Quick sanity check that we're signed correctly if updating;
17006                // we'll check this again later when scanning, but we want to
17007                // bail early here before tripping over redefined permissions.
17008                if (shouldCheckUpgradeKeySetLP(signatureCheckPs, scanFlags)) {
17009                    if (!checkUpgradeKeySetLP(signatureCheckPs, pkg)) {
17010                        res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
17011                                + pkg.packageName + " upgrade keys do not match the "
17012                                + "previously installed version");
17013                        return;
17014                    }
17015                } else {
17016                    try {
17017                        verifySignaturesLP(signatureCheckPs, pkg);
17018                    } catch (PackageManagerException e) {
17019                        res.setError(e.error, e.getMessage());
17020                        return;
17021                    }
17022                }
17023
17024                oldCodePath = mSettings.mPackages.get(pkgName).codePathString;
17025                if (ps.pkg != null && ps.pkg.applicationInfo != null) {
17026                    systemApp = (ps.pkg.applicationInfo.flags &
17027                            ApplicationInfo.FLAG_SYSTEM) != 0;
17028                }
17029                res.origUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
17030            }
17031
17032            int N = pkg.permissions.size();
17033            for (int i = N-1; i >= 0; i--) {
17034                PackageParser.Permission perm = pkg.permissions.get(i);
17035                BasePermission bp = mSettings.mPermissions.get(perm.info.name);
17036
17037                // Don't allow anyone but the platform to define ephemeral permissions.
17038                if ((perm.info.protectionLevel & PermissionInfo.PROTECTION_FLAG_EPHEMERAL) != 0
17039                        && !PLATFORM_PACKAGE_NAME.equals(pkg.packageName)) {
17040                    Slog.w(TAG, "Package " + pkg.packageName
17041                            + " attempting to delcare ephemeral permission "
17042                            + perm.info.name + "; Removing ephemeral.");
17043                    perm.info.protectionLevel &= ~PermissionInfo.PROTECTION_FLAG_EPHEMERAL;
17044                }
17045                // Check whether the newly-scanned package wants to define an already-defined perm
17046                if (bp != null) {
17047                    // If the defining package is signed with our cert, it's okay.  This
17048                    // also includes the "updating the same package" case, of course.
17049                    // "updating same package" could also involve key-rotation.
17050                    final boolean sigsOk;
17051                    if (bp.sourcePackage.equals(pkg.packageName)
17052                            && (bp.packageSetting instanceof PackageSetting)
17053                            && (shouldCheckUpgradeKeySetLP((PackageSetting) bp.packageSetting,
17054                                    scanFlags))) {
17055                        sigsOk = checkUpgradeKeySetLP((PackageSetting) bp.packageSetting, pkg);
17056                    } else {
17057                        sigsOk = compareSignatures(bp.packageSetting.signatures.mSignatures,
17058                                pkg.mSignatures) == PackageManager.SIGNATURE_MATCH;
17059                    }
17060                    if (!sigsOk) {
17061                        // If the owning package is the system itself, we log but allow
17062                        // install to proceed; we fail the install on all other permission
17063                        // redefinitions.
17064                        if (!bp.sourcePackage.equals("android")) {
17065                            res.setError(INSTALL_FAILED_DUPLICATE_PERMISSION, "Package "
17066                                    + pkg.packageName + " attempting to redeclare permission "
17067                                    + perm.info.name + " already owned by " + bp.sourcePackage);
17068                            res.origPermission = perm.info.name;
17069                            res.origPackage = bp.sourcePackage;
17070                            return;
17071                        } else {
17072                            Slog.w(TAG, "Package " + pkg.packageName
17073                                    + " attempting to redeclare system permission "
17074                                    + perm.info.name + "; ignoring new declaration");
17075                            pkg.permissions.remove(i);
17076                        }
17077                    } else if (!PLATFORM_PACKAGE_NAME.equals(pkg.packageName)) {
17078                        // Prevent apps to change protection level to dangerous from any other
17079                        // type as this would allow a privilege escalation where an app adds a
17080                        // normal/signature permission in other app's group and later redefines
17081                        // it as dangerous leading to the group auto-grant.
17082                        if ((perm.info.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
17083                                == PermissionInfo.PROTECTION_DANGEROUS) {
17084                            if (bp != null && !bp.isRuntime()) {
17085                                Slog.w(TAG, "Package " + pkg.packageName + " trying to change a "
17086                                        + "non-runtime permission " + perm.info.name
17087                                        + " to runtime; keeping old protection level");
17088                                perm.info.protectionLevel = bp.protectionLevel;
17089                            }
17090                        }
17091                    }
17092                }
17093            }
17094        }
17095
17096        if (systemApp) {
17097            if (onExternal) {
17098                // Abort update; system app can't be replaced with app on sdcard
17099                res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
17100                        "Cannot install updates to system apps on sdcard");
17101                return;
17102            } else if (instantApp) {
17103                // Abort update; system app can't be replaced with an instant app
17104                res.setError(INSTALL_FAILED_INSTANT_APP_INVALID,
17105                        "Cannot update a system app with an instant app");
17106                return;
17107            }
17108        }
17109
17110        if (args.move != null) {
17111            // We did an in-place move, so dex is ready to roll
17112            scanFlags |= SCAN_NO_DEX;
17113            scanFlags |= SCAN_MOVE;
17114
17115            synchronized (mPackages) {
17116                final PackageSetting ps = mSettings.mPackages.get(pkgName);
17117                if (ps == null) {
17118                    res.setError(INSTALL_FAILED_INTERNAL_ERROR,
17119                            "Missing settings for moved package " + pkgName);
17120                }
17121
17122                // We moved the entire application as-is, so bring over the
17123                // previously derived ABI information.
17124                pkg.applicationInfo.primaryCpuAbi = ps.primaryCpuAbiString;
17125                pkg.applicationInfo.secondaryCpuAbi = ps.secondaryCpuAbiString;
17126            }
17127
17128        } else if (!forwardLocked && !pkg.applicationInfo.isExternalAsec()) {
17129            // Enable SCAN_NO_DEX flag to skip dexopt at a later stage
17130            scanFlags |= SCAN_NO_DEX;
17131
17132            try {
17133                String abiOverride = (TextUtils.isEmpty(pkg.cpuAbiOverride) ?
17134                    args.abiOverride : pkg.cpuAbiOverride);
17135                derivePackageAbi(pkg, new File(pkg.codePath), abiOverride,
17136                        true /*extractLibs*/, mAppLib32InstallDir);
17137            } catch (PackageManagerException pme) {
17138                Slog.e(TAG, "Error deriving application ABI", pme);
17139                res.setError(INSTALL_FAILED_INTERNAL_ERROR, "Error deriving application ABI");
17140                return;
17141            }
17142
17143            // Shared libraries for the package need to be updated.
17144            synchronized (mPackages) {
17145                try {
17146                    updateSharedLibrariesLPr(pkg, null);
17147                } catch (PackageManagerException e) {
17148                    Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
17149                }
17150            }
17151
17152            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
17153            // Do not run PackageDexOptimizer through the local performDexOpt
17154            // method because `pkg` may not be in `mPackages` yet.
17155            //
17156            // Also, don't fail application installs if the dexopt step fails.
17157            mPackageDexOptimizer.performDexOpt(pkg, pkg.usesLibraryFiles,
17158                    null /* instructionSets */, false /* checkProfiles */,
17159                    getCompilerFilterForReason(REASON_INSTALL),
17160                    getOrCreateCompilerPackageStats(pkg),
17161                    mDexManager.isUsedByOtherApps(pkg.packageName));
17162            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
17163
17164            // Notify BackgroundDexOptService that the package has been changed.
17165            // If this is an update of a package which used to fail to compile,
17166            // BDOS will remove it from its blacklist.
17167            // TODO: Layering violation
17168            BackgroundDexOptService.notifyPackageChanged(pkg.packageName);
17169        }
17170
17171        if (!args.doRename(res.returnCode, pkg, oldCodePath)) {
17172            res.setError(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename");
17173            return;
17174        }
17175
17176        startIntentFilterVerifications(args.user.getIdentifier(), replace, pkg);
17177
17178        try (PackageFreezer freezer = freezePackageForInstall(pkgName, installFlags,
17179                "installPackageLI")) {
17180            if (replace) {
17181                if (pkg.applicationInfo.isStaticSharedLibrary()) {
17182                    // Static libs have a synthetic package name containing the version
17183                    // and cannot be updated as an update would get a new package name,
17184                    // unless this is the exact same version code which is useful for
17185                    // development.
17186                    PackageParser.Package existingPkg = mPackages.get(pkg.packageName);
17187                    if (existingPkg != null && existingPkg.mVersionCode != pkg.mVersionCode) {
17188                        res.setError(INSTALL_FAILED_DUPLICATE_PACKAGE, "Packages declaring "
17189                                + "static-shared libs cannot be updated");
17190                        return;
17191                    }
17192                }
17193                replacePackageLIF(pkg, parseFlags, scanFlags | SCAN_REPLACING, args.user,
17194                        installerPackageName, res, args.installReason);
17195            } else {
17196                installNewPackageLIF(pkg, parseFlags, scanFlags | SCAN_DELETE_DATA_ON_FAILURES,
17197                        args.user, installerPackageName, volumeUuid, res, args.installReason);
17198            }
17199        }
17200
17201        synchronized (mPackages) {
17202            final PackageSetting ps = mSettings.mPackages.get(pkgName);
17203            if (ps != null) {
17204                res.newUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
17205                ps.setUpdateAvailable(false /*updateAvailable*/);
17206            }
17207
17208            final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
17209            for (int i = 0; i < childCount; i++) {
17210                PackageParser.Package childPkg = pkg.childPackages.get(i);
17211                PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName);
17212                PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName);
17213                if (childPs != null) {
17214                    childRes.newUsers = childPs.queryInstalledUsers(
17215                            sUserManager.getUserIds(), true);
17216                }
17217            }
17218
17219            if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
17220                updateSequenceNumberLP(pkgName, res.newUsers);
17221                updateInstantAppInstallerLocked(pkgName);
17222            }
17223        }
17224    }
17225
17226    private void startIntentFilterVerifications(int userId, boolean replacing,
17227            PackageParser.Package pkg) {
17228        if (mIntentFilterVerifierComponent == null) {
17229            Slog.w(TAG, "No IntentFilter verification will not be done as "
17230                    + "there is no IntentFilterVerifier available!");
17231            return;
17232        }
17233
17234        final int verifierUid = getPackageUid(
17235                mIntentFilterVerifierComponent.getPackageName(),
17236                MATCH_DEBUG_TRIAGED_MISSING,
17237                (userId == UserHandle.USER_ALL) ? UserHandle.USER_SYSTEM : userId);
17238
17239        Message msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS);
17240        msg.obj = new IFVerificationParams(pkg, replacing, userId, verifierUid);
17241        mHandler.sendMessage(msg);
17242
17243        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
17244        for (int i = 0; i < childCount; i++) {
17245            PackageParser.Package childPkg = pkg.childPackages.get(i);
17246            msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS);
17247            msg.obj = new IFVerificationParams(childPkg, replacing, userId, verifierUid);
17248            mHandler.sendMessage(msg);
17249        }
17250    }
17251
17252    private void verifyIntentFiltersIfNeeded(int userId, int verifierUid, boolean replacing,
17253            PackageParser.Package pkg) {
17254        int size = pkg.activities.size();
17255        if (size == 0) {
17256            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
17257                    "No activity, so no need to verify any IntentFilter!");
17258            return;
17259        }
17260
17261        final boolean hasDomainURLs = hasDomainURLs(pkg);
17262        if (!hasDomainURLs) {
17263            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
17264                    "No domain URLs, so no need to verify any IntentFilter!");
17265            return;
17266        }
17267
17268        if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Checking for userId:" + userId
17269                + " if any IntentFilter from the " + size
17270                + " Activities needs verification ...");
17271
17272        int count = 0;
17273        final String packageName = pkg.packageName;
17274
17275        synchronized (mPackages) {
17276            // If this is a new install and we see that we've already run verification for this
17277            // package, we have nothing to do: it means the state was restored from backup.
17278            if (!replacing) {
17279                IntentFilterVerificationInfo ivi =
17280                        mSettings.getIntentFilterVerificationLPr(packageName);
17281                if (ivi != null) {
17282                    if (DEBUG_DOMAIN_VERIFICATION) {
17283                        Slog.i(TAG, "Package " + packageName+ " already verified: status="
17284                                + ivi.getStatusString());
17285                    }
17286                    return;
17287                }
17288            }
17289
17290            // If any filters need to be verified, then all need to be.
17291            boolean needToVerify = false;
17292            for (PackageParser.Activity a : pkg.activities) {
17293                for (ActivityIntentInfo filter : a.intents) {
17294                    if (filter.needsVerification() && needsNetworkVerificationLPr(filter)) {
17295                        if (DEBUG_DOMAIN_VERIFICATION) {
17296                            Slog.d(TAG, "Intent filter needs verification, so processing all filters");
17297                        }
17298                        needToVerify = true;
17299                        break;
17300                    }
17301                }
17302            }
17303
17304            if (needToVerify) {
17305                final int verificationId = mIntentFilterVerificationToken++;
17306                for (PackageParser.Activity a : pkg.activities) {
17307                    for (ActivityIntentInfo filter : a.intents) {
17308                        if (filter.handlesWebUris(true) && needsNetworkVerificationLPr(filter)) {
17309                            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
17310                                    "Verification needed for IntentFilter:" + filter.toString());
17311                            mIntentFilterVerifier.addOneIntentFilterVerification(
17312                                    verifierUid, userId, verificationId, filter, packageName);
17313                            count++;
17314                        }
17315                    }
17316                }
17317            }
17318        }
17319
17320        if (count > 0) {
17321            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Starting " + count
17322                    + " IntentFilter verification" + (count > 1 ? "s" : "")
17323                    +  " for userId:" + userId);
17324            mIntentFilterVerifier.startVerifications(userId);
17325        } else {
17326            if (DEBUG_DOMAIN_VERIFICATION) {
17327                Slog.d(TAG, "No filters or not all autoVerify for " + packageName);
17328            }
17329        }
17330    }
17331
17332    private boolean needsNetworkVerificationLPr(ActivityIntentInfo filter) {
17333        final ComponentName cn  = filter.activity.getComponentName();
17334        final String packageName = cn.getPackageName();
17335
17336        IntentFilterVerificationInfo ivi = mSettings.getIntentFilterVerificationLPr(
17337                packageName);
17338        if (ivi == null) {
17339            return true;
17340        }
17341        int status = ivi.getStatus();
17342        switch (status) {
17343            case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED:
17344            case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK:
17345                return true;
17346
17347            default:
17348                // Nothing to do
17349                return false;
17350        }
17351    }
17352
17353    private static boolean isMultiArch(ApplicationInfo info) {
17354        return (info.flags & ApplicationInfo.FLAG_MULTIARCH) != 0;
17355    }
17356
17357    private static boolean isExternal(PackageParser.Package pkg) {
17358        return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
17359    }
17360
17361    private static boolean isExternal(PackageSetting ps) {
17362        return (ps.pkgFlags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
17363    }
17364
17365    private static boolean isSystemApp(PackageParser.Package pkg) {
17366        return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
17367    }
17368
17369    private static boolean isPrivilegedApp(PackageParser.Package pkg) {
17370        return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0;
17371    }
17372
17373    private static boolean hasDomainURLs(PackageParser.Package pkg) {
17374        return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) != 0;
17375    }
17376
17377    private static boolean isSystemApp(PackageSetting ps) {
17378        return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0;
17379    }
17380
17381    private static boolean isUpdatedSystemApp(PackageSetting ps) {
17382        return (ps.pkgFlags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
17383    }
17384
17385    private int packageFlagsToInstallFlags(PackageSetting ps) {
17386        int installFlags = 0;
17387        if (isExternal(ps) && TextUtils.isEmpty(ps.volumeUuid)) {
17388            // This existing package was an external ASEC install when we have
17389            // the external flag without a UUID
17390            installFlags |= PackageManager.INSTALL_EXTERNAL;
17391        }
17392        if (ps.isForwardLocked()) {
17393            installFlags |= PackageManager.INSTALL_FORWARD_LOCK;
17394        }
17395        return installFlags;
17396    }
17397
17398    private String getVolumeUuidForPackage(PackageParser.Package pkg) {
17399        if (isExternal(pkg)) {
17400            if (TextUtils.isEmpty(pkg.volumeUuid)) {
17401                return StorageManager.UUID_PRIMARY_PHYSICAL;
17402            } else {
17403                return pkg.volumeUuid;
17404            }
17405        } else {
17406            return StorageManager.UUID_PRIVATE_INTERNAL;
17407        }
17408    }
17409
17410    private VersionInfo getSettingsVersionForPackage(PackageParser.Package pkg) {
17411        if (isExternal(pkg)) {
17412            if (TextUtils.isEmpty(pkg.volumeUuid)) {
17413                return mSettings.getExternalVersion();
17414            } else {
17415                return mSettings.findOrCreateVersion(pkg.volumeUuid);
17416            }
17417        } else {
17418            return mSettings.getInternalVersion();
17419        }
17420    }
17421
17422    private void deleteTempPackageFiles() {
17423        final FilenameFilter filter = new FilenameFilter() {
17424            public boolean accept(File dir, String name) {
17425                return name.startsWith("vmdl") && name.endsWith(".tmp");
17426            }
17427        };
17428        for (File file : mDrmAppPrivateInstallDir.listFiles(filter)) {
17429            file.delete();
17430        }
17431    }
17432
17433    @Override
17434    public void deletePackageAsUser(String packageName, int versionCode,
17435            IPackageDeleteObserver observer, int userId, int flags) {
17436        deletePackageVersioned(new VersionedPackage(packageName, versionCode),
17437                new LegacyPackageDeleteObserver(observer).getBinder(), userId, flags);
17438    }
17439
17440    @Override
17441    public void deletePackageVersioned(VersionedPackage versionedPackage,
17442            final IPackageDeleteObserver2 observer, final int userId, final int deleteFlags) {
17443        mContext.enforceCallingOrSelfPermission(
17444                android.Manifest.permission.DELETE_PACKAGES, null);
17445        Preconditions.checkNotNull(versionedPackage);
17446        Preconditions.checkNotNull(observer);
17447        Preconditions.checkArgumentInRange(versionedPackage.getVersionCode(),
17448                PackageManager.VERSION_CODE_HIGHEST,
17449                Integer.MAX_VALUE, "versionCode must be >= -1");
17450
17451        final String packageName = versionedPackage.getPackageName();
17452        // TODO: We will change version code to long, so in the new API it is long
17453        final int versionCode = (int) versionedPackage.getVersionCode();
17454        final String internalPackageName;
17455        synchronized (mPackages) {
17456            // Normalize package name to handle renamed packages and static libs
17457            internalPackageName = resolveInternalPackageNameLPr(versionedPackage.getPackageName(),
17458                    // TODO: We will change version code to long, so in the new API it is long
17459                    (int) versionedPackage.getVersionCode());
17460        }
17461
17462        final int uid = Binder.getCallingUid();
17463        if (!isOrphaned(internalPackageName)
17464                && !isCallerAllowedToSilentlyUninstall(uid, internalPackageName)) {
17465            try {
17466                final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE);
17467                intent.setData(Uri.fromParts(PACKAGE_SCHEME, packageName, null));
17468                intent.putExtra(PackageInstaller.EXTRA_CALLBACK, observer.asBinder());
17469                observer.onUserActionRequired(intent);
17470            } catch (RemoteException re) {
17471            }
17472            return;
17473        }
17474        final boolean deleteAllUsers = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0;
17475        final int[] users = deleteAllUsers ? sUserManager.getUserIds() : new int[]{ userId };
17476        if (UserHandle.getUserId(uid) != userId || (deleteAllUsers && users.length > 1)) {
17477            mContext.enforceCallingOrSelfPermission(
17478                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
17479                    "deletePackage for user " + userId);
17480        }
17481
17482        if (isUserRestricted(userId, UserManager.DISALLOW_UNINSTALL_APPS)) {
17483            try {
17484                observer.onPackageDeleted(packageName,
17485                        PackageManager.DELETE_FAILED_USER_RESTRICTED, null);
17486            } catch (RemoteException re) {
17487            }
17488            return;
17489        }
17490
17491        if (!deleteAllUsers && getBlockUninstallForUser(internalPackageName, userId)) {
17492            try {
17493                observer.onPackageDeleted(packageName,
17494                        PackageManager.DELETE_FAILED_OWNER_BLOCKED, null);
17495            } catch (RemoteException re) {
17496            }
17497            return;
17498        }
17499
17500        if (DEBUG_REMOVE) {
17501            Slog.d(TAG, "deletePackageAsUser: pkg=" + internalPackageName + " user=" + userId
17502                    + " deleteAllUsers: " + deleteAllUsers + " version="
17503                    + (versionCode == PackageManager.VERSION_CODE_HIGHEST
17504                    ? "VERSION_CODE_HIGHEST" : versionCode));
17505        }
17506        // Queue up an async operation since the package deletion may take a little while.
17507        mHandler.post(new Runnable() {
17508            public void run() {
17509                mHandler.removeCallbacks(this);
17510                int returnCode;
17511                if (!deleteAllUsers) {
17512                    returnCode = deletePackageX(internalPackageName, versionCode,
17513                            userId, deleteFlags);
17514                } else {
17515                    int[] blockUninstallUserIds = getBlockUninstallForUsers(
17516                            internalPackageName, users);
17517                    // If nobody is blocking uninstall, proceed with delete for all users
17518                    if (ArrayUtils.isEmpty(blockUninstallUserIds)) {
17519                        returnCode = deletePackageX(internalPackageName, versionCode,
17520                                userId, deleteFlags);
17521                    } else {
17522                        // Otherwise uninstall individually for users with blockUninstalls=false
17523                        final int userFlags = deleteFlags & ~PackageManager.DELETE_ALL_USERS;
17524                        for (int userId : users) {
17525                            if (!ArrayUtils.contains(blockUninstallUserIds, userId)) {
17526                                returnCode = deletePackageX(internalPackageName, versionCode,
17527                                        userId, userFlags);
17528                                if (returnCode != PackageManager.DELETE_SUCCEEDED) {
17529                                    Slog.w(TAG, "Package delete failed for user " + userId
17530                                            + ", returnCode " + returnCode);
17531                                }
17532                            }
17533                        }
17534                        // The app has only been marked uninstalled for certain users.
17535                        // We still need to report that delete was blocked
17536                        returnCode = PackageManager.DELETE_FAILED_OWNER_BLOCKED;
17537                    }
17538                }
17539                try {
17540                    observer.onPackageDeleted(packageName, returnCode, null);
17541                } catch (RemoteException e) {
17542                    Log.i(TAG, "Observer no longer exists.");
17543                } //end catch
17544            } //end run
17545        });
17546    }
17547
17548    private String resolveExternalPackageNameLPr(PackageParser.Package pkg) {
17549        if (pkg.staticSharedLibName != null) {
17550            return pkg.manifestPackageName;
17551        }
17552        return pkg.packageName;
17553    }
17554
17555    private String resolveInternalPackageNameLPr(String packageName, int versionCode) {
17556        // Handle renamed packages
17557        String normalizedPackageName = mSettings.getRenamedPackageLPr(packageName);
17558        packageName = normalizedPackageName != null ? normalizedPackageName : packageName;
17559
17560        // Is this a static library?
17561        SparseArray<SharedLibraryEntry> versionedLib =
17562                mStaticLibsByDeclaringPackage.get(packageName);
17563        if (versionedLib == null || versionedLib.size() <= 0) {
17564            return packageName;
17565        }
17566
17567        // Figure out which lib versions the caller can see
17568        SparseIntArray versionsCallerCanSee = null;
17569        final int callingAppId = UserHandle.getAppId(Binder.getCallingUid());
17570        if (callingAppId != Process.SYSTEM_UID && callingAppId != Process.SHELL_UID
17571                && callingAppId != Process.ROOT_UID) {
17572            versionsCallerCanSee = new SparseIntArray();
17573            String libName = versionedLib.valueAt(0).info.getName();
17574            String[] uidPackages = getPackagesForUid(Binder.getCallingUid());
17575            if (uidPackages != null) {
17576                for (String uidPackage : uidPackages) {
17577                    PackageSetting ps = mSettings.getPackageLPr(uidPackage);
17578                    final int libIdx = ArrayUtils.indexOf(ps.usesStaticLibraries, libName);
17579                    if (libIdx >= 0) {
17580                        final int libVersion = ps.usesStaticLibrariesVersions[libIdx];
17581                        versionsCallerCanSee.append(libVersion, libVersion);
17582                    }
17583                }
17584            }
17585        }
17586
17587        // Caller can see nothing - done
17588        if (versionsCallerCanSee != null && versionsCallerCanSee.size() <= 0) {
17589            return packageName;
17590        }
17591
17592        // Find the version the caller can see and the app version code
17593        SharedLibraryEntry highestVersion = null;
17594        final int versionCount = versionedLib.size();
17595        for (int i = 0; i < versionCount; i++) {
17596            SharedLibraryEntry libEntry = versionedLib.valueAt(i);
17597            if (versionsCallerCanSee != null && versionsCallerCanSee.indexOfKey(
17598                    // TODO: Remove cast for lib version once internally we support longs.
17599                    (int) libEntry.info.getVersion()) < 0) {
17600                continue;
17601            }
17602            // TODO: We will change version code to long, so in the new API it is long
17603            final int libVersionCode = (int) libEntry.info.getDeclaringPackage().getVersionCode();
17604            if (versionCode != PackageManager.VERSION_CODE_HIGHEST) {
17605                if (libVersionCode == versionCode) {
17606                    return libEntry.apk;
17607                }
17608            } else if (highestVersion == null) {
17609                highestVersion = libEntry;
17610            } else if (libVersionCode  > highestVersion.info
17611                    .getDeclaringPackage().getVersionCode()) {
17612                highestVersion = libEntry;
17613            }
17614        }
17615
17616        if (highestVersion != null) {
17617            return highestVersion.apk;
17618        }
17619
17620        return packageName;
17621    }
17622
17623    private boolean isCallerAllowedToSilentlyUninstall(int callingUid, String pkgName) {
17624        if (callingUid == Process.SHELL_UID || callingUid == Process.ROOT_UID
17625              || callingUid == Process.SYSTEM_UID) {
17626            return true;
17627        }
17628        final int callingUserId = UserHandle.getUserId(callingUid);
17629        // If the caller installed the pkgName, then allow it to silently uninstall.
17630        if (callingUid == getPackageUid(getInstallerPackageName(pkgName), 0, callingUserId)) {
17631            return true;
17632        }
17633
17634        // Allow package verifier to silently uninstall.
17635        if (mRequiredVerifierPackage != null &&
17636                callingUid == getPackageUid(mRequiredVerifierPackage, 0, callingUserId)) {
17637            return true;
17638        }
17639
17640        // Allow package uninstaller to silently uninstall.
17641        if (mRequiredUninstallerPackage != null &&
17642                callingUid == getPackageUid(mRequiredUninstallerPackage, 0, callingUserId)) {
17643            return true;
17644        }
17645
17646        // Allow storage manager to silently uninstall.
17647        if (mStorageManagerPackage != null &&
17648                callingUid == getPackageUid(mStorageManagerPackage, 0, callingUserId)) {
17649            return true;
17650        }
17651        return false;
17652    }
17653
17654    private int[] getBlockUninstallForUsers(String packageName, int[] userIds) {
17655        int[] result = EMPTY_INT_ARRAY;
17656        for (int userId : userIds) {
17657            if (getBlockUninstallForUser(packageName, userId)) {
17658                result = ArrayUtils.appendInt(result, userId);
17659            }
17660        }
17661        return result;
17662    }
17663
17664    @Override
17665    public boolean isPackageDeviceAdminOnAnyUser(String packageName) {
17666        return isPackageDeviceAdmin(packageName, UserHandle.USER_ALL);
17667    }
17668
17669    private boolean isPackageDeviceAdmin(String packageName, int userId) {
17670        IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
17671                ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
17672        try {
17673            if (dpm != null) {
17674                final ComponentName deviceOwnerComponentName = dpm.getDeviceOwnerComponent(
17675                        /* callingUserOnly =*/ false);
17676                final String deviceOwnerPackageName = deviceOwnerComponentName == null ? null
17677                        : deviceOwnerComponentName.getPackageName();
17678                // Does the package contains the device owner?
17679                // TODO Do we have to do it even if userId != UserHandle.USER_ALL?  Otherwise,
17680                // this check is probably not needed, since DO should be registered as a device
17681                // admin on some user too. (Original bug for this: b/17657954)
17682                if (packageName.equals(deviceOwnerPackageName)) {
17683                    return true;
17684                }
17685                // Does it contain a device admin for any user?
17686                int[] users;
17687                if (userId == UserHandle.USER_ALL) {
17688                    users = sUserManager.getUserIds();
17689                } else {
17690                    users = new int[]{userId};
17691                }
17692                for (int i = 0; i < users.length; ++i) {
17693                    if (dpm.packageHasActiveAdmins(packageName, users[i])) {
17694                        return true;
17695                    }
17696                }
17697            }
17698        } catch (RemoteException e) {
17699        }
17700        return false;
17701    }
17702
17703    private boolean shouldKeepUninstalledPackageLPr(String packageName) {
17704        return mKeepUninstalledPackages != null && mKeepUninstalledPackages.contains(packageName);
17705    }
17706
17707    /**
17708     *  This method is an internal method that could be get invoked either
17709     *  to delete an installed package or to clean up a failed installation.
17710     *  After deleting an installed package, a broadcast is sent to notify any
17711     *  listeners that the package has been removed. For cleaning up a failed
17712     *  installation, the broadcast is not necessary since the package's
17713     *  installation wouldn't have sent the initial broadcast either
17714     *  The key steps in deleting a package are
17715     *  deleting the package information in internal structures like mPackages,
17716     *  deleting the packages base directories through installd
17717     *  updating mSettings to reflect current status
17718     *  persisting settings for later use
17719     *  sending a broadcast if necessary
17720     */
17721    private int deletePackageX(String packageName, int versionCode, int userId, int deleteFlags) {
17722        final PackageRemovedInfo info = new PackageRemovedInfo();
17723        final boolean res;
17724
17725        final int removeUser = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0
17726                ? UserHandle.USER_ALL : userId;
17727
17728        if (isPackageDeviceAdmin(packageName, removeUser)) {
17729            Slog.w(TAG, "Not removing package " + packageName + ": has active device admin");
17730            return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER;
17731        }
17732
17733        PackageSetting uninstalledPs = null;
17734        PackageParser.Package pkg = null;
17735
17736        // for the uninstall-updates case and restricted profiles, remember the per-
17737        // user handle installed state
17738        int[] allUsers;
17739        synchronized (mPackages) {
17740            uninstalledPs = mSettings.mPackages.get(packageName);
17741            if (uninstalledPs == null) {
17742                Slog.w(TAG, "Not removing non-existent package " + packageName);
17743                return PackageManager.DELETE_FAILED_INTERNAL_ERROR;
17744            }
17745
17746            if (versionCode != PackageManager.VERSION_CODE_HIGHEST
17747                    && uninstalledPs.versionCode != versionCode) {
17748                Slog.w(TAG, "Not removing package " + packageName + " with versionCode "
17749                        + uninstalledPs.versionCode + " != " + versionCode);
17750                return PackageManager.DELETE_FAILED_INTERNAL_ERROR;
17751            }
17752
17753            // Static shared libs can be declared by any package, so let us not
17754            // allow removing a package if it provides a lib others depend on.
17755            pkg = mPackages.get(packageName);
17756            if (pkg != null && pkg.staticSharedLibName != null) {
17757                SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(pkg.staticSharedLibName,
17758                        pkg.staticSharedLibVersion);
17759                if (libEntry != null) {
17760                    List<VersionedPackage> libClientPackages = getPackagesUsingSharedLibraryLPr(
17761                            libEntry.info, 0, userId);
17762                    if (!ArrayUtils.isEmpty(libClientPackages)) {
17763                        Slog.w(TAG, "Not removing package " + pkg.manifestPackageName
17764                                + " hosting lib " + libEntry.info.getName() + " version "
17765                                + libEntry.info.getVersion()  + " used by " + libClientPackages);
17766                        return PackageManager.DELETE_FAILED_USED_SHARED_LIBRARY;
17767                    }
17768                }
17769            }
17770
17771            allUsers = sUserManager.getUserIds();
17772            info.origUsers = uninstalledPs.queryInstalledUsers(allUsers, true);
17773        }
17774
17775        final int freezeUser;
17776        if (isUpdatedSystemApp(uninstalledPs)
17777                && ((deleteFlags & PackageManager.DELETE_SYSTEM_APP) == 0)) {
17778            // We're downgrading a system app, which will apply to all users, so
17779            // freeze them all during the downgrade
17780            freezeUser = UserHandle.USER_ALL;
17781        } else {
17782            freezeUser = removeUser;
17783        }
17784
17785        synchronized (mInstallLock) {
17786            if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageX: pkg=" + packageName + " user=" + userId);
17787            try (PackageFreezer freezer = freezePackageForDelete(packageName, freezeUser,
17788                    deleteFlags, "deletePackageX")) {
17789                res = deletePackageLIF(packageName, UserHandle.of(removeUser), true, allUsers,
17790                        deleteFlags | FLAGS_REMOVE_CHATTY, info, true, null);
17791            }
17792            synchronized (mPackages) {
17793                if (res) {
17794                    if (pkg != null) {
17795                        mInstantAppRegistry.onPackageUninstalledLPw(pkg, info.removedUsers);
17796                    }
17797                    updateSequenceNumberLP(packageName, info.removedUsers);
17798                    updateInstantAppInstallerLocked(packageName);
17799                }
17800            }
17801        }
17802
17803        if (res) {
17804            final boolean killApp = (deleteFlags & PackageManager.DELETE_DONT_KILL_APP) == 0;
17805            info.sendPackageRemovedBroadcasts(killApp);
17806            info.sendSystemPackageUpdatedBroadcasts();
17807            info.sendSystemPackageAppearedBroadcasts();
17808        }
17809        // Force a gc here.
17810        Runtime.getRuntime().gc();
17811        // Delete the resources here after sending the broadcast to let
17812        // other processes clean up before deleting resources.
17813        if (info.args != null) {
17814            synchronized (mInstallLock) {
17815                info.args.doPostDeleteLI(true);
17816            }
17817        }
17818
17819        return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR;
17820    }
17821
17822    class PackageRemovedInfo {
17823        String removedPackage;
17824        int uid = -1;
17825        int removedAppId = -1;
17826        int[] origUsers;
17827        int[] removedUsers = null;
17828        int[] broadcastUsers = null;
17829        SparseArray<Integer> installReasons;
17830        boolean isRemovedPackageSystemUpdate = false;
17831        boolean isUpdate;
17832        boolean dataRemoved;
17833        boolean removedForAllUsers;
17834        boolean isStaticSharedLib;
17835        // Clean up resources deleted packages.
17836        InstallArgs args = null;
17837        ArrayMap<String, PackageRemovedInfo> removedChildPackages;
17838        ArrayMap<String, PackageInstalledInfo> appearedChildPackages;
17839
17840        void sendPackageRemovedBroadcasts(boolean killApp) {
17841            sendPackageRemovedBroadcastInternal(killApp);
17842            final int childCount = removedChildPackages != null ? removedChildPackages.size() : 0;
17843            for (int i = 0; i < childCount; i++) {
17844                PackageRemovedInfo childInfo = removedChildPackages.valueAt(i);
17845                childInfo.sendPackageRemovedBroadcastInternal(killApp);
17846            }
17847        }
17848
17849        void sendSystemPackageUpdatedBroadcasts() {
17850            if (isRemovedPackageSystemUpdate) {
17851                sendSystemPackageUpdatedBroadcastsInternal();
17852                final int childCount = (removedChildPackages != null)
17853                        ? removedChildPackages.size() : 0;
17854                for (int i = 0; i < childCount; i++) {
17855                    PackageRemovedInfo childInfo = removedChildPackages.valueAt(i);
17856                    if (childInfo.isRemovedPackageSystemUpdate) {
17857                        childInfo.sendSystemPackageUpdatedBroadcastsInternal();
17858                    }
17859                }
17860            }
17861        }
17862
17863        void sendSystemPackageAppearedBroadcasts() {
17864            final int packageCount = (appearedChildPackages != null)
17865                    ? appearedChildPackages.size() : 0;
17866            for (int i = 0; i < packageCount; i++) {
17867                PackageInstalledInfo installedInfo = appearedChildPackages.valueAt(i);
17868                sendPackageAddedForNewUsers(installedInfo.name, true,
17869                        UserHandle.getAppId(installedInfo.uid), installedInfo.newUsers);
17870            }
17871        }
17872
17873        private void sendSystemPackageUpdatedBroadcastsInternal() {
17874            Bundle extras = new Bundle(2);
17875            extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid);
17876            extras.putBoolean(Intent.EXTRA_REPLACING, true);
17877            sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, removedPackage,
17878                    extras, 0, null, null, null);
17879            sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, removedPackage,
17880                    extras, 0, null, null, null);
17881            sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, null,
17882                    null, 0, removedPackage, null, null);
17883        }
17884
17885        private void sendPackageRemovedBroadcastInternal(boolean killApp) {
17886            // Don't send static shared library removal broadcasts as these
17887            // libs are visible only the the apps that depend on them an one
17888            // cannot remove the library if it has a dependency.
17889            if (isStaticSharedLib) {
17890                return;
17891            }
17892            Bundle extras = new Bundle(2);
17893            extras.putInt(Intent.EXTRA_UID, removedAppId >= 0  ? removedAppId : uid);
17894            extras.putBoolean(Intent.EXTRA_DATA_REMOVED, dataRemoved);
17895            extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, !killApp);
17896            if (isUpdate || isRemovedPackageSystemUpdate) {
17897                extras.putBoolean(Intent.EXTRA_REPLACING, true);
17898            }
17899            extras.putBoolean(Intent.EXTRA_REMOVED_FOR_ALL_USERS, removedForAllUsers);
17900            if (removedPackage != null) {
17901                sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED, removedPackage,
17902                        extras, 0, null, null, broadcastUsers);
17903                if (dataRemoved && !isRemovedPackageSystemUpdate) {
17904                    sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED,
17905                            removedPackage, extras, Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND,
17906                            null, null, broadcastUsers);
17907                }
17908            }
17909            if (removedAppId >= 0) {
17910                sendPackageBroadcast(Intent.ACTION_UID_REMOVED, null, extras,
17911                        Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND, null, null, broadcastUsers);
17912            }
17913        }
17914    }
17915
17916    /*
17917     * This method deletes the package from internal data structures. If the DONT_DELETE_DATA
17918     * flag is not set, the data directory is removed as well.
17919     * make sure this flag is set for partially installed apps. If not its meaningless to
17920     * delete a partially installed application.
17921     */
17922    private void removePackageDataLIF(PackageSetting ps, int[] allUserHandles,
17923            PackageRemovedInfo outInfo, int flags, boolean writeSettings) {
17924        String packageName = ps.name;
17925        if (DEBUG_REMOVE) Slog.d(TAG, "removePackageDataLI: " + ps);
17926        // Retrieve object to delete permissions for shared user later on
17927        final PackageParser.Package deletedPkg;
17928        final PackageSetting deletedPs;
17929        // reader
17930        synchronized (mPackages) {
17931            deletedPkg = mPackages.get(packageName);
17932            deletedPs = mSettings.mPackages.get(packageName);
17933            if (outInfo != null) {
17934                outInfo.removedPackage = packageName;
17935                outInfo.isStaticSharedLib = deletedPkg != null
17936                        && deletedPkg.staticSharedLibName != null;
17937                outInfo.removedUsers = deletedPs != null
17938                        ? deletedPs.queryInstalledUsers(sUserManager.getUserIds(), true)
17939                        : null;
17940                if (outInfo.removedUsers == null) {
17941                    outInfo.broadcastUsers = null;
17942                } else {
17943                    outInfo.broadcastUsers = EMPTY_INT_ARRAY;
17944                    int[] allUsers = outInfo.removedUsers;
17945                    for (int i = allUsers.length - 1; i >= 0; --i) {
17946                        final int userId = allUsers[i];
17947                        if (deletedPs.getInstantApp(userId)) {
17948                            continue;
17949                        }
17950                        outInfo.broadcastUsers =
17951                                ArrayUtils.appendInt(outInfo.broadcastUsers, userId);
17952                    }
17953                }
17954            }
17955        }
17956
17957        removePackageLI(ps, (flags & FLAGS_REMOVE_CHATTY) != 0);
17958
17959        if ((flags & PackageManager.DELETE_KEEP_DATA) == 0) {
17960            final PackageParser.Package resolvedPkg;
17961            if (deletedPkg != null) {
17962                resolvedPkg = deletedPkg;
17963            } else {
17964                // We don't have a parsed package when it lives on an ejected
17965                // adopted storage device, so fake something together
17966                resolvedPkg = new PackageParser.Package(ps.name);
17967                resolvedPkg.setVolumeUuid(ps.volumeUuid);
17968            }
17969            destroyAppDataLIF(resolvedPkg, UserHandle.USER_ALL,
17970                    StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
17971            destroyAppProfilesLIF(resolvedPkg, UserHandle.USER_ALL);
17972            if (outInfo != null) {
17973                outInfo.dataRemoved = true;
17974            }
17975            schedulePackageCleaning(packageName, UserHandle.USER_ALL, true);
17976        }
17977
17978        int removedAppId = -1;
17979
17980        // writer
17981        synchronized (mPackages) {
17982            boolean installedStateChanged = false;
17983            if (deletedPs != null) {
17984                if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) {
17985                    clearIntentFilterVerificationsLPw(deletedPs.name, UserHandle.USER_ALL);
17986                    clearDefaultBrowserIfNeeded(packageName);
17987                    mSettings.mKeySetManagerService.removeAppKeySetDataLPw(packageName);
17988                    removedAppId = mSettings.removePackageLPw(packageName);
17989                    if (outInfo != null) {
17990                        outInfo.removedAppId = removedAppId;
17991                    }
17992                    updatePermissionsLPw(deletedPs.name, null, 0);
17993                    if (deletedPs.sharedUser != null) {
17994                        // Remove permissions associated with package. Since runtime
17995                        // permissions are per user we have to kill the removed package
17996                        // or packages running under the shared user of the removed
17997                        // package if revoking the permissions requested only by the removed
17998                        // package is successful and this causes a change in gids.
17999                        for (int userId : UserManagerService.getInstance().getUserIds()) {
18000                            final int userIdToKill = mSettings.updateSharedUserPermsLPw(deletedPs,
18001                                    userId);
18002                            if (userIdToKill == UserHandle.USER_ALL
18003                                    || userIdToKill >= UserHandle.USER_SYSTEM) {
18004                                // If gids changed for this user, kill all affected packages.
18005                                mHandler.post(new Runnable() {
18006                                    @Override
18007                                    public void run() {
18008                                        // This has to happen with no lock held.
18009                                        killApplication(deletedPs.name, deletedPs.appId,
18010                                                KILL_APP_REASON_GIDS_CHANGED);
18011                                    }
18012                                });
18013                                break;
18014                            }
18015                        }
18016                    }
18017                    clearPackagePreferredActivitiesLPw(deletedPs.name, UserHandle.USER_ALL);
18018                }
18019                // make sure to preserve per-user disabled state if this removal was just
18020                // a downgrade of a system app to the factory package
18021                if (allUserHandles != null && outInfo != null && outInfo.origUsers != null) {
18022                    if (DEBUG_REMOVE) {
18023                        Slog.d(TAG, "Propagating install state across downgrade");
18024                    }
18025                    for (int userId : allUserHandles) {
18026                        final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId);
18027                        if (DEBUG_REMOVE) {
18028                            Slog.d(TAG, "    user " + userId + " => " + installed);
18029                        }
18030                        if (installed != ps.getInstalled(userId)) {
18031                            installedStateChanged = true;
18032                        }
18033                        ps.setInstalled(installed, userId);
18034                    }
18035                }
18036            }
18037            // can downgrade to reader
18038            if (writeSettings) {
18039                // Save settings now
18040                mSettings.writeLPr();
18041            }
18042            if (installedStateChanged) {
18043                mSettings.writeKernelMappingLPr(ps);
18044            }
18045        }
18046        if (removedAppId != -1) {
18047            // A user ID was deleted here. Go through all users and remove it
18048            // from KeyStore.
18049            removeKeystoreDataIfNeeded(UserHandle.USER_ALL, removedAppId);
18050        }
18051    }
18052
18053    static boolean locationIsPrivileged(File path) {
18054        try {
18055            final String privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app")
18056                    .getCanonicalPath();
18057            return path.getCanonicalPath().startsWith(privilegedAppDir);
18058        } catch (IOException e) {
18059            Slog.e(TAG, "Unable to access code path " + path);
18060        }
18061        return false;
18062    }
18063
18064    /*
18065     * Tries to delete system package.
18066     */
18067    private boolean deleteSystemPackageLIF(PackageParser.Package deletedPkg,
18068            PackageSetting deletedPs, int[] allUserHandles, int flags, PackageRemovedInfo outInfo,
18069            boolean writeSettings) {
18070        if (deletedPs.parentPackageName != null) {
18071            Slog.w(TAG, "Attempt to delete child system package " + deletedPkg.packageName);
18072            return false;
18073        }
18074
18075        final boolean applyUserRestrictions
18076                = (allUserHandles != null) && (outInfo.origUsers != null);
18077        final PackageSetting disabledPs;
18078        // Confirm if the system package has been updated
18079        // An updated system app can be deleted. This will also have to restore
18080        // the system pkg from system partition
18081        // reader
18082        synchronized (mPackages) {
18083            disabledPs = mSettings.getDisabledSystemPkgLPr(deletedPs.name);
18084        }
18085
18086        if (DEBUG_REMOVE) Slog.d(TAG, "deleteSystemPackageLI: newPs=" + deletedPkg.packageName
18087                + " disabledPs=" + disabledPs);
18088
18089        if (disabledPs == null) {
18090            Slog.w(TAG, "Attempt to delete unknown system package "+ deletedPkg.packageName);
18091            return false;
18092        } else if (DEBUG_REMOVE) {
18093            Slog.d(TAG, "Deleting system pkg from data partition");
18094        }
18095
18096        if (DEBUG_REMOVE) {
18097            if (applyUserRestrictions) {
18098                Slog.d(TAG, "Remembering install states:");
18099                for (int userId : allUserHandles) {
18100                    final boolean finstalled = ArrayUtils.contains(outInfo.origUsers, userId);
18101                    Slog.d(TAG, "   u=" + userId + " inst=" + finstalled);
18102                }
18103            }
18104        }
18105
18106        // Delete the updated package
18107        outInfo.isRemovedPackageSystemUpdate = true;
18108        if (outInfo.removedChildPackages != null) {
18109            final int childCount = (deletedPs.childPackageNames != null)
18110                    ? deletedPs.childPackageNames.size() : 0;
18111            for (int i = 0; i < childCount; i++) {
18112                String childPackageName = deletedPs.childPackageNames.get(i);
18113                if (disabledPs.childPackageNames != null && disabledPs.childPackageNames
18114                        .contains(childPackageName)) {
18115                    PackageRemovedInfo childInfo = outInfo.removedChildPackages.get(
18116                            childPackageName);
18117                    if (childInfo != null) {
18118                        childInfo.isRemovedPackageSystemUpdate = true;
18119                    }
18120                }
18121            }
18122        }
18123
18124        if (disabledPs.versionCode < deletedPs.versionCode) {
18125            // Delete data for downgrades
18126            flags &= ~PackageManager.DELETE_KEEP_DATA;
18127        } else {
18128            // Preserve data by setting flag
18129            flags |= PackageManager.DELETE_KEEP_DATA;
18130        }
18131
18132        boolean ret = deleteInstalledPackageLIF(deletedPs, true, flags, allUserHandles,
18133                outInfo, writeSettings, disabledPs.pkg);
18134        if (!ret) {
18135            return false;
18136        }
18137
18138        // writer
18139        synchronized (mPackages) {
18140            // Reinstate the old system package
18141            enableSystemPackageLPw(disabledPs.pkg);
18142            // Remove any native libraries from the upgraded package.
18143            removeNativeBinariesLI(deletedPs);
18144        }
18145
18146        // Install the system package
18147        if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs);
18148        int parseFlags = mDefParseFlags
18149                | PackageParser.PARSE_MUST_BE_APK
18150                | PackageParser.PARSE_IS_SYSTEM
18151                | PackageParser.PARSE_IS_SYSTEM_DIR;
18152        if (locationIsPrivileged(disabledPs.codePath)) {
18153            parseFlags |= PackageParser.PARSE_IS_PRIVILEGED;
18154        }
18155
18156        final PackageParser.Package newPkg;
18157        try {
18158            newPkg = scanPackageTracedLI(disabledPs.codePath, parseFlags, 0 /* scanFlags */,
18159                0 /* currentTime */, null);
18160        } catch (PackageManagerException e) {
18161            Slog.w(TAG, "Failed to restore system package:" + deletedPkg.packageName + ": "
18162                    + e.getMessage());
18163            return false;
18164        }
18165
18166        try {
18167            // update shared libraries for the newly re-installed system package
18168            updateSharedLibrariesLPr(newPkg, null);
18169        } catch (PackageManagerException e) {
18170            Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
18171        }
18172
18173        prepareAppDataAfterInstallLIF(newPkg);
18174
18175        // writer
18176        synchronized (mPackages) {
18177            PackageSetting ps = mSettings.mPackages.get(newPkg.packageName);
18178
18179            // Propagate the permissions state as we do not want to drop on the floor
18180            // runtime permissions. The update permissions method below will take
18181            // care of removing obsolete permissions and grant install permissions.
18182            ps.getPermissionsState().copyFrom(deletedPs.getPermissionsState());
18183            updatePermissionsLPw(newPkg.packageName, newPkg,
18184                    UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG);
18185
18186            if (applyUserRestrictions) {
18187                boolean installedStateChanged = false;
18188                if (DEBUG_REMOVE) {
18189                    Slog.d(TAG, "Propagating install state across reinstall");
18190                }
18191                for (int userId : allUserHandles) {
18192                    final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId);
18193                    if (DEBUG_REMOVE) {
18194                        Slog.d(TAG, "    user " + userId + " => " + installed);
18195                    }
18196                    if (installed != ps.getInstalled(userId)) {
18197                        installedStateChanged = true;
18198                    }
18199                    ps.setInstalled(installed, userId);
18200
18201                    mSettings.writeRuntimePermissionsForUserLPr(userId, false);
18202                }
18203                // Regardless of writeSettings we need to ensure that this restriction
18204                // state propagation is persisted
18205                mSettings.writeAllUsersPackageRestrictionsLPr();
18206                if (installedStateChanged) {
18207                    mSettings.writeKernelMappingLPr(ps);
18208                }
18209            }
18210            // can downgrade to reader here
18211            if (writeSettings) {
18212                mSettings.writeLPr();
18213            }
18214        }
18215        return true;
18216    }
18217
18218    private boolean deleteInstalledPackageLIF(PackageSetting ps,
18219            boolean deleteCodeAndResources, int flags, int[] allUserHandles,
18220            PackageRemovedInfo outInfo, boolean writeSettings,
18221            PackageParser.Package replacingPackage) {
18222        synchronized (mPackages) {
18223            if (outInfo != null) {
18224                outInfo.uid = ps.appId;
18225            }
18226
18227            if (outInfo != null && outInfo.removedChildPackages != null) {
18228                final int childCount = (ps.childPackageNames != null)
18229                        ? ps.childPackageNames.size() : 0;
18230                for (int i = 0; i < childCount; i++) {
18231                    String childPackageName = ps.childPackageNames.get(i);
18232                    PackageSetting childPs = mSettings.mPackages.get(childPackageName);
18233                    if (childPs == null) {
18234                        return false;
18235                    }
18236                    PackageRemovedInfo childInfo = outInfo.removedChildPackages.get(
18237                            childPackageName);
18238                    if (childInfo != null) {
18239                        childInfo.uid = childPs.appId;
18240                    }
18241                }
18242            }
18243        }
18244
18245        // Delete package data from internal structures and also remove data if flag is set
18246        removePackageDataLIF(ps, allUserHandles, outInfo, flags, writeSettings);
18247
18248        // Delete the child packages data
18249        final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0;
18250        for (int i = 0; i < childCount; i++) {
18251            PackageSetting childPs;
18252            synchronized (mPackages) {
18253                childPs = mSettings.getPackageLPr(ps.childPackageNames.get(i));
18254            }
18255            if (childPs != null) {
18256                PackageRemovedInfo childOutInfo = (outInfo != null
18257                        && outInfo.removedChildPackages != null)
18258                        ? outInfo.removedChildPackages.get(childPs.name) : null;
18259                final int deleteFlags = (flags & DELETE_KEEP_DATA) != 0
18260                        && (replacingPackage != null
18261                        && !replacingPackage.hasChildPackage(childPs.name))
18262                        ? flags & ~DELETE_KEEP_DATA : flags;
18263                removePackageDataLIF(childPs, allUserHandles, childOutInfo,
18264                        deleteFlags, writeSettings);
18265            }
18266        }
18267
18268        // Delete application code and resources only for parent packages
18269        if (ps.parentPackageName == null) {
18270            if (deleteCodeAndResources && (outInfo != null)) {
18271                outInfo.args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
18272                        ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
18273                if (DEBUG_SD_INSTALL) Slog.i(TAG, "args=" + outInfo.args);
18274            }
18275        }
18276
18277        return true;
18278    }
18279
18280    @Override
18281    public boolean setBlockUninstallForUser(String packageName, boolean blockUninstall,
18282            int userId) {
18283        mContext.enforceCallingOrSelfPermission(
18284                android.Manifest.permission.DELETE_PACKAGES, null);
18285        synchronized (mPackages) {
18286            PackageSetting ps = mSettings.mPackages.get(packageName);
18287            if (ps == null) {
18288                Log.i(TAG, "Package doesn't exist in set block uninstall " + packageName);
18289                return false;
18290            }
18291            // Cannot block uninstall of static shared libs as they are
18292            // considered a part of the using app (emulating static linking).
18293            // Also static libs are installed always on internal storage.
18294            PackageParser.Package pkg = mPackages.get(packageName);
18295            if (pkg != null && pkg.staticSharedLibName != null) {
18296                Slog.w(TAG, "Cannot block uninstall of package: " + packageName
18297                        + " providing static shared library: " + pkg.staticSharedLibName);
18298                return false;
18299            }
18300            if (!ps.getInstalled(userId)) {
18301                // Can't block uninstall for an app that is not installed or enabled.
18302                Log.i(TAG, "Package not installed in set block uninstall " + packageName);
18303                return false;
18304            }
18305            ps.setBlockUninstall(blockUninstall, userId);
18306            mSettings.writePackageRestrictionsLPr(userId);
18307        }
18308        return true;
18309    }
18310
18311    @Override
18312    public boolean getBlockUninstallForUser(String packageName, int userId) {
18313        synchronized (mPackages) {
18314            PackageSetting ps = mSettings.mPackages.get(packageName);
18315            if (ps == null) {
18316                Log.i(TAG, "Package doesn't exist in get block uninstall " + packageName);
18317                return false;
18318            }
18319            return ps.getBlockUninstall(userId);
18320        }
18321    }
18322
18323    @Override
18324    public boolean setRequiredForSystemUser(String packageName, boolean systemUserApp) {
18325        int callingUid = Binder.getCallingUid();
18326        if (callingUid != Process.SYSTEM_UID && callingUid != Process.ROOT_UID) {
18327            throw new SecurityException(
18328                    "setRequiredForSystemUser can only be run by the system or root");
18329        }
18330        synchronized (mPackages) {
18331            PackageSetting ps = mSettings.mPackages.get(packageName);
18332            if (ps == null) {
18333                Log.w(TAG, "Package doesn't exist: " + packageName);
18334                return false;
18335            }
18336            if (systemUserApp) {
18337                ps.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER;
18338            } else {
18339                ps.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER;
18340            }
18341            mSettings.writeLPr();
18342        }
18343        return true;
18344    }
18345
18346    /*
18347     * This method handles package deletion in general
18348     */
18349    private boolean deletePackageLIF(String packageName, UserHandle user,
18350            boolean deleteCodeAndResources, int[] allUserHandles, int flags,
18351            PackageRemovedInfo outInfo, boolean writeSettings,
18352            PackageParser.Package replacingPackage) {
18353        if (packageName == null) {
18354            Slog.w(TAG, "Attempt to delete null packageName.");
18355            return false;
18356        }
18357
18358        if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: " + packageName + " user " + user);
18359
18360        PackageSetting ps;
18361        synchronized (mPackages) {
18362            ps = mSettings.mPackages.get(packageName);
18363            if (ps == null) {
18364                Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
18365                return false;
18366            }
18367
18368            if (ps.parentPackageName != null && (!isSystemApp(ps)
18369                    || (flags & PackageManager.DELETE_SYSTEM_APP) != 0)) {
18370                if (DEBUG_REMOVE) {
18371                    Slog.d(TAG, "Uninstalled child package:" + packageName + " for user:"
18372                            + ((user == null) ? UserHandle.USER_ALL : user));
18373                }
18374                final int removedUserId = (user != null) ? user.getIdentifier()
18375                        : UserHandle.USER_ALL;
18376                if (!clearPackageStateForUserLIF(ps, removedUserId, outInfo)) {
18377                    return false;
18378                }
18379                markPackageUninstalledForUserLPw(ps, user);
18380                scheduleWritePackageRestrictionsLocked(user);
18381                return true;
18382            }
18383        }
18384
18385        if (((!isSystemApp(ps) || (flags&PackageManager.DELETE_SYSTEM_APP) != 0) && user != null
18386                && user.getIdentifier() != UserHandle.USER_ALL)) {
18387            // The caller is asking that the package only be deleted for a single
18388            // user.  To do this, we just mark its uninstalled state and delete
18389            // its data. If this is a system app, we only allow this to happen if
18390            // they have set the special DELETE_SYSTEM_APP which requests different
18391            // semantics than normal for uninstalling system apps.
18392            markPackageUninstalledForUserLPw(ps, user);
18393
18394            if (!isSystemApp(ps)) {
18395                // Do not uninstall the APK if an app should be cached
18396                boolean keepUninstalledPackage = shouldKeepUninstalledPackageLPr(packageName);
18397                if (ps.isAnyInstalled(sUserManager.getUserIds()) || keepUninstalledPackage) {
18398                    // Other user still have this package installed, so all
18399                    // we need to do is clear this user's data and save that
18400                    // it is uninstalled.
18401                    if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users");
18402                    if (!clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo)) {
18403                        return false;
18404                    }
18405                    scheduleWritePackageRestrictionsLocked(user);
18406                    return true;
18407                } else {
18408                    // We need to set it back to 'installed' so the uninstall
18409                    // broadcasts will be sent correctly.
18410                    if (DEBUG_REMOVE) Slog.d(TAG, "Not installed by other users, full delete");
18411                    ps.setInstalled(true, user.getIdentifier());
18412                    mSettings.writeKernelMappingLPr(ps);
18413                }
18414            } else {
18415                // This is a system app, so we assume that the
18416                // other users still have this package installed, so all
18417                // we need to do is clear this user's data and save that
18418                // it is uninstalled.
18419                if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app");
18420                if (!clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo)) {
18421                    return false;
18422                }
18423                scheduleWritePackageRestrictionsLocked(user);
18424                return true;
18425            }
18426        }
18427
18428        // If we are deleting a composite package for all users, keep track
18429        // of result for each child.
18430        if (ps.childPackageNames != null && outInfo != null) {
18431            synchronized (mPackages) {
18432                final int childCount = ps.childPackageNames.size();
18433                outInfo.removedChildPackages = new ArrayMap<>(childCount);
18434                for (int i = 0; i < childCount; i++) {
18435                    String childPackageName = ps.childPackageNames.get(i);
18436                    PackageRemovedInfo childInfo = new PackageRemovedInfo();
18437                    childInfo.removedPackage = childPackageName;
18438                    outInfo.removedChildPackages.put(childPackageName, childInfo);
18439                    PackageSetting childPs = mSettings.getPackageLPr(childPackageName);
18440                    if (childPs != null) {
18441                        childInfo.origUsers = childPs.queryInstalledUsers(allUserHandles, true);
18442                    }
18443                }
18444            }
18445        }
18446
18447        boolean ret = false;
18448        if (isSystemApp(ps)) {
18449            if (DEBUG_REMOVE) Slog.d(TAG, "Removing system package: " + ps.name);
18450            // When an updated system application is deleted we delete the existing resources
18451            // as well and fall back to existing code in system partition
18452            ret = deleteSystemPackageLIF(ps.pkg, ps, allUserHandles, flags, outInfo, writeSettings);
18453        } else {
18454            if (DEBUG_REMOVE) Slog.d(TAG, "Removing non-system package: " + ps.name);
18455            ret = deleteInstalledPackageLIF(ps, deleteCodeAndResources, flags, allUserHandles,
18456                    outInfo, writeSettings, replacingPackage);
18457        }
18458
18459        // Take a note whether we deleted the package for all users
18460        if (outInfo != null) {
18461            outInfo.removedForAllUsers = mPackages.get(ps.name) == null;
18462            if (outInfo.removedChildPackages != null) {
18463                synchronized (mPackages) {
18464                    final int childCount = outInfo.removedChildPackages.size();
18465                    for (int i = 0; i < childCount; i++) {
18466                        PackageRemovedInfo childInfo = outInfo.removedChildPackages.valueAt(i);
18467                        if (childInfo != null) {
18468                            childInfo.removedForAllUsers = mPackages.get(
18469                                    childInfo.removedPackage) == null;
18470                        }
18471                    }
18472                }
18473            }
18474            // If we uninstalled an update to a system app there may be some
18475            // child packages that appeared as they are declared in the system
18476            // app but were not declared in the update.
18477            if (isSystemApp(ps)) {
18478                synchronized (mPackages) {
18479                    PackageSetting updatedPs = mSettings.getPackageLPr(ps.name);
18480                    final int childCount = (updatedPs.childPackageNames != null)
18481                            ? updatedPs.childPackageNames.size() : 0;
18482                    for (int i = 0; i < childCount; i++) {
18483                        String childPackageName = updatedPs.childPackageNames.get(i);
18484                        if (outInfo.removedChildPackages == null
18485                                || outInfo.removedChildPackages.indexOfKey(childPackageName) < 0) {
18486                            PackageSetting childPs = mSettings.getPackageLPr(childPackageName);
18487                            if (childPs == null) {
18488                                continue;
18489                            }
18490                            PackageInstalledInfo installRes = new PackageInstalledInfo();
18491                            installRes.name = childPackageName;
18492                            installRes.newUsers = childPs.queryInstalledUsers(allUserHandles, true);
18493                            installRes.pkg = mPackages.get(childPackageName);
18494                            installRes.uid = childPs.pkg.applicationInfo.uid;
18495                            if (outInfo.appearedChildPackages == null) {
18496                                outInfo.appearedChildPackages = new ArrayMap<>();
18497                            }
18498                            outInfo.appearedChildPackages.put(childPackageName, installRes);
18499                        }
18500                    }
18501                }
18502            }
18503        }
18504
18505        return ret;
18506    }
18507
18508    private void markPackageUninstalledForUserLPw(PackageSetting ps, UserHandle user) {
18509        final int[] userIds = (user == null || user.getIdentifier() == UserHandle.USER_ALL)
18510                ? sUserManager.getUserIds() : new int[] {user.getIdentifier()};
18511        for (int nextUserId : userIds) {
18512            if (DEBUG_REMOVE) {
18513                Slog.d(TAG, "Marking package:" + ps.name + " uninstalled for user:" + nextUserId);
18514            }
18515            ps.setUserState(nextUserId, 0, COMPONENT_ENABLED_STATE_DEFAULT,
18516                    false /*installed*/,
18517                    true /*stopped*/,
18518                    true /*notLaunched*/,
18519                    false /*hidden*/,
18520                    false /*suspended*/,
18521                    false /*instantApp*/,
18522                    null /*lastDisableAppCaller*/,
18523                    null /*enabledComponents*/,
18524                    null /*disabledComponents*/,
18525                    false /*blockUninstall*/,
18526                    ps.readUserState(nextUserId).domainVerificationStatus,
18527                    0, PackageManager.INSTALL_REASON_UNKNOWN);
18528        }
18529        mSettings.writeKernelMappingLPr(ps);
18530    }
18531
18532    private boolean clearPackageStateForUserLIF(PackageSetting ps, int userId,
18533            PackageRemovedInfo outInfo) {
18534        final PackageParser.Package pkg;
18535        synchronized (mPackages) {
18536            pkg = mPackages.get(ps.name);
18537        }
18538
18539        final int[] userIds = (userId == UserHandle.USER_ALL) ? sUserManager.getUserIds()
18540                : new int[] {userId};
18541        for (int nextUserId : userIds) {
18542            if (DEBUG_REMOVE) {
18543                Slog.d(TAG, "Updating package:" + ps.name + " install state for user:"
18544                        + nextUserId);
18545            }
18546
18547            destroyAppDataLIF(pkg, userId,
18548                    StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
18549            destroyAppProfilesLIF(pkg, userId);
18550            removeKeystoreDataIfNeeded(nextUserId, ps.appId);
18551            schedulePackageCleaning(ps.name, nextUserId, false);
18552            synchronized (mPackages) {
18553                if (clearPackagePreferredActivitiesLPw(ps.name, nextUserId)) {
18554                    scheduleWritePackageRestrictionsLocked(nextUserId);
18555                }
18556                resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, nextUserId);
18557            }
18558        }
18559
18560        if (outInfo != null) {
18561            outInfo.removedPackage = ps.name;
18562            outInfo.isStaticSharedLib = pkg != null && pkg.staticSharedLibName != null;
18563            outInfo.removedAppId = ps.appId;
18564            outInfo.removedUsers = userIds;
18565            outInfo.broadcastUsers = userIds;
18566        }
18567
18568        return true;
18569    }
18570
18571    private final class ClearStorageConnection implements ServiceConnection {
18572        IMediaContainerService mContainerService;
18573
18574        @Override
18575        public void onServiceConnected(ComponentName name, IBinder service) {
18576            synchronized (this) {
18577                mContainerService = IMediaContainerService.Stub
18578                        .asInterface(Binder.allowBlocking(service));
18579                notifyAll();
18580            }
18581        }
18582
18583        @Override
18584        public void onServiceDisconnected(ComponentName name) {
18585        }
18586    }
18587
18588    private void clearExternalStorageDataSync(String packageName, int userId, boolean allData) {
18589        if (DEFAULT_CONTAINER_PACKAGE.equals(packageName)) return;
18590
18591        final boolean mounted;
18592        if (Environment.isExternalStorageEmulated()) {
18593            mounted = true;
18594        } else {
18595            final String status = Environment.getExternalStorageState();
18596
18597            mounted = status.equals(Environment.MEDIA_MOUNTED)
18598                    || status.equals(Environment.MEDIA_MOUNTED_READ_ONLY);
18599        }
18600
18601        if (!mounted) {
18602            return;
18603        }
18604
18605        final Intent containerIntent = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
18606        int[] users;
18607        if (userId == UserHandle.USER_ALL) {
18608            users = sUserManager.getUserIds();
18609        } else {
18610            users = new int[] { userId };
18611        }
18612        final ClearStorageConnection conn = new ClearStorageConnection();
18613        if (mContext.bindServiceAsUser(
18614                containerIntent, conn, Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) {
18615            try {
18616                for (int curUser : users) {
18617                    long timeout = SystemClock.uptimeMillis() + 5000;
18618                    synchronized (conn) {
18619                        long now;
18620                        while (conn.mContainerService == null &&
18621                                (now = SystemClock.uptimeMillis()) < timeout) {
18622                            try {
18623                                conn.wait(timeout - now);
18624                            } catch (InterruptedException e) {
18625                            }
18626                        }
18627                    }
18628                    if (conn.mContainerService == null) {
18629                        return;
18630                    }
18631
18632                    final UserEnvironment userEnv = new UserEnvironment(curUser);
18633                    clearDirectory(conn.mContainerService,
18634                            userEnv.buildExternalStorageAppCacheDirs(packageName));
18635                    if (allData) {
18636                        clearDirectory(conn.mContainerService,
18637                                userEnv.buildExternalStorageAppDataDirs(packageName));
18638                        clearDirectory(conn.mContainerService,
18639                                userEnv.buildExternalStorageAppMediaDirs(packageName));
18640                    }
18641                }
18642            } finally {
18643                mContext.unbindService(conn);
18644            }
18645        }
18646    }
18647
18648    @Override
18649    public void clearApplicationProfileData(String packageName) {
18650        enforceSystemOrRoot("Only the system can clear all profile data");
18651
18652        final PackageParser.Package pkg;
18653        synchronized (mPackages) {
18654            pkg = mPackages.get(packageName);
18655        }
18656
18657        try (PackageFreezer freezer = freezePackage(packageName, "clearApplicationProfileData")) {
18658            synchronized (mInstallLock) {
18659                clearAppProfilesLIF(pkg, UserHandle.USER_ALL);
18660            }
18661        }
18662    }
18663
18664    @Override
18665    public void clearApplicationUserData(final String packageName,
18666            final IPackageDataObserver observer, final int userId) {
18667        mContext.enforceCallingOrSelfPermission(
18668                android.Manifest.permission.CLEAR_APP_USER_DATA, null);
18669
18670        enforceCrossUserPermission(Binder.getCallingUid(), userId,
18671                true /* requireFullPermission */, false /* checkShell */, "clear application data");
18672
18673        if (mProtectedPackages.isPackageDataProtected(userId, packageName)) {
18674            throw new SecurityException("Cannot clear data for a protected package: "
18675                    + packageName);
18676        }
18677        // Queue up an async operation since the package deletion may take a little while.
18678        mHandler.post(new Runnable() {
18679            public void run() {
18680                mHandler.removeCallbacks(this);
18681                final boolean succeeded;
18682                try (PackageFreezer freezer = freezePackage(packageName,
18683                        "clearApplicationUserData")) {
18684                    synchronized (mInstallLock) {
18685                        succeeded = clearApplicationUserDataLIF(packageName, userId);
18686                    }
18687                    clearExternalStorageDataSync(packageName, userId, true);
18688                    synchronized (mPackages) {
18689                        mInstantAppRegistry.deleteInstantApplicationMetadataLPw(
18690                                packageName, userId);
18691                    }
18692                }
18693                if (succeeded) {
18694                    // invoke DeviceStorageMonitor's update method to clear any notifications
18695                    DeviceStorageMonitorInternal dsm = LocalServices
18696                            .getService(DeviceStorageMonitorInternal.class);
18697                    if (dsm != null) {
18698                        dsm.checkMemory();
18699                    }
18700                }
18701                if(observer != null) {
18702                    try {
18703                        observer.onRemoveCompleted(packageName, succeeded);
18704                    } catch (RemoteException e) {
18705                        Log.i(TAG, "Observer no longer exists.");
18706                    }
18707                } //end if observer
18708            } //end run
18709        });
18710    }
18711
18712    private boolean clearApplicationUserDataLIF(String packageName, int userId) {
18713        if (packageName == null) {
18714            Slog.w(TAG, "Attempt to delete null packageName.");
18715            return false;
18716        }
18717
18718        // Try finding details about the requested package
18719        PackageParser.Package pkg;
18720        synchronized (mPackages) {
18721            pkg = mPackages.get(packageName);
18722            if (pkg == null) {
18723                final PackageSetting ps = mSettings.mPackages.get(packageName);
18724                if (ps != null) {
18725                    pkg = ps.pkg;
18726                }
18727            }
18728
18729            if (pkg == null) {
18730                Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
18731                return false;
18732            }
18733
18734            PackageSetting ps = (PackageSetting) pkg.mExtras;
18735            resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
18736        }
18737
18738        clearAppDataLIF(pkg, userId,
18739                StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
18740
18741        final int appId = UserHandle.getAppId(pkg.applicationInfo.uid);
18742        removeKeystoreDataIfNeeded(userId, appId);
18743
18744        UserManagerInternal umInternal = getUserManagerInternal();
18745        final int flags;
18746        if (umInternal.isUserUnlockingOrUnlocked(userId)) {
18747            flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
18748        } else if (umInternal.isUserRunning(userId)) {
18749            flags = StorageManager.FLAG_STORAGE_DE;
18750        } else {
18751            flags = 0;
18752        }
18753        prepareAppDataContentsLIF(pkg, userId, flags);
18754
18755        return true;
18756    }
18757
18758    /**
18759     * Reverts user permission state changes (permissions and flags) in
18760     * all packages for a given user.
18761     *
18762     * @param userId The device user for which to do a reset.
18763     */
18764    private void resetUserChangesToRuntimePermissionsAndFlagsLPw(int userId) {
18765        final int packageCount = mPackages.size();
18766        for (int i = 0; i < packageCount; i++) {
18767            PackageParser.Package pkg = mPackages.valueAt(i);
18768            PackageSetting ps = (PackageSetting) pkg.mExtras;
18769            resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
18770        }
18771    }
18772
18773    private void resetNetworkPolicies(int userId) {
18774        LocalServices.getService(NetworkPolicyManagerInternal.class).resetUserState(userId);
18775    }
18776
18777    /**
18778     * Reverts user permission state changes (permissions and flags).
18779     *
18780     * @param ps The package for which to reset.
18781     * @param userId The device user for which to do a reset.
18782     */
18783    private void resetUserChangesToRuntimePermissionsAndFlagsLPw(
18784            final PackageSetting ps, final int userId) {
18785        if (ps.pkg == null) {
18786            return;
18787        }
18788
18789        // These are flags that can change base on user actions.
18790        final int userSettableMask = FLAG_PERMISSION_USER_SET
18791                | FLAG_PERMISSION_USER_FIXED
18792                | FLAG_PERMISSION_REVOKE_ON_UPGRADE
18793                | FLAG_PERMISSION_REVIEW_REQUIRED;
18794
18795        final int policyOrSystemFlags = FLAG_PERMISSION_SYSTEM_FIXED
18796                | FLAG_PERMISSION_POLICY_FIXED;
18797
18798        boolean writeInstallPermissions = false;
18799        boolean writeRuntimePermissions = false;
18800
18801        final int permissionCount = ps.pkg.requestedPermissions.size();
18802        for (int i = 0; i < permissionCount; i++) {
18803            String permission = ps.pkg.requestedPermissions.get(i);
18804
18805            BasePermission bp = mSettings.mPermissions.get(permission);
18806            if (bp == null) {
18807                continue;
18808            }
18809
18810            // If shared user we just reset the state to which only this app contributed.
18811            if (ps.sharedUser != null) {
18812                boolean used = false;
18813                final int packageCount = ps.sharedUser.packages.size();
18814                for (int j = 0; j < packageCount; j++) {
18815                    PackageSetting pkg = ps.sharedUser.packages.valueAt(j);
18816                    if (pkg.pkg != null && !pkg.pkg.packageName.equals(ps.pkg.packageName)
18817                            && pkg.pkg.requestedPermissions.contains(permission)) {
18818                        used = true;
18819                        break;
18820                    }
18821                }
18822                if (used) {
18823                    continue;
18824                }
18825            }
18826
18827            PermissionsState permissionsState = ps.getPermissionsState();
18828
18829            final int oldFlags = permissionsState.getPermissionFlags(bp.name, userId);
18830
18831            // Always clear the user settable flags.
18832            final boolean hasInstallState = permissionsState.getInstallPermissionState(
18833                    bp.name) != null;
18834            // If permission review is enabled and this is a legacy app, mark the
18835            // permission as requiring a review as this is the initial state.
18836            int flags = 0;
18837            if (mPermissionReviewRequired
18838                    && ps.pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
18839                flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
18840            }
18841            if (permissionsState.updatePermissionFlags(bp, userId, userSettableMask, flags)) {
18842                if (hasInstallState) {
18843                    writeInstallPermissions = true;
18844                } else {
18845                    writeRuntimePermissions = true;
18846                }
18847            }
18848
18849            // Below is only runtime permission handling.
18850            if (!bp.isRuntime()) {
18851                continue;
18852            }
18853
18854            // Never clobber system or policy.
18855            if ((oldFlags & policyOrSystemFlags) != 0) {
18856                continue;
18857            }
18858
18859            // If this permission was granted by default, make sure it is.
18860            if ((oldFlags & FLAG_PERMISSION_GRANTED_BY_DEFAULT) != 0) {
18861                if (permissionsState.grantRuntimePermission(bp, userId)
18862                        != PERMISSION_OPERATION_FAILURE) {
18863                    writeRuntimePermissions = true;
18864                }
18865            // If permission review is enabled the permissions for a legacy apps
18866            // are represented as constantly granted runtime ones, so don't revoke.
18867            } else if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) {
18868                // Otherwise, reset the permission.
18869                final int revokeResult = permissionsState.revokeRuntimePermission(bp, userId);
18870                switch (revokeResult) {
18871                    case PERMISSION_OPERATION_SUCCESS:
18872                    case PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
18873                        writeRuntimePermissions = true;
18874                        final int appId = ps.appId;
18875                        mHandler.post(new Runnable() {
18876                            @Override
18877                            public void run() {
18878                                killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED);
18879                            }
18880                        });
18881                    } break;
18882                }
18883            }
18884        }
18885
18886        // Synchronously write as we are taking permissions away.
18887        if (writeRuntimePermissions) {
18888            mSettings.writeRuntimePermissionsForUserLPr(userId, true);
18889        }
18890
18891        // Synchronously write as we are taking permissions away.
18892        if (writeInstallPermissions) {
18893            mSettings.writeLPr();
18894        }
18895    }
18896
18897    /**
18898     * Remove entries from the keystore daemon. Will only remove it if the
18899     * {@code appId} is valid.
18900     */
18901    private static void removeKeystoreDataIfNeeded(int userId, int appId) {
18902        if (appId < 0) {
18903            return;
18904        }
18905
18906        final KeyStore keyStore = KeyStore.getInstance();
18907        if (keyStore != null) {
18908            if (userId == UserHandle.USER_ALL) {
18909                for (final int individual : sUserManager.getUserIds()) {
18910                    keyStore.clearUid(UserHandle.getUid(individual, appId));
18911                }
18912            } else {
18913                keyStore.clearUid(UserHandle.getUid(userId, appId));
18914            }
18915        } else {
18916            Slog.w(TAG, "Could not contact keystore to clear entries for app id " + appId);
18917        }
18918    }
18919
18920    @Override
18921    public void deleteApplicationCacheFiles(final String packageName,
18922            final IPackageDataObserver observer) {
18923        final int userId = UserHandle.getCallingUserId();
18924        deleteApplicationCacheFilesAsUser(packageName, userId, observer);
18925    }
18926
18927    @Override
18928    public void deleteApplicationCacheFilesAsUser(final String packageName, final int userId,
18929            final IPackageDataObserver observer) {
18930        mContext.enforceCallingOrSelfPermission(
18931                android.Manifest.permission.DELETE_CACHE_FILES, null);
18932        enforceCrossUserPermission(Binder.getCallingUid(), userId,
18933                /* requireFullPermission= */ true, /* checkShell= */ false,
18934                "delete application cache files");
18935
18936        final PackageParser.Package pkg;
18937        synchronized (mPackages) {
18938            pkg = mPackages.get(packageName);
18939        }
18940
18941        // Queue up an async operation since the package deletion may take a little while.
18942        mHandler.post(new Runnable() {
18943            public void run() {
18944                synchronized (mInstallLock) {
18945                    final int flags = StorageManager.FLAG_STORAGE_DE
18946                            | StorageManager.FLAG_STORAGE_CE;
18947                    // We're only clearing cache files, so we don't care if the
18948                    // app is unfrozen and still able to run
18949                    clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CACHE_ONLY);
18950                    clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
18951                }
18952                clearExternalStorageDataSync(packageName, userId, false);
18953                if (observer != null) {
18954                    try {
18955                        observer.onRemoveCompleted(packageName, true);
18956                    } catch (RemoteException e) {
18957                        Log.i(TAG, "Observer no longer exists.");
18958                    }
18959                }
18960            }
18961        });
18962    }
18963
18964    @Override
18965    public void getPackageSizeInfo(final String packageName, int userHandle,
18966            final IPackageStatsObserver observer) {
18967        throw new UnsupportedOperationException(
18968                "Shame on you for calling the hidden API getPackageSizeInfo(). Shame!");
18969    }
18970
18971    private boolean getPackageSizeInfoLI(String packageName, int userId, PackageStats stats) {
18972        final PackageSetting ps;
18973        synchronized (mPackages) {
18974            ps = mSettings.mPackages.get(packageName);
18975            if (ps == null) {
18976                Slog.w(TAG, "Failed to find settings for " + packageName);
18977                return false;
18978            }
18979        }
18980
18981        final String[] packageNames = { packageName };
18982        final long[] ceDataInodes = { ps.getCeDataInode(userId) };
18983        final String[] codePaths = { ps.codePathString };
18984
18985        try {
18986            mInstaller.getAppSize(ps.volumeUuid, packageNames, userId, 0,
18987                    ps.appId, ceDataInodes, codePaths, stats);
18988
18989            // For now, ignore code size of packages on system partition
18990            if (isSystemApp(ps) && !isUpdatedSystemApp(ps)) {
18991                stats.codeSize = 0;
18992            }
18993
18994            // External clients expect these to be tracked separately
18995            stats.dataSize -= stats.cacheSize;
18996
18997        } catch (InstallerException e) {
18998            Slog.w(TAG, String.valueOf(e));
18999            return false;
19000        }
19001
19002        return true;
19003    }
19004
19005    private int getUidTargetSdkVersionLockedLPr(int uid) {
19006        Object obj = mSettings.getUserIdLPr(uid);
19007        if (obj instanceof SharedUserSetting) {
19008            final SharedUserSetting sus = (SharedUserSetting) obj;
19009            int vers = Build.VERSION_CODES.CUR_DEVELOPMENT;
19010            final Iterator<PackageSetting> it = sus.packages.iterator();
19011            while (it.hasNext()) {
19012                final PackageSetting ps = it.next();
19013                if (ps.pkg != null) {
19014                    int v = ps.pkg.applicationInfo.targetSdkVersion;
19015                    if (v < vers) vers = v;
19016                }
19017            }
19018            return vers;
19019        } else if (obj instanceof PackageSetting) {
19020            final PackageSetting ps = (PackageSetting) obj;
19021            if (ps.pkg != null) {
19022                return ps.pkg.applicationInfo.targetSdkVersion;
19023            }
19024        }
19025        return Build.VERSION_CODES.CUR_DEVELOPMENT;
19026    }
19027
19028    @Override
19029    public void addPreferredActivity(IntentFilter filter, int match,
19030            ComponentName[] set, ComponentName activity, int userId) {
19031        addPreferredActivityInternal(filter, match, set, activity, true, userId,
19032                "Adding preferred");
19033    }
19034
19035    private void addPreferredActivityInternal(IntentFilter filter, int match,
19036            ComponentName[] set, ComponentName activity, boolean always, int userId,
19037            String opname) {
19038        // writer
19039        int callingUid = Binder.getCallingUid();
19040        enforceCrossUserPermission(callingUid, userId,
19041                true /* requireFullPermission */, false /* checkShell */, "add preferred activity");
19042        if (filter.countActions() == 0) {
19043            Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
19044            return;
19045        }
19046        synchronized (mPackages) {
19047            if (mContext.checkCallingOrSelfPermission(
19048                    android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
19049                    != PackageManager.PERMISSION_GRANTED) {
19050                if (getUidTargetSdkVersionLockedLPr(callingUid)
19051                        < Build.VERSION_CODES.FROYO) {
19052                    Slog.w(TAG, "Ignoring addPreferredActivity() from uid "
19053                            + callingUid);
19054                    return;
19055                }
19056                mContext.enforceCallingOrSelfPermission(
19057                        android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
19058            }
19059
19060            PreferredIntentResolver pir = mSettings.editPreferredActivitiesLPw(userId);
19061            Slog.i(TAG, opname + " activity " + activity.flattenToShortString() + " for user "
19062                    + userId + ":");
19063            filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
19064            pir.addFilter(new PreferredActivity(filter, match, set, activity, always));
19065            scheduleWritePackageRestrictionsLocked(userId);
19066            postPreferredActivityChangedBroadcast(userId);
19067        }
19068    }
19069
19070    private void postPreferredActivityChangedBroadcast(int userId) {
19071        mHandler.post(() -> {
19072            final IActivityManager am = ActivityManager.getService();
19073            if (am == null) {
19074                return;
19075            }
19076
19077            final Intent intent = new Intent(Intent.ACTION_PREFERRED_ACTIVITY_CHANGED);
19078            intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19079            try {
19080                am.broadcastIntent(null, intent, null, null,
19081                        0, null, null, null, android.app.AppOpsManager.OP_NONE,
19082                        null, false, false, userId);
19083            } catch (RemoteException e) {
19084            }
19085        });
19086    }
19087
19088    @Override
19089    public void replacePreferredActivity(IntentFilter filter, int match,
19090            ComponentName[] set, ComponentName activity, int userId) {
19091        if (filter.countActions() != 1) {
19092            throw new IllegalArgumentException(
19093                    "replacePreferredActivity expects filter to have only 1 action.");
19094        }
19095        if (filter.countDataAuthorities() != 0
19096                || filter.countDataPaths() != 0
19097                || filter.countDataSchemes() > 1
19098                || filter.countDataTypes() != 0) {
19099            throw new IllegalArgumentException(
19100                    "replacePreferredActivity expects filter to have no data authorities, " +
19101                    "paths, or types; and at most one scheme.");
19102        }
19103
19104        final int callingUid = Binder.getCallingUid();
19105        enforceCrossUserPermission(callingUid, userId,
19106                true /* requireFullPermission */, false /* checkShell */,
19107                "replace preferred activity");
19108        synchronized (mPackages) {
19109            if (mContext.checkCallingOrSelfPermission(
19110                    android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
19111                    != PackageManager.PERMISSION_GRANTED) {
19112                if (getUidTargetSdkVersionLockedLPr(callingUid)
19113                        < Build.VERSION_CODES.FROYO) {
19114                    Slog.w(TAG, "Ignoring replacePreferredActivity() from uid "
19115                            + Binder.getCallingUid());
19116                    return;
19117                }
19118                mContext.enforceCallingOrSelfPermission(
19119                        android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
19120            }
19121
19122            PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
19123            if (pir != null) {
19124                // Get all of the existing entries that exactly match this filter.
19125                ArrayList<PreferredActivity> existing = pir.findFilters(filter);
19126                if (existing != null && existing.size() == 1) {
19127                    PreferredActivity cur = existing.get(0);
19128                    if (DEBUG_PREFERRED) {
19129                        Slog.i(TAG, "Checking replace of preferred:");
19130                        filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
19131                        if (!cur.mPref.mAlways) {
19132                            Slog.i(TAG, "  -- CUR; not mAlways!");
19133                        } else {
19134                            Slog.i(TAG, "  -- CUR: mMatch=" + cur.mPref.mMatch);
19135                            Slog.i(TAG, "  -- CUR: mSet="
19136                                    + Arrays.toString(cur.mPref.mSetComponents));
19137                            Slog.i(TAG, "  -- CUR: mComponent=" + cur.mPref.mShortComponent);
19138                            Slog.i(TAG, "  -- NEW: mMatch="
19139                                    + (match&IntentFilter.MATCH_CATEGORY_MASK));
19140                            Slog.i(TAG, "  -- CUR: mSet=" + Arrays.toString(set));
19141                            Slog.i(TAG, "  -- CUR: mComponent=" + activity.flattenToShortString());
19142                        }
19143                    }
19144                    if (cur.mPref.mAlways && cur.mPref.mComponent.equals(activity)
19145                            && cur.mPref.mMatch == (match&IntentFilter.MATCH_CATEGORY_MASK)
19146                            && cur.mPref.sameSet(set)) {
19147                        // Setting the preferred activity to what it happens to be already
19148                        if (DEBUG_PREFERRED) {
19149                            Slog.i(TAG, "Replacing with same preferred activity "
19150                                    + cur.mPref.mShortComponent + " for user "
19151                                    + userId + ":");
19152                            filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
19153                        }
19154                        return;
19155                    }
19156                }
19157
19158                if (existing != null) {
19159                    if (DEBUG_PREFERRED) {
19160                        Slog.i(TAG, existing.size() + " existing preferred matches for:");
19161                        filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
19162                    }
19163                    for (int i = 0; i < existing.size(); i++) {
19164                        PreferredActivity pa = existing.get(i);
19165                        if (DEBUG_PREFERRED) {
19166                            Slog.i(TAG, "Removing existing preferred activity "
19167                                    + pa.mPref.mComponent + ":");
19168                            pa.dump(new LogPrinter(Log.INFO, TAG), "  ");
19169                        }
19170                        pir.removeFilter(pa);
19171                    }
19172                }
19173            }
19174            addPreferredActivityInternal(filter, match, set, activity, true, userId,
19175                    "Replacing preferred");
19176        }
19177    }
19178
19179    @Override
19180    public void clearPackagePreferredActivities(String packageName) {
19181        final int uid = Binder.getCallingUid();
19182        // writer
19183        synchronized (mPackages) {
19184            PackageParser.Package pkg = mPackages.get(packageName);
19185            if (pkg == null || pkg.applicationInfo.uid != uid) {
19186                if (mContext.checkCallingOrSelfPermission(
19187                        android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
19188                        != PackageManager.PERMISSION_GRANTED) {
19189                    if (getUidTargetSdkVersionLockedLPr(Binder.getCallingUid())
19190                            < Build.VERSION_CODES.FROYO) {
19191                        Slog.w(TAG, "Ignoring clearPackagePreferredActivities() from uid "
19192                                + Binder.getCallingUid());
19193                        return;
19194                    }
19195                    mContext.enforceCallingOrSelfPermission(
19196                            android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
19197                }
19198            }
19199
19200            int user = UserHandle.getCallingUserId();
19201            if (clearPackagePreferredActivitiesLPw(packageName, user)) {
19202                scheduleWritePackageRestrictionsLocked(user);
19203            }
19204        }
19205    }
19206
19207    /** This method takes a specific user id as well as UserHandle.USER_ALL. */
19208    boolean clearPackagePreferredActivitiesLPw(String packageName, int userId) {
19209        ArrayList<PreferredActivity> removed = null;
19210        boolean changed = false;
19211        for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
19212            final int thisUserId = mSettings.mPreferredActivities.keyAt(i);
19213            PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
19214            if (userId != UserHandle.USER_ALL && userId != thisUserId) {
19215                continue;
19216            }
19217            Iterator<PreferredActivity> it = pir.filterIterator();
19218            while (it.hasNext()) {
19219                PreferredActivity pa = it.next();
19220                // Mark entry for removal only if it matches the package name
19221                // and the entry is of type "always".
19222                if (packageName == null ||
19223                        (pa.mPref.mComponent.getPackageName().equals(packageName)
19224                                && pa.mPref.mAlways)) {
19225                    if (removed == null) {
19226                        removed = new ArrayList<PreferredActivity>();
19227                    }
19228                    removed.add(pa);
19229                }
19230            }
19231            if (removed != null) {
19232                for (int j=0; j<removed.size(); j++) {
19233                    PreferredActivity pa = removed.get(j);
19234                    pir.removeFilter(pa);
19235                }
19236                changed = true;
19237            }
19238        }
19239        if (changed) {
19240            postPreferredActivityChangedBroadcast(userId);
19241        }
19242        return changed;
19243    }
19244
19245    /** This method takes a specific user id as well as UserHandle.USER_ALL. */
19246    private void clearIntentFilterVerificationsLPw(int userId) {
19247        final int packageCount = mPackages.size();
19248        for (int i = 0; i < packageCount; i++) {
19249            PackageParser.Package pkg = mPackages.valueAt(i);
19250            clearIntentFilterVerificationsLPw(pkg.packageName, userId);
19251        }
19252    }
19253
19254    /** This method takes a specific user id as well as UserHandle.USER_ALL. */
19255    void clearIntentFilterVerificationsLPw(String packageName, int userId) {
19256        if (userId == UserHandle.USER_ALL) {
19257            if (mSettings.removeIntentFilterVerificationLPw(packageName,
19258                    sUserManager.getUserIds())) {
19259                for (int oneUserId : sUserManager.getUserIds()) {
19260                    scheduleWritePackageRestrictionsLocked(oneUserId);
19261                }
19262            }
19263        } else {
19264            if (mSettings.removeIntentFilterVerificationLPw(packageName, userId)) {
19265                scheduleWritePackageRestrictionsLocked(userId);
19266            }
19267        }
19268    }
19269
19270    void clearDefaultBrowserIfNeeded(String packageName) {
19271        for (int oneUserId : sUserManager.getUserIds()) {
19272            String defaultBrowserPackageName = getDefaultBrowserPackageName(oneUserId);
19273            if (TextUtils.isEmpty(defaultBrowserPackageName)) continue;
19274            if (packageName.equals(defaultBrowserPackageName)) {
19275                setDefaultBrowserPackageName(null, oneUserId);
19276            }
19277        }
19278    }
19279
19280    @Override
19281    public void resetApplicationPreferences(int userId) {
19282        mContext.enforceCallingOrSelfPermission(
19283                android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
19284        final long identity = Binder.clearCallingIdentity();
19285        // writer
19286        try {
19287            synchronized (mPackages) {
19288                clearPackagePreferredActivitiesLPw(null, userId);
19289                mSettings.applyDefaultPreferredAppsLPw(this, userId);
19290                // TODO: We have to reset the default SMS and Phone. This requires
19291                // significant refactoring to keep all default apps in the package
19292                // manager (cleaner but more work) or have the services provide
19293                // callbacks to the package manager to request a default app reset.
19294                applyFactoryDefaultBrowserLPw(userId);
19295                clearIntentFilterVerificationsLPw(userId);
19296                primeDomainVerificationsLPw(userId);
19297                resetUserChangesToRuntimePermissionsAndFlagsLPw(userId);
19298                scheduleWritePackageRestrictionsLocked(userId);
19299            }
19300            resetNetworkPolicies(userId);
19301        } finally {
19302            Binder.restoreCallingIdentity(identity);
19303        }
19304    }
19305
19306    @Override
19307    public int getPreferredActivities(List<IntentFilter> outFilters,
19308            List<ComponentName> outActivities, String packageName) {
19309
19310        int num = 0;
19311        final int userId = UserHandle.getCallingUserId();
19312        // reader
19313        synchronized (mPackages) {
19314            PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
19315            if (pir != null) {
19316                final Iterator<PreferredActivity> it = pir.filterIterator();
19317                while (it.hasNext()) {
19318                    final PreferredActivity pa = it.next();
19319                    if (packageName == null
19320                            || (pa.mPref.mComponent.getPackageName().equals(packageName)
19321                                    && pa.mPref.mAlways)) {
19322                        if (outFilters != null) {
19323                            outFilters.add(new IntentFilter(pa));
19324                        }
19325                        if (outActivities != null) {
19326                            outActivities.add(pa.mPref.mComponent);
19327                        }
19328                    }
19329                }
19330            }
19331        }
19332
19333        return num;
19334    }
19335
19336    @Override
19337    public void addPersistentPreferredActivity(IntentFilter filter, ComponentName activity,
19338            int userId) {
19339        int callingUid = Binder.getCallingUid();
19340        if (callingUid != Process.SYSTEM_UID) {
19341            throw new SecurityException(
19342                    "addPersistentPreferredActivity can only be run by the system");
19343        }
19344        if (filter.countActions() == 0) {
19345            Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
19346            return;
19347        }
19348        synchronized (mPackages) {
19349            Slog.i(TAG, "Adding persistent preferred activity " + activity + " for user " + userId +
19350                    ":");
19351            filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
19352            mSettings.editPersistentPreferredActivitiesLPw(userId).addFilter(
19353                    new PersistentPreferredActivity(filter, activity));
19354            scheduleWritePackageRestrictionsLocked(userId);
19355            postPreferredActivityChangedBroadcast(userId);
19356        }
19357    }
19358
19359    @Override
19360    public void clearPackagePersistentPreferredActivities(String packageName, int userId) {
19361        int callingUid = Binder.getCallingUid();
19362        if (callingUid != Process.SYSTEM_UID) {
19363            throw new SecurityException(
19364                    "clearPackagePersistentPreferredActivities can only be run by the system");
19365        }
19366        ArrayList<PersistentPreferredActivity> removed = null;
19367        boolean changed = false;
19368        synchronized (mPackages) {
19369            for (int i=0; i<mSettings.mPersistentPreferredActivities.size(); i++) {
19370                final int thisUserId = mSettings.mPersistentPreferredActivities.keyAt(i);
19371                PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
19372                        .valueAt(i);
19373                if (userId != thisUserId) {
19374                    continue;
19375                }
19376                Iterator<PersistentPreferredActivity> it = ppir.filterIterator();
19377                while (it.hasNext()) {
19378                    PersistentPreferredActivity ppa = it.next();
19379                    // Mark entry for removal only if it matches the package name.
19380                    if (ppa.mComponent.getPackageName().equals(packageName)) {
19381                        if (removed == null) {
19382                            removed = new ArrayList<PersistentPreferredActivity>();
19383                        }
19384                        removed.add(ppa);
19385                    }
19386                }
19387                if (removed != null) {
19388                    for (int j=0; j<removed.size(); j++) {
19389                        PersistentPreferredActivity ppa = removed.get(j);
19390                        ppir.removeFilter(ppa);
19391                    }
19392                    changed = true;
19393                }
19394            }
19395
19396            if (changed) {
19397                scheduleWritePackageRestrictionsLocked(userId);
19398                postPreferredActivityChangedBroadcast(userId);
19399            }
19400        }
19401    }
19402
19403    /**
19404     * Common machinery for picking apart a restored XML blob and passing
19405     * it to a caller-supplied functor to be applied to the running system.
19406     */
19407    private void restoreFromXml(XmlPullParser parser, int userId,
19408            String expectedStartTag, BlobXmlRestorer functor)
19409            throws IOException, XmlPullParserException {
19410        int type;
19411        while ((type = parser.next()) != XmlPullParser.START_TAG
19412                && type != XmlPullParser.END_DOCUMENT) {
19413        }
19414        if (type != XmlPullParser.START_TAG) {
19415            // oops didn't find a start tag?!
19416            if (DEBUG_BACKUP) {
19417                Slog.e(TAG, "Didn't find start tag during restore");
19418            }
19419            return;
19420        }
19421Slog.v(TAG, ":: restoreFromXml() : got to tag " + parser.getName());
19422        // this is supposed to be TAG_PREFERRED_BACKUP
19423        if (!expectedStartTag.equals(parser.getName())) {
19424            if (DEBUG_BACKUP) {
19425                Slog.e(TAG, "Found unexpected tag " + parser.getName());
19426            }
19427            return;
19428        }
19429
19430        // skip interfering stuff, then we're aligned with the backing implementation
19431        while ((type = parser.next()) == XmlPullParser.TEXT) { }
19432Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName());
19433        functor.apply(parser, userId);
19434    }
19435
19436    private interface BlobXmlRestorer {
19437        public void apply(XmlPullParser parser, int userId) throws IOException, XmlPullParserException;
19438    }
19439
19440    /**
19441     * Non-Binder method, support for the backup/restore mechanism: write the
19442     * full set of preferred activities in its canonical XML format.  Returns the
19443     * XML output as a byte array, or null if there is none.
19444     */
19445    @Override
19446    public byte[] getPreferredActivityBackup(int userId) {
19447        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19448            throw new SecurityException("Only the system may call getPreferredActivityBackup()");
19449        }
19450
19451        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
19452        try {
19453            final XmlSerializer serializer = new FastXmlSerializer();
19454            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
19455            serializer.startDocument(null, true);
19456            serializer.startTag(null, TAG_PREFERRED_BACKUP);
19457
19458            synchronized (mPackages) {
19459                mSettings.writePreferredActivitiesLPr(serializer, userId, true);
19460            }
19461
19462            serializer.endTag(null, TAG_PREFERRED_BACKUP);
19463            serializer.endDocument();
19464            serializer.flush();
19465        } catch (Exception e) {
19466            if (DEBUG_BACKUP) {
19467                Slog.e(TAG, "Unable to write preferred activities for backup", e);
19468            }
19469            return null;
19470        }
19471
19472        return dataStream.toByteArray();
19473    }
19474
19475    @Override
19476    public void restorePreferredActivities(byte[] backup, int userId) {
19477        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19478            throw new SecurityException("Only the system may call restorePreferredActivities()");
19479        }
19480
19481        try {
19482            final XmlPullParser parser = Xml.newPullParser();
19483            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
19484            restoreFromXml(parser, userId, TAG_PREFERRED_BACKUP,
19485                    new BlobXmlRestorer() {
19486                        @Override
19487                        public void apply(XmlPullParser parser, int userId)
19488                                throws XmlPullParserException, IOException {
19489                            synchronized (mPackages) {
19490                                mSettings.readPreferredActivitiesLPw(parser, userId);
19491                            }
19492                        }
19493                    } );
19494        } catch (Exception e) {
19495            if (DEBUG_BACKUP) {
19496                Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
19497            }
19498        }
19499    }
19500
19501    /**
19502     * Non-Binder method, support for the backup/restore mechanism: write the
19503     * default browser (etc) settings in its canonical XML format.  Returns the default
19504     * browser XML representation as a byte array, or null if there is none.
19505     */
19506    @Override
19507    public byte[] getDefaultAppsBackup(int userId) {
19508        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19509            throw new SecurityException("Only the system may call getDefaultAppsBackup()");
19510        }
19511
19512        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
19513        try {
19514            final XmlSerializer serializer = new FastXmlSerializer();
19515            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
19516            serializer.startDocument(null, true);
19517            serializer.startTag(null, TAG_DEFAULT_APPS);
19518
19519            synchronized (mPackages) {
19520                mSettings.writeDefaultAppsLPr(serializer, userId);
19521            }
19522
19523            serializer.endTag(null, TAG_DEFAULT_APPS);
19524            serializer.endDocument();
19525            serializer.flush();
19526        } catch (Exception e) {
19527            if (DEBUG_BACKUP) {
19528                Slog.e(TAG, "Unable to write default apps for backup", e);
19529            }
19530            return null;
19531        }
19532
19533        return dataStream.toByteArray();
19534    }
19535
19536    @Override
19537    public void restoreDefaultApps(byte[] backup, int userId) {
19538        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19539            throw new SecurityException("Only the system may call restoreDefaultApps()");
19540        }
19541
19542        try {
19543            final XmlPullParser parser = Xml.newPullParser();
19544            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
19545            restoreFromXml(parser, userId, TAG_DEFAULT_APPS,
19546                    new BlobXmlRestorer() {
19547                        @Override
19548                        public void apply(XmlPullParser parser, int userId)
19549                                throws XmlPullParserException, IOException {
19550                            synchronized (mPackages) {
19551                                mSettings.readDefaultAppsLPw(parser, userId);
19552                            }
19553                        }
19554                    } );
19555        } catch (Exception e) {
19556            if (DEBUG_BACKUP) {
19557                Slog.e(TAG, "Exception restoring default apps: " + e.getMessage());
19558            }
19559        }
19560    }
19561
19562    @Override
19563    public byte[] getIntentFilterVerificationBackup(int userId) {
19564        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19565            throw new SecurityException("Only the system may call getIntentFilterVerificationBackup()");
19566        }
19567
19568        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
19569        try {
19570            final XmlSerializer serializer = new FastXmlSerializer();
19571            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
19572            serializer.startDocument(null, true);
19573            serializer.startTag(null, TAG_INTENT_FILTER_VERIFICATION);
19574
19575            synchronized (mPackages) {
19576                mSettings.writeAllDomainVerificationsLPr(serializer, userId);
19577            }
19578
19579            serializer.endTag(null, TAG_INTENT_FILTER_VERIFICATION);
19580            serializer.endDocument();
19581            serializer.flush();
19582        } catch (Exception e) {
19583            if (DEBUG_BACKUP) {
19584                Slog.e(TAG, "Unable to write default apps for backup", e);
19585            }
19586            return null;
19587        }
19588
19589        return dataStream.toByteArray();
19590    }
19591
19592    @Override
19593    public void restoreIntentFilterVerification(byte[] backup, int userId) {
19594        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19595            throw new SecurityException("Only the system may call restorePreferredActivities()");
19596        }
19597
19598        try {
19599            final XmlPullParser parser = Xml.newPullParser();
19600            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
19601            restoreFromXml(parser, userId, TAG_INTENT_FILTER_VERIFICATION,
19602                    new BlobXmlRestorer() {
19603                        @Override
19604                        public void apply(XmlPullParser parser, int userId)
19605                                throws XmlPullParserException, IOException {
19606                            synchronized (mPackages) {
19607                                mSettings.readAllDomainVerificationsLPr(parser, userId);
19608                                mSettings.writeLPr();
19609                            }
19610                        }
19611                    } );
19612        } catch (Exception e) {
19613            if (DEBUG_BACKUP) {
19614                Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
19615            }
19616        }
19617    }
19618
19619    @Override
19620    public byte[] getPermissionGrantBackup(int userId) {
19621        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19622            throw new SecurityException("Only the system may call getPermissionGrantBackup()");
19623        }
19624
19625        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
19626        try {
19627            final XmlSerializer serializer = new FastXmlSerializer();
19628            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
19629            serializer.startDocument(null, true);
19630            serializer.startTag(null, TAG_PERMISSION_BACKUP);
19631
19632            synchronized (mPackages) {
19633                serializeRuntimePermissionGrantsLPr(serializer, userId);
19634            }
19635
19636            serializer.endTag(null, TAG_PERMISSION_BACKUP);
19637            serializer.endDocument();
19638            serializer.flush();
19639        } catch (Exception e) {
19640            if (DEBUG_BACKUP) {
19641                Slog.e(TAG, "Unable to write default apps for backup", e);
19642            }
19643            return null;
19644        }
19645
19646        return dataStream.toByteArray();
19647    }
19648
19649    @Override
19650    public void restorePermissionGrants(byte[] backup, int userId) {
19651        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19652            throw new SecurityException("Only the system may call restorePermissionGrants()");
19653        }
19654
19655        try {
19656            final XmlPullParser parser = Xml.newPullParser();
19657            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
19658            restoreFromXml(parser, userId, TAG_PERMISSION_BACKUP,
19659                    new BlobXmlRestorer() {
19660                        @Override
19661                        public void apply(XmlPullParser parser, int userId)
19662                                throws XmlPullParserException, IOException {
19663                            synchronized (mPackages) {
19664                                processRestoredPermissionGrantsLPr(parser, userId);
19665                            }
19666                        }
19667                    } );
19668        } catch (Exception e) {
19669            if (DEBUG_BACKUP) {
19670                Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
19671            }
19672        }
19673    }
19674
19675    private void serializeRuntimePermissionGrantsLPr(XmlSerializer serializer, final int userId)
19676            throws IOException {
19677        serializer.startTag(null, TAG_ALL_GRANTS);
19678
19679        final int N = mSettings.mPackages.size();
19680        for (int i = 0; i < N; i++) {
19681            final PackageSetting ps = mSettings.mPackages.valueAt(i);
19682            boolean pkgGrantsKnown = false;
19683
19684            PermissionsState packagePerms = ps.getPermissionsState();
19685
19686            for (PermissionState state : packagePerms.getRuntimePermissionStates(userId)) {
19687                final int grantFlags = state.getFlags();
19688                // only look at grants that are not system/policy fixed
19689                if ((grantFlags & SYSTEM_RUNTIME_GRANT_MASK) == 0) {
19690                    final boolean isGranted = state.isGranted();
19691                    // And only back up the user-twiddled state bits
19692                    if (isGranted || (grantFlags & USER_RUNTIME_GRANT_MASK) != 0) {
19693                        final String packageName = mSettings.mPackages.keyAt(i);
19694                        if (!pkgGrantsKnown) {
19695                            serializer.startTag(null, TAG_GRANT);
19696                            serializer.attribute(null, ATTR_PACKAGE_NAME, packageName);
19697                            pkgGrantsKnown = true;
19698                        }
19699
19700                        final boolean userSet =
19701                                (grantFlags & FLAG_PERMISSION_USER_SET) != 0;
19702                        final boolean userFixed =
19703                                (grantFlags & FLAG_PERMISSION_USER_FIXED) != 0;
19704                        final boolean revoke =
19705                                (grantFlags & FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0;
19706
19707                        serializer.startTag(null, TAG_PERMISSION);
19708                        serializer.attribute(null, ATTR_PERMISSION_NAME, state.getName());
19709                        if (isGranted) {
19710                            serializer.attribute(null, ATTR_IS_GRANTED, "true");
19711                        }
19712                        if (userSet) {
19713                            serializer.attribute(null, ATTR_USER_SET, "true");
19714                        }
19715                        if (userFixed) {
19716                            serializer.attribute(null, ATTR_USER_FIXED, "true");
19717                        }
19718                        if (revoke) {
19719                            serializer.attribute(null, ATTR_REVOKE_ON_UPGRADE, "true");
19720                        }
19721                        serializer.endTag(null, TAG_PERMISSION);
19722                    }
19723                }
19724            }
19725
19726            if (pkgGrantsKnown) {
19727                serializer.endTag(null, TAG_GRANT);
19728            }
19729        }
19730
19731        serializer.endTag(null, TAG_ALL_GRANTS);
19732    }
19733
19734    private void processRestoredPermissionGrantsLPr(XmlPullParser parser, int userId)
19735            throws XmlPullParserException, IOException {
19736        String pkgName = null;
19737        int outerDepth = parser.getDepth();
19738        int type;
19739        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
19740                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
19741            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
19742                continue;
19743            }
19744
19745            final String tagName = parser.getName();
19746            if (tagName.equals(TAG_GRANT)) {
19747                pkgName = parser.getAttributeValue(null, ATTR_PACKAGE_NAME);
19748                if (DEBUG_BACKUP) {
19749                    Slog.v(TAG, "+++ Restoring grants for package " + pkgName);
19750                }
19751            } else if (tagName.equals(TAG_PERMISSION)) {
19752
19753                final boolean isGranted = "true".equals(parser.getAttributeValue(null, ATTR_IS_GRANTED));
19754                final String permName = parser.getAttributeValue(null, ATTR_PERMISSION_NAME);
19755
19756                int newFlagSet = 0;
19757                if ("true".equals(parser.getAttributeValue(null, ATTR_USER_SET))) {
19758                    newFlagSet |= FLAG_PERMISSION_USER_SET;
19759                }
19760                if ("true".equals(parser.getAttributeValue(null, ATTR_USER_FIXED))) {
19761                    newFlagSet |= FLAG_PERMISSION_USER_FIXED;
19762                }
19763                if ("true".equals(parser.getAttributeValue(null, ATTR_REVOKE_ON_UPGRADE))) {
19764                    newFlagSet |= FLAG_PERMISSION_REVOKE_ON_UPGRADE;
19765                }
19766                if (DEBUG_BACKUP) {
19767                    Slog.v(TAG, "  + Restoring grant: pkg=" + pkgName + " perm=" + permName
19768                            + " granted=" + isGranted + " bits=0x" + Integer.toHexString(newFlagSet));
19769                }
19770                final PackageSetting ps = mSettings.mPackages.get(pkgName);
19771                if (ps != null) {
19772                    // Already installed so we apply the grant immediately
19773                    if (DEBUG_BACKUP) {
19774                        Slog.v(TAG, "        + already installed; applying");
19775                    }
19776                    PermissionsState perms = ps.getPermissionsState();
19777                    BasePermission bp = mSettings.mPermissions.get(permName);
19778                    if (bp != null) {
19779                        if (isGranted) {
19780                            perms.grantRuntimePermission(bp, userId);
19781                        }
19782                        if (newFlagSet != 0) {
19783                            perms.updatePermissionFlags(bp, userId, USER_RUNTIME_GRANT_MASK, newFlagSet);
19784                        }
19785                    }
19786                } else {
19787                    // Need to wait for post-restore install to apply the grant
19788                    if (DEBUG_BACKUP) {
19789                        Slog.v(TAG, "        - not yet installed; saving for later");
19790                    }
19791                    mSettings.processRestoredPermissionGrantLPr(pkgName, permName,
19792                            isGranted, newFlagSet, userId);
19793                }
19794            } else {
19795                PackageManagerService.reportSettingsProblem(Log.WARN,
19796                        "Unknown element under <" + TAG_PERMISSION_BACKUP + ">: " + tagName);
19797                XmlUtils.skipCurrentTag(parser);
19798            }
19799        }
19800
19801        scheduleWriteSettingsLocked();
19802        mSettings.writeRuntimePermissionsForUserLPr(userId, false);
19803    }
19804
19805    @Override
19806    public void addCrossProfileIntentFilter(IntentFilter intentFilter, String ownerPackage,
19807            int sourceUserId, int targetUserId, int flags) {
19808        mContext.enforceCallingOrSelfPermission(
19809                        android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
19810        int callingUid = Binder.getCallingUid();
19811        enforceOwnerRights(ownerPackage, callingUid);
19812        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
19813        if (intentFilter.countActions() == 0) {
19814            Slog.w(TAG, "Cannot set a crossProfile intent filter with no filter actions");
19815            return;
19816        }
19817        synchronized (mPackages) {
19818            CrossProfileIntentFilter newFilter = new CrossProfileIntentFilter(intentFilter,
19819                    ownerPackage, targetUserId, flags);
19820            CrossProfileIntentResolver resolver =
19821                    mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
19822            ArrayList<CrossProfileIntentFilter> existing = resolver.findFilters(intentFilter);
19823            // We have all those whose filter is equal. Now checking if the rest is equal as well.
19824            if (existing != null) {
19825                int size = existing.size();
19826                for (int i = 0; i < size; i++) {
19827                    if (newFilter.equalsIgnoreFilter(existing.get(i))) {
19828                        return;
19829                    }
19830                }
19831            }
19832            resolver.addFilter(newFilter);
19833            scheduleWritePackageRestrictionsLocked(sourceUserId);
19834        }
19835    }
19836
19837    @Override
19838    public void clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage) {
19839        mContext.enforceCallingOrSelfPermission(
19840                        android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
19841        int callingUid = Binder.getCallingUid();
19842        enforceOwnerRights(ownerPackage, callingUid);
19843        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
19844        synchronized (mPackages) {
19845            CrossProfileIntentResolver resolver =
19846                    mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
19847            ArraySet<CrossProfileIntentFilter> set =
19848                    new ArraySet<CrossProfileIntentFilter>(resolver.filterSet());
19849            for (CrossProfileIntentFilter filter : set) {
19850                if (filter.getOwnerPackage().equals(ownerPackage)) {
19851                    resolver.removeFilter(filter);
19852                }
19853            }
19854            scheduleWritePackageRestrictionsLocked(sourceUserId);
19855        }
19856    }
19857
19858    // Enforcing that callingUid is owning pkg on userId
19859    private void enforceOwnerRights(String pkg, int callingUid) {
19860        // The system owns everything.
19861        if (UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) {
19862            return;
19863        }
19864        int callingUserId = UserHandle.getUserId(callingUid);
19865        PackageInfo pi = getPackageInfo(pkg, 0, callingUserId);
19866        if (pi == null) {
19867            throw new IllegalArgumentException("Unknown package " + pkg + " on user "
19868                    + callingUserId);
19869        }
19870        if (!UserHandle.isSameApp(pi.applicationInfo.uid, callingUid)) {
19871            throw new SecurityException("Calling uid " + callingUid
19872                    + " does not own package " + pkg);
19873        }
19874    }
19875
19876    @Override
19877    public ComponentName getHomeActivities(List<ResolveInfo> allHomeCandidates) {
19878        return getHomeActivitiesAsUser(allHomeCandidates, UserHandle.getCallingUserId());
19879    }
19880
19881    /**
19882     * Report the 'Home' activity which is currently set as "always use this one". If non is set
19883     * then reports the most likely home activity or null if there are more than one.
19884     */
19885    public ComponentName getDefaultHomeActivity(int userId) {
19886        List<ResolveInfo> allHomeCandidates = new ArrayList<>();
19887        ComponentName cn = getHomeActivitiesAsUser(allHomeCandidates, userId);
19888        if (cn != null) {
19889            return cn;
19890        }
19891
19892        // Find the launcher with the highest priority and return that component if there are no
19893        // other home activity with the same priority.
19894        int lastPriority = Integer.MIN_VALUE;
19895        ComponentName lastComponent = null;
19896        final int size = allHomeCandidates.size();
19897        for (int i = 0; i < size; i++) {
19898            final ResolveInfo ri = allHomeCandidates.get(i);
19899            if (ri.priority > lastPriority) {
19900                lastComponent = ri.activityInfo.getComponentName();
19901                lastPriority = ri.priority;
19902            } else if (ri.priority == lastPriority) {
19903                // Two components found with same priority.
19904                lastComponent = null;
19905            }
19906        }
19907        return lastComponent;
19908    }
19909
19910    private Intent getHomeIntent() {
19911        Intent intent = new Intent(Intent.ACTION_MAIN);
19912        intent.addCategory(Intent.CATEGORY_HOME);
19913        intent.addCategory(Intent.CATEGORY_DEFAULT);
19914        return intent;
19915    }
19916
19917    private IntentFilter getHomeFilter() {
19918        IntentFilter filter = new IntentFilter(Intent.ACTION_MAIN);
19919        filter.addCategory(Intent.CATEGORY_HOME);
19920        filter.addCategory(Intent.CATEGORY_DEFAULT);
19921        return filter;
19922    }
19923
19924    ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates,
19925            int userId) {
19926        Intent intent  = getHomeIntent();
19927        List<ResolveInfo> list = queryIntentActivitiesInternal(intent, null,
19928                PackageManager.GET_META_DATA, userId);
19929        ResolveInfo preferred = findPreferredActivity(intent, null, 0, list, 0,
19930                true, false, false, userId);
19931
19932        allHomeCandidates.clear();
19933        if (list != null) {
19934            for (ResolveInfo ri : list) {
19935                allHomeCandidates.add(ri);
19936            }
19937        }
19938        return (preferred == null || preferred.activityInfo == null)
19939                ? null
19940                : new ComponentName(preferred.activityInfo.packageName,
19941                        preferred.activityInfo.name);
19942    }
19943
19944    @Override
19945    public void setHomeActivity(ComponentName comp, int userId) {
19946        ArrayList<ResolveInfo> homeActivities = new ArrayList<>();
19947        getHomeActivitiesAsUser(homeActivities, userId);
19948
19949        boolean found = false;
19950
19951        final int size = homeActivities.size();
19952        final ComponentName[] set = new ComponentName[size];
19953        for (int i = 0; i < size; i++) {
19954            final ResolveInfo candidate = homeActivities.get(i);
19955            final ActivityInfo info = candidate.activityInfo;
19956            final ComponentName activityName = new ComponentName(info.packageName, info.name);
19957            set[i] = activityName;
19958            if (!found && activityName.equals(comp)) {
19959                found = true;
19960            }
19961        }
19962        if (!found) {
19963            throw new IllegalArgumentException("Component " + comp + " cannot be home on user "
19964                    + userId);
19965        }
19966        replacePreferredActivity(getHomeFilter(), IntentFilter.MATCH_CATEGORY_EMPTY,
19967                set, comp, userId);
19968    }
19969
19970    private @Nullable String getSetupWizardPackageName() {
19971        final Intent intent = new Intent(Intent.ACTION_MAIN);
19972        intent.addCategory(Intent.CATEGORY_SETUP_WIZARD);
19973
19974        final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null,
19975                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE
19976                        | MATCH_DISABLED_COMPONENTS,
19977                UserHandle.myUserId());
19978        if (matches.size() == 1) {
19979            return matches.get(0).getComponentInfo().packageName;
19980        } else {
19981            Slog.e(TAG, "There should probably be exactly one setup wizard; found " + matches.size()
19982                    + ": matches=" + matches);
19983            return null;
19984        }
19985    }
19986
19987    private @Nullable String getStorageManagerPackageName() {
19988        final Intent intent = new Intent(StorageManager.ACTION_MANAGE_STORAGE);
19989
19990        final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null,
19991                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE
19992                        | MATCH_DISABLED_COMPONENTS,
19993                UserHandle.myUserId());
19994        if (matches.size() == 1) {
19995            return matches.get(0).getComponentInfo().packageName;
19996        } else {
19997            Slog.e(TAG, "There should probably be exactly one storage manager; found "
19998                    + matches.size() + ": matches=" + matches);
19999            return null;
20000        }
20001    }
20002
20003    @Override
20004    public void setApplicationEnabledSetting(String appPackageName,
20005            int newState, int flags, int userId, String callingPackage) {
20006        if (!sUserManager.exists(userId)) return;
20007        if (callingPackage == null) {
20008            callingPackage = Integer.toString(Binder.getCallingUid());
20009        }
20010        setEnabledSetting(appPackageName, null, newState, flags, userId, callingPackage);
20011    }
20012
20013    @Override
20014    public void setUpdateAvailable(String packageName, boolean updateAvailable) {
20015        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null);
20016        synchronized (mPackages) {
20017            final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
20018            if (pkgSetting != null) {
20019                pkgSetting.setUpdateAvailable(updateAvailable);
20020            }
20021        }
20022    }
20023
20024    @Override
20025    public void setComponentEnabledSetting(ComponentName componentName,
20026            int newState, int flags, int userId) {
20027        if (!sUserManager.exists(userId)) return;
20028        setEnabledSetting(componentName.getPackageName(),
20029                componentName.getClassName(), newState, flags, userId, null);
20030    }
20031
20032    private void setEnabledSetting(final String packageName, String className, int newState,
20033            final int flags, int userId, String callingPackage) {
20034        if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT
20035              || newState == COMPONENT_ENABLED_STATE_ENABLED
20036              || newState == COMPONENT_ENABLED_STATE_DISABLED
20037              || newState == COMPONENT_ENABLED_STATE_DISABLED_USER
20038              || newState == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED)) {
20039            throw new IllegalArgumentException("Invalid new component state: "
20040                    + newState);
20041        }
20042        PackageSetting pkgSetting;
20043        final int uid = Binder.getCallingUid();
20044        final int permission;
20045        if (uid == Process.SYSTEM_UID) {
20046            permission = PackageManager.PERMISSION_GRANTED;
20047        } else {
20048            permission = mContext.checkCallingOrSelfPermission(
20049                    android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
20050        }
20051        enforceCrossUserPermission(uid, userId,
20052                false /* requireFullPermission */, true /* checkShell */, "set enabled");
20053        final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
20054        boolean sendNow = false;
20055        boolean isApp = (className == null);
20056        String componentName = isApp ? packageName : className;
20057        int packageUid = -1;
20058        ArrayList<String> components;
20059
20060        // writer
20061        synchronized (mPackages) {
20062            pkgSetting = mSettings.mPackages.get(packageName);
20063            if (pkgSetting == null) {
20064                if (className == null) {
20065                    throw new IllegalArgumentException("Unknown package: " + packageName);
20066                }
20067                throw new IllegalArgumentException(
20068                        "Unknown component: " + packageName + "/" + className);
20069            }
20070        }
20071
20072        // Limit who can change which apps
20073        if (!UserHandle.isSameApp(uid, pkgSetting.appId)) {
20074            // Don't allow apps that don't have permission to modify other apps
20075            if (!allowedByPermission) {
20076                throw new SecurityException(
20077                        "Permission Denial: attempt to change component state from pid="
20078                        + Binder.getCallingPid()
20079                        + ", uid=" + uid + ", package uid=" + pkgSetting.appId);
20080            }
20081            // Don't allow changing protected packages.
20082            if (mProtectedPackages.isPackageStateProtected(userId, packageName)) {
20083                throw new SecurityException("Cannot disable a protected package: " + packageName);
20084            }
20085        }
20086
20087        synchronized (mPackages) {
20088            if (uid == Process.SHELL_UID
20089                    && (pkgSetting.pkgFlags & ApplicationInfo.FLAG_TEST_ONLY) == 0) {
20090                // Shell can only change whole packages between ENABLED and DISABLED_USER states
20091                // unless it is a test package.
20092                int oldState = pkgSetting.getEnabled(userId);
20093                if (className == null
20094                    &&
20095                    (oldState == COMPONENT_ENABLED_STATE_DISABLED_USER
20096                     || oldState == COMPONENT_ENABLED_STATE_DEFAULT
20097                     || oldState == COMPONENT_ENABLED_STATE_ENABLED)
20098                    &&
20099                    (newState == COMPONENT_ENABLED_STATE_DISABLED_USER
20100                     || newState == COMPONENT_ENABLED_STATE_DEFAULT
20101                     || newState == COMPONENT_ENABLED_STATE_ENABLED)) {
20102                    // ok
20103                } else {
20104                    throw new SecurityException(
20105                            "Shell cannot change component state for " + packageName + "/"
20106                            + className + " to " + newState);
20107                }
20108            }
20109            if (className == null) {
20110                // We're dealing with an application/package level state change
20111                if (pkgSetting.getEnabled(userId) == newState) {
20112                    // Nothing to do
20113                    return;
20114                }
20115                if (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
20116                    || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {
20117                    // Don't care about who enables an app.
20118                    callingPackage = null;
20119                }
20120                pkgSetting.setEnabled(newState, userId, callingPackage);
20121                // pkgSetting.pkg.mSetEnabled = newState;
20122            } else {
20123                // We're dealing with a component level state change
20124                // First, verify that this is a valid class name.
20125                PackageParser.Package pkg = pkgSetting.pkg;
20126                if (pkg == null || !pkg.hasComponentClassName(className)) {
20127                    if (pkg != null &&
20128                            pkg.applicationInfo.targetSdkVersion >=
20129                                    Build.VERSION_CODES.JELLY_BEAN) {
20130                        throw new IllegalArgumentException("Component class " + className
20131                                + " does not exist in " + packageName);
20132                    } else {
20133                        Slog.w(TAG, "Failed setComponentEnabledSetting: component class "
20134                                + className + " does not exist in " + packageName);
20135                    }
20136                }
20137                switch (newState) {
20138                case COMPONENT_ENABLED_STATE_ENABLED:
20139                    if (!pkgSetting.enableComponentLPw(className, userId)) {
20140                        return;
20141                    }
20142                    break;
20143                case COMPONENT_ENABLED_STATE_DISABLED:
20144                    if (!pkgSetting.disableComponentLPw(className, userId)) {
20145                        return;
20146                    }
20147                    break;
20148                case COMPONENT_ENABLED_STATE_DEFAULT:
20149                    if (!pkgSetting.restoreComponentLPw(className, userId)) {
20150                        return;
20151                    }
20152                    break;
20153                default:
20154                    Slog.e(TAG, "Invalid new component state: " + newState);
20155                    return;
20156                }
20157            }
20158            scheduleWritePackageRestrictionsLocked(userId);
20159            updateSequenceNumberLP(packageName, new int[] { userId });
20160            final long callingId = Binder.clearCallingIdentity();
20161            try {
20162                updateInstantAppInstallerLocked(packageName);
20163            } finally {
20164                Binder.restoreCallingIdentity(callingId);
20165            }
20166            components = mPendingBroadcasts.get(userId, packageName);
20167            final boolean newPackage = components == null;
20168            if (newPackage) {
20169                components = new ArrayList<String>();
20170            }
20171            if (!components.contains(componentName)) {
20172                components.add(componentName);
20173            }
20174            if ((flags&PackageManager.DONT_KILL_APP) == 0) {
20175                sendNow = true;
20176                // Purge entry from pending broadcast list if another one exists already
20177                // since we are sending one right away.
20178                mPendingBroadcasts.remove(userId, packageName);
20179            } else {
20180                if (newPackage) {
20181                    mPendingBroadcasts.put(userId, packageName, components);
20182                }
20183                if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) {
20184                    // Schedule a message
20185                    mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, BROADCAST_DELAY);
20186                }
20187            }
20188        }
20189
20190        long callingId = Binder.clearCallingIdentity();
20191        try {
20192            if (sendNow) {
20193                packageUid = UserHandle.getUid(userId, pkgSetting.appId);
20194                sendPackageChangedBroadcast(packageName,
20195                        (flags&PackageManager.DONT_KILL_APP) != 0, components, packageUid);
20196            }
20197        } finally {
20198            Binder.restoreCallingIdentity(callingId);
20199        }
20200    }
20201
20202    @Override
20203    public void flushPackageRestrictionsAsUser(int userId) {
20204        if (!sUserManager.exists(userId)) {
20205            return;
20206        }
20207        enforceCrossUserPermission(Binder.getCallingUid(), userId, false /* requireFullPermission*/,
20208                false /* checkShell */, "flushPackageRestrictions");
20209        synchronized (mPackages) {
20210            mSettings.writePackageRestrictionsLPr(userId);
20211            mDirtyUsers.remove(userId);
20212            if (mDirtyUsers.isEmpty()) {
20213                mHandler.removeMessages(WRITE_PACKAGE_RESTRICTIONS);
20214            }
20215        }
20216    }
20217
20218    private void sendPackageChangedBroadcast(String packageName,
20219            boolean killFlag, ArrayList<String> componentNames, int packageUid) {
20220        if (DEBUG_INSTALL)
20221            Log.v(TAG, "Sending package changed: package=" + packageName + " components="
20222                    + componentNames);
20223        Bundle extras = new Bundle(4);
20224        extras.putString(Intent.EXTRA_CHANGED_COMPONENT_NAME, componentNames.get(0));
20225        String nameList[] = new String[componentNames.size()];
20226        componentNames.toArray(nameList);
20227        extras.putStringArray(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST, nameList);
20228        extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, killFlag);
20229        extras.putInt(Intent.EXTRA_UID, packageUid);
20230        // If this is not reporting a change of the overall package, then only send it
20231        // to registered receivers.  We don't want to launch a swath of apps for every
20232        // little component state change.
20233        final int flags = !componentNames.contains(packageName)
20234                ? Intent.FLAG_RECEIVER_REGISTERED_ONLY : 0;
20235        sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED,  packageName, extras, flags, null, null,
20236                new int[] {UserHandle.getUserId(packageUid)});
20237    }
20238
20239    @Override
20240    public void setPackageStoppedState(String packageName, boolean stopped, int userId) {
20241        if (!sUserManager.exists(userId)) return;
20242        final int uid = Binder.getCallingUid();
20243        final int permission = mContext.checkCallingOrSelfPermission(
20244                android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
20245        final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
20246        enforceCrossUserPermission(uid, userId,
20247                true /* requireFullPermission */, true /* checkShell */, "stop package");
20248        // writer
20249        synchronized (mPackages) {
20250            if (mSettings.setPackageStoppedStateLPw(this, packageName, stopped,
20251                    allowedByPermission, uid, userId)) {
20252                scheduleWritePackageRestrictionsLocked(userId);
20253            }
20254        }
20255    }
20256
20257    @Override
20258    public String getInstallerPackageName(String packageName) {
20259        // reader
20260        synchronized (mPackages) {
20261            return mSettings.getInstallerPackageNameLPr(packageName);
20262        }
20263    }
20264
20265    public boolean isOrphaned(String packageName) {
20266        // reader
20267        synchronized (mPackages) {
20268            return mSettings.isOrphaned(packageName);
20269        }
20270    }
20271
20272    @Override
20273    public int getApplicationEnabledSetting(String packageName, int userId) {
20274        if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
20275        int uid = Binder.getCallingUid();
20276        enforceCrossUserPermission(uid, userId,
20277                false /* requireFullPermission */, false /* checkShell */, "get enabled");
20278        // reader
20279        synchronized (mPackages) {
20280            return mSettings.getApplicationEnabledSettingLPr(packageName, userId);
20281        }
20282    }
20283
20284    @Override
20285    public int getComponentEnabledSetting(ComponentName componentName, int userId) {
20286        if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
20287        int uid = Binder.getCallingUid();
20288        enforceCrossUserPermission(uid, userId,
20289                false /* requireFullPermission */, false /* checkShell */, "get component enabled");
20290        // reader
20291        synchronized (mPackages) {
20292            return mSettings.getComponentEnabledSettingLPr(componentName, userId);
20293        }
20294    }
20295
20296    @Override
20297    public void enterSafeMode() {
20298        enforceSystemOrRoot("Only the system can request entering safe mode");
20299
20300        if (!mSystemReady) {
20301            mSafeMode = true;
20302        }
20303    }
20304
20305    @Override
20306    public void systemReady() {
20307        mSystemReady = true;
20308        final ContentResolver resolver = mContext.getContentResolver();
20309        ContentObserver co = new ContentObserver(mHandler) {
20310            @Override
20311            public void onChange(boolean selfChange) {
20312                mEphemeralAppsDisabled =
20313                        (Global.getInt(resolver, Global.ENABLE_EPHEMERAL_FEATURE, 1) == 0) ||
20314                                (Secure.getInt(resolver, Secure.INSTANT_APPS_ENABLED, 1) == 0);
20315            }
20316        };
20317        mContext.getContentResolver().registerContentObserver(android.provider.Settings.Global
20318                        .getUriFor(Global.ENABLE_EPHEMERAL_FEATURE),
20319                false, co, UserHandle.USER_SYSTEM);
20320        mContext.getContentResolver().registerContentObserver(android.provider.Settings.Global
20321                        .getUriFor(Secure.INSTANT_APPS_ENABLED), false, co, UserHandle.USER_SYSTEM);
20322        co.onChange(true);
20323
20324        // Disable any carrier apps. We do this very early in boot to prevent the apps from being
20325        // disabled after already being started.
20326        CarrierAppUtils.disableCarrierAppsUntilPrivileged(mContext.getOpPackageName(), this,
20327                mContext.getContentResolver(), UserHandle.USER_SYSTEM);
20328
20329        // Read the compatibilty setting when the system is ready.
20330        boolean compatibilityModeEnabled = android.provider.Settings.Global.getInt(
20331                mContext.getContentResolver(),
20332                android.provider.Settings.Global.COMPATIBILITY_MODE, 1) == 1;
20333        PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled);
20334        if (DEBUG_SETTINGS) {
20335            Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled);
20336        }
20337
20338        int[] grantPermissionsUserIds = EMPTY_INT_ARRAY;
20339
20340        synchronized (mPackages) {
20341            // Verify that all of the preferred activity components actually
20342            // exist.  It is possible for applications to be updated and at
20343            // that point remove a previously declared activity component that
20344            // had been set as a preferred activity.  We try to clean this up
20345            // the next time we encounter that preferred activity, but it is
20346            // possible for the user flow to never be able to return to that
20347            // situation so here we do a sanity check to make sure we haven't
20348            // left any junk around.
20349            ArrayList<PreferredActivity> removed = new ArrayList<PreferredActivity>();
20350            for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
20351                PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
20352                removed.clear();
20353                for (PreferredActivity pa : pir.filterSet()) {
20354                    if (mActivities.mActivities.get(pa.mPref.mComponent) == null) {
20355                        removed.add(pa);
20356                    }
20357                }
20358                if (removed.size() > 0) {
20359                    for (int r=0; r<removed.size(); r++) {
20360                        PreferredActivity pa = removed.get(r);
20361                        Slog.w(TAG, "Removing dangling preferred activity: "
20362                                + pa.mPref.mComponent);
20363                        pir.removeFilter(pa);
20364                    }
20365                    mSettings.writePackageRestrictionsLPr(
20366                            mSettings.mPreferredActivities.keyAt(i));
20367                }
20368            }
20369
20370            for (int userId : UserManagerService.getInstance().getUserIds()) {
20371                if (!mSettings.areDefaultRuntimePermissionsGrantedLPr(userId)) {
20372                    grantPermissionsUserIds = ArrayUtils.appendInt(
20373                            grantPermissionsUserIds, userId);
20374                }
20375            }
20376        }
20377        sUserManager.systemReady();
20378
20379        // If we upgraded grant all default permissions before kicking off.
20380        for (int userId : grantPermissionsUserIds) {
20381            mDefaultPermissionPolicy.grantDefaultPermissions(userId);
20382        }
20383
20384        // If we did not grant default permissions, we preload from this the
20385        // default permission exceptions lazily to ensure we don't hit the
20386        // disk on a new user creation.
20387        if (grantPermissionsUserIds == EMPTY_INT_ARRAY) {
20388            mDefaultPermissionPolicy.scheduleReadDefaultPermissionExceptions();
20389        }
20390
20391        // Kick off any messages waiting for system ready
20392        if (mPostSystemReadyMessages != null) {
20393            for (Message msg : mPostSystemReadyMessages) {
20394                msg.sendToTarget();
20395            }
20396            mPostSystemReadyMessages = null;
20397        }
20398
20399        // Watch for external volumes that come and go over time
20400        final StorageManager storage = mContext.getSystemService(StorageManager.class);
20401        storage.registerListener(mStorageListener);
20402
20403        mInstallerService.systemReady();
20404        mPackageDexOptimizer.systemReady();
20405
20406        StorageManagerInternal StorageManagerInternal = LocalServices.getService(
20407                StorageManagerInternal.class);
20408        StorageManagerInternal.addExternalStoragePolicy(
20409                new StorageManagerInternal.ExternalStorageMountPolicy() {
20410            @Override
20411            public int getMountMode(int uid, String packageName) {
20412                if (Process.isIsolated(uid)) {
20413                    return Zygote.MOUNT_EXTERNAL_NONE;
20414                }
20415                if (checkUidPermission(WRITE_MEDIA_STORAGE, uid) == PERMISSION_GRANTED) {
20416                    return Zygote.MOUNT_EXTERNAL_DEFAULT;
20417                }
20418                if (checkUidPermission(READ_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) {
20419                    return Zygote.MOUNT_EXTERNAL_DEFAULT;
20420                }
20421                if (checkUidPermission(WRITE_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) {
20422                    return Zygote.MOUNT_EXTERNAL_READ;
20423                }
20424                return Zygote.MOUNT_EXTERNAL_WRITE;
20425            }
20426
20427            @Override
20428            public boolean hasExternalStorage(int uid, String packageName) {
20429                return true;
20430            }
20431        });
20432
20433        // Now that we're mostly running, clean up stale users and apps
20434        sUserManager.reconcileUsers(StorageManager.UUID_PRIVATE_INTERNAL);
20435        reconcileApps(StorageManager.UUID_PRIVATE_INTERNAL);
20436
20437        if (mPrivappPermissionsViolations != null) {
20438            Slog.wtf(TAG,"Signature|privileged permissions not in "
20439                    + "privapp-permissions whitelist: " + mPrivappPermissionsViolations);
20440            mPrivappPermissionsViolations = null;
20441        }
20442    }
20443
20444    public void waitForAppDataPrepared() {
20445        if (mPrepareAppDataFuture == null) {
20446            return;
20447        }
20448        ConcurrentUtils.waitForFutureNoInterrupt(mPrepareAppDataFuture, "wait for prepareAppData");
20449        mPrepareAppDataFuture = null;
20450    }
20451
20452    @Override
20453    public boolean isSafeMode() {
20454        return mSafeMode;
20455    }
20456
20457    @Override
20458    public boolean hasSystemUidErrors() {
20459        return mHasSystemUidErrors;
20460    }
20461
20462    static String arrayToString(int[] array) {
20463        StringBuffer buf = new StringBuffer(128);
20464        buf.append('[');
20465        if (array != null) {
20466            for (int i=0; i<array.length; i++) {
20467                if (i > 0) buf.append(", ");
20468                buf.append(array[i]);
20469            }
20470        }
20471        buf.append(']');
20472        return buf.toString();
20473    }
20474
20475    static class DumpState {
20476        public static final int DUMP_LIBS = 1 << 0;
20477        public static final int DUMP_FEATURES = 1 << 1;
20478        public static final int DUMP_ACTIVITY_RESOLVERS = 1 << 2;
20479        public static final int DUMP_SERVICE_RESOLVERS = 1 << 3;
20480        public static final int DUMP_RECEIVER_RESOLVERS = 1 << 4;
20481        public static final int DUMP_CONTENT_RESOLVERS = 1 << 5;
20482        public static final int DUMP_PERMISSIONS = 1 << 6;
20483        public static final int DUMP_PACKAGES = 1 << 7;
20484        public static final int DUMP_SHARED_USERS = 1 << 8;
20485        public static final int DUMP_MESSAGES = 1 << 9;
20486        public static final int DUMP_PROVIDERS = 1 << 10;
20487        public static final int DUMP_VERIFIERS = 1 << 11;
20488        public static final int DUMP_PREFERRED = 1 << 12;
20489        public static final int DUMP_PREFERRED_XML = 1 << 13;
20490        public static final int DUMP_KEYSETS = 1 << 14;
20491        public static final int DUMP_VERSION = 1 << 15;
20492        public static final int DUMP_INSTALLS = 1 << 16;
20493        public static final int DUMP_INTENT_FILTER_VERIFIERS = 1 << 17;
20494        public static final int DUMP_DOMAIN_PREFERRED = 1 << 18;
20495        public static final int DUMP_FROZEN = 1 << 19;
20496        public static final int DUMP_DEXOPT = 1 << 20;
20497        public static final int DUMP_COMPILER_STATS = 1 << 21;
20498        public static final int DUMP_ENABLED_OVERLAYS = 1 << 22;
20499
20500        public static final int OPTION_SHOW_FILTERS = 1 << 0;
20501
20502        private int mTypes;
20503
20504        private int mOptions;
20505
20506        private boolean mTitlePrinted;
20507
20508        private SharedUserSetting mSharedUser;
20509
20510        public boolean isDumping(int type) {
20511            if (mTypes == 0 && type != DUMP_PREFERRED_XML) {
20512                return true;
20513            }
20514
20515            return (mTypes & type) != 0;
20516        }
20517
20518        public void setDump(int type) {
20519            mTypes |= type;
20520        }
20521
20522        public boolean isOptionEnabled(int option) {
20523            return (mOptions & option) != 0;
20524        }
20525
20526        public void setOptionEnabled(int option) {
20527            mOptions |= option;
20528        }
20529
20530        public boolean onTitlePrinted() {
20531            final boolean printed = mTitlePrinted;
20532            mTitlePrinted = true;
20533            return printed;
20534        }
20535
20536        public boolean getTitlePrinted() {
20537            return mTitlePrinted;
20538        }
20539
20540        public void setTitlePrinted(boolean enabled) {
20541            mTitlePrinted = enabled;
20542        }
20543
20544        public SharedUserSetting getSharedUser() {
20545            return mSharedUser;
20546        }
20547
20548        public void setSharedUser(SharedUserSetting user) {
20549            mSharedUser = user;
20550        }
20551    }
20552
20553    @Override
20554    public void onShellCommand(FileDescriptor in, FileDescriptor out,
20555            FileDescriptor err, String[] args, ShellCallback callback,
20556            ResultReceiver resultReceiver) {
20557        (new PackageManagerShellCommand(this)).exec(
20558                this, in, out, err, args, callback, resultReceiver);
20559    }
20560
20561    @Override
20562    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
20563        if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
20564
20565        DumpState dumpState = new DumpState();
20566        boolean fullPreferred = false;
20567        boolean checkin = false;
20568
20569        String packageName = null;
20570        ArraySet<String> permissionNames = null;
20571
20572        int opti = 0;
20573        while (opti < args.length) {
20574            String opt = args[opti];
20575            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
20576                break;
20577            }
20578            opti++;
20579
20580            if ("-a".equals(opt)) {
20581                // Right now we only know how to print all.
20582            } else if ("-h".equals(opt)) {
20583                pw.println("Package manager dump options:");
20584                pw.println("  [-h] [-f] [--checkin] [cmd] ...");
20585                pw.println("    --checkin: dump for a checkin");
20586                pw.println("    -f: print details of intent filters");
20587                pw.println("    -h: print this help");
20588                pw.println("  cmd may be one of:");
20589                pw.println("    l[ibraries]: list known shared libraries");
20590                pw.println("    f[eatures]: list device features");
20591                pw.println("    k[eysets]: print known keysets");
20592                pw.println("    r[esolvers] [activity|service|receiver|content]: dump intent resolvers");
20593                pw.println("    perm[issions]: dump permissions");
20594                pw.println("    permission [name ...]: dump declaration and use of given permission");
20595                pw.println("    pref[erred]: print preferred package settings");
20596                pw.println("    preferred-xml [--full]: print preferred package settings as xml");
20597                pw.println("    prov[iders]: dump content providers");
20598                pw.println("    p[ackages]: dump installed packages");
20599                pw.println("    s[hared-users]: dump shared user IDs");
20600                pw.println("    m[essages]: print collected runtime messages");
20601                pw.println("    v[erifiers]: print package verifier info");
20602                pw.println("    d[omain-preferred-apps]: print domains preferred apps");
20603                pw.println("    i[ntent-filter-verifiers]|ifv: print intent filter verifier info");
20604                pw.println("    version: print database version info");
20605                pw.println("    write: write current settings now");
20606                pw.println("    installs: details about install sessions");
20607                pw.println("    check-permission <permission> <package> [<user>]: does pkg hold perm?");
20608                pw.println("    dexopt: dump dexopt state");
20609                pw.println("    compiler-stats: dump compiler statistics");
20610                pw.println("    enabled-overlays: dump list of enabled overlay packages");
20611                pw.println("    <package.name>: info about given package");
20612                return;
20613            } else if ("--checkin".equals(opt)) {
20614                checkin = true;
20615            } else if ("-f".equals(opt)) {
20616                dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
20617            } else if ("--proto".equals(opt)) {
20618                dumpProto(fd);
20619                return;
20620            } else {
20621                pw.println("Unknown argument: " + opt + "; use -h for help");
20622            }
20623        }
20624
20625        // Is the caller requesting to dump a particular piece of data?
20626        if (opti < args.length) {
20627            String cmd = args[opti];
20628            opti++;
20629            // Is this a package name?
20630            if ("android".equals(cmd) || cmd.contains(".")) {
20631                packageName = cmd;
20632                // When dumping a single package, we always dump all of its
20633                // filter information since the amount of data will be reasonable.
20634                dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
20635            } else if ("check-permission".equals(cmd)) {
20636                if (opti >= args.length) {
20637                    pw.println("Error: check-permission missing permission argument");
20638                    return;
20639                }
20640                String perm = args[opti];
20641                opti++;
20642                if (opti >= args.length) {
20643                    pw.println("Error: check-permission missing package argument");
20644                    return;
20645                }
20646
20647                String pkg = args[opti];
20648                opti++;
20649                int user = UserHandle.getUserId(Binder.getCallingUid());
20650                if (opti < args.length) {
20651                    try {
20652                        user = Integer.parseInt(args[opti]);
20653                    } catch (NumberFormatException e) {
20654                        pw.println("Error: check-permission user argument is not a number: "
20655                                + args[opti]);
20656                        return;
20657                    }
20658                }
20659
20660                // Normalize package name to handle renamed packages and static libs
20661                pkg = resolveInternalPackageNameLPr(pkg, PackageManager.VERSION_CODE_HIGHEST);
20662
20663                pw.println(checkPermission(perm, pkg, user));
20664                return;
20665            } else if ("l".equals(cmd) || "libraries".equals(cmd)) {
20666                dumpState.setDump(DumpState.DUMP_LIBS);
20667            } else if ("f".equals(cmd) || "features".equals(cmd)) {
20668                dumpState.setDump(DumpState.DUMP_FEATURES);
20669            } else if ("r".equals(cmd) || "resolvers".equals(cmd)) {
20670                if (opti >= args.length) {
20671                    dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS
20672                            | DumpState.DUMP_SERVICE_RESOLVERS
20673                            | DumpState.DUMP_RECEIVER_RESOLVERS
20674                            | DumpState.DUMP_CONTENT_RESOLVERS);
20675                } else {
20676                    while (opti < args.length) {
20677                        String name = args[opti];
20678                        if ("a".equals(name) || "activity".equals(name)) {
20679                            dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS);
20680                        } else if ("s".equals(name) || "service".equals(name)) {
20681                            dumpState.setDump(DumpState.DUMP_SERVICE_RESOLVERS);
20682                        } else if ("r".equals(name) || "receiver".equals(name)) {
20683                            dumpState.setDump(DumpState.DUMP_RECEIVER_RESOLVERS);
20684                        } else if ("c".equals(name) || "content".equals(name)) {
20685                            dumpState.setDump(DumpState.DUMP_CONTENT_RESOLVERS);
20686                        } else {
20687                            pw.println("Error: unknown resolver table type: " + name);
20688                            return;
20689                        }
20690                        opti++;
20691                    }
20692                }
20693            } else if ("perm".equals(cmd) || "permissions".equals(cmd)) {
20694                dumpState.setDump(DumpState.DUMP_PERMISSIONS);
20695            } else if ("permission".equals(cmd)) {
20696                if (opti >= args.length) {
20697                    pw.println("Error: permission requires permission name");
20698                    return;
20699                }
20700                permissionNames = new ArraySet<>();
20701                while (opti < args.length) {
20702                    permissionNames.add(args[opti]);
20703                    opti++;
20704                }
20705                dumpState.setDump(DumpState.DUMP_PERMISSIONS
20706                        | DumpState.DUMP_PACKAGES | DumpState.DUMP_SHARED_USERS);
20707            } else if ("pref".equals(cmd) || "preferred".equals(cmd)) {
20708                dumpState.setDump(DumpState.DUMP_PREFERRED);
20709            } else if ("preferred-xml".equals(cmd)) {
20710                dumpState.setDump(DumpState.DUMP_PREFERRED_XML);
20711                if (opti < args.length && "--full".equals(args[opti])) {
20712                    fullPreferred = true;
20713                    opti++;
20714                }
20715            } else if ("d".equals(cmd) || "domain-preferred-apps".equals(cmd)) {
20716                dumpState.setDump(DumpState.DUMP_DOMAIN_PREFERRED);
20717            } else if ("p".equals(cmd) || "packages".equals(cmd)) {
20718                dumpState.setDump(DumpState.DUMP_PACKAGES);
20719            } else if ("s".equals(cmd) || "shared-users".equals(cmd)) {
20720                dumpState.setDump(DumpState.DUMP_SHARED_USERS);
20721            } else if ("prov".equals(cmd) || "providers".equals(cmd)) {
20722                dumpState.setDump(DumpState.DUMP_PROVIDERS);
20723            } else if ("m".equals(cmd) || "messages".equals(cmd)) {
20724                dumpState.setDump(DumpState.DUMP_MESSAGES);
20725            } else if ("v".equals(cmd) || "verifiers".equals(cmd)) {
20726                dumpState.setDump(DumpState.DUMP_VERIFIERS);
20727            } else if ("i".equals(cmd) || "ifv".equals(cmd)
20728                    || "intent-filter-verifiers".equals(cmd)) {
20729                dumpState.setDump(DumpState.DUMP_INTENT_FILTER_VERIFIERS);
20730            } else if ("version".equals(cmd)) {
20731                dumpState.setDump(DumpState.DUMP_VERSION);
20732            } else if ("k".equals(cmd) || "keysets".equals(cmd)) {
20733                dumpState.setDump(DumpState.DUMP_KEYSETS);
20734            } else if ("installs".equals(cmd)) {
20735                dumpState.setDump(DumpState.DUMP_INSTALLS);
20736            } else if ("frozen".equals(cmd)) {
20737                dumpState.setDump(DumpState.DUMP_FROZEN);
20738            } else if ("dexopt".equals(cmd)) {
20739                dumpState.setDump(DumpState.DUMP_DEXOPT);
20740            } else if ("compiler-stats".equals(cmd)) {
20741                dumpState.setDump(DumpState.DUMP_COMPILER_STATS);
20742            } else if ("enabled-overlays".equals(cmd)) {
20743                dumpState.setDump(DumpState.DUMP_ENABLED_OVERLAYS);
20744            } else if ("write".equals(cmd)) {
20745                synchronized (mPackages) {
20746                    mSettings.writeLPr();
20747                    pw.println("Settings written.");
20748                    return;
20749                }
20750            }
20751        }
20752
20753        if (checkin) {
20754            pw.println("vers,1");
20755        }
20756
20757        // reader
20758        synchronized (mPackages) {
20759            if (dumpState.isDumping(DumpState.DUMP_VERSION) && packageName == null) {
20760                if (!checkin) {
20761                    if (dumpState.onTitlePrinted())
20762                        pw.println();
20763                    pw.println("Database versions:");
20764                    mSettings.dumpVersionLPr(new IndentingPrintWriter(pw, "  "));
20765                }
20766            }
20767
20768            if (dumpState.isDumping(DumpState.DUMP_VERIFIERS) && packageName == null) {
20769                if (!checkin) {
20770                    if (dumpState.onTitlePrinted())
20771                        pw.println();
20772                    pw.println("Verifiers:");
20773                    pw.print("  Required: ");
20774                    pw.print(mRequiredVerifierPackage);
20775                    pw.print(" (uid=");
20776                    pw.print(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
20777                            UserHandle.USER_SYSTEM));
20778                    pw.println(")");
20779                } else if (mRequiredVerifierPackage != null) {
20780                    pw.print("vrfy,"); pw.print(mRequiredVerifierPackage);
20781                    pw.print(",");
20782                    pw.println(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
20783                            UserHandle.USER_SYSTEM));
20784                }
20785            }
20786
20787            if (dumpState.isDumping(DumpState.DUMP_INTENT_FILTER_VERIFIERS) &&
20788                    packageName == null) {
20789                if (mIntentFilterVerifierComponent != null) {
20790                    String verifierPackageName = mIntentFilterVerifierComponent.getPackageName();
20791                    if (!checkin) {
20792                        if (dumpState.onTitlePrinted())
20793                            pw.println();
20794                        pw.println("Intent Filter Verifier:");
20795                        pw.print("  Using: ");
20796                        pw.print(verifierPackageName);
20797                        pw.print(" (uid=");
20798                        pw.print(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING,
20799                                UserHandle.USER_SYSTEM));
20800                        pw.println(")");
20801                    } else if (verifierPackageName != null) {
20802                        pw.print("ifv,"); pw.print(verifierPackageName);
20803                        pw.print(",");
20804                        pw.println(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING,
20805                                UserHandle.USER_SYSTEM));
20806                    }
20807                } else {
20808                    pw.println();
20809                    pw.println("No Intent Filter Verifier available!");
20810                }
20811            }
20812
20813            if (dumpState.isDumping(DumpState.DUMP_LIBS) && packageName == null) {
20814                boolean printedHeader = false;
20815                final Iterator<String> it = mSharedLibraries.keySet().iterator();
20816                while (it.hasNext()) {
20817                    String libName = it.next();
20818                    SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(libName);
20819                    if (versionedLib == null) {
20820                        continue;
20821                    }
20822                    final int versionCount = versionedLib.size();
20823                    for (int i = 0; i < versionCount; i++) {
20824                        SharedLibraryEntry libEntry = versionedLib.valueAt(i);
20825                        if (!checkin) {
20826                            if (!printedHeader) {
20827                                if (dumpState.onTitlePrinted())
20828                                    pw.println();
20829                                pw.println("Libraries:");
20830                                printedHeader = true;
20831                            }
20832                            pw.print("  ");
20833                        } else {
20834                            pw.print("lib,");
20835                        }
20836                        pw.print(libEntry.info.getName());
20837                        if (libEntry.info.isStatic()) {
20838                            pw.print(" version=" + libEntry.info.getVersion());
20839                        }
20840                        if (!checkin) {
20841                            pw.print(" -> ");
20842                        }
20843                        if (libEntry.path != null) {
20844                            pw.print(" (jar) ");
20845                            pw.print(libEntry.path);
20846                        } else {
20847                            pw.print(" (apk) ");
20848                            pw.print(libEntry.apk);
20849                        }
20850                        pw.println();
20851                    }
20852                }
20853            }
20854
20855            if (dumpState.isDumping(DumpState.DUMP_FEATURES) && packageName == null) {
20856                if (dumpState.onTitlePrinted())
20857                    pw.println();
20858                if (!checkin) {
20859                    pw.println("Features:");
20860                }
20861
20862                synchronized (mAvailableFeatures) {
20863                    for (FeatureInfo feat : mAvailableFeatures.values()) {
20864                        if (checkin) {
20865                            pw.print("feat,");
20866                            pw.print(feat.name);
20867                            pw.print(",");
20868                            pw.println(feat.version);
20869                        } else {
20870                            pw.print("  ");
20871                            pw.print(feat.name);
20872                            if (feat.version > 0) {
20873                                pw.print(" version=");
20874                                pw.print(feat.version);
20875                            }
20876                            pw.println();
20877                        }
20878                    }
20879                }
20880            }
20881
20882            if (!checkin && dumpState.isDumping(DumpState.DUMP_ACTIVITY_RESOLVERS)) {
20883                if (mActivities.dump(pw, dumpState.getTitlePrinted() ? "\nActivity Resolver Table:"
20884                        : "Activity Resolver Table:", "  ", packageName,
20885                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
20886                    dumpState.setTitlePrinted(true);
20887                }
20888            }
20889            if (!checkin && dumpState.isDumping(DumpState.DUMP_RECEIVER_RESOLVERS)) {
20890                if (mReceivers.dump(pw, dumpState.getTitlePrinted() ? "\nReceiver Resolver Table:"
20891                        : "Receiver Resolver Table:", "  ", packageName,
20892                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
20893                    dumpState.setTitlePrinted(true);
20894                }
20895            }
20896            if (!checkin && dumpState.isDumping(DumpState.DUMP_SERVICE_RESOLVERS)) {
20897                if (mServices.dump(pw, dumpState.getTitlePrinted() ? "\nService Resolver Table:"
20898                        : "Service Resolver Table:", "  ", packageName,
20899                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
20900                    dumpState.setTitlePrinted(true);
20901                }
20902            }
20903            if (!checkin && dumpState.isDumping(DumpState.DUMP_CONTENT_RESOLVERS)) {
20904                if (mProviders.dump(pw, dumpState.getTitlePrinted() ? "\nProvider Resolver Table:"
20905                        : "Provider Resolver Table:", "  ", packageName,
20906                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
20907                    dumpState.setTitlePrinted(true);
20908                }
20909            }
20910
20911            if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED)) {
20912                for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
20913                    PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
20914                    int user = mSettings.mPreferredActivities.keyAt(i);
20915                    if (pir.dump(pw,
20916                            dumpState.getTitlePrinted()
20917                                ? "\nPreferred Activities User " + user + ":"
20918                                : "Preferred Activities User " + user + ":", "  ",
20919                            packageName, true, false)) {
20920                        dumpState.setTitlePrinted(true);
20921                    }
20922                }
20923            }
20924
20925            if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED_XML)) {
20926                pw.flush();
20927                FileOutputStream fout = new FileOutputStream(fd);
20928                BufferedOutputStream str = new BufferedOutputStream(fout);
20929                XmlSerializer serializer = new FastXmlSerializer();
20930                try {
20931                    serializer.setOutput(str, StandardCharsets.UTF_8.name());
20932                    serializer.startDocument(null, true);
20933                    serializer.setFeature(
20934                            "http://xmlpull.org/v1/doc/features.html#indent-output", true);
20935                    mSettings.writePreferredActivitiesLPr(serializer, 0, fullPreferred);
20936                    serializer.endDocument();
20937                    serializer.flush();
20938                } catch (IllegalArgumentException e) {
20939                    pw.println("Failed writing: " + e);
20940                } catch (IllegalStateException e) {
20941                    pw.println("Failed writing: " + e);
20942                } catch (IOException e) {
20943                    pw.println("Failed writing: " + e);
20944                }
20945            }
20946
20947            if (!checkin
20948                    && dumpState.isDumping(DumpState.DUMP_DOMAIN_PREFERRED)
20949                    && packageName == null) {
20950                pw.println();
20951                int count = mSettings.mPackages.size();
20952                if (count == 0) {
20953                    pw.println("No applications!");
20954                    pw.println();
20955                } else {
20956                    final String prefix = "  ";
20957                    Collection<PackageSetting> allPackageSettings = mSettings.mPackages.values();
20958                    if (allPackageSettings.size() == 0) {
20959                        pw.println("No domain preferred apps!");
20960                        pw.println();
20961                    } else {
20962                        pw.println("App verification status:");
20963                        pw.println();
20964                        count = 0;
20965                        for (PackageSetting ps : allPackageSettings) {
20966                            IntentFilterVerificationInfo ivi = ps.getIntentFilterVerificationInfo();
20967                            if (ivi == null || ivi.getPackageName() == null) continue;
20968                            pw.println(prefix + "Package: " + ivi.getPackageName());
20969                            pw.println(prefix + "Domains: " + ivi.getDomainsString());
20970                            pw.println(prefix + "Status:  " + ivi.getStatusString());
20971                            pw.println();
20972                            count++;
20973                        }
20974                        if (count == 0) {
20975                            pw.println(prefix + "No app verification established.");
20976                            pw.println();
20977                        }
20978                        for (int userId : sUserManager.getUserIds()) {
20979                            pw.println("App linkages for user " + userId + ":");
20980                            pw.println();
20981                            count = 0;
20982                            for (PackageSetting ps : allPackageSettings) {
20983                                final long status = ps.getDomainVerificationStatusForUser(userId);
20984                                if (status >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED
20985                                        && !DEBUG_DOMAIN_VERIFICATION) {
20986                                    continue;
20987                                }
20988                                pw.println(prefix + "Package: " + ps.name);
20989                                pw.println(prefix + "Domains: " + dumpDomainString(ps.name));
20990                                String statusStr = IntentFilterVerificationInfo.
20991                                        getStatusStringFromValue(status);
20992                                pw.println(prefix + "Status:  " + statusStr);
20993                                pw.println();
20994                                count++;
20995                            }
20996                            if (count == 0) {
20997                                pw.println(prefix + "No configured app linkages.");
20998                                pw.println();
20999                            }
21000                        }
21001                    }
21002                }
21003            }
21004
21005            if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) {
21006                mSettings.dumpPermissionsLPr(pw, packageName, permissionNames, dumpState);
21007                if (packageName == null && permissionNames == null) {
21008                    for (int iperm=0; iperm<mAppOpPermissionPackages.size(); iperm++) {
21009                        if (iperm == 0) {
21010                            if (dumpState.onTitlePrinted())
21011                                pw.println();
21012                            pw.println("AppOp Permissions:");
21013                        }
21014                        pw.print("  AppOp Permission ");
21015                        pw.print(mAppOpPermissionPackages.keyAt(iperm));
21016                        pw.println(":");
21017                        ArraySet<String> pkgs = mAppOpPermissionPackages.valueAt(iperm);
21018                        for (int ipkg=0; ipkg<pkgs.size(); ipkg++) {
21019                            pw.print("    "); pw.println(pkgs.valueAt(ipkg));
21020                        }
21021                    }
21022                }
21023            }
21024
21025            if (!checkin && dumpState.isDumping(DumpState.DUMP_PROVIDERS)) {
21026                boolean printedSomething = false;
21027                for (PackageParser.Provider p : mProviders.mProviders.values()) {
21028                    if (packageName != null && !packageName.equals(p.info.packageName)) {
21029                        continue;
21030                    }
21031                    if (!printedSomething) {
21032                        if (dumpState.onTitlePrinted())
21033                            pw.println();
21034                        pw.println("Registered ContentProviders:");
21035                        printedSomething = true;
21036                    }
21037                    pw.print("  "); p.printComponentShortName(pw); pw.println(":");
21038                    pw.print("    "); pw.println(p.toString());
21039                }
21040                printedSomething = false;
21041                for (Map.Entry<String, PackageParser.Provider> entry :
21042                        mProvidersByAuthority.entrySet()) {
21043                    PackageParser.Provider p = entry.getValue();
21044                    if (packageName != null && !packageName.equals(p.info.packageName)) {
21045                        continue;
21046                    }
21047                    if (!printedSomething) {
21048                        if (dumpState.onTitlePrinted())
21049                            pw.println();
21050                        pw.println("ContentProvider Authorities:");
21051                        printedSomething = true;
21052                    }
21053                    pw.print("  ["); pw.print(entry.getKey()); pw.println("]:");
21054                    pw.print("    "); pw.println(p.toString());
21055                    if (p.info != null && p.info.applicationInfo != null) {
21056                        final String appInfo = p.info.applicationInfo.toString();
21057                        pw.print("      applicationInfo="); pw.println(appInfo);
21058                    }
21059                }
21060            }
21061
21062            if (!checkin && dumpState.isDumping(DumpState.DUMP_KEYSETS)) {
21063                mSettings.mKeySetManagerService.dumpLPr(pw, packageName, dumpState);
21064            }
21065
21066            if (dumpState.isDumping(DumpState.DUMP_PACKAGES)) {
21067                mSettings.dumpPackagesLPr(pw, packageName, permissionNames, dumpState, checkin);
21068            }
21069
21070            if (dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) {
21071                mSettings.dumpSharedUsersLPr(pw, packageName, permissionNames, dumpState, checkin);
21072            }
21073
21074            if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS) && packageName == null) {
21075                mSettings.dumpRestoredPermissionGrantsLPr(pw, dumpState);
21076            }
21077
21078            if (!checkin && dumpState.isDumping(DumpState.DUMP_FROZEN) && packageName == null) {
21079                // XXX should handle packageName != null by dumping only install data that
21080                // the given package is involved with.
21081                if (dumpState.onTitlePrinted()) pw.println();
21082
21083                final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ", 120);
21084                ipw.println();
21085                ipw.println("Frozen packages:");
21086                ipw.increaseIndent();
21087                if (mFrozenPackages.size() == 0) {
21088                    ipw.println("(none)");
21089                } else {
21090                    for (int i = 0; i < mFrozenPackages.size(); i++) {
21091                        ipw.println(mFrozenPackages.valueAt(i));
21092                    }
21093                }
21094                ipw.decreaseIndent();
21095            }
21096
21097            if (!checkin && dumpState.isDumping(DumpState.DUMP_DEXOPT)) {
21098                if (dumpState.onTitlePrinted()) pw.println();
21099                dumpDexoptStateLPr(pw, packageName);
21100            }
21101
21102            if (!checkin && dumpState.isDumping(DumpState.DUMP_COMPILER_STATS)) {
21103                if (dumpState.onTitlePrinted()) pw.println();
21104                dumpCompilerStatsLPr(pw, packageName);
21105            }
21106
21107            if (!checkin && dumpState.isDumping(DumpState.DUMP_ENABLED_OVERLAYS)) {
21108                if (dumpState.onTitlePrinted()) pw.println();
21109                dumpEnabledOverlaysLPr(pw);
21110            }
21111
21112            if (!checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES) && packageName == null) {
21113                if (dumpState.onTitlePrinted()) pw.println();
21114                mSettings.dumpReadMessagesLPr(pw, dumpState);
21115
21116                pw.println();
21117                pw.println("Package warning messages:");
21118                BufferedReader in = null;
21119                String line = null;
21120                try {
21121                    in = new BufferedReader(new FileReader(getSettingsProblemFile()));
21122                    while ((line = in.readLine()) != null) {
21123                        if (line.contains("ignored: updated version")) continue;
21124                        pw.println(line);
21125                    }
21126                } catch (IOException ignored) {
21127                } finally {
21128                    IoUtils.closeQuietly(in);
21129                }
21130            }
21131
21132            if (checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES)) {
21133                BufferedReader in = null;
21134                String line = null;
21135                try {
21136                    in = new BufferedReader(new FileReader(getSettingsProblemFile()));
21137                    while ((line = in.readLine()) != null) {
21138                        if (line.contains("ignored: updated version")) continue;
21139                        pw.print("msg,");
21140                        pw.println(line);
21141                    }
21142                } catch (IOException ignored) {
21143                } finally {
21144                    IoUtils.closeQuietly(in);
21145                }
21146            }
21147        }
21148
21149        // PackageInstaller should be called outside of mPackages lock
21150        if (!checkin && dumpState.isDumping(DumpState.DUMP_INSTALLS) && packageName == null) {
21151            // XXX should handle packageName != null by dumping only install data that
21152            // the given package is involved with.
21153            if (dumpState.onTitlePrinted()) pw.println();
21154            mInstallerService.dump(new IndentingPrintWriter(pw, "  ", 120));
21155        }
21156    }
21157
21158    private void dumpProto(FileDescriptor fd) {
21159        final ProtoOutputStream proto = new ProtoOutputStream(fd);
21160
21161        synchronized (mPackages) {
21162            final long requiredVerifierPackageToken =
21163                    proto.start(PackageServiceDumpProto.REQUIRED_VERIFIER_PACKAGE);
21164            proto.write(PackageServiceDumpProto.PackageShortProto.NAME, mRequiredVerifierPackage);
21165            proto.write(
21166                    PackageServiceDumpProto.PackageShortProto.UID,
21167                    getPackageUid(
21168                            mRequiredVerifierPackage,
21169                            MATCH_DEBUG_TRIAGED_MISSING,
21170                            UserHandle.USER_SYSTEM));
21171            proto.end(requiredVerifierPackageToken);
21172
21173            if (mIntentFilterVerifierComponent != null) {
21174                String verifierPackageName = mIntentFilterVerifierComponent.getPackageName();
21175                final long verifierPackageToken =
21176                        proto.start(PackageServiceDumpProto.VERIFIER_PACKAGE);
21177                proto.write(PackageServiceDumpProto.PackageShortProto.NAME, verifierPackageName);
21178                proto.write(
21179                        PackageServiceDumpProto.PackageShortProto.UID,
21180                        getPackageUid(
21181                                verifierPackageName,
21182                                MATCH_DEBUG_TRIAGED_MISSING,
21183                                UserHandle.USER_SYSTEM));
21184                proto.end(verifierPackageToken);
21185            }
21186
21187            dumpSharedLibrariesProto(proto);
21188            dumpFeaturesProto(proto);
21189            mSettings.dumpPackagesProto(proto);
21190            mSettings.dumpSharedUsersProto(proto);
21191            dumpMessagesProto(proto);
21192        }
21193        proto.flush();
21194    }
21195
21196    private void dumpMessagesProto(ProtoOutputStream proto) {
21197        BufferedReader in = null;
21198        String line = null;
21199        try {
21200            in = new BufferedReader(new FileReader(getSettingsProblemFile()));
21201            while ((line = in.readLine()) != null) {
21202                if (line.contains("ignored: updated version")) continue;
21203                proto.write(PackageServiceDumpProto.MESSAGES, line);
21204            }
21205        } catch (IOException ignored) {
21206        } finally {
21207            IoUtils.closeQuietly(in);
21208        }
21209    }
21210
21211    private void dumpFeaturesProto(ProtoOutputStream proto) {
21212        synchronized (mAvailableFeatures) {
21213            final int count = mAvailableFeatures.size();
21214            for (int i = 0; i < count; i++) {
21215                final FeatureInfo feat = mAvailableFeatures.valueAt(i);
21216                final long featureToken = proto.start(PackageServiceDumpProto.FEATURES);
21217                proto.write(PackageServiceDumpProto.FeatureProto.NAME, feat.name);
21218                proto.write(PackageServiceDumpProto.FeatureProto.VERSION, feat.version);
21219                proto.end(featureToken);
21220            }
21221        }
21222    }
21223
21224    private void dumpSharedLibrariesProto(ProtoOutputStream proto) {
21225        final int count = mSharedLibraries.size();
21226        for (int i = 0; i < count; i++) {
21227            final String libName = mSharedLibraries.keyAt(i);
21228            SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(libName);
21229            if (versionedLib == null) {
21230                continue;
21231            }
21232            final int versionCount = versionedLib.size();
21233            for (int j = 0; j < versionCount; j++) {
21234                final SharedLibraryEntry libEntry = versionedLib.valueAt(j);
21235                final long sharedLibraryToken =
21236                        proto.start(PackageServiceDumpProto.SHARED_LIBRARIES);
21237                proto.write(PackageServiceDumpProto.SharedLibraryProto.NAME, libEntry.info.getName());
21238                final boolean isJar = (libEntry.path != null);
21239                proto.write(PackageServiceDumpProto.SharedLibraryProto.IS_JAR, isJar);
21240                if (isJar) {
21241                    proto.write(PackageServiceDumpProto.SharedLibraryProto.PATH, libEntry.path);
21242                } else {
21243                    proto.write(PackageServiceDumpProto.SharedLibraryProto.APK, libEntry.apk);
21244                }
21245                proto.end(sharedLibraryToken);
21246            }
21247        }
21248    }
21249
21250    private void dumpDexoptStateLPr(PrintWriter pw, String packageName) {
21251        final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ", 120);
21252        ipw.println();
21253        ipw.println("Dexopt state:");
21254        ipw.increaseIndent();
21255        Collection<PackageParser.Package> packages = null;
21256        if (packageName != null) {
21257            PackageParser.Package targetPackage = mPackages.get(packageName);
21258            if (targetPackage != null) {
21259                packages = Collections.singletonList(targetPackage);
21260            } else {
21261                ipw.println("Unable to find package: " + packageName);
21262                return;
21263            }
21264        } else {
21265            packages = mPackages.values();
21266        }
21267
21268        for (PackageParser.Package pkg : packages) {
21269            ipw.println("[" + pkg.packageName + "]");
21270            ipw.increaseIndent();
21271            mPackageDexOptimizer.dumpDexoptState(ipw, pkg);
21272            ipw.decreaseIndent();
21273        }
21274    }
21275
21276    private void dumpCompilerStatsLPr(PrintWriter pw, String packageName) {
21277        final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ", 120);
21278        ipw.println();
21279        ipw.println("Compiler stats:");
21280        ipw.increaseIndent();
21281        Collection<PackageParser.Package> packages = null;
21282        if (packageName != null) {
21283            PackageParser.Package targetPackage = mPackages.get(packageName);
21284            if (targetPackage != null) {
21285                packages = Collections.singletonList(targetPackage);
21286            } else {
21287                ipw.println("Unable to find package: " + packageName);
21288                return;
21289            }
21290        } else {
21291            packages = mPackages.values();
21292        }
21293
21294        for (PackageParser.Package pkg : packages) {
21295            ipw.println("[" + pkg.packageName + "]");
21296            ipw.increaseIndent();
21297
21298            CompilerStats.PackageStats stats = getCompilerPackageStats(pkg.packageName);
21299            if (stats == null) {
21300                ipw.println("(No recorded stats)");
21301            } else {
21302                stats.dump(ipw);
21303            }
21304            ipw.decreaseIndent();
21305        }
21306    }
21307
21308    private void dumpEnabledOverlaysLPr(PrintWriter pw) {
21309        pw.println("Enabled overlay paths:");
21310        final int N = mEnabledOverlayPaths.size();
21311        for (int i = 0; i < N; i++) {
21312            final int userId = mEnabledOverlayPaths.keyAt(i);
21313            pw.println(String.format("    User %d:", userId));
21314            final ArrayMap<String, ArrayList<String>> userSpecificOverlays =
21315                mEnabledOverlayPaths.valueAt(i);
21316            final int M = userSpecificOverlays.size();
21317            for (int j = 0; j < M; j++) {
21318                final String targetPackageName = userSpecificOverlays.keyAt(j);
21319                final ArrayList<String> overlayPackagePaths = userSpecificOverlays.valueAt(j);
21320                pw.println(String.format("        %s: %s", targetPackageName, overlayPackagePaths));
21321            }
21322        }
21323    }
21324
21325    private String dumpDomainString(String packageName) {
21326        List<IntentFilterVerificationInfo> iviList = getIntentFilterVerifications(packageName)
21327                .getList();
21328        List<IntentFilter> filters = getAllIntentFilters(packageName).getList();
21329
21330        ArraySet<String> result = new ArraySet<>();
21331        if (iviList.size() > 0) {
21332            for (IntentFilterVerificationInfo ivi : iviList) {
21333                for (String host : ivi.getDomains()) {
21334                    result.add(host);
21335                }
21336            }
21337        }
21338        if (filters != null && filters.size() > 0) {
21339            for (IntentFilter filter : filters) {
21340                if (filter.hasCategory(Intent.CATEGORY_BROWSABLE)
21341                        && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) ||
21342                                filter.hasDataScheme(IntentFilter.SCHEME_HTTPS))) {
21343                    result.addAll(filter.getHostsList());
21344                }
21345            }
21346        }
21347
21348        StringBuilder sb = new StringBuilder(result.size() * 16);
21349        for (String domain : result) {
21350            if (sb.length() > 0) sb.append(" ");
21351            sb.append(domain);
21352        }
21353        return sb.toString();
21354    }
21355
21356    // ------- apps on sdcard specific code -------
21357    static final boolean DEBUG_SD_INSTALL = false;
21358
21359    private static final String SD_ENCRYPTION_KEYSTORE_NAME = "AppsOnSD";
21360
21361    private static final String SD_ENCRYPTION_ALGORITHM = "AES";
21362
21363    private boolean mMediaMounted = false;
21364
21365    static String getEncryptKey() {
21366        try {
21367            String sdEncKey = SystemKeyStore.getInstance().retrieveKeyHexString(
21368                    SD_ENCRYPTION_KEYSTORE_NAME);
21369            if (sdEncKey == null) {
21370                sdEncKey = SystemKeyStore.getInstance().generateNewKeyHexString(128,
21371                        SD_ENCRYPTION_ALGORITHM, SD_ENCRYPTION_KEYSTORE_NAME);
21372                if (sdEncKey == null) {
21373                    Slog.e(TAG, "Failed to create encryption keys");
21374                    return null;
21375                }
21376            }
21377            return sdEncKey;
21378        } catch (NoSuchAlgorithmException nsae) {
21379            Slog.e(TAG, "Failed to create encryption keys with exception: " + nsae);
21380            return null;
21381        } catch (IOException ioe) {
21382            Slog.e(TAG, "Failed to retrieve encryption keys with exception: " + ioe);
21383            return null;
21384        }
21385    }
21386
21387    /*
21388     * Update media status on PackageManager.
21389     */
21390    @Override
21391    public void updateExternalMediaStatus(final boolean mediaStatus, final boolean reportStatus) {
21392        int callingUid = Binder.getCallingUid();
21393        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
21394            throw new SecurityException("Media status can only be updated by the system");
21395        }
21396        // reader; this apparently protects mMediaMounted, but should probably
21397        // be a different lock in that case.
21398        synchronized (mPackages) {
21399            Log.i(TAG, "Updating external media status from "
21400                    + (mMediaMounted ? "mounted" : "unmounted") + " to "
21401                    + (mediaStatus ? "mounted" : "unmounted"));
21402            if (DEBUG_SD_INSTALL)
21403                Log.i(TAG, "updateExternalMediaStatus:: mediaStatus=" + mediaStatus
21404                        + ", mMediaMounted=" + mMediaMounted);
21405            if (mediaStatus == mMediaMounted) {
21406                final Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1
21407                        : 0, -1);
21408                mHandler.sendMessage(msg);
21409                return;
21410            }
21411            mMediaMounted = mediaStatus;
21412        }
21413        // Queue up an async operation since the package installation may take a
21414        // little while.
21415        mHandler.post(new Runnable() {
21416            public void run() {
21417                updateExternalMediaStatusInner(mediaStatus, reportStatus, true);
21418            }
21419        });
21420    }
21421
21422    /**
21423     * Called by StorageManagerService when the initial ASECs to scan are available.
21424     * Should block until all the ASEC containers are finished being scanned.
21425     */
21426    public void scanAvailableAsecs() {
21427        updateExternalMediaStatusInner(true, false, false);
21428    }
21429
21430    /*
21431     * Collect information of applications on external media, map them against
21432     * existing containers and update information based on current mount status.
21433     * Please note that we always have to report status if reportStatus has been
21434     * set to true especially when unloading packages.
21435     */
21436    private void updateExternalMediaStatusInner(boolean isMounted, boolean reportStatus,
21437            boolean externalStorage) {
21438        ArrayMap<AsecInstallArgs, String> processCids = new ArrayMap<>();
21439        int[] uidArr = EmptyArray.INT;
21440
21441        final String[] list = PackageHelper.getSecureContainerList();
21442        if (ArrayUtils.isEmpty(list)) {
21443            Log.i(TAG, "No secure containers found");
21444        } else {
21445            // Process list of secure containers and categorize them
21446            // as active or stale based on their package internal state.
21447
21448            // reader
21449            synchronized (mPackages) {
21450                for (String cid : list) {
21451                    // Leave stages untouched for now; installer service owns them
21452                    if (PackageInstallerService.isStageName(cid)) continue;
21453
21454                    if (DEBUG_SD_INSTALL)
21455                        Log.i(TAG, "Processing container " + cid);
21456                    String pkgName = getAsecPackageName(cid);
21457                    if (pkgName == null) {
21458                        Slog.i(TAG, "Found stale container " + cid + " with no package name");
21459                        continue;
21460                    }
21461                    if (DEBUG_SD_INSTALL)
21462                        Log.i(TAG, "Looking for pkg : " + pkgName);
21463
21464                    final PackageSetting ps = mSettings.mPackages.get(pkgName);
21465                    if (ps == null) {
21466                        Slog.i(TAG, "Found stale container " + cid + " with no matching settings");
21467                        continue;
21468                    }
21469
21470                    /*
21471                     * Skip packages that are not external if we're unmounting
21472                     * external storage.
21473                     */
21474                    if (externalStorage && !isMounted && !isExternal(ps)) {
21475                        continue;
21476                    }
21477
21478                    final AsecInstallArgs args = new AsecInstallArgs(cid,
21479                            getAppDexInstructionSets(ps), ps.isForwardLocked());
21480                    // The package status is changed only if the code path
21481                    // matches between settings and the container id.
21482                    if (ps.codePathString != null
21483                            && ps.codePathString.startsWith(args.getCodePath())) {
21484                        if (DEBUG_SD_INSTALL) {
21485                            Log.i(TAG, "Container : " + cid + " corresponds to pkg : " + pkgName
21486                                    + " at code path: " + ps.codePathString);
21487                        }
21488
21489                        // We do have a valid package installed on sdcard
21490                        processCids.put(args, ps.codePathString);
21491                        final int uid = ps.appId;
21492                        if (uid != -1) {
21493                            uidArr = ArrayUtils.appendInt(uidArr, uid);
21494                        }
21495                    } else {
21496                        Slog.i(TAG, "Found stale container " + cid + ": expected codePath="
21497                                + ps.codePathString);
21498                    }
21499                }
21500            }
21501
21502            Arrays.sort(uidArr);
21503        }
21504
21505        // Process packages with valid entries.
21506        if (isMounted) {
21507            if (DEBUG_SD_INSTALL)
21508                Log.i(TAG, "Loading packages");
21509            loadMediaPackages(processCids, uidArr, externalStorage);
21510            startCleaningPackages();
21511            mInstallerService.onSecureContainersAvailable();
21512        } else {
21513            if (DEBUG_SD_INSTALL)
21514                Log.i(TAG, "Unloading packages");
21515            unloadMediaPackages(processCids, uidArr, reportStatus);
21516        }
21517    }
21518
21519    private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
21520            ArrayList<ApplicationInfo> infos, IIntentReceiver finishedReceiver) {
21521        final int size = infos.size();
21522        final String[] packageNames = new String[size];
21523        final int[] packageUids = new int[size];
21524        for (int i = 0; i < size; i++) {
21525            final ApplicationInfo info = infos.get(i);
21526            packageNames[i] = info.packageName;
21527            packageUids[i] = info.uid;
21528        }
21529        sendResourcesChangedBroadcast(mediaStatus, replacing, packageNames, packageUids,
21530                finishedReceiver);
21531    }
21532
21533    private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
21534            ArrayList<String> pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
21535        sendResourcesChangedBroadcast(mediaStatus, replacing,
21536                pkgList.toArray(new String[pkgList.size()]), uidArr, finishedReceiver);
21537    }
21538
21539    private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
21540            String[] pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
21541        int size = pkgList.length;
21542        if (size > 0) {
21543            // Send broadcasts here
21544            Bundle extras = new Bundle();
21545            extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
21546            if (uidArr != null) {
21547                extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidArr);
21548            }
21549            if (replacing) {
21550                extras.putBoolean(Intent.EXTRA_REPLACING, replacing);
21551            }
21552            String action = mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE
21553                    : Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE;
21554            sendPackageBroadcast(action, null, extras, 0, null, finishedReceiver, null);
21555        }
21556    }
21557
21558   /*
21559     * Look at potentially valid container ids from processCids If package
21560     * information doesn't match the one on record or package scanning fails,
21561     * the cid is added to list of removeCids. We currently don't delete stale
21562     * containers.
21563     */
21564    private void loadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int[] uidArr,
21565            boolean externalStorage) {
21566        ArrayList<String> pkgList = new ArrayList<String>();
21567        Set<AsecInstallArgs> keys = processCids.keySet();
21568
21569        for (AsecInstallArgs args : keys) {
21570            String codePath = processCids.get(args);
21571            if (DEBUG_SD_INSTALL)
21572                Log.i(TAG, "Loading container : " + args.cid);
21573            int retCode = PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
21574            try {
21575                // Make sure there are no container errors first.
21576                if (args.doPreInstall(PackageManager.INSTALL_SUCCEEDED) != PackageManager.INSTALL_SUCCEEDED) {
21577                    Slog.e(TAG, "Failed to mount cid : " + args.cid
21578                            + " when installing from sdcard");
21579                    continue;
21580                }
21581                // Check code path here.
21582                if (codePath == null || !codePath.startsWith(args.getCodePath())) {
21583                    Slog.e(TAG, "Container " + args.cid + " cachepath " + args.getCodePath()
21584                            + " does not match one in settings " + codePath);
21585                    continue;
21586                }
21587                // Parse package
21588                int parseFlags = mDefParseFlags;
21589                if (args.isExternalAsec()) {
21590                    parseFlags |= PackageParser.PARSE_EXTERNAL_STORAGE;
21591                }
21592                if (args.isFwdLocked()) {
21593                    parseFlags |= PackageParser.PARSE_FORWARD_LOCK;
21594                }
21595
21596                synchronized (mInstallLock) {
21597                    PackageParser.Package pkg = null;
21598                    try {
21599                        // Sadly we don't know the package name yet to freeze it
21600                        pkg = scanPackageTracedLI(new File(codePath), parseFlags,
21601                                SCAN_IGNORE_FROZEN, 0, null);
21602                    } catch (PackageManagerException e) {
21603                        Slog.w(TAG, "Failed to scan " + codePath + ": " + e.getMessage());
21604                    }
21605                    // Scan the package
21606                    if (pkg != null) {
21607                        /*
21608                         * TODO why is the lock being held? doPostInstall is
21609                         * called in other places without the lock. This needs
21610                         * to be straightened out.
21611                         */
21612                        // writer
21613                        synchronized (mPackages) {
21614                            retCode = PackageManager.INSTALL_SUCCEEDED;
21615                            pkgList.add(pkg.packageName);
21616                            // Post process args
21617                            args.doPostInstall(PackageManager.INSTALL_SUCCEEDED,
21618                                    pkg.applicationInfo.uid);
21619                        }
21620                    } else {
21621                        Slog.i(TAG, "Failed to install pkg from  " + codePath + " from sdcard");
21622                    }
21623                }
21624
21625            } finally {
21626                if (retCode != PackageManager.INSTALL_SUCCEEDED) {
21627                    Log.w(TAG, "Container " + args.cid + " is stale, retCode=" + retCode);
21628                }
21629            }
21630        }
21631        // writer
21632        synchronized (mPackages) {
21633            // If the platform SDK has changed since the last time we booted,
21634            // we need to re-grant app permission to catch any new ones that
21635            // appear. This is really a hack, and means that apps can in some
21636            // cases get permissions that the user didn't initially explicitly
21637            // allow... it would be nice to have some better way to handle
21638            // this situation.
21639            final VersionInfo ver = externalStorage ? mSettings.getExternalVersion()
21640                    : mSettings.getInternalVersion();
21641            final String volumeUuid = externalStorage ? StorageManager.UUID_PRIMARY_PHYSICAL
21642                    : StorageManager.UUID_PRIVATE_INTERNAL;
21643
21644            int updateFlags = UPDATE_PERMISSIONS_ALL;
21645            if (ver.sdkVersion != mSdkVersion) {
21646                logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to "
21647                        + mSdkVersion + "; regranting permissions for external");
21648                updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
21649            }
21650            updatePermissionsLPw(null, null, volumeUuid, updateFlags);
21651
21652            // Yay, everything is now upgraded
21653            ver.forceCurrent();
21654
21655            // can downgrade to reader
21656            // Persist settings
21657            mSettings.writeLPr();
21658        }
21659        // Send a broadcast to let everyone know we are done processing
21660        if (pkgList.size() > 0) {
21661            sendResourcesChangedBroadcast(true, false, pkgList, uidArr, null);
21662        }
21663    }
21664
21665   /*
21666     * Utility method to unload a list of specified containers
21667     */
21668    private void unloadAllContainers(Set<AsecInstallArgs> cidArgs) {
21669        // Just unmount all valid containers.
21670        for (AsecInstallArgs arg : cidArgs) {
21671            synchronized (mInstallLock) {
21672                arg.doPostDeleteLI(false);
21673           }
21674       }
21675   }
21676
21677    /*
21678     * Unload packages mounted on external media. This involves deleting package
21679     * data from internal structures, sending broadcasts about disabled packages,
21680     * gc'ing to free up references, unmounting all secure containers
21681     * corresponding to packages on external media, and posting a
21682     * UPDATED_MEDIA_STATUS message if status has been requested. Please note
21683     * that we always have to post this message if status has been requested no
21684     * matter what.
21685     */
21686    private void unloadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int uidArr[],
21687            final boolean reportStatus) {
21688        if (DEBUG_SD_INSTALL)
21689            Log.i(TAG, "unloading media packages");
21690        ArrayList<String> pkgList = new ArrayList<String>();
21691        ArrayList<AsecInstallArgs> failedList = new ArrayList<AsecInstallArgs>();
21692        final Set<AsecInstallArgs> keys = processCids.keySet();
21693        for (AsecInstallArgs args : keys) {
21694            String pkgName = args.getPackageName();
21695            if (DEBUG_SD_INSTALL)
21696                Log.i(TAG, "Trying to unload pkg : " + pkgName);
21697            // Delete package internally
21698            PackageRemovedInfo outInfo = new PackageRemovedInfo();
21699            synchronized (mInstallLock) {
21700                final int deleteFlags = PackageManager.DELETE_KEEP_DATA;
21701                final boolean res;
21702                try (PackageFreezer freezer = freezePackageForDelete(pkgName, deleteFlags,
21703                        "unloadMediaPackages")) {
21704                    res = deletePackageLIF(pkgName, null, false, null, deleteFlags, outInfo, false,
21705                            null);
21706                }
21707                if (res) {
21708                    pkgList.add(pkgName);
21709                } else {
21710                    Slog.e(TAG, "Failed to delete pkg from sdcard : " + pkgName);
21711                    failedList.add(args);
21712                }
21713            }
21714        }
21715
21716        // reader
21717        synchronized (mPackages) {
21718            // We didn't update the settings after removing each package;
21719            // write them now for all packages.
21720            mSettings.writeLPr();
21721        }
21722
21723        // We have to absolutely send UPDATED_MEDIA_STATUS only
21724        // after confirming that all the receivers processed the ordered
21725        // broadcast when packages get disabled, force a gc to clean things up.
21726        // and unload all the containers.
21727        if (pkgList.size() > 0) {
21728            sendResourcesChangedBroadcast(false, false, pkgList, uidArr,
21729                    new IIntentReceiver.Stub() {
21730                public void performReceive(Intent intent, int resultCode, String data,
21731                        Bundle extras, boolean ordered, boolean sticky,
21732                        int sendingUser) throws RemoteException {
21733                    Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS,
21734                            reportStatus ? 1 : 0, 1, keys);
21735                    mHandler.sendMessage(msg);
21736                }
21737            });
21738        } else {
21739            Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1 : 0, -1,
21740                    keys);
21741            mHandler.sendMessage(msg);
21742        }
21743    }
21744
21745    private void loadPrivatePackages(final VolumeInfo vol) {
21746        mHandler.post(new Runnable() {
21747            @Override
21748            public void run() {
21749                loadPrivatePackagesInner(vol);
21750            }
21751        });
21752    }
21753
21754    private void loadPrivatePackagesInner(VolumeInfo vol) {
21755        final String volumeUuid = vol.fsUuid;
21756        if (TextUtils.isEmpty(volumeUuid)) {
21757            Slog.e(TAG, "Loading internal storage is probably a mistake; ignoring");
21758            return;
21759        }
21760
21761        final ArrayList<PackageFreezer> freezers = new ArrayList<>();
21762        final ArrayList<ApplicationInfo> loaded = new ArrayList<>();
21763        final int parseFlags = mDefParseFlags | PackageParser.PARSE_EXTERNAL_STORAGE;
21764
21765        final VersionInfo ver;
21766        final List<PackageSetting> packages;
21767        synchronized (mPackages) {
21768            ver = mSettings.findOrCreateVersion(volumeUuid);
21769            packages = mSettings.getVolumePackagesLPr(volumeUuid);
21770        }
21771
21772        for (PackageSetting ps : packages) {
21773            freezers.add(freezePackage(ps.name, "loadPrivatePackagesInner"));
21774            synchronized (mInstallLock) {
21775                final PackageParser.Package pkg;
21776                try {
21777                    pkg = scanPackageTracedLI(ps.codePath, parseFlags, SCAN_INITIAL, 0, null);
21778                    loaded.add(pkg.applicationInfo);
21779
21780                } catch (PackageManagerException e) {
21781                    Slog.w(TAG, "Failed to scan " + ps.codePath + ": " + e.getMessage());
21782                }
21783
21784                if (!Build.FINGERPRINT.equals(ver.fingerprint)) {
21785                    clearAppDataLIF(ps.pkg, UserHandle.USER_ALL,
21786                            StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE
21787                                    | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
21788                }
21789            }
21790        }
21791
21792        // Reconcile app data for all started/unlocked users
21793        final StorageManager sm = mContext.getSystemService(StorageManager.class);
21794        final UserManager um = mContext.getSystemService(UserManager.class);
21795        UserManagerInternal umInternal = getUserManagerInternal();
21796        for (UserInfo user : um.getUsers()) {
21797            final int flags;
21798            if (umInternal.isUserUnlockingOrUnlocked(user.id)) {
21799                flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
21800            } else if (umInternal.isUserRunning(user.id)) {
21801                flags = StorageManager.FLAG_STORAGE_DE;
21802            } else {
21803                continue;
21804            }
21805
21806            try {
21807                sm.prepareUserStorage(volumeUuid, user.id, user.serialNumber, flags);
21808                synchronized (mInstallLock) {
21809                    reconcileAppsDataLI(volumeUuid, user.id, flags, true /* migrateAppData */);
21810                }
21811            } catch (IllegalStateException e) {
21812                // Device was probably ejected, and we'll process that event momentarily
21813                Slog.w(TAG, "Failed to prepare storage: " + e);
21814            }
21815        }
21816
21817        synchronized (mPackages) {
21818            int updateFlags = UPDATE_PERMISSIONS_ALL;
21819            if (ver.sdkVersion != mSdkVersion) {
21820                logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to "
21821                        + mSdkVersion + "; regranting permissions for " + volumeUuid);
21822                updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
21823            }
21824            updatePermissionsLPw(null, null, volumeUuid, updateFlags);
21825
21826            // Yay, everything is now upgraded
21827            ver.forceCurrent();
21828
21829            mSettings.writeLPr();
21830        }
21831
21832        for (PackageFreezer freezer : freezers) {
21833            freezer.close();
21834        }
21835
21836        if (DEBUG_INSTALL) Slog.d(TAG, "Loaded packages " + loaded);
21837        sendResourcesChangedBroadcast(true, false, loaded, null);
21838    }
21839
21840    private void unloadPrivatePackages(final VolumeInfo vol) {
21841        mHandler.post(new Runnable() {
21842            @Override
21843            public void run() {
21844                unloadPrivatePackagesInner(vol);
21845            }
21846        });
21847    }
21848
21849    private void unloadPrivatePackagesInner(VolumeInfo vol) {
21850        final String volumeUuid = vol.fsUuid;
21851        if (TextUtils.isEmpty(volumeUuid)) {
21852            Slog.e(TAG, "Unloading internal storage is probably a mistake; ignoring");
21853            return;
21854        }
21855
21856        final ArrayList<ApplicationInfo> unloaded = new ArrayList<>();
21857        synchronized (mInstallLock) {
21858        synchronized (mPackages) {
21859            final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(volumeUuid);
21860            for (PackageSetting ps : packages) {
21861                if (ps.pkg == null) continue;
21862
21863                final ApplicationInfo info = ps.pkg.applicationInfo;
21864                final int deleteFlags = PackageManager.DELETE_KEEP_DATA;
21865                final PackageRemovedInfo outInfo = new PackageRemovedInfo();
21866
21867                try (PackageFreezer freezer = freezePackageForDelete(ps.name, deleteFlags,
21868                        "unloadPrivatePackagesInner")) {
21869                    if (deletePackageLIF(ps.name, null, false, null, deleteFlags, outInfo,
21870                            false, null)) {
21871                        unloaded.add(info);
21872                    } else {
21873                        Slog.w(TAG, "Failed to unload " + ps.codePath);
21874                    }
21875                }
21876
21877                // Try very hard to release any references to this package
21878                // so we don't risk the system server being killed due to
21879                // open FDs
21880                AttributeCache.instance().removePackage(ps.name);
21881            }
21882
21883            mSettings.writeLPr();
21884        }
21885        }
21886
21887        if (DEBUG_INSTALL) Slog.d(TAG, "Unloaded packages " + unloaded);
21888        sendResourcesChangedBroadcast(false, false, unloaded, null);
21889
21890        // Try very hard to release any references to this path so we don't risk
21891        // the system server being killed due to open FDs
21892        ResourcesManager.getInstance().invalidatePath(vol.getPath().getAbsolutePath());
21893
21894        for (int i = 0; i < 3; i++) {
21895            System.gc();
21896            System.runFinalization();
21897        }
21898    }
21899
21900    private void assertPackageKnown(String volumeUuid, String packageName)
21901            throws PackageManagerException {
21902        synchronized (mPackages) {
21903            // Normalize package name to handle renamed packages
21904            packageName = normalizePackageNameLPr(packageName);
21905
21906            final PackageSetting ps = mSettings.mPackages.get(packageName);
21907            if (ps == null) {
21908                throw new PackageManagerException("Package " + packageName + " is unknown");
21909            } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) {
21910                throw new PackageManagerException(
21911                        "Package " + packageName + " found on unknown volume " + volumeUuid
21912                                + "; expected volume " + ps.volumeUuid);
21913            }
21914        }
21915    }
21916
21917    private void assertPackageKnownAndInstalled(String volumeUuid, String packageName, int userId)
21918            throws PackageManagerException {
21919        synchronized (mPackages) {
21920            // Normalize package name to handle renamed packages
21921            packageName = normalizePackageNameLPr(packageName);
21922
21923            final PackageSetting ps = mSettings.mPackages.get(packageName);
21924            if (ps == null) {
21925                throw new PackageManagerException("Package " + packageName + " is unknown");
21926            } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) {
21927                throw new PackageManagerException(
21928                        "Package " + packageName + " found on unknown volume " + volumeUuid
21929                                + "; expected volume " + ps.volumeUuid);
21930            } else if (!ps.getInstalled(userId)) {
21931                throw new PackageManagerException(
21932                        "Package " + packageName + " not installed for user " + userId);
21933            }
21934        }
21935    }
21936
21937    private List<String> collectAbsoluteCodePaths() {
21938        synchronized (mPackages) {
21939            List<String> codePaths = new ArrayList<>();
21940            final int packageCount = mSettings.mPackages.size();
21941            for (int i = 0; i < packageCount; i++) {
21942                final PackageSetting ps = mSettings.mPackages.valueAt(i);
21943                codePaths.add(ps.codePath.getAbsolutePath());
21944            }
21945            return codePaths;
21946        }
21947    }
21948
21949    /**
21950     * Examine all apps present on given mounted volume, and destroy apps that
21951     * aren't expected, either due to uninstallation or reinstallation on
21952     * another volume.
21953     */
21954    private void reconcileApps(String volumeUuid) {
21955        List<String> absoluteCodePaths = collectAbsoluteCodePaths();
21956        List<File> filesToDelete = null;
21957
21958        final File[] files = FileUtils.listFilesOrEmpty(
21959                Environment.getDataAppDirectory(volumeUuid));
21960        for (File file : files) {
21961            final boolean isPackage = (isApkFile(file) || file.isDirectory())
21962                    && !PackageInstallerService.isStageName(file.getName());
21963            if (!isPackage) {
21964                // Ignore entries which are not packages
21965                continue;
21966            }
21967
21968            String absolutePath = file.getAbsolutePath();
21969
21970            boolean pathValid = false;
21971            final int absoluteCodePathCount = absoluteCodePaths.size();
21972            for (int i = 0; i < absoluteCodePathCount; i++) {
21973                String absoluteCodePath = absoluteCodePaths.get(i);
21974                if (absolutePath.startsWith(absoluteCodePath)) {
21975                    pathValid = true;
21976                    break;
21977                }
21978            }
21979
21980            if (!pathValid) {
21981                if (filesToDelete == null) {
21982                    filesToDelete = new ArrayList<>();
21983                }
21984                filesToDelete.add(file);
21985            }
21986        }
21987
21988        if (filesToDelete != null) {
21989            final int fileToDeleteCount = filesToDelete.size();
21990            for (int i = 0; i < fileToDeleteCount; i++) {
21991                File fileToDelete = filesToDelete.get(i);
21992                logCriticalInfo(Log.WARN, "Destroying orphaned" + fileToDelete);
21993                synchronized (mInstallLock) {
21994                    removeCodePathLI(fileToDelete);
21995                }
21996            }
21997        }
21998    }
21999
22000    /**
22001     * Reconcile all app data for the given user.
22002     * <p>
22003     * Verifies that directories exist and that ownership and labeling is
22004     * correct for all installed apps on all mounted volumes.
22005     */
22006    void reconcileAppsData(int userId, int flags, boolean migrateAppsData) {
22007        final StorageManager storage = mContext.getSystemService(StorageManager.class);
22008        for (VolumeInfo vol : storage.getWritablePrivateVolumes()) {
22009            final String volumeUuid = vol.getFsUuid();
22010            synchronized (mInstallLock) {
22011                reconcileAppsDataLI(volumeUuid, userId, flags, migrateAppsData);
22012            }
22013        }
22014    }
22015
22016    private void reconcileAppsDataLI(String volumeUuid, int userId, int flags,
22017            boolean migrateAppData) {
22018        reconcileAppsDataLI(volumeUuid, userId, flags, migrateAppData, false /* onlyCoreApps */);
22019    }
22020
22021    /**
22022     * Reconcile all app data on given mounted volume.
22023     * <p>
22024     * Destroys app data that isn't expected, either due to uninstallation or
22025     * reinstallation on another volume.
22026     * <p>
22027     * Verifies that directories exist and that ownership and labeling is
22028     * correct for all installed apps.
22029     * @returns list of skipped non-core packages (if {@code onlyCoreApps} is true)
22030     */
22031    private List<String> reconcileAppsDataLI(String volumeUuid, int userId, int flags,
22032            boolean migrateAppData, boolean onlyCoreApps) {
22033        Slog.v(TAG, "reconcileAppsData for " + volumeUuid + " u" + userId + " 0x"
22034                + Integer.toHexString(flags) + " migrateAppData=" + migrateAppData);
22035        List<String> result = onlyCoreApps ? new ArrayList<>() : null;
22036
22037        final File ceDir = Environment.getDataUserCeDirectory(volumeUuid, userId);
22038        final File deDir = Environment.getDataUserDeDirectory(volumeUuid, userId);
22039
22040        // First look for stale data that doesn't belong, and check if things
22041        // have changed since we did our last restorecon
22042        if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
22043            if (StorageManager.isFileEncryptedNativeOrEmulated()
22044                    && !StorageManager.isUserKeyUnlocked(userId)) {
22045                throw new RuntimeException(
22046                        "Yikes, someone asked us to reconcile CE storage while " + userId
22047                                + " was still locked; this would have caused massive data loss!");
22048            }
22049
22050            final File[] files = FileUtils.listFilesOrEmpty(ceDir);
22051            for (File file : files) {
22052                final String packageName = file.getName();
22053                try {
22054                    assertPackageKnownAndInstalled(volumeUuid, packageName, userId);
22055                } catch (PackageManagerException e) {
22056                    logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e);
22057                    try {
22058                        mInstaller.destroyAppData(volumeUuid, packageName, userId,
22059                                StorageManager.FLAG_STORAGE_CE, 0);
22060                    } catch (InstallerException e2) {
22061                        logCriticalInfo(Log.WARN, "Failed to destroy: " + e2);
22062                    }
22063                }
22064            }
22065        }
22066        if ((flags & StorageManager.FLAG_STORAGE_DE) != 0) {
22067            final File[] files = FileUtils.listFilesOrEmpty(deDir);
22068            for (File file : files) {
22069                final String packageName = file.getName();
22070                try {
22071                    assertPackageKnownAndInstalled(volumeUuid, packageName, userId);
22072                } catch (PackageManagerException e) {
22073                    logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e);
22074                    try {
22075                        mInstaller.destroyAppData(volumeUuid, packageName, userId,
22076                                StorageManager.FLAG_STORAGE_DE, 0);
22077                    } catch (InstallerException e2) {
22078                        logCriticalInfo(Log.WARN, "Failed to destroy: " + e2);
22079                    }
22080                }
22081            }
22082        }
22083
22084        // Ensure that data directories are ready to roll for all packages
22085        // installed for this volume and user
22086        final List<PackageSetting> packages;
22087        synchronized (mPackages) {
22088            packages = mSettings.getVolumePackagesLPr(volumeUuid);
22089        }
22090        int preparedCount = 0;
22091        for (PackageSetting ps : packages) {
22092            final String packageName = ps.name;
22093            if (ps.pkg == null) {
22094                Slog.w(TAG, "Odd, missing scanned package " + packageName);
22095                // TODO: might be due to legacy ASEC apps; we should circle back
22096                // and reconcile again once they're scanned
22097                continue;
22098            }
22099            // Skip non-core apps if requested
22100            if (onlyCoreApps && !ps.pkg.coreApp) {
22101                result.add(packageName);
22102                continue;
22103            }
22104
22105            if (ps.getInstalled(userId)) {
22106                prepareAppDataAndMigrateLIF(ps.pkg, userId, flags, migrateAppData);
22107                preparedCount++;
22108            }
22109        }
22110
22111        Slog.v(TAG, "reconcileAppsData finished " + preparedCount + " packages");
22112        return result;
22113    }
22114
22115    /**
22116     * Prepare app data for the given app just after it was installed or
22117     * upgraded. This method carefully only touches users that it's installed
22118     * for, and it forces a restorecon to handle any seinfo changes.
22119     * <p>
22120     * Verifies that directories exist and that ownership and labeling is
22121     * correct for all installed apps. If there is an ownership mismatch, it
22122     * will try recovering system apps by wiping data; third-party app data is
22123     * left intact.
22124     * <p>
22125     * <em>Note: To avoid a deadlock, do not call this method with {@code mPackages} lock held</em>
22126     */
22127    private void prepareAppDataAfterInstallLIF(PackageParser.Package pkg) {
22128        final PackageSetting ps;
22129        synchronized (mPackages) {
22130            ps = mSettings.mPackages.get(pkg.packageName);
22131            mSettings.writeKernelMappingLPr(ps);
22132        }
22133
22134        final UserManager um = mContext.getSystemService(UserManager.class);
22135        UserManagerInternal umInternal = getUserManagerInternal();
22136        for (UserInfo user : um.getUsers()) {
22137            final int flags;
22138            if (umInternal.isUserUnlockingOrUnlocked(user.id)) {
22139                flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
22140            } else if (umInternal.isUserRunning(user.id)) {
22141                flags = StorageManager.FLAG_STORAGE_DE;
22142            } else {
22143                continue;
22144            }
22145
22146            if (ps.getInstalled(user.id)) {
22147                // TODO: when user data is locked, mark that we're still dirty
22148                prepareAppDataLIF(pkg, user.id, flags);
22149            }
22150        }
22151    }
22152
22153    /**
22154     * Prepare app data for the given app.
22155     * <p>
22156     * Verifies that directories exist and that ownership and labeling is
22157     * correct for all installed apps. If there is an ownership mismatch, this
22158     * will try recovering system apps by wiping data; third-party app data is
22159     * left intact.
22160     */
22161    private void prepareAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
22162        if (pkg == null) {
22163            Slog.wtf(TAG, "Package was null!", new Throwable());
22164            return;
22165        }
22166        prepareAppDataLeafLIF(pkg, userId, flags);
22167        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
22168        for (int i = 0; i < childCount; i++) {
22169            prepareAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
22170        }
22171    }
22172
22173    private void prepareAppDataAndMigrateLIF(PackageParser.Package pkg, int userId, int flags,
22174            boolean maybeMigrateAppData) {
22175        prepareAppDataLIF(pkg, userId, flags);
22176
22177        if (maybeMigrateAppData && maybeMigrateAppDataLIF(pkg, userId)) {
22178            // We may have just shuffled around app data directories, so
22179            // prepare them one more time
22180            prepareAppDataLIF(pkg, userId, flags);
22181        }
22182    }
22183
22184    private void prepareAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
22185        if (DEBUG_APP_DATA) {
22186            Slog.v(TAG, "prepareAppData for " + pkg.packageName + " u" + userId + " 0x"
22187                    + Integer.toHexString(flags));
22188        }
22189
22190        final String volumeUuid = pkg.volumeUuid;
22191        final String packageName = pkg.packageName;
22192        final ApplicationInfo app = pkg.applicationInfo;
22193        final int appId = UserHandle.getAppId(app.uid);
22194
22195        Preconditions.checkNotNull(app.seInfo);
22196
22197        long ceDataInode = -1;
22198        try {
22199            ceDataInode = mInstaller.createAppData(volumeUuid, packageName, userId, flags,
22200                    appId, app.seInfo, app.targetSdkVersion);
22201        } catch (InstallerException e) {
22202            if (app.isSystemApp()) {
22203                logCriticalInfo(Log.ERROR, "Failed to create app data for " + packageName
22204                        + ", but trying to recover: " + e);
22205                destroyAppDataLeafLIF(pkg, userId, flags);
22206                try {
22207                    ceDataInode = mInstaller.createAppData(volumeUuid, packageName, userId, flags,
22208                            appId, app.seInfo, app.targetSdkVersion);
22209                    logCriticalInfo(Log.DEBUG, "Recovery succeeded!");
22210                } catch (InstallerException e2) {
22211                    logCriticalInfo(Log.DEBUG, "Recovery failed!");
22212                }
22213            } else {
22214                Slog.e(TAG, "Failed to create app data for " + packageName + ": " + e);
22215            }
22216        }
22217
22218        if ((flags & StorageManager.FLAG_STORAGE_CE) != 0 && ceDataInode != -1) {
22219            // TODO: mark this structure as dirty so we persist it!
22220            synchronized (mPackages) {
22221                final PackageSetting ps = mSettings.mPackages.get(packageName);
22222                if (ps != null) {
22223                    ps.setCeDataInode(ceDataInode, userId);
22224                }
22225            }
22226        }
22227
22228        prepareAppDataContentsLeafLIF(pkg, userId, flags);
22229    }
22230
22231    private void prepareAppDataContentsLIF(PackageParser.Package pkg, int userId, int flags) {
22232        if (pkg == null) {
22233            Slog.wtf(TAG, "Package was null!", new Throwable());
22234            return;
22235        }
22236        prepareAppDataContentsLeafLIF(pkg, userId, flags);
22237        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
22238        for (int i = 0; i < childCount; i++) {
22239            prepareAppDataContentsLeafLIF(pkg.childPackages.get(i), userId, flags);
22240        }
22241    }
22242
22243    private void prepareAppDataContentsLeafLIF(PackageParser.Package pkg, int userId, int flags) {
22244        final String volumeUuid = pkg.volumeUuid;
22245        final String packageName = pkg.packageName;
22246        final ApplicationInfo app = pkg.applicationInfo;
22247
22248        if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
22249            // Create a native library symlink only if we have native libraries
22250            // and if the native libraries are 32 bit libraries. We do not provide
22251            // this symlink for 64 bit libraries.
22252            if (app.primaryCpuAbi != null && !VMRuntime.is64BitAbi(app.primaryCpuAbi)) {
22253                final String nativeLibPath = app.nativeLibraryDir;
22254                try {
22255                    mInstaller.linkNativeLibraryDirectory(volumeUuid, packageName,
22256                            nativeLibPath, userId);
22257                } catch (InstallerException e) {
22258                    Slog.e(TAG, "Failed to link native for " + packageName + ": " + e);
22259                }
22260            }
22261        }
22262    }
22263
22264    /**
22265     * For system apps on non-FBE devices, this method migrates any existing
22266     * CE/DE data to match the {@code defaultToDeviceProtectedStorage} flag
22267     * requested by the app.
22268     */
22269    private boolean maybeMigrateAppDataLIF(PackageParser.Package pkg, int userId) {
22270        if (pkg.isSystemApp() && !StorageManager.isFileEncryptedNativeOrEmulated()
22271                && PackageManager.APPLY_DEFAULT_TO_DEVICE_PROTECTED_STORAGE) {
22272            final int storageTarget = pkg.applicationInfo.isDefaultToDeviceProtectedStorage()
22273                    ? StorageManager.FLAG_STORAGE_DE : StorageManager.FLAG_STORAGE_CE;
22274            try {
22275                mInstaller.migrateAppData(pkg.volumeUuid, pkg.packageName, userId,
22276                        storageTarget);
22277            } catch (InstallerException e) {
22278                logCriticalInfo(Log.WARN,
22279                        "Failed to migrate " + pkg.packageName + ": " + e.getMessage());
22280            }
22281            return true;
22282        } else {
22283            return false;
22284        }
22285    }
22286
22287    public PackageFreezer freezePackage(String packageName, String killReason) {
22288        return freezePackage(packageName, UserHandle.USER_ALL, killReason);
22289    }
22290
22291    public PackageFreezer freezePackage(String packageName, int userId, String killReason) {
22292        return new PackageFreezer(packageName, userId, killReason);
22293    }
22294
22295    public PackageFreezer freezePackageForInstall(String packageName, int installFlags,
22296            String killReason) {
22297        return freezePackageForInstall(packageName, UserHandle.USER_ALL, installFlags, killReason);
22298    }
22299
22300    public PackageFreezer freezePackageForInstall(String packageName, int userId, int installFlags,
22301            String killReason) {
22302        if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) {
22303            return new PackageFreezer();
22304        } else {
22305            return freezePackage(packageName, userId, killReason);
22306        }
22307    }
22308
22309    public PackageFreezer freezePackageForDelete(String packageName, int deleteFlags,
22310            String killReason) {
22311        return freezePackageForDelete(packageName, UserHandle.USER_ALL, deleteFlags, killReason);
22312    }
22313
22314    public PackageFreezer freezePackageForDelete(String packageName, int userId, int deleteFlags,
22315            String killReason) {
22316        if ((deleteFlags & PackageManager.DELETE_DONT_KILL_APP) != 0) {
22317            return new PackageFreezer();
22318        } else {
22319            return freezePackage(packageName, userId, killReason);
22320        }
22321    }
22322
22323    /**
22324     * Class that freezes and kills the given package upon creation, and
22325     * unfreezes it upon closing. This is typically used when doing surgery on
22326     * app code/data to prevent the app from running while you're working.
22327     */
22328    private class PackageFreezer implements AutoCloseable {
22329        private final String mPackageName;
22330        private final PackageFreezer[] mChildren;
22331
22332        private final boolean mWeFroze;
22333
22334        private final AtomicBoolean mClosed = new AtomicBoolean();
22335        private final CloseGuard mCloseGuard = CloseGuard.get();
22336
22337        /**
22338         * Create and return a stub freezer that doesn't actually do anything,
22339         * typically used when someone requested
22340         * {@link PackageManager#INSTALL_DONT_KILL_APP} or
22341         * {@link PackageManager#DELETE_DONT_KILL_APP}.
22342         */
22343        public PackageFreezer() {
22344            mPackageName = null;
22345            mChildren = null;
22346            mWeFroze = false;
22347            mCloseGuard.open("close");
22348        }
22349
22350        public PackageFreezer(String packageName, int userId, String killReason) {
22351            synchronized (mPackages) {
22352                mPackageName = packageName;
22353                mWeFroze = mFrozenPackages.add(mPackageName);
22354
22355                final PackageSetting ps = mSettings.mPackages.get(mPackageName);
22356                if (ps != null) {
22357                    killApplication(ps.name, ps.appId, userId, killReason);
22358                }
22359
22360                final PackageParser.Package p = mPackages.get(packageName);
22361                if (p != null && p.childPackages != null) {
22362                    final int N = p.childPackages.size();
22363                    mChildren = new PackageFreezer[N];
22364                    for (int i = 0; i < N; i++) {
22365                        mChildren[i] = new PackageFreezer(p.childPackages.get(i).packageName,
22366                                userId, killReason);
22367                    }
22368                } else {
22369                    mChildren = null;
22370                }
22371            }
22372            mCloseGuard.open("close");
22373        }
22374
22375        @Override
22376        protected void finalize() throws Throwable {
22377            try {
22378                mCloseGuard.warnIfOpen();
22379                close();
22380            } finally {
22381                super.finalize();
22382            }
22383        }
22384
22385        @Override
22386        public void close() {
22387            mCloseGuard.close();
22388            if (mClosed.compareAndSet(false, true)) {
22389                synchronized (mPackages) {
22390                    if (mWeFroze) {
22391                        mFrozenPackages.remove(mPackageName);
22392                    }
22393
22394                    if (mChildren != null) {
22395                        for (PackageFreezer freezer : mChildren) {
22396                            freezer.close();
22397                        }
22398                    }
22399                }
22400            }
22401        }
22402    }
22403
22404    /**
22405     * Verify that given package is currently frozen.
22406     */
22407    private void checkPackageFrozen(String packageName) {
22408        synchronized (mPackages) {
22409            if (!mFrozenPackages.contains(packageName)) {
22410                Slog.wtf(TAG, "Expected " + packageName + " to be frozen!", new Throwable());
22411            }
22412        }
22413    }
22414
22415    @Override
22416    public int movePackage(final String packageName, final String volumeUuid) {
22417        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
22418
22419        final UserHandle user = new UserHandle(UserHandle.getCallingUserId());
22420        final int moveId = mNextMoveId.getAndIncrement();
22421        mHandler.post(new Runnable() {
22422            @Override
22423            public void run() {
22424                try {
22425                    movePackageInternal(packageName, volumeUuid, moveId, user);
22426                } catch (PackageManagerException e) {
22427                    Slog.w(TAG, "Failed to move " + packageName, e);
22428                    mMoveCallbacks.notifyStatusChanged(moveId,
22429                            PackageManager.MOVE_FAILED_INTERNAL_ERROR);
22430                }
22431            }
22432        });
22433        return moveId;
22434    }
22435
22436    private void movePackageInternal(final String packageName, final String volumeUuid,
22437            final int moveId, UserHandle user) throws PackageManagerException {
22438        final StorageManager storage = mContext.getSystemService(StorageManager.class);
22439        final PackageManager pm = mContext.getPackageManager();
22440
22441        final boolean currentAsec;
22442        final String currentVolumeUuid;
22443        final File codeFile;
22444        final String installerPackageName;
22445        final String packageAbiOverride;
22446        final int appId;
22447        final String seinfo;
22448        final String label;
22449        final int targetSdkVersion;
22450        final PackageFreezer freezer;
22451        final int[] installedUserIds;
22452
22453        // reader
22454        synchronized (mPackages) {
22455            final PackageParser.Package pkg = mPackages.get(packageName);
22456            final PackageSetting ps = mSettings.mPackages.get(packageName);
22457            if (pkg == null || ps == null) {
22458                throw new PackageManagerException(MOVE_FAILED_DOESNT_EXIST, "Missing package");
22459            }
22460
22461            if (pkg.applicationInfo.isSystemApp()) {
22462                throw new PackageManagerException(MOVE_FAILED_SYSTEM_PACKAGE,
22463                        "Cannot move system application");
22464            }
22465
22466            final boolean isInternalStorage = VolumeInfo.ID_PRIVATE_INTERNAL.equals(volumeUuid);
22467            final boolean allow3rdPartyOnInternal = mContext.getResources().getBoolean(
22468                    com.android.internal.R.bool.config_allow3rdPartyAppOnInternal);
22469            if (isInternalStorage && !allow3rdPartyOnInternal) {
22470                throw new PackageManagerException(MOVE_FAILED_3RD_PARTY_NOT_ALLOWED_ON_INTERNAL,
22471                        "3rd party apps are not allowed on internal storage");
22472            }
22473
22474            if (pkg.applicationInfo.isExternalAsec()) {
22475                currentAsec = true;
22476                currentVolumeUuid = StorageManager.UUID_PRIMARY_PHYSICAL;
22477            } else if (pkg.applicationInfo.isForwardLocked()) {
22478                currentAsec = true;
22479                currentVolumeUuid = "forward_locked";
22480            } else {
22481                currentAsec = false;
22482                currentVolumeUuid = ps.volumeUuid;
22483
22484                final File probe = new File(pkg.codePath);
22485                final File probeOat = new File(probe, "oat");
22486                if (!probe.isDirectory() || !probeOat.isDirectory()) {
22487                    throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
22488                            "Move only supported for modern cluster style installs");
22489                }
22490            }
22491
22492            if (Objects.equals(currentVolumeUuid, volumeUuid)) {
22493                throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
22494                        "Package already moved to " + volumeUuid);
22495            }
22496            if (pkg.applicationInfo.isInternal() && isPackageDeviceAdminOnAnyUser(packageName)) {
22497                throw new PackageManagerException(MOVE_FAILED_DEVICE_ADMIN,
22498                        "Device admin cannot be moved");
22499            }
22500
22501            if (mFrozenPackages.contains(packageName)) {
22502                throw new PackageManagerException(MOVE_FAILED_OPERATION_PENDING,
22503                        "Failed to move already frozen package");
22504            }
22505
22506            codeFile = new File(pkg.codePath);
22507            installerPackageName = ps.installerPackageName;
22508            packageAbiOverride = ps.cpuAbiOverrideString;
22509            appId = UserHandle.getAppId(pkg.applicationInfo.uid);
22510            seinfo = pkg.applicationInfo.seInfo;
22511            label = String.valueOf(pm.getApplicationLabel(pkg.applicationInfo));
22512            targetSdkVersion = pkg.applicationInfo.targetSdkVersion;
22513            freezer = freezePackage(packageName, "movePackageInternal");
22514            installedUserIds = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
22515        }
22516
22517        final Bundle extras = new Bundle();
22518        extras.putString(Intent.EXTRA_PACKAGE_NAME, packageName);
22519        extras.putString(Intent.EXTRA_TITLE, label);
22520        mMoveCallbacks.notifyCreated(moveId, extras);
22521
22522        int installFlags;
22523        final boolean moveCompleteApp;
22524        final File measurePath;
22525
22526        if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, volumeUuid)) {
22527            installFlags = INSTALL_INTERNAL;
22528            moveCompleteApp = !currentAsec;
22529            measurePath = Environment.getDataAppDirectory(volumeUuid);
22530        } else if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, volumeUuid)) {
22531            installFlags = INSTALL_EXTERNAL;
22532            moveCompleteApp = false;
22533            measurePath = storage.getPrimaryPhysicalVolume().getPath();
22534        } else {
22535            final VolumeInfo volume = storage.findVolumeByUuid(volumeUuid);
22536            if (volume == null || volume.getType() != VolumeInfo.TYPE_PRIVATE
22537                    || !volume.isMountedWritable()) {
22538                freezer.close();
22539                throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
22540                        "Move location not mounted private volume");
22541            }
22542
22543            Preconditions.checkState(!currentAsec);
22544
22545            installFlags = INSTALL_INTERNAL;
22546            moveCompleteApp = true;
22547            measurePath = Environment.getDataAppDirectory(volumeUuid);
22548        }
22549
22550        final PackageStats stats = new PackageStats(null, -1);
22551        synchronized (mInstaller) {
22552            for (int userId : installedUserIds) {
22553                if (!getPackageSizeInfoLI(packageName, userId, stats)) {
22554                    freezer.close();
22555                    throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
22556                            "Failed to measure package size");
22557                }
22558            }
22559        }
22560
22561        if (DEBUG_INSTALL) Slog.d(TAG, "Measured code size " + stats.codeSize + ", data size "
22562                + stats.dataSize);
22563
22564        final long startFreeBytes = measurePath.getUsableSpace();
22565        final long sizeBytes;
22566        if (moveCompleteApp) {
22567            sizeBytes = stats.codeSize + stats.dataSize;
22568        } else {
22569            sizeBytes = stats.codeSize;
22570        }
22571
22572        if (sizeBytes > storage.getStorageBytesUntilLow(measurePath)) {
22573            freezer.close();
22574            throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
22575                    "Not enough free space to move");
22576        }
22577
22578        mMoveCallbacks.notifyStatusChanged(moveId, 10);
22579
22580        final CountDownLatch installedLatch = new CountDownLatch(1);
22581        final IPackageInstallObserver2 installObserver = new IPackageInstallObserver2.Stub() {
22582            @Override
22583            public void onUserActionRequired(Intent intent) throws RemoteException {
22584                throw new IllegalStateException();
22585            }
22586
22587            @Override
22588            public void onPackageInstalled(String basePackageName, int returnCode, String msg,
22589                    Bundle extras) throws RemoteException {
22590                if (DEBUG_INSTALL) Slog.d(TAG, "Install result for move: "
22591                        + PackageManager.installStatusToString(returnCode, msg));
22592
22593                installedLatch.countDown();
22594                freezer.close();
22595
22596                final int status = PackageManager.installStatusToPublicStatus(returnCode);
22597                switch (status) {
22598                    case PackageInstaller.STATUS_SUCCESS:
22599                        mMoveCallbacks.notifyStatusChanged(moveId,
22600                                PackageManager.MOVE_SUCCEEDED);
22601                        break;
22602                    case PackageInstaller.STATUS_FAILURE_STORAGE:
22603                        mMoveCallbacks.notifyStatusChanged(moveId,
22604                                PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE);
22605                        break;
22606                    default:
22607                        mMoveCallbacks.notifyStatusChanged(moveId,
22608                                PackageManager.MOVE_FAILED_INTERNAL_ERROR);
22609                        break;
22610                }
22611            }
22612        };
22613
22614        final MoveInfo move;
22615        if (moveCompleteApp) {
22616            // Kick off a thread to report progress estimates
22617            new Thread() {
22618                @Override
22619                public void run() {
22620                    while (true) {
22621                        try {
22622                            if (installedLatch.await(1, TimeUnit.SECONDS)) {
22623                                break;
22624                            }
22625                        } catch (InterruptedException ignored) {
22626                        }
22627
22628                        final long deltaFreeBytes = startFreeBytes - measurePath.getUsableSpace();
22629                        final int progress = 10 + (int) MathUtils.constrain(
22630                                ((deltaFreeBytes * 80) / sizeBytes), 0, 80);
22631                        mMoveCallbacks.notifyStatusChanged(moveId, progress);
22632                    }
22633                }
22634            }.start();
22635
22636            final String dataAppName = codeFile.getName();
22637            move = new MoveInfo(moveId, currentVolumeUuid, volumeUuid, packageName,
22638                    dataAppName, appId, seinfo, targetSdkVersion);
22639        } else {
22640            move = null;
22641        }
22642
22643        installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
22644
22645        final Message msg = mHandler.obtainMessage(INIT_COPY);
22646        final OriginInfo origin = OriginInfo.fromExistingFile(codeFile);
22647        final InstallParams params = new InstallParams(origin, move, installObserver, installFlags,
22648                installerPackageName, volumeUuid, null /*verificationInfo*/, user,
22649                packageAbiOverride, null /*grantedPermissions*/, null /*certificates*/,
22650                PackageManager.INSTALL_REASON_UNKNOWN);
22651        params.setTraceMethod("movePackage").setTraceCookie(System.identityHashCode(params));
22652        msg.obj = params;
22653
22654        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "movePackage",
22655                System.identityHashCode(msg.obj));
22656        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
22657                System.identityHashCode(msg.obj));
22658
22659        mHandler.sendMessage(msg);
22660    }
22661
22662    @Override
22663    public int movePrimaryStorage(String volumeUuid) throws RemoteException {
22664        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
22665
22666        final int realMoveId = mNextMoveId.getAndIncrement();
22667        final Bundle extras = new Bundle();
22668        extras.putString(VolumeRecord.EXTRA_FS_UUID, volumeUuid);
22669        mMoveCallbacks.notifyCreated(realMoveId, extras);
22670
22671        final IPackageMoveObserver callback = new IPackageMoveObserver.Stub() {
22672            @Override
22673            public void onCreated(int moveId, Bundle extras) {
22674                // Ignored
22675            }
22676
22677            @Override
22678            public void onStatusChanged(int moveId, int status, long estMillis) {
22679                mMoveCallbacks.notifyStatusChanged(realMoveId, status, estMillis);
22680            }
22681        };
22682
22683        final StorageManager storage = mContext.getSystemService(StorageManager.class);
22684        storage.setPrimaryStorageUuid(volumeUuid, callback);
22685        return realMoveId;
22686    }
22687
22688    @Override
22689    public int getMoveStatus(int moveId) {
22690        mContext.enforceCallingOrSelfPermission(
22691                android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
22692        return mMoveCallbacks.mLastStatus.get(moveId);
22693    }
22694
22695    @Override
22696    public void registerMoveCallback(IPackageMoveObserver callback) {
22697        mContext.enforceCallingOrSelfPermission(
22698                android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
22699        mMoveCallbacks.register(callback);
22700    }
22701
22702    @Override
22703    public void unregisterMoveCallback(IPackageMoveObserver callback) {
22704        mContext.enforceCallingOrSelfPermission(
22705                android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
22706        mMoveCallbacks.unregister(callback);
22707    }
22708
22709    @Override
22710    public boolean setInstallLocation(int loc) {
22711        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS,
22712                null);
22713        if (getInstallLocation() == loc) {
22714            return true;
22715        }
22716        if (loc == PackageHelper.APP_INSTALL_AUTO || loc == PackageHelper.APP_INSTALL_INTERNAL
22717                || loc == PackageHelper.APP_INSTALL_EXTERNAL) {
22718            android.provider.Settings.Global.putInt(mContext.getContentResolver(),
22719                    android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, loc);
22720            return true;
22721        }
22722        return false;
22723   }
22724
22725    @Override
22726    public int getInstallLocation() {
22727        return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
22728                android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION,
22729                PackageHelper.APP_INSTALL_AUTO);
22730    }
22731
22732    /** Called by UserManagerService */
22733    void cleanUpUser(UserManagerService userManager, int userHandle) {
22734        synchronized (mPackages) {
22735            mDirtyUsers.remove(userHandle);
22736            mUserNeedsBadging.delete(userHandle);
22737            mSettings.removeUserLPw(userHandle);
22738            mPendingBroadcasts.remove(userHandle);
22739            mInstantAppRegistry.onUserRemovedLPw(userHandle);
22740            removeUnusedPackagesLPw(userManager, userHandle);
22741        }
22742    }
22743
22744    /**
22745     * We're removing userHandle and would like to remove any downloaded packages
22746     * that are no longer in use by any other user.
22747     * @param userHandle the user being removed
22748     */
22749    private void removeUnusedPackagesLPw(UserManagerService userManager, final int userHandle) {
22750        final boolean DEBUG_CLEAN_APKS = false;
22751        int [] users = userManager.getUserIds();
22752        Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
22753        while (psit.hasNext()) {
22754            PackageSetting ps = psit.next();
22755            if (ps.pkg == null) {
22756                continue;
22757            }
22758            final String packageName = ps.pkg.packageName;
22759            // Skip over if system app
22760            if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) {
22761                continue;
22762            }
22763            if (DEBUG_CLEAN_APKS) {
22764                Slog.i(TAG, "Checking package " + packageName);
22765            }
22766            boolean keep = shouldKeepUninstalledPackageLPr(packageName);
22767            if (keep) {
22768                if (DEBUG_CLEAN_APKS) {
22769                    Slog.i(TAG, "  Keeping package " + packageName + " - requested by DO");
22770                }
22771            } else {
22772                for (int i = 0; i < users.length; i++) {
22773                    if (users[i] != userHandle && ps.getInstalled(users[i])) {
22774                        keep = true;
22775                        if (DEBUG_CLEAN_APKS) {
22776                            Slog.i(TAG, "  Keeping package " + packageName + " for user "
22777                                    + users[i]);
22778                        }
22779                        break;
22780                    }
22781                }
22782            }
22783            if (!keep) {
22784                if (DEBUG_CLEAN_APKS) {
22785                    Slog.i(TAG, "  Removing package " + packageName);
22786                }
22787                mHandler.post(new Runnable() {
22788                    public void run() {
22789                        deletePackageX(packageName, PackageManager.VERSION_CODE_HIGHEST,
22790                                userHandle, 0);
22791                    } //end run
22792                });
22793            }
22794        }
22795    }
22796
22797    /** Called by UserManagerService */
22798    void createNewUser(int userId, String[] disallowedPackages) {
22799        synchronized (mInstallLock) {
22800            mSettings.createNewUserLI(this, mInstaller, userId, disallowedPackages);
22801        }
22802        synchronized (mPackages) {
22803            scheduleWritePackageRestrictionsLocked(userId);
22804            scheduleWritePackageListLocked(userId);
22805            applyFactoryDefaultBrowserLPw(userId);
22806            primeDomainVerificationsLPw(userId);
22807        }
22808    }
22809
22810    void onNewUserCreated(final int userId) {
22811        mDefaultPermissionPolicy.grantDefaultPermissions(userId);
22812        // If permission review for legacy apps is required, we represent
22813        // dagerous permissions for such apps as always granted runtime
22814        // permissions to keep per user flag state whether review is needed.
22815        // Hence, if a new user is added we have to propagate dangerous
22816        // permission grants for these legacy apps.
22817        if (mPermissionReviewRequired) {
22818            updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL
22819                    | UPDATE_PERMISSIONS_REPLACE_ALL);
22820        }
22821    }
22822
22823    @Override
22824    public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException {
22825        mContext.enforceCallingOrSelfPermission(
22826                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
22827                "Only package verification agents can read the verifier device identity");
22828
22829        synchronized (mPackages) {
22830            return mSettings.getVerifierDeviceIdentityLPw();
22831        }
22832    }
22833
22834    @Override
22835    public void setPermissionEnforced(String permission, boolean enforced) {
22836        // TODO: Now that we no longer change GID for storage, this should to away.
22837        mContext.enforceCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
22838                "setPermissionEnforced");
22839        if (READ_EXTERNAL_STORAGE.equals(permission)) {
22840            synchronized (mPackages) {
22841                if (mSettings.mReadExternalStorageEnforced == null
22842                        || mSettings.mReadExternalStorageEnforced != enforced) {
22843                    mSettings.mReadExternalStorageEnforced = enforced;
22844                    mSettings.writeLPr();
22845                }
22846            }
22847            // kill any non-foreground processes so we restart them and
22848            // grant/revoke the GID.
22849            final IActivityManager am = ActivityManager.getService();
22850            if (am != null) {
22851                final long token = Binder.clearCallingIdentity();
22852                try {
22853                    am.killProcessesBelowForeground("setPermissionEnforcement");
22854                } catch (RemoteException e) {
22855                } finally {
22856                    Binder.restoreCallingIdentity(token);
22857                }
22858            }
22859        } else {
22860            throw new IllegalArgumentException("No selective enforcement for " + permission);
22861        }
22862    }
22863
22864    @Override
22865    @Deprecated
22866    public boolean isPermissionEnforced(String permission) {
22867        return true;
22868    }
22869
22870    @Override
22871    public boolean isStorageLow() {
22872        final long token = Binder.clearCallingIdentity();
22873        try {
22874            final DeviceStorageMonitorInternal
22875                    dsm = LocalServices.getService(DeviceStorageMonitorInternal.class);
22876            if (dsm != null) {
22877                return dsm.isMemoryLow();
22878            } else {
22879                return false;
22880            }
22881        } finally {
22882            Binder.restoreCallingIdentity(token);
22883        }
22884    }
22885
22886    @Override
22887    public IPackageInstaller getPackageInstaller() {
22888        return mInstallerService;
22889    }
22890
22891    private boolean userNeedsBadging(int userId) {
22892        int index = mUserNeedsBadging.indexOfKey(userId);
22893        if (index < 0) {
22894            final UserInfo userInfo;
22895            final long token = Binder.clearCallingIdentity();
22896            try {
22897                userInfo = sUserManager.getUserInfo(userId);
22898            } finally {
22899                Binder.restoreCallingIdentity(token);
22900            }
22901            final boolean b;
22902            if (userInfo != null && userInfo.isManagedProfile()) {
22903                b = true;
22904            } else {
22905                b = false;
22906            }
22907            mUserNeedsBadging.put(userId, b);
22908            return b;
22909        }
22910        return mUserNeedsBadging.valueAt(index);
22911    }
22912
22913    @Override
22914    public KeySet getKeySetByAlias(String packageName, String alias) {
22915        if (packageName == null || alias == null) {
22916            return null;
22917        }
22918        synchronized(mPackages) {
22919            final PackageParser.Package pkg = mPackages.get(packageName);
22920            if (pkg == null) {
22921                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
22922                throw new IllegalArgumentException("Unknown package: " + packageName);
22923            }
22924            KeySetManagerService ksms = mSettings.mKeySetManagerService;
22925            return new KeySet(ksms.getKeySetByAliasAndPackageNameLPr(packageName, alias));
22926        }
22927    }
22928
22929    @Override
22930    public KeySet getSigningKeySet(String packageName) {
22931        if (packageName == null) {
22932            return null;
22933        }
22934        synchronized(mPackages) {
22935            final PackageParser.Package pkg = mPackages.get(packageName);
22936            if (pkg == null) {
22937                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
22938                throw new IllegalArgumentException("Unknown package: " + packageName);
22939            }
22940            if (pkg.applicationInfo.uid != Binder.getCallingUid()
22941                    && Process.SYSTEM_UID != Binder.getCallingUid()) {
22942                throw new SecurityException("May not access signing KeySet of other apps.");
22943            }
22944            KeySetManagerService ksms = mSettings.mKeySetManagerService;
22945            return new KeySet(ksms.getSigningKeySetByPackageNameLPr(packageName));
22946        }
22947    }
22948
22949    @Override
22950    public boolean isPackageSignedByKeySet(String packageName, KeySet ks) {
22951        if (packageName == null || ks == null) {
22952            return false;
22953        }
22954        synchronized(mPackages) {
22955            final PackageParser.Package pkg = mPackages.get(packageName);
22956            if (pkg == null) {
22957                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
22958                throw new IllegalArgumentException("Unknown package: " + packageName);
22959            }
22960            IBinder ksh = ks.getToken();
22961            if (ksh instanceof KeySetHandle) {
22962                KeySetManagerService ksms = mSettings.mKeySetManagerService;
22963                return ksms.packageIsSignedByLPr(packageName, (KeySetHandle) ksh);
22964            }
22965            return false;
22966        }
22967    }
22968
22969    @Override
22970    public boolean isPackageSignedByKeySetExactly(String packageName, KeySet ks) {
22971        if (packageName == null || ks == null) {
22972            return false;
22973        }
22974        synchronized(mPackages) {
22975            final PackageParser.Package pkg = mPackages.get(packageName);
22976            if (pkg == null) {
22977                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
22978                throw new IllegalArgumentException("Unknown package: " + packageName);
22979            }
22980            IBinder ksh = ks.getToken();
22981            if (ksh instanceof KeySetHandle) {
22982                KeySetManagerService ksms = mSettings.mKeySetManagerService;
22983                return ksms.packageIsSignedByExactlyLPr(packageName, (KeySetHandle) ksh);
22984            }
22985            return false;
22986        }
22987    }
22988
22989    private void deletePackageIfUnusedLPr(final String packageName) {
22990        PackageSetting ps = mSettings.mPackages.get(packageName);
22991        if (ps == null) {
22992            return;
22993        }
22994        if (!ps.isAnyInstalled(sUserManager.getUserIds())) {
22995            // TODO Implement atomic delete if package is unused
22996            // It is currently possible that the package will be deleted even if it is installed
22997            // after this method returns.
22998            mHandler.post(new Runnable() {
22999                public void run() {
23000                    deletePackageX(packageName, PackageManager.VERSION_CODE_HIGHEST,
23001                            0, PackageManager.DELETE_ALL_USERS);
23002                }
23003            });
23004        }
23005    }
23006
23007    /**
23008     * Check and throw if the given before/after packages would be considered a
23009     * downgrade.
23010     */
23011    private static void checkDowngrade(PackageParser.Package before, PackageInfoLite after)
23012            throws PackageManagerException {
23013        if (after.versionCode < before.mVersionCode) {
23014            throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
23015                    "Update version code " + after.versionCode + " is older than current "
23016                    + before.mVersionCode);
23017        } else if (after.versionCode == before.mVersionCode) {
23018            if (after.baseRevisionCode < before.baseRevisionCode) {
23019                throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
23020                        "Update base revision code " + after.baseRevisionCode
23021                        + " is older than current " + before.baseRevisionCode);
23022            }
23023
23024            if (!ArrayUtils.isEmpty(after.splitNames)) {
23025                for (int i = 0; i < after.splitNames.length; i++) {
23026                    final String splitName = after.splitNames[i];
23027                    final int j = ArrayUtils.indexOf(before.splitNames, splitName);
23028                    if (j != -1) {
23029                        if (after.splitRevisionCodes[i] < before.splitRevisionCodes[j]) {
23030                            throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
23031                                    "Update split " + splitName + " revision code "
23032                                    + after.splitRevisionCodes[i] + " is older than current "
23033                                    + before.splitRevisionCodes[j]);
23034                        }
23035                    }
23036                }
23037            }
23038        }
23039    }
23040
23041    private static class MoveCallbacks extends Handler {
23042        private static final int MSG_CREATED = 1;
23043        private static final int MSG_STATUS_CHANGED = 2;
23044
23045        private final RemoteCallbackList<IPackageMoveObserver>
23046                mCallbacks = new RemoteCallbackList<>();
23047
23048        private final SparseIntArray mLastStatus = new SparseIntArray();
23049
23050        public MoveCallbacks(Looper looper) {
23051            super(looper);
23052        }
23053
23054        public void register(IPackageMoveObserver callback) {
23055            mCallbacks.register(callback);
23056        }
23057
23058        public void unregister(IPackageMoveObserver callback) {
23059            mCallbacks.unregister(callback);
23060        }
23061
23062        @Override
23063        public void handleMessage(Message msg) {
23064            final SomeArgs args = (SomeArgs) msg.obj;
23065            final int n = mCallbacks.beginBroadcast();
23066            for (int i = 0; i < n; i++) {
23067                final IPackageMoveObserver callback = mCallbacks.getBroadcastItem(i);
23068                try {
23069                    invokeCallback(callback, msg.what, args);
23070                } catch (RemoteException ignored) {
23071                }
23072            }
23073            mCallbacks.finishBroadcast();
23074            args.recycle();
23075        }
23076
23077        private void invokeCallback(IPackageMoveObserver callback, int what, SomeArgs args)
23078                throws RemoteException {
23079            switch (what) {
23080                case MSG_CREATED: {
23081                    callback.onCreated(args.argi1, (Bundle) args.arg2);
23082                    break;
23083                }
23084                case MSG_STATUS_CHANGED: {
23085                    callback.onStatusChanged(args.argi1, args.argi2, (long) args.arg3);
23086                    break;
23087                }
23088            }
23089        }
23090
23091        private void notifyCreated(int moveId, Bundle extras) {
23092            Slog.v(TAG, "Move " + moveId + " created " + extras.toString());
23093
23094            final SomeArgs args = SomeArgs.obtain();
23095            args.argi1 = moveId;
23096            args.arg2 = extras;
23097            obtainMessage(MSG_CREATED, args).sendToTarget();
23098        }
23099
23100        private void notifyStatusChanged(int moveId, int status) {
23101            notifyStatusChanged(moveId, status, -1);
23102        }
23103
23104        private void notifyStatusChanged(int moveId, int status, long estMillis) {
23105            Slog.v(TAG, "Move " + moveId + " status " + status);
23106
23107            final SomeArgs args = SomeArgs.obtain();
23108            args.argi1 = moveId;
23109            args.argi2 = status;
23110            args.arg3 = estMillis;
23111            obtainMessage(MSG_STATUS_CHANGED, args).sendToTarget();
23112
23113            synchronized (mLastStatus) {
23114                mLastStatus.put(moveId, status);
23115            }
23116        }
23117    }
23118
23119    private final static class OnPermissionChangeListeners extends Handler {
23120        private static final int MSG_ON_PERMISSIONS_CHANGED = 1;
23121
23122        private final RemoteCallbackList<IOnPermissionsChangeListener> mPermissionListeners =
23123                new RemoteCallbackList<>();
23124
23125        public OnPermissionChangeListeners(Looper looper) {
23126            super(looper);
23127        }
23128
23129        @Override
23130        public void handleMessage(Message msg) {
23131            switch (msg.what) {
23132                case MSG_ON_PERMISSIONS_CHANGED: {
23133                    final int uid = msg.arg1;
23134                    handleOnPermissionsChanged(uid);
23135                } break;
23136            }
23137        }
23138
23139        public void addListenerLocked(IOnPermissionsChangeListener listener) {
23140            mPermissionListeners.register(listener);
23141
23142        }
23143
23144        public void removeListenerLocked(IOnPermissionsChangeListener listener) {
23145            mPermissionListeners.unregister(listener);
23146        }
23147
23148        public void onPermissionsChanged(int uid) {
23149            if (mPermissionListeners.getRegisteredCallbackCount() > 0) {
23150                obtainMessage(MSG_ON_PERMISSIONS_CHANGED, uid, 0).sendToTarget();
23151            }
23152        }
23153
23154        private void handleOnPermissionsChanged(int uid) {
23155            final int count = mPermissionListeners.beginBroadcast();
23156            try {
23157                for (int i = 0; i < count; i++) {
23158                    IOnPermissionsChangeListener callback = mPermissionListeners
23159                            .getBroadcastItem(i);
23160                    try {
23161                        callback.onPermissionsChanged(uid);
23162                    } catch (RemoteException e) {
23163                        Log.e(TAG, "Permission listener is dead", e);
23164                    }
23165                }
23166            } finally {
23167                mPermissionListeners.finishBroadcast();
23168            }
23169        }
23170    }
23171
23172    private class PackageManagerInternalImpl extends PackageManagerInternal {
23173        @Override
23174        public void setLocationPackagesProvider(PackagesProvider provider) {
23175            synchronized (mPackages) {
23176                mDefaultPermissionPolicy.setLocationPackagesProviderLPw(provider);
23177            }
23178        }
23179
23180        @Override
23181        public void setVoiceInteractionPackagesProvider(PackagesProvider provider) {
23182            synchronized (mPackages) {
23183                mDefaultPermissionPolicy.setVoiceInteractionPackagesProviderLPw(provider);
23184            }
23185        }
23186
23187        @Override
23188        public void setSmsAppPackagesProvider(PackagesProvider provider) {
23189            synchronized (mPackages) {
23190                mDefaultPermissionPolicy.setSmsAppPackagesProviderLPw(provider);
23191            }
23192        }
23193
23194        @Override
23195        public void setDialerAppPackagesProvider(PackagesProvider provider) {
23196            synchronized (mPackages) {
23197                mDefaultPermissionPolicy.setDialerAppPackagesProviderLPw(provider);
23198            }
23199        }
23200
23201        @Override
23202        public void setSimCallManagerPackagesProvider(PackagesProvider provider) {
23203            synchronized (mPackages) {
23204                mDefaultPermissionPolicy.setSimCallManagerPackagesProviderLPw(provider);
23205            }
23206        }
23207
23208        @Override
23209        public void setSyncAdapterPackagesprovider(SyncAdapterPackagesProvider provider) {
23210            synchronized (mPackages) {
23211                mDefaultPermissionPolicy.setSyncAdapterPackagesProviderLPw(provider);
23212            }
23213        }
23214
23215        @Override
23216        public void grantDefaultPermissionsToDefaultSmsApp(String packageName, int userId) {
23217            synchronized (mPackages) {
23218                mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSmsAppLPr(
23219                        packageName, userId);
23220            }
23221        }
23222
23223        @Override
23224        public void grantDefaultPermissionsToDefaultDialerApp(String packageName, int userId) {
23225            synchronized (mPackages) {
23226                mSettings.setDefaultDialerPackageNameLPw(packageName, userId);
23227                mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultDialerAppLPr(
23228                        packageName, userId);
23229            }
23230        }
23231
23232        @Override
23233        public void grantDefaultPermissionsToDefaultSimCallManager(String packageName, int userId) {
23234            synchronized (mPackages) {
23235                mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSimCallManagerLPr(
23236                        packageName, userId);
23237            }
23238        }
23239
23240        @Override
23241        public void setKeepUninstalledPackages(final List<String> packageList) {
23242            Preconditions.checkNotNull(packageList);
23243            List<String> removedFromList = null;
23244            synchronized (mPackages) {
23245                if (mKeepUninstalledPackages != null) {
23246                    final int packagesCount = mKeepUninstalledPackages.size();
23247                    for (int i = 0; i < packagesCount; i++) {
23248                        String oldPackage = mKeepUninstalledPackages.get(i);
23249                        if (packageList != null && packageList.contains(oldPackage)) {
23250                            continue;
23251                        }
23252                        if (removedFromList == null) {
23253                            removedFromList = new ArrayList<>();
23254                        }
23255                        removedFromList.add(oldPackage);
23256                    }
23257                }
23258                mKeepUninstalledPackages = new ArrayList<>(packageList);
23259                if (removedFromList != null) {
23260                    final int removedCount = removedFromList.size();
23261                    for (int i = 0; i < removedCount; i++) {
23262                        deletePackageIfUnusedLPr(removedFromList.get(i));
23263                    }
23264                }
23265            }
23266        }
23267
23268        @Override
23269        public boolean isPermissionsReviewRequired(String packageName, int userId) {
23270            synchronized (mPackages) {
23271                // If we do not support permission review, done.
23272                if (!mPermissionReviewRequired) {
23273                    return false;
23274                }
23275
23276                PackageSetting packageSetting = mSettings.mPackages.get(packageName);
23277                if (packageSetting == null) {
23278                    return false;
23279                }
23280
23281                // Permission review applies only to apps not supporting the new permission model.
23282                if (packageSetting.pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.M) {
23283                    return false;
23284                }
23285
23286                // Legacy apps have the permission and get user consent on launch.
23287                PermissionsState permissionsState = packageSetting.getPermissionsState();
23288                return permissionsState.isPermissionReviewRequired(userId);
23289            }
23290        }
23291
23292        @Override
23293        public ApplicationInfo getApplicationInfo(String packageName, int userId) {
23294            return PackageManagerService.this.getApplicationInfo(packageName, 0 /*flags*/, userId);
23295        }
23296
23297        @Override
23298        public ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates,
23299                int userId) {
23300            return PackageManagerService.this.getHomeActivitiesAsUser(allHomeCandidates, userId);
23301        }
23302
23303        @Override
23304        public void setDeviceAndProfileOwnerPackages(
23305                int deviceOwnerUserId, String deviceOwnerPackage,
23306                SparseArray<String> profileOwnerPackages) {
23307            mProtectedPackages.setDeviceAndProfileOwnerPackages(
23308                    deviceOwnerUserId, deviceOwnerPackage, profileOwnerPackages);
23309        }
23310
23311        @Override
23312        public boolean isPackageDataProtected(int userId, String packageName) {
23313            return mProtectedPackages.isPackageDataProtected(userId, packageName);
23314        }
23315
23316        @Override
23317        public boolean isPackageEphemeral(int userId, String packageName) {
23318            synchronized (mPackages) {
23319                final PackageSetting ps = mSettings.mPackages.get(packageName);
23320                return ps != null ? ps.getInstantApp(userId) : false;
23321            }
23322        }
23323
23324        @Override
23325        public boolean wasPackageEverLaunched(String packageName, int userId) {
23326            synchronized (mPackages) {
23327                return mSettings.wasPackageEverLaunchedLPr(packageName, userId);
23328            }
23329        }
23330
23331        @Override
23332        public void grantRuntimePermission(String packageName, String name, int userId,
23333                boolean overridePolicy) {
23334            PackageManagerService.this.grantRuntimePermission(packageName, name, userId,
23335                    overridePolicy);
23336        }
23337
23338        @Override
23339        public void revokeRuntimePermission(String packageName, String name, int userId,
23340                boolean overridePolicy) {
23341            PackageManagerService.this.revokeRuntimePermission(packageName, name, userId,
23342                    overridePolicy);
23343        }
23344
23345        @Override
23346        public String getNameForUid(int uid) {
23347            return PackageManagerService.this.getNameForUid(uid);
23348        }
23349
23350        @Override
23351        public void requestInstantAppResolutionPhaseTwo(AuxiliaryResolveInfo responseObj,
23352                Intent origIntent, String resolvedType, String callingPackage, int userId) {
23353            PackageManagerService.this.requestInstantAppResolutionPhaseTwo(
23354                    responseObj, origIntent, resolvedType, callingPackage, userId);
23355        }
23356
23357        @Override
23358        public void grantEphemeralAccess(int userId, Intent intent,
23359                int targetAppId, int ephemeralAppId) {
23360            synchronized (mPackages) {
23361                mInstantAppRegistry.grantInstantAccessLPw(userId, intent,
23362                        targetAppId, ephemeralAppId);
23363            }
23364        }
23365
23366        @Override
23367        public boolean isInstantAppInstallerComponent(ComponentName component) {
23368            synchronized (mPackages) {
23369                return mInstantAppInstallerActivity != null
23370                        && mInstantAppInstallerActivity.getComponentName().equals(component);
23371            }
23372        }
23373
23374        @Override
23375        public void pruneInstantApps() {
23376            synchronized (mPackages) {
23377                mInstantAppRegistry.pruneInstantAppsLPw();
23378            }
23379        }
23380
23381        @Override
23382        public String getSetupWizardPackageName() {
23383            return mSetupWizardPackage;
23384        }
23385
23386        public void setExternalSourcesPolicy(ExternalSourcesPolicy policy) {
23387            if (policy != null) {
23388                mExternalSourcesPolicy = policy;
23389            }
23390        }
23391
23392        @Override
23393        public boolean isPackagePersistent(String packageName) {
23394            synchronized (mPackages) {
23395                PackageParser.Package pkg = mPackages.get(packageName);
23396                return pkg != null
23397                        ? ((pkg.applicationInfo.flags&(ApplicationInfo.FLAG_SYSTEM
23398                                        | ApplicationInfo.FLAG_PERSISTENT)) ==
23399                                (ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_PERSISTENT))
23400                        : false;
23401            }
23402        }
23403
23404        @Override
23405        public List<PackageInfo> getOverlayPackages(int userId) {
23406            final ArrayList<PackageInfo> overlayPackages = new ArrayList<PackageInfo>();
23407            synchronized (mPackages) {
23408                for (PackageParser.Package p : mPackages.values()) {
23409                    if (p.mOverlayTarget != null) {
23410                        PackageInfo pkg = generatePackageInfo((PackageSetting)p.mExtras, 0, userId);
23411                        if (pkg != null) {
23412                            overlayPackages.add(pkg);
23413                        }
23414                    }
23415                }
23416            }
23417            return overlayPackages;
23418        }
23419
23420        @Override
23421        public List<String> getTargetPackageNames(int userId) {
23422            List<String> targetPackages = new ArrayList<>();
23423            synchronized (mPackages) {
23424                for (PackageParser.Package p : mPackages.values()) {
23425                    if (p.mOverlayTarget == null) {
23426                        targetPackages.add(p.packageName);
23427                    }
23428                }
23429            }
23430            return targetPackages;
23431        }
23432
23433        @Override
23434        public boolean setEnabledOverlayPackages(int userId, @NonNull String targetPackageName,
23435                @Nullable List<String> overlayPackageNames) {
23436            synchronized (mPackages) {
23437                if (targetPackageName == null || mPackages.get(targetPackageName) == null) {
23438                    Slog.e(TAG, "failed to find package " + targetPackageName);
23439                    return false;
23440                }
23441
23442                ArrayList<String> paths = null;
23443                if (overlayPackageNames != null) {
23444                    final int N = overlayPackageNames.size();
23445                    paths = new ArrayList<>(N);
23446                    for (int i = 0; i < N; i++) {
23447                        final String packageName = overlayPackageNames.get(i);
23448                        final PackageParser.Package pkg = mPackages.get(packageName);
23449                        if (pkg == null) {
23450                            Slog.e(TAG, "failed to find package " + packageName);
23451                            return false;
23452                        }
23453                        paths.add(pkg.baseCodePath);
23454                    }
23455                }
23456
23457                ArrayMap<String, ArrayList<String>> userSpecificOverlays =
23458                    mEnabledOverlayPaths.get(userId);
23459                if (userSpecificOverlays == null) {
23460                    userSpecificOverlays = new ArrayMap<>();
23461                    mEnabledOverlayPaths.put(userId, userSpecificOverlays);
23462                }
23463
23464                if (paths != null && paths.size() > 0) {
23465                    userSpecificOverlays.put(targetPackageName, paths);
23466                } else {
23467                    userSpecificOverlays.remove(targetPackageName);
23468                }
23469                return true;
23470            }
23471        }
23472
23473        @Override
23474        public ResolveInfo resolveIntent(Intent intent, String resolvedType,
23475                int flags, int userId) {
23476            return resolveIntentInternal(
23477                    intent, resolvedType, flags, userId, true /*includeInstantApps*/);
23478        }
23479
23480        @Override
23481        public ResolveInfo resolveService(Intent intent, String resolvedType,
23482                int flags, int userId, int callingUid) {
23483            return resolveServiceInternal(
23484                    intent, resolvedType, flags, userId, callingUid, true /*includeInstantApps*/);
23485        }
23486
23487        @Override
23488        public void addIsolatedUid(int isolatedUid, int ownerUid) {
23489            synchronized (mPackages) {
23490                mIsolatedOwners.put(isolatedUid, ownerUid);
23491            }
23492        }
23493
23494        @Override
23495        public void removeIsolatedUid(int isolatedUid) {
23496            synchronized (mPackages) {
23497                mIsolatedOwners.delete(isolatedUid);
23498            }
23499        }
23500    }
23501
23502    @Override
23503    public void grantDefaultPermissionsToEnabledCarrierApps(String[] packageNames, int userId) {
23504        enforceSystemOrPhoneCaller("grantPermissionsToEnabledCarrierApps");
23505        synchronized (mPackages) {
23506            final long identity = Binder.clearCallingIdentity();
23507            try {
23508                mDefaultPermissionPolicy.grantDefaultPermissionsToEnabledCarrierAppsLPr(
23509                        packageNames, userId);
23510            } finally {
23511                Binder.restoreCallingIdentity(identity);
23512            }
23513        }
23514    }
23515
23516    @Override
23517    public void grantDefaultPermissionsToEnabledImsServices(String[] packageNames, int userId) {
23518        enforceSystemOrPhoneCaller("grantDefaultPermissionsToEnabledImsServices");
23519        synchronized (mPackages) {
23520            final long identity = Binder.clearCallingIdentity();
23521            try {
23522                mDefaultPermissionPolicy.grantDefaultPermissionsToEnabledImsServicesLPr(
23523                        packageNames, userId);
23524            } finally {
23525                Binder.restoreCallingIdentity(identity);
23526            }
23527        }
23528    }
23529
23530    private static void enforceSystemOrPhoneCaller(String tag) {
23531        int callingUid = Binder.getCallingUid();
23532        if (callingUid != Process.PHONE_UID && callingUid != Process.SYSTEM_UID) {
23533            throw new SecurityException(
23534                    "Cannot call " + tag + " from UID " + callingUid);
23535        }
23536    }
23537
23538    boolean isHistoricalPackageUsageAvailable() {
23539        return mPackageUsage.isHistoricalPackageUsageAvailable();
23540    }
23541
23542    /**
23543     * Return a <b>copy</b> of the collection of packages known to the package manager.
23544     * @return A copy of the values of mPackages.
23545     */
23546    Collection<PackageParser.Package> getPackages() {
23547        synchronized (mPackages) {
23548            return new ArrayList<>(mPackages.values());
23549        }
23550    }
23551
23552    /**
23553     * Logs process start information (including base APK hash) to the security log.
23554     * @hide
23555     */
23556    public void logAppProcessStartIfNeeded(String processName, int uid, String seinfo,
23557            String apkFile, int pid) {
23558        if (!SecurityLog.isLoggingEnabled()) {
23559            return;
23560        }
23561        Bundle data = new Bundle();
23562        data.putLong("startTimestamp", System.currentTimeMillis());
23563        data.putString("processName", processName);
23564        data.putInt("uid", uid);
23565        data.putString("seinfo", seinfo);
23566        data.putString("apkFile", apkFile);
23567        data.putInt("pid", pid);
23568        Message msg = mProcessLoggingHandler.obtainMessage(
23569                ProcessLoggingHandler.LOG_APP_PROCESS_START_MSG);
23570        msg.setData(data);
23571        mProcessLoggingHandler.sendMessage(msg);
23572    }
23573
23574    public CompilerStats.PackageStats getCompilerPackageStats(String pkgName) {
23575        return mCompilerStats.getPackageStats(pkgName);
23576    }
23577
23578    public CompilerStats.PackageStats getOrCreateCompilerPackageStats(PackageParser.Package pkg) {
23579        return getOrCreateCompilerPackageStats(pkg.packageName);
23580    }
23581
23582    public CompilerStats.PackageStats getOrCreateCompilerPackageStats(String pkgName) {
23583        return mCompilerStats.getOrCreatePackageStats(pkgName);
23584    }
23585
23586    public void deleteCompilerPackageStats(String pkgName) {
23587        mCompilerStats.deletePackageStats(pkgName);
23588    }
23589
23590    @Override
23591    public int getInstallReason(String packageName, int userId) {
23592        enforceCrossUserPermission(Binder.getCallingUid(), userId,
23593                true /* requireFullPermission */, false /* checkShell */,
23594                "get install reason");
23595        synchronized (mPackages) {
23596            final PackageSetting ps = mSettings.mPackages.get(packageName);
23597            if (ps != null) {
23598                return ps.getInstallReason(userId);
23599            }
23600        }
23601        return PackageManager.INSTALL_REASON_UNKNOWN;
23602    }
23603
23604    @Override
23605    public boolean canRequestPackageInstalls(String packageName, int userId) {
23606        int callingUid = Binder.getCallingUid();
23607        int uid = getPackageUid(packageName, 0, userId);
23608        if (callingUid != uid && callingUid != Process.ROOT_UID
23609                && callingUid != Process.SYSTEM_UID) {
23610            throw new SecurityException(
23611                    "Caller uid " + callingUid + " does not own package " + packageName);
23612        }
23613        ApplicationInfo info = getApplicationInfo(packageName, 0, userId);
23614        if (info == null) {
23615            return false;
23616        }
23617        if (info.targetSdkVersion < Build.VERSION_CODES.O) {
23618            throw new UnsupportedOperationException(
23619                    "Operation only supported on apps targeting Android O or higher");
23620        }
23621        String appOpPermission = Manifest.permission.REQUEST_INSTALL_PACKAGES;
23622        String[] packagesDeclaringPermission = getAppOpPermissionPackages(appOpPermission);
23623        if (!ArrayUtils.contains(packagesDeclaringPermission, packageName)) {
23624            throw new SecurityException("Need to declare " + appOpPermission + " to call this api");
23625        }
23626        if (sUserManager.hasUserRestriction(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, userId)) {
23627            return false;
23628        }
23629        if (mExternalSourcesPolicy != null) {
23630            int isTrusted = mExternalSourcesPolicy.getPackageTrustedToInstallApps(packageName, uid);
23631            if (isTrusted != PackageManagerInternal.ExternalSourcesPolicy.USER_DEFAULT) {
23632                return isTrusted == PackageManagerInternal.ExternalSourcesPolicy.USER_TRUSTED;
23633            }
23634        }
23635        return checkUidPermission(appOpPermission, uid) == PERMISSION_GRANTED;
23636    }
23637
23638    @Override
23639    public ComponentName getInstantAppResolverSettingsComponent() {
23640        return mInstantAppResolverSettingsComponent;
23641    }
23642
23643    @Override
23644    public ComponentName getInstantAppInstallerComponent() {
23645        return mInstantAppInstallerActivity == null
23646                ? null : mInstantAppInstallerActivity.getComponentName();
23647    }
23648}
23649