PackageManagerService.java revision 68f68701e69ceed0edb0e8831ce2ed507ba154a5
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_EPHEMERAL_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.Installer.DEXOPT_PUBLIC;
94import static com.android.server.pm.InstructionSets.getAppDexInstructionSets;
95import static com.android.server.pm.InstructionSets.getDexCodeInstructionSet;
96import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets;
97import static com.android.server.pm.InstructionSets.getPreferredInstructionSet;
98import static com.android.server.pm.InstructionSets.getPrimaryInstructionSet;
99import static com.android.server.pm.PackageManagerServiceCompilerMapping.getCompilerFilterForReason;
100import static com.android.server.pm.PackageManagerServiceCompilerMapping.getFullCompilerFilter;
101import static com.android.server.pm.PackageManagerServiceCompilerMapping.getNonProfileGuidedCompilerFilter;
102import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_FAILURE;
103import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_SUCCESS;
104import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED;
105
106import android.Manifest;
107import android.annotation.NonNull;
108import android.annotation.Nullable;
109import android.app.ActivityManager;
110import android.app.AppOpsManager;
111import android.app.IActivityManager;
112import android.app.ResourcesManager;
113import android.app.admin.IDevicePolicyManager;
114import android.app.admin.SecurityLog;
115import android.app.backup.IBackupManager;
116import android.content.BroadcastReceiver;
117import android.content.ComponentName;
118import android.content.ContentResolver;
119import android.content.Context;
120import android.content.IIntentReceiver;
121import android.content.Intent;
122import android.content.IntentFilter;
123import android.content.IntentSender;
124import android.content.IntentSender.SendIntentException;
125import android.content.ServiceConnection;
126import android.content.pm.ActivityInfo;
127import android.content.pm.ApplicationInfo;
128import android.content.pm.AppsQueryHelper;
129import android.content.pm.ComponentInfo;
130import android.content.pm.InstantAppInfo;
131import android.content.pm.EphemeralRequest;
132import android.content.pm.EphemeralResolveInfo;
133import android.content.pm.EphemeralResponse;
134import android.content.pm.FallbackCategoryProvider;
135import android.content.pm.FeatureInfo;
136import android.content.pm.IOnPermissionsChangeListener;
137import android.content.pm.IPackageDataObserver;
138import android.content.pm.IPackageDeleteObserver;
139import android.content.pm.IPackageDeleteObserver2;
140import android.content.pm.IPackageInstallObserver2;
141import android.content.pm.IPackageInstaller;
142import android.content.pm.IPackageManager;
143import android.content.pm.IPackageMoveObserver;
144import android.content.pm.IPackageStatsObserver;
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.graphics.Bitmap;
175import android.hardware.display.DisplayManager;
176import android.net.Uri;
177import android.os.Binder;
178import android.os.Build;
179import android.os.Bundle;
180import android.os.Debug;
181import android.os.Environment;
182import android.os.Environment.UserEnvironment;
183import android.os.FileUtils;
184import android.os.Handler;
185import android.os.IBinder;
186import android.os.Looper;
187import android.os.Message;
188import android.os.Parcel;
189import android.os.ParcelFileDescriptor;
190import android.os.PatternMatcher;
191import android.os.Process;
192import android.os.RemoteCallbackList;
193import android.os.RemoteException;
194import android.os.ResultReceiver;
195import android.os.SELinux;
196import android.os.ServiceManager;
197import android.os.ShellCallback;
198import android.os.SystemClock;
199import android.os.SystemProperties;
200import android.os.Trace;
201import android.os.UserHandle;
202import android.os.UserManager;
203import android.os.UserManagerInternal;
204import android.os.storage.IStorageManager;
205import android.os.storage.StorageManagerInternal;
206import android.os.storage.StorageEventListener;
207import android.os.storage.StorageManager;
208import android.os.storage.VolumeInfo;
209import android.os.storage.VolumeRecord;
210import android.provider.Settings.Global;
211import android.provider.Settings.Secure;
212import android.security.KeyStore;
213import android.security.SystemKeyStore;
214import android.system.ErrnoException;
215import android.system.Os;
216import android.text.TextUtils;
217import android.text.format.DateUtils;
218import android.util.ArrayMap;
219import android.util.ArraySet;
220import android.util.Base64;
221import android.util.DisplayMetrics;
222import android.util.EventLog;
223import android.util.ExceptionUtils;
224import android.util.Log;
225import android.util.LogPrinter;
226import android.util.MathUtils;
227import android.util.PackageUtils;
228import android.util.Pair;
229import android.util.PrintStreamPrinter;
230import android.util.Slog;
231import android.util.SparseArray;
232import android.util.SparseBooleanArray;
233import android.util.SparseIntArray;
234import android.util.Xml;
235import android.util.jar.StrictJarFile;
236import android.view.Display;
237
238import com.android.internal.R;
239import com.android.internal.annotations.GuardedBy;
240import com.android.internal.app.IMediaContainerService;
241import com.android.internal.app.ResolverActivity;
242import com.android.internal.content.NativeLibraryHelper;
243import com.android.internal.content.PackageHelper;
244import com.android.internal.logging.MetricsLogger;
245import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
246import com.android.internal.os.IParcelFileDescriptorFactory;
247import com.android.internal.os.RoSystemProperties;
248import com.android.internal.os.SomeArgs;
249import com.android.internal.os.Zygote;
250import com.android.internal.telephony.CarrierAppUtils;
251import com.android.internal.util.ArrayUtils;
252import com.android.internal.util.FastPrintWriter;
253import com.android.internal.util.FastXmlSerializer;
254import com.android.internal.util.IndentingPrintWriter;
255import com.android.internal.util.Preconditions;
256import com.android.internal.util.XmlUtils;
257import com.android.server.AttributeCache;
258import com.android.server.BackgroundDexOptJobService;
259import com.android.server.EventLogTags;
260import com.android.server.FgThread;
261import com.android.server.IntentResolver;
262import com.android.server.LocalServices;
263import com.android.server.ServiceThread;
264import com.android.server.SystemConfig;
265import com.android.server.Watchdog;
266import com.android.server.net.NetworkPolicyManagerInternal;
267import com.android.server.pm.Installer.InstallerException;
268import com.android.server.pm.PermissionsState.PermissionState;
269import com.android.server.pm.Settings.DatabaseVersion;
270import com.android.server.pm.Settings.VersionInfo;
271import com.android.server.pm.dex.DexManager;
272import com.android.server.storage.DeviceStorageMonitorInternal;
273
274import dalvik.system.CloseGuard;
275import dalvik.system.DexFile;
276import dalvik.system.VMRuntime;
277
278import libcore.io.IoUtils;
279import libcore.util.EmptyArray;
280
281import org.xmlpull.v1.XmlPullParser;
282import org.xmlpull.v1.XmlPullParserException;
283import org.xmlpull.v1.XmlSerializer;
284
285import java.io.BufferedOutputStream;
286import java.io.BufferedReader;
287import java.io.ByteArrayInputStream;
288import java.io.ByteArrayOutputStream;
289import java.io.File;
290import java.io.FileDescriptor;
291import java.io.FileInputStream;
292import java.io.FileNotFoundException;
293import java.io.FileOutputStream;
294import java.io.FileReader;
295import java.io.FilenameFilter;
296import java.io.IOException;
297import java.io.PrintWriter;
298import java.nio.charset.StandardCharsets;
299import java.security.DigestInputStream;
300import java.security.MessageDigest;
301import java.security.NoSuchAlgorithmException;
302import java.security.PublicKey;
303import java.security.SecureRandom;
304import java.security.cert.Certificate;
305import java.security.cert.CertificateEncodingException;
306import java.security.cert.CertificateException;
307import java.text.SimpleDateFormat;
308import java.util.ArrayList;
309import java.util.Arrays;
310import java.util.Collection;
311import java.util.Collections;
312import java.util.Comparator;
313import java.util.Date;
314import java.util.HashSet;
315import java.util.HashMap;
316import java.util.Iterator;
317import java.util.List;
318import java.util.Map;
319import java.util.Objects;
320import java.util.Set;
321import java.util.concurrent.CountDownLatch;
322import java.util.concurrent.TimeUnit;
323import java.util.concurrent.atomic.AtomicBoolean;
324import java.util.concurrent.atomic.AtomicInteger;
325
326/**
327 * Keep track of all those APKs everywhere.
328 * <p>
329 * Internally there are two important locks:
330 * <ul>
331 * <li>{@link #mPackages} is used to guard all in-memory parsed package details
332 * and other related state. It is a fine-grained lock that should only be held
333 * momentarily, as it's one of the most contended locks in the system.
334 * <li>{@link #mInstallLock} is used to guard all {@code installd} access, whose
335 * operations typically involve heavy lifting of application data on disk. Since
336 * {@code installd} is single-threaded, and it's operations can often be slow,
337 * this lock should never be acquired while already holding {@link #mPackages}.
338 * Conversely, it's safe to acquire {@link #mPackages} momentarily while already
339 * holding {@link #mInstallLock}.
340 * </ul>
341 * Many internal methods rely on the caller to hold the appropriate locks, and
342 * this contract is expressed through method name suffixes:
343 * <ul>
344 * <li>fooLI(): the caller must hold {@link #mInstallLock}
345 * <li>fooLIF(): the caller must hold {@link #mInstallLock} and the package
346 * being modified must be frozen
347 * <li>fooLPr(): the caller must hold {@link #mPackages} for reading
348 * <li>fooLPw(): the caller must hold {@link #mPackages} for writing
349 * </ul>
350 * <p>
351 * Because this class is very central to the platform's security; please run all
352 * CTS and unit tests whenever making modifications:
353 *
354 * <pre>
355 * $ runtest -c android.content.pm.PackageManagerTests frameworks-core
356 * $ cts-tradefed run commandAndExit cts -m CtsAppSecurityHostTestCases
357 * </pre>
358 */
359public class PackageManagerService extends IPackageManager.Stub {
360    static final String TAG = "PackageManager";
361    static final boolean DEBUG_SETTINGS = false;
362    static final boolean DEBUG_PREFERRED = false;
363    static final boolean DEBUG_UPGRADE = false;
364    static final boolean DEBUG_DOMAIN_VERIFICATION = false;
365    private static final boolean DEBUG_BACKUP = false;
366    private static final boolean DEBUG_INSTALL = false;
367    private static final boolean DEBUG_REMOVE = false;
368    private static final boolean DEBUG_BROADCASTS = false;
369    private static final boolean DEBUG_SHOW_INFO = false;
370    private static final boolean DEBUG_PACKAGE_INFO = false;
371    private static final boolean DEBUG_INTENT_MATCHING = false;
372    private static final boolean DEBUG_PACKAGE_SCANNING = false;
373    private static final boolean DEBUG_VERIFY = false;
374    private static final boolean DEBUG_FILTERS = false;
375
376    // Debug output for dexopting. This is shared between PackageManagerService, OtaDexoptService
377    // and PackageDexOptimizer. All these classes have their own flag to allow switching a single
378    // user, but by default initialize to this.
379    public static final boolean DEBUG_DEXOPT = false;
380
381    private static final boolean DEBUG_ABI_SELECTION = false;
382    private static final boolean DEBUG_EPHEMERAL = Build.IS_DEBUGGABLE;
383    private static final boolean DEBUG_TRIAGED_MISSING = false;
384    private static final boolean DEBUG_APP_DATA = false;
385
386    /** REMOVE. According to Svet, this was only used to reset permissions during development. */
387    static final boolean CLEAR_RUNTIME_PERMISSIONS_ON_UPGRADE = false;
388
389    private static final boolean DISABLE_EPHEMERAL_APPS = false;
390    private static final boolean HIDE_EPHEMERAL_APIS = false;
391
392    private static final boolean ENABLE_QUOTA =
393            SystemProperties.getBoolean("persist.fw.quota", false);
394
395    private static final int RADIO_UID = Process.PHONE_UID;
396    private static final int LOG_UID = Process.LOG_UID;
397    private static final int NFC_UID = Process.NFC_UID;
398    private static final int BLUETOOTH_UID = Process.BLUETOOTH_UID;
399    private static final int SHELL_UID = Process.SHELL_UID;
400
401    // Cap the size of permission trees that 3rd party apps can define
402    private static final int MAX_PERMISSION_TREE_FOOTPRINT = 32768;     // characters of text
403
404    // Suffix used during package installation when copying/moving
405    // package apks to install directory.
406    private static final String INSTALL_PACKAGE_SUFFIX = "-";
407
408    static final int SCAN_NO_DEX = 1<<1;
409    static final int SCAN_FORCE_DEX = 1<<2;
410    static final int SCAN_UPDATE_SIGNATURE = 1<<3;
411    static final int SCAN_NEW_INSTALL = 1<<4;
412    static final int SCAN_UPDATE_TIME = 1<<5;
413    static final int SCAN_BOOTING = 1<<6;
414    static final int SCAN_TRUSTED_OVERLAY = 1<<7;
415    static final int SCAN_DELETE_DATA_ON_FAILURES = 1<<8;
416    static final int SCAN_REPLACING = 1<<9;
417    static final int SCAN_REQUIRE_KNOWN = 1<<10;
418    static final int SCAN_MOVE = 1<<11;
419    static final int SCAN_INITIAL = 1<<12;
420    static final int SCAN_CHECK_ONLY = 1<<13;
421    static final int SCAN_DONT_KILL_APP = 1<<14;
422    static final int SCAN_IGNORE_FROZEN = 1<<15;
423    static final int REMOVE_CHATTY = 1<<16;
424    static final int SCAN_FIRST_BOOT_OR_UPGRADE = 1<<17;
425
426    private static final String STATIC_SHARED_LIB_DELIMITER = "_";
427
428    private static final int[] EMPTY_INT_ARRAY = new int[0];
429
430    /**
431     * Timeout (in milliseconds) after which the watchdog should declare that
432     * our handler thread is wedged.  The usual default for such things is one
433     * minute but we sometimes do very lengthy I/O operations on this thread,
434     * such as installing multi-gigabyte applications, so ours needs to be longer.
435     */
436    private static final long WATCHDOG_TIMEOUT = 1000*60*10;     // ten minutes
437
438    /**
439     * Wall-clock timeout (in milliseconds) after which we *require* that an fstrim
440     * be run on this device.  We use the value in the Settings.Global.MANDATORY_FSTRIM_INTERVAL
441     * settings entry if available, otherwise we use the hardcoded default.  If it's been
442     * more than this long since the last fstrim, we force one during the boot sequence.
443     *
444     * This backstops other fstrim scheduling:  if the device is alive at midnight+idle,
445     * one gets run at the next available charging+idle time.  This final mandatory
446     * no-fstrim check kicks in only of the other scheduling criteria is never met.
447     */
448    private static final long DEFAULT_MANDATORY_FSTRIM_INTERVAL = 3 * DateUtils.DAY_IN_MILLIS;
449
450    /**
451     * Whether verification is enabled by default.
452     */
453    private static final boolean DEFAULT_VERIFY_ENABLE = true;
454
455    /**
456     * The default maximum time to wait for the verification agent to return in
457     * milliseconds.
458     */
459    private static final long DEFAULT_VERIFICATION_TIMEOUT = 10 * 1000;
460
461    /**
462     * The default response for package verification timeout.
463     *
464     * This can be either PackageManager.VERIFICATION_ALLOW or
465     * PackageManager.VERIFICATION_REJECT.
466     */
467    private static final int DEFAULT_VERIFICATION_RESPONSE = PackageManager.VERIFICATION_ALLOW;
468
469    static final String PLATFORM_PACKAGE_NAME = "android";
470
471    static final String DEFAULT_CONTAINER_PACKAGE = "com.android.defcontainer";
472
473    static final ComponentName DEFAULT_CONTAINER_COMPONENT = new ComponentName(
474            DEFAULT_CONTAINER_PACKAGE,
475            "com.android.defcontainer.DefaultContainerService");
476
477    private static final String KILL_APP_REASON_GIDS_CHANGED =
478            "permission grant or revoke changed gids";
479
480    private static final String KILL_APP_REASON_PERMISSIONS_REVOKED =
481            "permissions revoked";
482
483    private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive";
484
485    private static final String PACKAGE_SCHEME = "package";
486
487    private static final String VENDOR_OVERLAY_DIR = "/vendor/overlay";
488    /**
489     * If VENDOR_OVERLAY_THEME_PROPERTY is set, search for runtime resource overlay APKs also in
490     * VENDOR_OVERLAY_DIR/<value of VENDOR_OVERLAY_THEME_PROPERTY> in addition to
491     * VENDOR_OVERLAY_DIR.
492     */
493    private static final String VENDOR_OVERLAY_THEME_PROPERTY = "ro.boot.vendor.overlay.theme";
494    /**
495     * Same as VENDOR_OVERLAY_THEME_PROPERTY, except persistent. If set will override whatever
496     * is in VENDOR_OVERLAY_THEME_PROPERTY.
497     */
498    private static final String VENDOR_OVERLAY_THEME_PERSIST_PROPERTY
499            = "persist.vendor.overlay.theme";
500
501    /** Permission grant: not grant the permission. */
502    private static final int GRANT_DENIED = 1;
503
504    /** Permission grant: grant the permission as an install permission. */
505    private static final int GRANT_INSTALL = 2;
506
507    /** Permission grant: grant the permission as a runtime one. */
508    private static final int GRANT_RUNTIME = 3;
509
510    /** Permission grant: grant as runtime a permission that was granted as an install time one. */
511    private static final int GRANT_UPGRADE = 4;
512
513    /** Canonical intent used to identify what counts as a "web browser" app */
514    private static final Intent sBrowserIntent;
515    static {
516        sBrowserIntent = new Intent();
517        sBrowserIntent.setAction(Intent.ACTION_VIEW);
518        sBrowserIntent.addCategory(Intent.CATEGORY_BROWSABLE);
519        sBrowserIntent.setData(Uri.parse("http:"));
520    }
521
522    /**
523     * The set of all protected actions [i.e. those actions for which a high priority
524     * intent filter is disallowed].
525     */
526    private static final Set<String> PROTECTED_ACTIONS = new ArraySet<>();
527    static {
528        PROTECTED_ACTIONS.add(Intent.ACTION_SEND);
529        PROTECTED_ACTIONS.add(Intent.ACTION_SENDTO);
530        PROTECTED_ACTIONS.add(Intent.ACTION_SEND_MULTIPLE);
531        PROTECTED_ACTIONS.add(Intent.ACTION_VIEW);
532    }
533
534    // Compilation reasons.
535    public static final int REASON_FIRST_BOOT = 0;
536    public static final int REASON_BOOT = 1;
537    public static final int REASON_INSTALL = 2;
538    public static final int REASON_BACKGROUND_DEXOPT = 3;
539    public static final int REASON_AB_OTA = 4;
540    public static final int REASON_NON_SYSTEM_LIBRARY = 5;
541    public static final int REASON_SHARED_APK = 6;
542    public static final int REASON_FORCED_DEXOPT = 7;
543    public static final int REASON_CORE_APP = 8;
544
545    public static final int REASON_LAST = REASON_CORE_APP;
546
547    /** Special library name that skips shared libraries check during compilation. */
548    private static final String SKIP_SHARED_LIBRARY_CHECK = "&";
549
550    /** All dangerous permission names in the same order as the events in MetricsEvent */
551    private static final List<String> ALL_DANGEROUS_PERMISSIONS = Arrays.asList(
552            Manifest.permission.READ_CALENDAR,
553            Manifest.permission.WRITE_CALENDAR,
554            Manifest.permission.CAMERA,
555            Manifest.permission.READ_CONTACTS,
556            Manifest.permission.WRITE_CONTACTS,
557            Manifest.permission.GET_ACCOUNTS,
558            Manifest.permission.ACCESS_FINE_LOCATION,
559            Manifest.permission.ACCESS_COARSE_LOCATION,
560            Manifest.permission.RECORD_AUDIO,
561            Manifest.permission.READ_PHONE_STATE,
562            Manifest.permission.CALL_PHONE,
563            Manifest.permission.READ_CALL_LOG,
564            Manifest.permission.WRITE_CALL_LOG,
565            Manifest.permission.ADD_VOICEMAIL,
566            Manifest.permission.USE_SIP,
567            Manifest.permission.PROCESS_OUTGOING_CALLS,
568            Manifest.permission.READ_CELL_BROADCASTS,
569            Manifest.permission.BODY_SENSORS,
570            Manifest.permission.SEND_SMS,
571            Manifest.permission.RECEIVE_SMS,
572            Manifest.permission.READ_SMS,
573            Manifest.permission.RECEIVE_WAP_PUSH,
574            Manifest.permission.RECEIVE_MMS,
575            Manifest.permission.READ_EXTERNAL_STORAGE,
576            Manifest.permission.WRITE_EXTERNAL_STORAGE,
577            Manifest.permission.READ_PHONE_NUMBER);
578
579
580    /**
581     * Version number for the package parser cache. Increment this whenever the format or
582     * extent of cached data changes. See {@code PackageParser#setCacheDir}.
583     */
584    private static final String PACKAGE_PARSER_CACHE_VERSION = "1";
585
586    /**
587     * Whether the package parser cache is enabled.
588     */
589    private static final boolean DEFAULT_PACKAGE_PARSER_CACHE_ENABLED = true;
590
591    final ServiceThread mHandlerThread;
592
593    final PackageHandler mHandler;
594
595    private final ProcessLoggingHandler mProcessLoggingHandler;
596
597    /**
598     * Messages for {@link #mHandler} that need to wait for system ready before
599     * being dispatched.
600     */
601    private ArrayList<Message> mPostSystemReadyMessages;
602
603    final int mSdkVersion = Build.VERSION.SDK_INT;
604
605    final Context mContext;
606    final boolean mFactoryTest;
607    final boolean mOnlyCore;
608    final DisplayMetrics mMetrics;
609    final int mDefParseFlags;
610    final String[] mSeparateProcesses;
611    final boolean mIsUpgrade;
612    final boolean mIsPreNUpgrade;
613    final boolean mIsPreNMR1Upgrade;
614
615    @GuardedBy("mPackages")
616    private boolean mDexOptDialogShown;
617
618    /** The location for ASEC container files on internal storage. */
619    final String mAsecInternalPath;
620
621    // Used for privilege escalation. MUST NOT BE CALLED WITH mPackages
622    // LOCK HELD.  Can be called with mInstallLock held.
623    @GuardedBy("mInstallLock")
624    final Installer mInstaller;
625
626    /** Directory where installed third-party apps stored */
627    final File mAppInstallDir;
628    final File mEphemeralInstallDir;
629
630    /**
631     * Directory to which applications installed internally have their
632     * 32 bit native libraries copied.
633     */
634    private File mAppLib32InstallDir;
635
636    // Directory containing the private parts (e.g. code and non-resource assets) of forward-locked
637    // apps.
638    final File mDrmAppPrivateInstallDir;
639
640    // ----------------------------------------------------------------
641
642    // Lock for state used when installing and doing other long running
643    // operations.  Methods that must be called with this lock held have
644    // the suffix "LI".
645    final Object mInstallLock = new Object();
646
647    // ----------------------------------------------------------------
648
649    // Keys are String (package name), values are Package.  This also serves
650    // as the lock for the global state.  Methods that must be called with
651    // this lock held have the prefix "LP".
652    @GuardedBy("mPackages")
653    final ArrayMap<String, PackageParser.Package> mPackages =
654            new ArrayMap<String, PackageParser.Package>();
655
656    final ArrayMap<String, Set<String>> mKnownCodebase =
657            new ArrayMap<String, Set<String>>();
658
659    // Tracks available target package names -> overlay package paths.
660    final ArrayMap<String, ArrayMap<String, PackageParser.Package>> mOverlays =
661        new ArrayMap<String, ArrayMap<String, PackageParser.Package>>();
662
663    /**
664     * Tracks new system packages [received in an OTA] that we expect to
665     * find updated user-installed versions. Keys are package name, values
666     * are package location.
667     */
668    final private ArrayMap<String, File> mExpectingBetter = new ArrayMap<>();
669    /**
670     * Tracks high priority intent filters for protected actions. During boot, certain
671     * filter actions are protected and should never be allowed to have a high priority
672     * intent filter for them. However, there is one, and only one exception -- the
673     * setup wizard. It must be able to define a high priority intent filter for these
674     * actions to ensure there are no escapes from the wizard. We need to delay processing
675     * of these during boot as we need to look at all of the system packages in order
676     * to know which component is the setup wizard.
677     */
678    private final List<PackageParser.ActivityIntentInfo> mProtectedFilters = new ArrayList<>();
679    /**
680     * Whether or not processing protected filters should be deferred.
681     */
682    private boolean mDeferProtectedFilters = true;
683
684    /**
685     * Tracks existing system packages prior to receiving an OTA. Keys are package name.
686     */
687    final private ArraySet<String> mExistingSystemPackages = new ArraySet<>();
688    /**
689     * Whether or not system app permissions should be promoted from install to runtime.
690     */
691    boolean mPromoteSystemApps;
692
693    @GuardedBy("mPackages")
694    final Settings mSettings;
695
696    /**
697     * Set of package names that are currently "frozen", which means active
698     * surgery is being done on the code/data for that package. The platform
699     * will refuse to launch frozen packages to avoid race conditions.
700     *
701     * @see PackageFreezer
702     */
703    @GuardedBy("mPackages")
704    final ArraySet<String> mFrozenPackages = new ArraySet<>();
705
706    final ProtectedPackages mProtectedPackages;
707
708    boolean mFirstBoot;
709
710    PackageManagerInternal.ExternalSourcesPolicy mExternalSourcesPolicy;
711
712    // System configuration read by SystemConfig.
713    final int[] mGlobalGids;
714    final SparseArray<ArraySet<String>> mSystemPermissions;
715    @GuardedBy("mAvailableFeatures")
716    final ArrayMap<String, FeatureInfo> mAvailableFeatures;
717
718    // If mac_permissions.xml was found for seinfo labeling.
719    boolean mFoundPolicyFile;
720
721    private final InstantAppRegistry mInstantAppRegistry;
722
723    public static final class SharedLibraryEntry {
724        public final String path;
725        public final String apk;
726        public final SharedLibraryInfo info;
727
728        SharedLibraryEntry(String _path, String _apk, String name, int version, int type,
729                String declaringPackageName, int declaringPackageVersionCode) {
730            path = _path;
731            apk = _apk;
732            info = new SharedLibraryInfo(name, version, type, new VersionedPackage(
733                    declaringPackageName, declaringPackageVersionCode), null);
734        }
735    }
736
737    // Currently known shared libraries.
738    final ArrayMap<String, SparseArray<SharedLibraryEntry>> mSharedLibraries = new ArrayMap<>();
739    final ArrayMap<String, SparseArray<SharedLibraryEntry>> mStaticLibsByDeclaringPackage =
740            new ArrayMap<>();
741
742    // All available activities, for your resolving pleasure.
743    final ActivityIntentResolver mActivities =
744            new ActivityIntentResolver();
745
746    // All available receivers, for your resolving pleasure.
747    final ActivityIntentResolver mReceivers =
748            new ActivityIntentResolver();
749
750    // All available services, for your resolving pleasure.
751    final ServiceIntentResolver mServices = new ServiceIntentResolver();
752
753    // All available providers, for your resolving pleasure.
754    final ProviderIntentResolver mProviders = new ProviderIntentResolver();
755
756    // Mapping from provider base names (first directory in content URI codePath)
757    // to the provider information.
758    final ArrayMap<String, PackageParser.Provider> mProvidersByAuthority =
759            new ArrayMap<String, PackageParser.Provider>();
760
761    // Mapping from instrumentation class names to info about them.
762    final ArrayMap<ComponentName, PackageParser.Instrumentation> mInstrumentation =
763            new ArrayMap<ComponentName, PackageParser.Instrumentation>();
764
765    // Mapping from permission names to info about them.
766    final ArrayMap<String, PackageParser.PermissionGroup> mPermissionGroups =
767            new ArrayMap<String, PackageParser.PermissionGroup>();
768
769    // Packages whose data we have transfered into another package, thus
770    // should no longer exist.
771    final ArraySet<String> mTransferedPackages = new ArraySet<String>();
772
773    // Broadcast actions that are only available to the system.
774    final ArraySet<String> mProtectedBroadcasts = new ArraySet<String>();
775
776    /** List of packages waiting for verification. */
777    final SparseArray<PackageVerificationState> mPendingVerification
778            = new SparseArray<PackageVerificationState>();
779
780    /** Set of packages associated with each app op permission. */
781    final ArrayMap<String, ArraySet<String>> mAppOpPermissionPackages = new ArrayMap<>();
782
783    final PackageInstallerService mInstallerService;
784
785    private final PackageDexOptimizer mPackageDexOptimizer;
786    // DexManager handles the usage of dex files (e.g. secondary files, whether or not a package
787    // is used by other apps).
788    private final DexManager mDexManager;
789
790    private AtomicInteger mNextMoveId = new AtomicInteger();
791    private final MoveCallbacks mMoveCallbacks;
792
793    private final OnPermissionChangeListeners mOnPermissionChangeListeners;
794
795    // Cache of users who need badging.
796    SparseBooleanArray mUserNeedsBadging = new SparseBooleanArray();
797
798    /** Token for keys in mPendingVerification. */
799    private int mPendingVerificationToken = 0;
800
801    volatile boolean mSystemReady;
802    volatile boolean mSafeMode;
803    volatile boolean mHasSystemUidErrors;
804
805    ApplicationInfo mAndroidApplication;
806    final ActivityInfo mResolveActivity = new ActivityInfo();
807    final ResolveInfo mResolveInfo = new ResolveInfo();
808    ComponentName mResolveComponentName;
809    PackageParser.Package mPlatformPackage;
810    ComponentName mCustomResolverComponentName;
811
812    boolean mResolverReplaced = false;
813
814    private final @Nullable ComponentName mIntentFilterVerifierComponent;
815    private final @Nullable IntentFilterVerifier<ActivityIntentInfo> mIntentFilterVerifier;
816
817    private int mIntentFilterVerificationToken = 0;
818
819    /** The service connection to the ephemeral resolver */
820    final EphemeralResolverConnection mEphemeralResolverConnection;
821
822    /** Component used to install ephemeral applications */
823    ComponentName mEphemeralInstallerComponent;
824    final ActivityInfo mEphemeralInstallerActivity = new ActivityInfo();
825    final ResolveInfo mEphemeralInstallerInfo = new ResolveInfo();
826
827    final SparseArray<IntentFilterVerificationState> mIntentFilterVerificationStates
828            = new SparseArray<IntentFilterVerificationState>();
829
830    final DefaultPermissionGrantPolicy mDefaultPermissionPolicy;
831
832    // List of packages names to keep cached, even if they are uninstalled for all users
833    private List<String> mKeepUninstalledPackages;
834
835    private UserManagerInternal mUserManagerInternal;
836    private final UserDataPreparer mUserDataPreparer;
837
838    private File mCacheDir;
839
840    private static class IFVerificationParams {
841        PackageParser.Package pkg;
842        boolean replacing;
843        int userId;
844        int verifierUid;
845
846        public IFVerificationParams(PackageParser.Package _pkg, boolean _replacing,
847                int _userId, int _verifierUid) {
848            pkg = _pkg;
849            replacing = _replacing;
850            userId = _userId;
851            replacing = _replacing;
852            verifierUid = _verifierUid;
853        }
854    }
855
856    private interface IntentFilterVerifier<T extends IntentFilter> {
857        boolean addOneIntentFilterVerification(int verifierId, int userId, int verificationId,
858                                               T filter, String packageName);
859        void startVerifications(int userId);
860        void receiveVerificationResponse(int verificationId);
861    }
862
863    private class IntentVerifierProxy implements IntentFilterVerifier<ActivityIntentInfo> {
864        private Context mContext;
865        private ComponentName mIntentFilterVerifierComponent;
866        private ArrayList<Integer> mCurrentIntentFilterVerifications = new ArrayList<Integer>();
867
868        public IntentVerifierProxy(Context context, ComponentName verifierComponent) {
869            mContext = context;
870            mIntentFilterVerifierComponent = verifierComponent;
871        }
872
873        private String getDefaultScheme() {
874            return IntentFilter.SCHEME_HTTPS;
875        }
876
877        @Override
878        public void startVerifications(int userId) {
879            // Launch verifications requests
880            int count = mCurrentIntentFilterVerifications.size();
881            for (int n=0; n<count; n++) {
882                int verificationId = mCurrentIntentFilterVerifications.get(n);
883                final IntentFilterVerificationState ivs =
884                        mIntentFilterVerificationStates.get(verificationId);
885
886                String packageName = ivs.getPackageName();
887
888                ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters();
889                final int filterCount = filters.size();
890                ArraySet<String> domainsSet = new ArraySet<>();
891                for (int m=0; m<filterCount; m++) {
892                    PackageParser.ActivityIntentInfo filter = filters.get(m);
893                    domainsSet.addAll(filter.getHostsList());
894                }
895                synchronized (mPackages) {
896                    if (mSettings.createIntentFilterVerificationIfNeededLPw(
897                            packageName, domainsSet) != null) {
898                        scheduleWriteSettingsLocked();
899                    }
900                }
901                sendVerificationRequest(userId, verificationId, ivs);
902            }
903            mCurrentIntentFilterVerifications.clear();
904        }
905
906        private void sendVerificationRequest(int userId, int verificationId,
907                IntentFilterVerificationState ivs) {
908
909            Intent verificationIntent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION);
910            verificationIntent.putExtra(
911                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_ID,
912                    verificationId);
913            verificationIntent.putExtra(
914                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_URI_SCHEME,
915                    getDefaultScheme());
916            verificationIntent.putExtra(
917                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_HOSTS,
918                    ivs.getHostsString());
919            verificationIntent.putExtra(
920                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_PACKAGE_NAME,
921                    ivs.getPackageName());
922            verificationIntent.setComponent(mIntentFilterVerifierComponent);
923            verificationIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
924
925            UserHandle user = new UserHandle(userId);
926            mContext.sendBroadcastAsUser(verificationIntent, user);
927            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
928                    "Sending IntentFilter verification broadcast");
929        }
930
931        public void receiveVerificationResponse(int verificationId) {
932            IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId);
933
934            final boolean verified = ivs.isVerified();
935
936            ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters();
937            final int count = filters.size();
938            if (DEBUG_DOMAIN_VERIFICATION) {
939                Slog.i(TAG, "Received verification response " + verificationId
940                        + " for " + count + " filters, verified=" + verified);
941            }
942            for (int n=0; n<count; n++) {
943                PackageParser.ActivityIntentInfo filter = filters.get(n);
944                filter.setVerified(verified);
945
946                if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "IntentFilter " + filter.toString()
947                        + " verified with result:" + verified + " and hosts:"
948                        + ivs.getHostsString());
949            }
950
951            mIntentFilterVerificationStates.remove(verificationId);
952
953            final String packageName = ivs.getPackageName();
954            IntentFilterVerificationInfo ivi = null;
955
956            synchronized (mPackages) {
957                ivi = mSettings.getIntentFilterVerificationLPr(packageName);
958            }
959            if (ivi == null) {
960                Slog.w(TAG, "IntentFilterVerificationInfo not found for verificationId:"
961                        + verificationId + " packageName:" + packageName);
962                return;
963            }
964            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
965                    "Updating IntentFilterVerificationInfo for package " + packageName
966                            +" verificationId:" + verificationId);
967
968            synchronized (mPackages) {
969                if (verified) {
970                    ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS);
971                } else {
972                    ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK);
973                }
974                scheduleWriteSettingsLocked();
975
976                final int userId = ivs.getUserId();
977                if (userId != UserHandle.USER_ALL) {
978                    final int userStatus =
979                            mSettings.getIntentFilterVerificationStatusLPr(packageName, userId);
980
981                    int updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
982                    boolean needUpdate = false;
983
984                    // We cannot override the STATUS_ALWAYS / STATUS_NEVER states if they have
985                    // already been set by the User thru the Disambiguation dialog
986                    switch (userStatus) {
987                        case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED:
988                            if (verified) {
989                                updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
990                            } else {
991                                updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK;
992                            }
993                            needUpdate = true;
994                            break;
995
996                        case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK:
997                            if (verified) {
998                                updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
999                                needUpdate = true;
1000                            }
1001                            break;
1002
1003                        default:
1004                            // Nothing to do
1005                    }
1006
1007                    if (needUpdate) {
1008                        mSettings.updateIntentFilterVerificationStatusLPw(
1009                                packageName, updatedStatus, userId);
1010                        scheduleWritePackageRestrictionsLocked(userId);
1011                    }
1012                }
1013            }
1014        }
1015
1016        @Override
1017        public boolean addOneIntentFilterVerification(int verifierUid, int userId, int verificationId,
1018                    ActivityIntentInfo filter, String packageName) {
1019            if (!hasValidDomains(filter)) {
1020                return false;
1021            }
1022            IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId);
1023            if (ivs == null) {
1024                ivs = createDomainVerificationState(verifierUid, userId, verificationId,
1025                        packageName);
1026            }
1027            if (DEBUG_DOMAIN_VERIFICATION) {
1028                Slog.d(TAG, "Adding verification filter for " + packageName + ": " + filter);
1029            }
1030            ivs.addFilter(filter);
1031            return true;
1032        }
1033
1034        private IntentFilterVerificationState createDomainVerificationState(int verifierUid,
1035                int userId, int verificationId, String packageName) {
1036            IntentFilterVerificationState ivs = new IntentFilterVerificationState(
1037                    verifierUid, userId, packageName);
1038            ivs.setPendingState();
1039            synchronized (mPackages) {
1040                mIntentFilterVerificationStates.append(verificationId, ivs);
1041                mCurrentIntentFilterVerifications.add(verificationId);
1042            }
1043            return ivs;
1044        }
1045    }
1046
1047    private static boolean hasValidDomains(ActivityIntentInfo filter) {
1048        return filter.hasCategory(Intent.CATEGORY_BROWSABLE)
1049                && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) ||
1050                        filter.hasDataScheme(IntentFilter.SCHEME_HTTPS));
1051    }
1052
1053    // Set of pending broadcasts for aggregating enable/disable of components.
1054    static class PendingPackageBroadcasts {
1055        // for each user id, a map of <package name -> components within that package>
1056        final SparseArray<ArrayMap<String, ArrayList<String>>> mUidMap;
1057
1058        public PendingPackageBroadcasts() {
1059            mUidMap = new SparseArray<ArrayMap<String, ArrayList<String>>>(2);
1060        }
1061
1062        public ArrayList<String> get(int userId, String packageName) {
1063            ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId);
1064            return packages.get(packageName);
1065        }
1066
1067        public void put(int userId, String packageName, ArrayList<String> components) {
1068            ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId);
1069            packages.put(packageName, components);
1070        }
1071
1072        public void remove(int userId, String packageName) {
1073            ArrayMap<String, ArrayList<String>> packages = mUidMap.get(userId);
1074            if (packages != null) {
1075                packages.remove(packageName);
1076            }
1077        }
1078
1079        public void remove(int userId) {
1080            mUidMap.remove(userId);
1081        }
1082
1083        public int userIdCount() {
1084            return mUidMap.size();
1085        }
1086
1087        public int userIdAt(int n) {
1088            return mUidMap.keyAt(n);
1089        }
1090
1091        public ArrayMap<String, ArrayList<String>> packagesForUserId(int userId) {
1092            return mUidMap.get(userId);
1093        }
1094
1095        public int size() {
1096            // total number of pending broadcast entries across all userIds
1097            int num = 0;
1098            for (int i = 0; i< mUidMap.size(); i++) {
1099                num += mUidMap.valueAt(i).size();
1100            }
1101            return num;
1102        }
1103
1104        public void clear() {
1105            mUidMap.clear();
1106        }
1107
1108        private ArrayMap<String, ArrayList<String>> getOrAllocate(int userId) {
1109            ArrayMap<String, ArrayList<String>> map = mUidMap.get(userId);
1110            if (map == null) {
1111                map = new ArrayMap<String, ArrayList<String>>();
1112                mUidMap.put(userId, map);
1113            }
1114            return map;
1115        }
1116    }
1117    final PendingPackageBroadcasts mPendingBroadcasts = new PendingPackageBroadcasts();
1118
1119    // Service Connection to remote media container service to copy
1120    // package uri's from external media onto secure containers
1121    // or internal storage.
1122    private IMediaContainerService mContainerService = null;
1123
1124    static final int SEND_PENDING_BROADCAST = 1;
1125    static final int MCS_BOUND = 3;
1126    static final int END_COPY = 4;
1127    static final int INIT_COPY = 5;
1128    static final int MCS_UNBIND = 6;
1129    static final int START_CLEANING_PACKAGE = 7;
1130    static final int FIND_INSTALL_LOC = 8;
1131    static final int POST_INSTALL = 9;
1132    static final int MCS_RECONNECT = 10;
1133    static final int MCS_GIVE_UP = 11;
1134    static final int UPDATED_MEDIA_STATUS = 12;
1135    static final int WRITE_SETTINGS = 13;
1136    static final int WRITE_PACKAGE_RESTRICTIONS = 14;
1137    static final int PACKAGE_VERIFIED = 15;
1138    static final int CHECK_PENDING_VERIFICATION = 16;
1139    static final int START_INTENT_FILTER_VERIFICATIONS = 17;
1140    static final int INTENT_FILTER_VERIFIED = 18;
1141    static final int WRITE_PACKAGE_LIST = 19;
1142    static final int EPHEMERAL_RESOLUTION_PHASE_TWO = 20;
1143
1144    static final int WRITE_SETTINGS_DELAY = 10*1000;  // 10 seconds
1145
1146    // Delay time in millisecs
1147    static final int BROADCAST_DELAY = 10 * 1000;
1148
1149    static UserManagerService sUserManager;
1150
1151    // Stores a list of users whose package restrictions file needs to be updated
1152    private ArraySet<Integer> mDirtyUsers = new ArraySet<Integer>();
1153
1154    final private DefaultContainerConnection mDefContainerConn =
1155            new DefaultContainerConnection();
1156    class DefaultContainerConnection implements ServiceConnection {
1157        public void onServiceConnected(ComponentName name, IBinder service) {
1158            if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceConnected");
1159            final IMediaContainerService imcs = IMediaContainerService.Stub
1160                    .asInterface(Binder.allowBlocking(service));
1161            mHandler.sendMessage(mHandler.obtainMessage(MCS_BOUND, imcs));
1162        }
1163
1164        public void onServiceDisconnected(ComponentName name) {
1165            if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceDisconnected");
1166        }
1167    }
1168
1169    // Recordkeeping of restore-after-install operations that are currently in flight
1170    // between the Package Manager and the Backup Manager
1171    static class PostInstallData {
1172        public InstallArgs args;
1173        public PackageInstalledInfo res;
1174
1175        PostInstallData(InstallArgs _a, PackageInstalledInfo _r) {
1176            args = _a;
1177            res = _r;
1178        }
1179    }
1180
1181    final SparseArray<PostInstallData> mRunningInstalls = new SparseArray<PostInstallData>();
1182    int mNextInstallToken = 1;  // nonzero; will be wrapped back to 1 when ++ overflows
1183
1184    // XML tags for backup/restore of various bits of state
1185    private static final String TAG_PREFERRED_BACKUP = "pa";
1186    private static final String TAG_DEFAULT_APPS = "da";
1187    private static final String TAG_INTENT_FILTER_VERIFICATION = "iv";
1188
1189    private static final String TAG_PERMISSION_BACKUP = "perm-grant-backup";
1190    private static final String TAG_ALL_GRANTS = "rt-grants";
1191    private static final String TAG_GRANT = "grant";
1192    private static final String ATTR_PACKAGE_NAME = "pkg";
1193
1194    private static final String TAG_PERMISSION = "perm";
1195    private static final String ATTR_PERMISSION_NAME = "name";
1196    private static final String ATTR_IS_GRANTED = "g";
1197    private static final String ATTR_USER_SET = "set";
1198    private static final String ATTR_USER_FIXED = "fixed";
1199    private static final String ATTR_REVOKE_ON_UPGRADE = "rou";
1200
1201    // System/policy permission grants are not backed up
1202    private static final int SYSTEM_RUNTIME_GRANT_MASK =
1203            FLAG_PERMISSION_POLICY_FIXED
1204            | FLAG_PERMISSION_SYSTEM_FIXED
1205            | FLAG_PERMISSION_GRANTED_BY_DEFAULT;
1206
1207    // And we back up these user-adjusted states
1208    private static final int USER_RUNTIME_GRANT_MASK =
1209            FLAG_PERMISSION_USER_SET
1210            | FLAG_PERMISSION_USER_FIXED
1211            | FLAG_PERMISSION_REVOKE_ON_UPGRADE;
1212
1213    final @Nullable String mRequiredVerifierPackage;
1214    final @NonNull String mRequiredInstallerPackage;
1215    final @NonNull String mRequiredUninstallerPackage;
1216    final @Nullable String mSetupWizardPackage;
1217    final @Nullable String mStorageManagerPackage;
1218    final @NonNull String mServicesSystemSharedLibraryPackageName;
1219    final @NonNull String mSharedSystemSharedLibraryPackageName;
1220
1221    final boolean mPermissionReviewRequired;
1222
1223    private final PackageUsage mPackageUsage = new PackageUsage();
1224    private final CompilerStats mCompilerStats = new CompilerStats();
1225
1226    class PackageHandler extends Handler {
1227        private boolean mBound = false;
1228        final ArrayList<HandlerParams> mPendingInstalls =
1229            new ArrayList<HandlerParams>();
1230
1231        private boolean connectToService() {
1232            if (DEBUG_SD_INSTALL) Log.i(TAG, "Trying to bind to" +
1233                    " DefaultContainerService");
1234            Intent service = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
1235            Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1236            if (mContext.bindServiceAsUser(service, mDefContainerConn,
1237                    Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) {
1238                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1239                mBound = true;
1240                return true;
1241            }
1242            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1243            return false;
1244        }
1245
1246        private void disconnectService() {
1247            mContainerService = null;
1248            mBound = false;
1249            Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1250            mContext.unbindService(mDefContainerConn);
1251            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1252        }
1253
1254        PackageHandler(Looper looper) {
1255            super(looper);
1256        }
1257
1258        public void handleMessage(Message msg) {
1259            try {
1260                doHandleMessage(msg);
1261            } finally {
1262                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1263            }
1264        }
1265
1266        void doHandleMessage(Message msg) {
1267            switch (msg.what) {
1268                case INIT_COPY: {
1269                    HandlerParams params = (HandlerParams) msg.obj;
1270                    int idx = mPendingInstalls.size();
1271                    if (DEBUG_INSTALL) Slog.i(TAG, "init_copy idx=" + idx + ": " + params);
1272                    // If a bind was already initiated we dont really
1273                    // need to do anything. The pending install
1274                    // will be processed later on.
1275                    if (!mBound) {
1276                        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1277                                System.identityHashCode(mHandler));
1278                        // If this is the only one pending we might
1279                        // have to bind to the service again.
1280                        if (!connectToService()) {
1281                            Slog.e(TAG, "Failed to bind to media container service");
1282                            params.serviceError();
1283                            Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1284                                    System.identityHashCode(mHandler));
1285                            if (params.traceMethod != null) {
1286                                Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, params.traceMethod,
1287                                        params.traceCookie);
1288                            }
1289                            return;
1290                        } else {
1291                            // Once we bind to the service, the first
1292                            // pending request will be processed.
1293                            mPendingInstalls.add(idx, params);
1294                        }
1295                    } else {
1296                        mPendingInstalls.add(idx, params);
1297                        // Already bound to the service. Just make
1298                        // sure we trigger off processing the first request.
1299                        if (idx == 0) {
1300                            mHandler.sendEmptyMessage(MCS_BOUND);
1301                        }
1302                    }
1303                    break;
1304                }
1305                case MCS_BOUND: {
1306                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_bound");
1307                    if (msg.obj != null) {
1308                        mContainerService = (IMediaContainerService) msg.obj;
1309                        Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1310                                System.identityHashCode(mHandler));
1311                    }
1312                    if (mContainerService == null) {
1313                        if (!mBound) {
1314                            // Something seriously wrong since we are not bound and we are not
1315                            // waiting for connection. Bail out.
1316                            Slog.e(TAG, "Cannot bind to media container service");
1317                            for (HandlerParams params : mPendingInstalls) {
1318                                // Indicate service bind error
1319                                params.serviceError();
1320                                Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1321                                        System.identityHashCode(params));
1322                                if (params.traceMethod != null) {
1323                                    Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER,
1324                                            params.traceMethod, params.traceCookie);
1325                                }
1326                                return;
1327                            }
1328                            mPendingInstalls.clear();
1329                        } else {
1330                            Slog.w(TAG, "Waiting to connect to media container service");
1331                        }
1332                    } else if (mPendingInstalls.size() > 0) {
1333                        HandlerParams params = mPendingInstalls.get(0);
1334                        if (params != null) {
1335                            Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1336                                    System.identityHashCode(params));
1337                            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "startCopy");
1338                            if (params.startCopy()) {
1339                                // We are done...  look for more work or to
1340                                // go idle.
1341                                if (DEBUG_SD_INSTALL) Log.i(TAG,
1342                                        "Checking for more work or unbind...");
1343                                // Delete pending install
1344                                if (mPendingInstalls.size() > 0) {
1345                                    mPendingInstalls.remove(0);
1346                                }
1347                                if (mPendingInstalls.size() == 0) {
1348                                    if (mBound) {
1349                                        if (DEBUG_SD_INSTALL) Log.i(TAG,
1350                                                "Posting delayed MCS_UNBIND");
1351                                        removeMessages(MCS_UNBIND);
1352                                        Message ubmsg = obtainMessage(MCS_UNBIND);
1353                                        // Unbind after a little delay, to avoid
1354                                        // continual thrashing.
1355                                        sendMessageDelayed(ubmsg, 10000);
1356                                    }
1357                                } else {
1358                                    // There are more pending requests in queue.
1359                                    // Just post MCS_BOUND message to trigger processing
1360                                    // of next pending install.
1361                                    if (DEBUG_SD_INSTALL) Log.i(TAG,
1362                                            "Posting MCS_BOUND for next work");
1363                                    mHandler.sendEmptyMessage(MCS_BOUND);
1364                                }
1365                            }
1366                            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
1367                        }
1368                    } else {
1369                        // Should never happen ideally.
1370                        Slog.w(TAG, "Empty queue");
1371                    }
1372                    break;
1373                }
1374                case MCS_RECONNECT: {
1375                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_reconnect");
1376                    if (mPendingInstalls.size() > 0) {
1377                        if (mBound) {
1378                            disconnectService();
1379                        }
1380                        if (!connectToService()) {
1381                            Slog.e(TAG, "Failed to bind to media container service");
1382                            for (HandlerParams params : mPendingInstalls) {
1383                                // Indicate service bind error
1384                                params.serviceError();
1385                                Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1386                                        System.identityHashCode(params));
1387                            }
1388                            mPendingInstalls.clear();
1389                        }
1390                    }
1391                    break;
1392                }
1393                case MCS_UNBIND: {
1394                    // If there is no actual work left, then time to unbind.
1395                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_unbind");
1396
1397                    if (mPendingInstalls.size() == 0 && mPendingVerification.size() == 0) {
1398                        if (mBound) {
1399                            if (DEBUG_INSTALL) Slog.i(TAG, "calling disconnectService()");
1400
1401                            disconnectService();
1402                        }
1403                    } else if (mPendingInstalls.size() > 0) {
1404                        // There are more pending requests in queue.
1405                        // Just post MCS_BOUND message to trigger processing
1406                        // of next pending install.
1407                        mHandler.sendEmptyMessage(MCS_BOUND);
1408                    }
1409
1410                    break;
1411                }
1412                case MCS_GIVE_UP: {
1413                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_giveup too many retries");
1414                    HandlerParams params = mPendingInstalls.remove(0);
1415                    Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1416                            System.identityHashCode(params));
1417                    break;
1418                }
1419                case SEND_PENDING_BROADCAST: {
1420                    String packages[];
1421                    ArrayList<String> components[];
1422                    int size = 0;
1423                    int uids[];
1424                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1425                    synchronized (mPackages) {
1426                        if (mPendingBroadcasts == null) {
1427                            return;
1428                        }
1429                        size = mPendingBroadcasts.size();
1430                        if (size <= 0) {
1431                            // Nothing to be done. Just return
1432                            return;
1433                        }
1434                        packages = new String[size];
1435                        components = new ArrayList[size];
1436                        uids = new int[size];
1437                        int i = 0;  // filling out the above arrays
1438
1439                        for (int n = 0; n < mPendingBroadcasts.userIdCount(); n++) {
1440                            int packageUserId = mPendingBroadcasts.userIdAt(n);
1441                            Iterator<Map.Entry<String, ArrayList<String>>> it
1442                                    = mPendingBroadcasts.packagesForUserId(packageUserId)
1443                                            .entrySet().iterator();
1444                            while (it.hasNext() && i < size) {
1445                                Map.Entry<String, ArrayList<String>> ent = it.next();
1446                                packages[i] = ent.getKey();
1447                                components[i] = ent.getValue();
1448                                PackageSetting ps = mSettings.mPackages.get(ent.getKey());
1449                                uids[i] = (ps != null)
1450                                        ? UserHandle.getUid(packageUserId, ps.appId)
1451                                        : -1;
1452                                i++;
1453                            }
1454                        }
1455                        size = i;
1456                        mPendingBroadcasts.clear();
1457                    }
1458                    // Send broadcasts
1459                    for (int i = 0; i < size; i++) {
1460                        sendPackageChangedBroadcast(packages[i], true, components[i], uids[i]);
1461                    }
1462                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1463                    break;
1464                }
1465                case START_CLEANING_PACKAGE: {
1466                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1467                    final String packageName = (String)msg.obj;
1468                    final int userId = msg.arg1;
1469                    final boolean andCode = msg.arg2 != 0;
1470                    synchronized (mPackages) {
1471                        if (userId == UserHandle.USER_ALL) {
1472                            int[] users = sUserManager.getUserIds();
1473                            for (int user : users) {
1474                                mSettings.addPackageToCleanLPw(
1475                                        new PackageCleanItem(user, packageName, andCode));
1476                            }
1477                        } else {
1478                            mSettings.addPackageToCleanLPw(
1479                                    new PackageCleanItem(userId, packageName, andCode));
1480                        }
1481                    }
1482                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1483                    startCleaningPackages();
1484                } break;
1485                case POST_INSTALL: {
1486                    if (DEBUG_INSTALL) Log.v(TAG, "Handling post-install for " + msg.arg1);
1487
1488                    PostInstallData data = mRunningInstalls.get(msg.arg1);
1489                    final boolean didRestore = (msg.arg2 != 0);
1490                    mRunningInstalls.delete(msg.arg1);
1491
1492                    if (data != null) {
1493                        InstallArgs args = data.args;
1494                        PackageInstalledInfo parentRes = data.res;
1495
1496                        final boolean grantPermissions = (args.installFlags
1497                                & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0;
1498                        final boolean killApp = (args.installFlags
1499                                & PackageManager.INSTALL_DONT_KILL_APP) == 0;
1500                        final String[] grantedPermissions = args.installGrantPermissions;
1501
1502                        // Handle the parent package
1503                        handlePackagePostInstall(parentRes, grantPermissions, killApp,
1504                                grantedPermissions, didRestore, args.installerPackageName,
1505                                args.observer);
1506
1507                        // Handle the child packages
1508                        final int childCount = (parentRes.addedChildPackages != null)
1509                                ? parentRes.addedChildPackages.size() : 0;
1510                        for (int i = 0; i < childCount; i++) {
1511                            PackageInstalledInfo childRes = parentRes.addedChildPackages.valueAt(i);
1512                            handlePackagePostInstall(childRes, grantPermissions, killApp,
1513                                    grantedPermissions, false, args.installerPackageName,
1514                                    args.observer);
1515                        }
1516
1517                        // Log tracing if needed
1518                        if (args.traceMethod != null) {
1519                            Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, args.traceMethod,
1520                                    args.traceCookie);
1521                        }
1522                    } else {
1523                        Slog.e(TAG, "Bogus post-install token " + msg.arg1);
1524                    }
1525
1526                    Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "postInstall", msg.arg1);
1527                } break;
1528                case UPDATED_MEDIA_STATUS: {
1529                    if (DEBUG_SD_INSTALL) Log.i(TAG, "Got message UPDATED_MEDIA_STATUS");
1530                    boolean reportStatus = msg.arg1 == 1;
1531                    boolean doGc = msg.arg2 == 1;
1532                    if (DEBUG_SD_INSTALL) Log.i(TAG, "reportStatus=" + reportStatus + ", doGc = " + doGc);
1533                    if (doGc) {
1534                        // Force a gc to clear up stale containers.
1535                        Runtime.getRuntime().gc();
1536                    }
1537                    if (msg.obj != null) {
1538                        @SuppressWarnings("unchecked")
1539                        Set<AsecInstallArgs> args = (Set<AsecInstallArgs>) msg.obj;
1540                        if (DEBUG_SD_INSTALL) Log.i(TAG, "Unloading all containers");
1541                        // Unload containers
1542                        unloadAllContainers(args);
1543                    }
1544                    if (reportStatus) {
1545                        try {
1546                            if (DEBUG_SD_INSTALL) Log.i(TAG,
1547                                    "Invoking StorageManagerService call back");
1548                            PackageHelper.getStorageManager().finishMediaUpdate();
1549                        } catch (RemoteException e) {
1550                            Log.e(TAG, "StorageManagerService not running?");
1551                        }
1552                    }
1553                } break;
1554                case WRITE_SETTINGS: {
1555                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1556                    synchronized (mPackages) {
1557                        removeMessages(WRITE_SETTINGS);
1558                        removeMessages(WRITE_PACKAGE_RESTRICTIONS);
1559                        mSettings.writeLPr();
1560                        mDirtyUsers.clear();
1561                    }
1562                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1563                } break;
1564                case WRITE_PACKAGE_RESTRICTIONS: {
1565                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1566                    synchronized (mPackages) {
1567                        removeMessages(WRITE_PACKAGE_RESTRICTIONS);
1568                        for (int userId : mDirtyUsers) {
1569                            mSettings.writePackageRestrictionsLPr(userId);
1570                        }
1571                        mDirtyUsers.clear();
1572                    }
1573                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1574                } break;
1575                case WRITE_PACKAGE_LIST: {
1576                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1577                    synchronized (mPackages) {
1578                        removeMessages(WRITE_PACKAGE_LIST);
1579                        mSettings.writePackageListLPr(msg.arg1);
1580                    }
1581                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1582                } break;
1583                case CHECK_PENDING_VERIFICATION: {
1584                    final int verificationId = msg.arg1;
1585                    final PackageVerificationState state = mPendingVerification.get(verificationId);
1586
1587                    if ((state != null) && !state.timeoutExtended()) {
1588                        final InstallArgs args = state.getInstallArgs();
1589                        final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
1590
1591                        Slog.i(TAG, "Verification timed out for " + originUri);
1592                        mPendingVerification.remove(verificationId);
1593
1594                        int ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
1595
1596                        if (getDefaultVerificationResponse() == PackageManager.VERIFICATION_ALLOW) {
1597                            Slog.i(TAG, "Continuing with installation of " + originUri);
1598                            state.setVerifierResponse(Binder.getCallingUid(),
1599                                    PackageManager.VERIFICATION_ALLOW_WITHOUT_SUFFICIENT);
1600                            broadcastPackageVerified(verificationId, originUri,
1601                                    PackageManager.VERIFICATION_ALLOW,
1602                                    state.getInstallArgs().getUser());
1603                            try {
1604                                ret = args.copyApk(mContainerService, true);
1605                            } catch (RemoteException e) {
1606                                Slog.e(TAG, "Could not contact the ContainerService");
1607                            }
1608                        } else {
1609                            broadcastPackageVerified(verificationId, originUri,
1610                                    PackageManager.VERIFICATION_REJECT,
1611                                    state.getInstallArgs().getUser());
1612                        }
1613
1614                        Trace.asyncTraceEnd(
1615                                TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
1616
1617                        processPendingInstall(args, ret);
1618                        mHandler.sendEmptyMessage(MCS_UNBIND);
1619                    }
1620                    break;
1621                }
1622                case PACKAGE_VERIFIED: {
1623                    final int verificationId = msg.arg1;
1624
1625                    final PackageVerificationState state = mPendingVerification.get(verificationId);
1626                    if (state == null) {
1627                        Slog.w(TAG, "Invalid verification token " + verificationId + " received");
1628                        break;
1629                    }
1630
1631                    final PackageVerificationResponse response = (PackageVerificationResponse) msg.obj;
1632
1633                    state.setVerifierResponse(response.callerUid, response.code);
1634
1635                    if (state.isVerificationComplete()) {
1636                        mPendingVerification.remove(verificationId);
1637
1638                        final InstallArgs args = state.getInstallArgs();
1639                        final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
1640
1641                        int ret;
1642                        if (state.isInstallAllowed()) {
1643                            ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
1644                            broadcastPackageVerified(verificationId, originUri,
1645                                    response.code, state.getInstallArgs().getUser());
1646                            try {
1647                                ret = args.copyApk(mContainerService, true);
1648                            } catch (RemoteException e) {
1649                                Slog.e(TAG, "Could not contact the ContainerService");
1650                            }
1651                        } else {
1652                            ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
1653                        }
1654
1655                        Trace.asyncTraceEnd(
1656                                TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
1657
1658                        processPendingInstall(args, ret);
1659                        mHandler.sendEmptyMessage(MCS_UNBIND);
1660                    }
1661
1662                    break;
1663                }
1664                case START_INTENT_FILTER_VERIFICATIONS: {
1665                    IFVerificationParams params = (IFVerificationParams) msg.obj;
1666                    verifyIntentFiltersIfNeeded(params.userId, params.verifierUid,
1667                            params.replacing, params.pkg);
1668                    break;
1669                }
1670                case INTENT_FILTER_VERIFIED: {
1671                    final int verificationId = msg.arg1;
1672
1673                    final IntentFilterVerificationState state = mIntentFilterVerificationStates.get(
1674                            verificationId);
1675                    if (state == null) {
1676                        Slog.w(TAG, "Invalid IntentFilter verification token "
1677                                + verificationId + " received");
1678                        break;
1679                    }
1680
1681                    final int userId = state.getUserId();
1682
1683                    if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1684                            "Processing IntentFilter verification with token:"
1685                            + verificationId + " and userId:" + userId);
1686
1687                    final IntentFilterVerificationResponse response =
1688                            (IntentFilterVerificationResponse) msg.obj;
1689
1690                    state.setVerifierResponse(response.callerUid, response.code);
1691
1692                    if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1693                            "IntentFilter verification with token:" + verificationId
1694                            + " and userId:" + userId
1695                            + " is settings verifier response with response code:"
1696                            + response.code);
1697
1698                    if (response.code == PackageManager.INTENT_FILTER_VERIFICATION_FAILURE) {
1699                        if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Domains failing verification: "
1700                                + response.getFailedDomainsString());
1701                    }
1702
1703                    if (state.isVerificationComplete()) {
1704                        mIntentFilterVerifier.receiveVerificationResponse(verificationId);
1705                    } else {
1706                        if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1707                                "IntentFilter verification with token:" + verificationId
1708                                + " was not said to be complete");
1709                    }
1710
1711                    break;
1712                }
1713                case EPHEMERAL_RESOLUTION_PHASE_TWO: {
1714                    EphemeralResolver.doEphemeralResolutionPhaseTwo(mContext,
1715                            mEphemeralResolverConnection,
1716                            (EphemeralRequest) msg.obj,
1717                            mEphemeralInstallerActivity,
1718                            mHandler);
1719                }
1720            }
1721        }
1722    }
1723
1724    private void handlePackagePostInstall(PackageInstalledInfo res, boolean grantPermissions,
1725            boolean killApp, String[] grantedPermissions,
1726            boolean launchedForRestore, String installerPackage,
1727            IPackageInstallObserver2 installObserver) {
1728        if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
1729            // Send the removed broadcasts
1730            if (res.removedInfo != null) {
1731                res.removedInfo.sendPackageRemovedBroadcasts(killApp);
1732            }
1733
1734            // Now that we successfully installed the package, grant runtime
1735            // permissions if requested before broadcasting the install. Also
1736            // for legacy apps in permission review mode we clear the permission
1737            // review flag which is used to emulate runtime permissions for
1738            // legacy apps.
1739            if (grantPermissions) {
1740                grantRequestedRuntimePermissions(res.pkg, res.newUsers, grantedPermissions);
1741            }
1742
1743            final boolean update = res.removedInfo != null
1744                    && res.removedInfo.removedPackage != null;
1745
1746            // If this is the first time we have child packages for a disabled privileged
1747            // app that had no children, we grant requested runtime permissions to the new
1748            // children if the parent on the system image had them already granted.
1749            if (res.pkg.parentPackage != null) {
1750                synchronized (mPackages) {
1751                    grantRuntimePermissionsGrantedToDisabledPrivSysPackageParentLPw(res.pkg);
1752                }
1753            }
1754
1755            synchronized (mPackages) {
1756                mInstantAppRegistry.onPackageInstalledLPw(res.pkg, res.newUsers);
1757            }
1758
1759            final String packageName = res.pkg.applicationInfo.packageName;
1760
1761            // Determine the set of users who are adding this package for
1762            // the first time vs. those who are seeing an update.
1763            int[] firstUsers = EMPTY_INT_ARRAY;
1764            int[] updateUsers = EMPTY_INT_ARRAY;
1765            if (res.origUsers == null || res.origUsers.length == 0) {
1766                firstUsers = res.newUsers;
1767            } else {
1768                for (int newUser : res.newUsers) {
1769                    boolean isNew = true;
1770                    for (int origUser : res.origUsers) {
1771                        if (origUser == newUser) {
1772                            isNew = false;
1773                            break;
1774                        }
1775                    }
1776                    if (isNew) {
1777                        firstUsers = ArrayUtils.appendInt(firstUsers, newUser);
1778                    } else {
1779                        updateUsers = ArrayUtils.appendInt(updateUsers, newUser);
1780                    }
1781                }
1782            }
1783
1784            // Send installed broadcasts if the install/update is not ephemeral
1785            // and the package is not a static shared lib.
1786            if (!isEphemeral(res.pkg) && res.pkg.staticSharedLibName == null) {
1787                mProcessLoggingHandler.invalidateProcessLoggingBaseApkHash(res.pkg.baseCodePath);
1788
1789                // Send added for users that see the package for the first time
1790                // sendPackageAddedForNewUsers also deals with system apps
1791                int appId = UserHandle.getAppId(res.uid);
1792                boolean isSystem = res.pkg.applicationInfo.isSystemApp();
1793                sendPackageAddedForNewUsers(packageName, isSystem, appId, firstUsers);
1794
1795                // Send added for users that don't see the package for the first time
1796                Bundle extras = new Bundle(1);
1797                extras.putInt(Intent.EXTRA_UID, res.uid);
1798                if (update) {
1799                    extras.putBoolean(Intent.EXTRA_REPLACING, true);
1800                }
1801                sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
1802                        extras, 0 /*flags*/, null /*targetPackage*/,
1803                        null /*finishedReceiver*/, updateUsers);
1804
1805                // Send replaced for users that don't see the package for the first time
1806                if (update) {
1807                    sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
1808                            packageName, extras, 0 /*flags*/,
1809                            null /*targetPackage*/, null /*finishedReceiver*/,
1810                            updateUsers);
1811                    sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
1812                            null /*package*/, null /*extras*/, 0 /*flags*/,
1813                            packageName /*targetPackage*/,
1814                            null /*finishedReceiver*/, updateUsers);
1815                } else if (launchedForRestore && !isSystemApp(res.pkg)) {
1816                    // First-install and we did a restore, so we're responsible for the
1817                    // first-launch broadcast.
1818                    if (DEBUG_BACKUP) {
1819                        Slog.i(TAG, "Post-restore of " + packageName
1820                                + " sending FIRST_LAUNCH in " + Arrays.toString(firstUsers));
1821                    }
1822                    sendFirstLaunchBroadcast(packageName, installerPackage, firstUsers);
1823                }
1824
1825                // Send broadcast package appeared if forward locked/external for all users
1826                // treat asec-hosted packages like removable media on upgrade
1827                if (res.pkg.isForwardLocked() || isExternal(res.pkg)) {
1828                    if (DEBUG_INSTALL) {
1829                        Slog.i(TAG, "upgrading pkg " + res.pkg
1830                                + " is ASEC-hosted -> AVAILABLE");
1831                    }
1832                    final int[] uidArray = new int[]{res.pkg.applicationInfo.uid};
1833                    ArrayList<String> pkgList = new ArrayList<>(1);
1834                    pkgList.add(packageName);
1835                    sendResourcesChangedBroadcast(true, true, pkgList, uidArray, null);
1836                }
1837            }
1838
1839            // Work that needs to happen on first install within each user
1840            if (firstUsers != null && firstUsers.length > 0) {
1841                synchronized (mPackages) {
1842                    for (int userId : firstUsers) {
1843                        // If this app is a browser and it's newly-installed for some
1844                        // users, clear any default-browser state in those users. The
1845                        // app's nature doesn't depend on the user, so we can just check
1846                        // its browser nature in any user and generalize.
1847                        if (packageIsBrowser(packageName, userId)) {
1848                            mSettings.setDefaultBrowserPackageNameLPw(null, userId);
1849                        }
1850
1851                        // We may also need to apply pending (restored) runtime
1852                        // permission grants within these users.
1853                        mSettings.applyPendingPermissionGrantsLPw(packageName, userId);
1854                    }
1855                }
1856            }
1857
1858            // Log current value of "unknown sources" setting
1859            EventLog.writeEvent(EventLogTags.UNKNOWN_SOURCES_ENABLED,
1860                    getUnknownSourcesSettings());
1861
1862            // Force a gc to clear up things
1863            Runtime.getRuntime().gc();
1864
1865            // Remove the replaced package's older resources safely now
1866            // We delete after a gc for applications  on sdcard.
1867            if (res.removedInfo != null && res.removedInfo.args != null) {
1868                synchronized (mInstallLock) {
1869                    res.removedInfo.args.doPostDeleteLI(true);
1870                }
1871            }
1872
1873            if (!isEphemeral(res.pkg)) {
1874                // Notify DexManager that the package was installed for new users.
1875                // The updated users should already be indexed and the package code paths
1876                // should not change.
1877                // Don't notify the manager for ephemeral apps as they are not expected to
1878                // survive long enough to benefit of background optimizations.
1879                for (int userId : firstUsers) {
1880                    PackageInfo info = getPackageInfo(packageName, /*flags*/ 0, userId);
1881                    mDexManager.notifyPackageInstalled(info, userId);
1882                }
1883            }
1884        }
1885
1886        // If someone is watching installs - notify them
1887        if (installObserver != null) {
1888            try {
1889                Bundle extras = extrasForInstallResult(res);
1890                installObserver.onPackageInstalled(res.name, res.returnCode,
1891                        res.returnMsg, extras);
1892            } catch (RemoteException e) {
1893                Slog.i(TAG, "Observer no longer exists.");
1894            }
1895        }
1896    }
1897
1898    private void grantRuntimePermissionsGrantedToDisabledPrivSysPackageParentLPw(
1899            PackageParser.Package pkg) {
1900        if (pkg.parentPackage == null) {
1901            return;
1902        }
1903        if (pkg.requestedPermissions == null) {
1904            return;
1905        }
1906        final PackageSetting disabledSysParentPs = mSettings
1907                .getDisabledSystemPkgLPr(pkg.parentPackage.packageName);
1908        if (disabledSysParentPs == null || disabledSysParentPs.pkg == null
1909                || !disabledSysParentPs.isPrivileged()
1910                || (disabledSysParentPs.childPackageNames != null
1911                        && !disabledSysParentPs.childPackageNames.isEmpty())) {
1912            return;
1913        }
1914        final int[] allUserIds = sUserManager.getUserIds();
1915        final int permCount = pkg.requestedPermissions.size();
1916        for (int i = 0; i < permCount; i++) {
1917            String permission = pkg.requestedPermissions.get(i);
1918            BasePermission bp = mSettings.mPermissions.get(permission);
1919            if (bp == null || !(bp.isRuntime() || bp.isDevelopment())) {
1920                continue;
1921            }
1922            for (int userId : allUserIds) {
1923                if (disabledSysParentPs.getPermissionsState().hasRuntimePermission(
1924                        permission, userId)) {
1925                    grantRuntimePermission(pkg.packageName, permission, userId);
1926                }
1927            }
1928        }
1929    }
1930
1931    private StorageEventListener mStorageListener = new StorageEventListener() {
1932        @Override
1933        public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState) {
1934            if (vol.type == VolumeInfo.TYPE_PRIVATE) {
1935                if (vol.state == VolumeInfo.STATE_MOUNTED) {
1936                    final String volumeUuid = vol.getFsUuid();
1937
1938                    // Clean up any users or apps that were removed or recreated
1939                    // while this volume was missing
1940                    reconcileUsers(volumeUuid);
1941                    reconcileApps(volumeUuid);
1942
1943                    // Clean up any install sessions that expired or were
1944                    // cancelled while this volume was missing
1945                    mInstallerService.onPrivateVolumeMounted(volumeUuid);
1946
1947                    loadPrivatePackages(vol);
1948
1949                } else if (vol.state == VolumeInfo.STATE_EJECTING) {
1950                    unloadPrivatePackages(vol);
1951                }
1952            }
1953
1954            if (vol.type == VolumeInfo.TYPE_PUBLIC && vol.isPrimary()) {
1955                if (vol.state == VolumeInfo.STATE_MOUNTED) {
1956                    updateExternalMediaStatus(true, false);
1957                } else if (vol.state == VolumeInfo.STATE_EJECTING) {
1958                    updateExternalMediaStatus(false, false);
1959                }
1960            }
1961        }
1962
1963        @Override
1964        public void onVolumeForgotten(String fsUuid) {
1965            if (TextUtils.isEmpty(fsUuid)) {
1966                Slog.e(TAG, "Forgetting internal storage is probably a mistake; ignoring");
1967                return;
1968            }
1969
1970            // Remove any apps installed on the forgotten volume
1971            synchronized (mPackages) {
1972                final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(fsUuid);
1973                for (PackageSetting ps : packages) {
1974                    Slog.d(TAG, "Destroying " + ps.name + " because volume was forgotten");
1975                    deletePackageVersioned(new VersionedPackage(ps.name,
1976                            PackageManager.VERSION_CODE_HIGHEST),
1977                            new LegacyPackageDeleteObserver(null).getBinder(),
1978                            UserHandle.USER_SYSTEM, PackageManager.DELETE_ALL_USERS);
1979                    // Try very hard to release any references to this package
1980                    // so we don't risk the system server being killed due to
1981                    // open FDs
1982                    AttributeCache.instance().removePackage(ps.name);
1983                }
1984
1985                mSettings.onVolumeForgotten(fsUuid);
1986                mSettings.writeLPr();
1987            }
1988        }
1989    };
1990
1991    private void grantRequestedRuntimePermissions(PackageParser.Package pkg, int[] userIds,
1992            String[] grantedPermissions) {
1993        for (int userId : userIds) {
1994            grantRequestedRuntimePermissionsForUser(pkg, userId, grantedPermissions);
1995        }
1996    }
1997
1998    private void grantRequestedRuntimePermissionsForUser(PackageParser.Package pkg, int userId,
1999            String[] grantedPermissions) {
2000        SettingBase sb = (SettingBase) pkg.mExtras;
2001        if (sb == null) {
2002            return;
2003        }
2004
2005        PermissionsState permissionsState = sb.getPermissionsState();
2006
2007        final int immutableFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
2008                | PackageManager.FLAG_PERMISSION_POLICY_FIXED;
2009
2010        final boolean supportsRuntimePermissions = pkg.applicationInfo.targetSdkVersion
2011                >= Build.VERSION_CODES.M;
2012
2013        for (String permission : pkg.requestedPermissions) {
2014            final BasePermission bp;
2015            synchronized (mPackages) {
2016                bp = mSettings.mPermissions.get(permission);
2017            }
2018            if (bp != null && (bp.isRuntime() || bp.isDevelopment())
2019                    && (grantedPermissions == null
2020                           || ArrayUtils.contains(grantedPermissions, permission))) {
2021                final int flags = permissionsState.getPermissionFlags(permission, userId);
2022                if (supportsRuntimePermissions) {
2023                    // Installer cannot change immutable permissions.
2024                    if ((flags & immutableFlags) == 0) {
2025                        grantRuntimePermission(pkg.packageName, permission, userId);
2026                    }
2027                } else if (mPermissionReviewRequired) {
2028                    // In permission review mode we clear the review flag when we
2029                    // are asked to install the app with all permissions granted.
2030                    if ((flags & PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
2031                        updatePermissionFlags(permission, pkg.packageName,
2032                                PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED, 0, userId);
2033                    }
2034                }
2035            }
2036        }
2037    }
2038
2039    Bundle extrasForInstallResult(PackageInstalledInfo res) {
2040        Bundle extras = null;
2041        switch (res.returnCode) {
2042            case PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION: {
2043                extras = new Bundle();
2044                extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PERMISSION,
2045                        res.origPermission);
2046                extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PACKAGE,
2047                        res.origPackage);
2048                break;
2049            }
2050            case PackageManager.INSTALL_SUCCEEDED: {
2051                extras = new Bundle();
2052                extras.putBoolean(Intent.EXTRA_REPLACING,
2053                        res.removedInfo != null && res.removedInfo.removedPackage != null);
2054                break;
2055            }
2056        }
2057        return extras;
2058    }
2059
2060    void scheduleWriteSettingsLocked() {
2061        if (!mHandler.hasMessages(WRITE_SETTINGS)) {
2062            mHandler.sendEmptyMessageDelayed(WRITE_SETTINGS, WRITE_SETTINGS_DELAY);
2063        }
2064    }
2065
2066    void scheduleWritePackageListLocked(int userId) {
2067        if (!mHandler.hasMessages(WRITE_PACKAGE_LIST)) {
2068            Message msg = mHandler.obtainMessage(WRITE_PACKAGE_LIST);
2069            msg.arg1 = userId;
2070            mHandler.sendMessageDelayed(msg, WRITE_SETTINGS_DELAY);
2071        }
2072    }
2073
2074    void scheduleWritePackageRestrictionsLocked(UserHandle user) {
2075        final int userId = user == null ? UserHandle.USER_ALL : user.getIdentifier();
2076        scheduleWritePackageRestrictionsLocked(userId);
2077    }
2078
2079    void scheduleWritePackageRestrictionsLocked(int userId) {
2080        final int[] userIds = (userId == UserHandle.USER_ALL)
2081                ? sUserManager.getUserIds() : new int[]{userId};
2082        for (int nextUserId : userIds) {
2083            if (!sUserManager.exists(nextUserId)) return;
2084            mDirtyUsers.add(nextUserId);
2085            if (!mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) {
2086                mHandler.sendEmptyMessageDelayed(WRITE_PACKAGE_RESTRICTIONS, WRITE_SETTINGS_DELAY);
2087            }
2088        }
2089    }
2090
2091    public static PackageManagerService main(Context context, Installer installer,
2092            boolean factoryTest, boolean onlyCore) {
2093        // Self-check for initial settings.
2094        PackageManagerServiceCompilerMapping.checkProperties();
2095
2096        PackageManagerService m = new PackageManagerService(context, installer,
2097                factoryTest, onlyCore);
2098        m.enableSystemUserPackages();
2099        ServiceManager.addService("package", m);
2100        return m;
2101    }
2102
2103    private void enableSystemUserPackages() {
2104        if (!UserManager.isSplitSystemUser()) {
2105            return;
2106        }
2107        // For system user, enable apps based on the following conditions:
2108        // - app is whitelisted or belong to one of these groups:
2109        //   -- system app which has no launcher icons
2110        //   -- system app which has INTERACT_ACROSS_USERS permission
2111        //   -- system IME app
2112        // - app is not in the blacklist
2113        AppsQueryHelper queryHelper = new AppsQueryHelper(this);
2114        Set<String> enableApps = new ArraySet<>();
2115        enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_NON_LAUNCHABLE_APPS
2116                | AppsQueryHelper.GET_APPS_WITH_INTERACT_ACROSS_USERS_PERM
2117                | AppsQueryHelper.GET_IMES, /* systemAppsOnly */ true, UserHandle.SYSTEM));
2118        ArraySet<String> wlApps = SystemConfig.getInstance().getSystemUserWhitelistedApps();
2119        enableApps.addAll(wlApps);
2120        enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_REQUIRED_FOR_SYSTEM_USER,
2121                /* systemAppsOnly */ false, UserHandle.SYSTEM));
2122        ArraySet<String> blApps = SystemConfig.getInstance().getSystemUserBlacklistedApps();
2123        enableApps.removeAll(blApps);
2124        Log.i(TAG, "Applications installed for system user: " + enableApps);
2125        List<String> allAps = queryHelper.queryApps(0, /* systemAppsOnly */ false,
2126                UserHandle.SYSTEM);
2127        final int allAppsSize = allAps.size();
2128        synchronized (mPackages) {
2129            for (int i = 0; i < allAppsSize; i++) {
2130                String pName = allAps.get(i);
2131                PackageSetting pkgSetting = mSettings.mPackages.get(pName);
2132                // Should not happen, but we shouldn't be failing if it does
2133                if (pkgSetting == null) {
2134                    continue;
2135                }
2136                boolean install = enableApps.contains(pName);
2137                if (pkgSetting.getInstalled(UserHandle.USER_SYSTEM) != install) {
2138                    Log.i(TAG, (install ? "Installing " : "Uninstalling ") + pName
2139                            + " for system user");
2140                    pkgSetting.setInstalled(install, UserHandle.USER_SYSTEM);
2141                }
2142            }
2143        }
2144    }
2145
2146    private static void getDefaultDisplayMetrics(Context context, DisplayMetrics metrics) {
2147        DisplayManager displayManager = (DisplayManager) context.getSystemService(
2148                Context.DISPLAY_SERVICE);
2149        displayManager.getDisplay(Display.DEFAULT_DISPLAY).getMetrics(metrics);
2150    }
2151
2152    /**
2153     * Requests that files preopted on a secondary system partition be copied to the data partition
2154     * if possible.  Note that the actual copying of the files is accomplished by init for security
2155     * reasons. This simply requests that the copy takes place and awaits confirmation of its
2156     * completion. See platform/system/extras/cppreopt/ for the implementation of the actual copy.
2157     */
2158    private static void requestCopyPreoptedFiles() {
2159        final int WAIT_TIME_MS = 100;
2160        final String CP_PREOPT_PROPERTY = "sys.cppreopt";
2161        if (SystemProperties.getInt("ro.cp_system_other_odex", 0) == 1) {
2162            SystemProperties.set(CP_PREOPT_PROPERTY, "requested");
2163            // We will wait for up to 100 seconds.
2164            final long timeStart = SystemClock.uptimeMillis();
2165            final long timeEnd = timeStart + 100 * 1000;
2166            long timeNow = timeStart;
2167            while (!SystemProperties.get(CP_PREOPT_PROPERTY).equals("finished")) {
2168                try {
2169                    Thread.sleep(WAIT_TIME_MS);
2170                } catch (InterruptedException e) {
2171                    // Do nothing
2172                }
2173                timeNow = SystemClock.uptimeMillis();
2174                if (timeNow > timeEnd) {
2175                    SystemProperties.set(CP_PREOPT_PROPERTY, "timed-out");
2176                    Slog.wtf(TAG, "cppreopt did not finish!");
2177                    break;
2178                }
2179            }
2180
2181            Slog.i(TAG, "cppreopts took " + (timeNow - timeStart) + " ms");
2182        }
2183    }
2184
2185    public PackageManagerService(Context context, Installer installer,
2186            boolean factoryTest, boolean onlyCore) {
2187        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "create package manager");
2188        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START,
2189                SystemClock.uptimeMillis());
2190
2191        if (mSdkVersion <= 0) {
2192            Slog.w(TAG, "**** ro.build.version.sdk not set!");
2193        }
2194
2195        mContext = context;
2196
2197        mPermissionReviewRequired = context.getResources().getBoolean(
2198                R.bool.config_permissionReviewRequired);
2199
2200        mFactoryTest = factoryTest;
2201        mOnlyCore = onlyCore;
2202        mMetrics = new DisplayMetrics();
2203        mSettings = new Settings(mPackages);
2204        mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID,
2205                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2206        mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID,
2207                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2208        mSettings.addSharedUserLPw("android.uid.log", LOG_UID,
2209                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2210        mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID,
2211                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2212        mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID,
2213                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2214        mSettings.addSharedUserLPw("android.uid.shell", SHELL_UID,
2215                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2216
2217        String separateProcesses = SystemProperties.get("debug.separate_processes");
2218        if (separateProcesses != null && separateProcesses.length() > 0) {
2219            if ("*".equals(separateProcesses)) {
2220                mDefParseFlags = PackageParser.PARSE_IGNORE_PROCESSES;
2221                mSeparateProcesses = null;
2222                Slog.w(TAG, "Running with debug.separate_processes: * (ALL)");
2223            } else {
2224                mDefParseFlags = 0;
2225                mSeparateProcesses = separateProcesses.split(",");
2226                Slog.w(TAG, "Running with debug.separate_processes: "
2227                        + separateProcesses);
2228            }
2229        } else {
2230            mDefParseFlags = 0;
2231            mSeparateProcesses = null;
2232        }
2233
2234        mInstaller = installer;
2235        mPackageDexOptimizer = new PackageDexOptimizer(installer, mInstallLock, context,
2236                "*dexopt*");
2237        mDexManager = new DexManager(this, mPackageDexOptimizer, installer, mInstallLock);
2238        mMoveCallbacks = new MoveCallbacks(FgThread.get().getLooper());
2239
2240        mOnPermissionChangeListeners = new OnPermissionChangeListeners(
2241                FgThread.get().getLooper());
2242
2243        getDefaultDisplayMetrics(context, mMetrics);
2244
2245        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "get system config");
2246        SystemConfig systemConfig = SystemConfig.getInstance();
2247        mGlobalGids = systemConfig.getGlobalGids();
2248        mSystemPermissions = systemConfig.getSystemPermissions();
2249        mAvailableFeatures = systemConfig.getAvailableFeatures();
2250        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2251
2252        mProtectedPackages = new ProtectedPackages(mContext);
2253
2254        synchronized (mInstallLock) {
2255        // writer
2256        synchronized (mPackages) {
2257            mHandlerThread = new ServiceThread(TAG,
2258                    Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
2259            mHandlerThread.start();
2260            mHandler = new PackageHandler(mHandlerThread.getLooper());
2261            mProcessLoggingHandler = new ProcessLoggingHandler();
2262            Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT);
2263
2264            mDefaultPermissionPolicy = new DefaultPermissionGrantPolicy(this);
2265            mInstantAppRegistry = new InstantAppRegistry(this);
2266
2267            File dataDir = Environment.getDataDirectory();
2268            mAppInstallDir = new File(dataDir, "app");
2269            mAppLib32InstallDir = new File(dataDir, "app-lib");
2270            mEphemeralInstallDir = new File(dataDir, "app-ephemeral");
2271            mAsecInternalPath = new File(dataDir, "app-asec").getPath();
2272            mDrmAppPrivateInstallDir = new File(dataDir, "app-private");
2273            mUserDataPreparer = new UserDataPreparer(mInstaller, mInstallLock, mContext, mOnlyCore);
2274            sUserManager = new UserManagerService(context, this, mUserDataPreparer, mPackages);
2275
2276            // Propagate permission configuration in to package manager.
2277            ArrayMap<String, SystemConfig.PermissionEntry> permConfig
2278                    = systemConfig.getPermissions();
2279            for (int i=0; i<permConfig.size(); i++) {
2280                SystemConfig.PermissionEntry perm = permConfig.valueAt(i);
2281                BasePermission bp = mSettings.mPermissions.get(perm.name);
2282                if (bp == null) {
2283                    bp = new BasePermission(perm.name, "android", BasePermission.TYPE_BUILTIN);
2284                    mSettings.mPermissions.put(perm.name, bp);
2285                }
2286                if (perm.gids != null) {
2287                    bp.setGids(perm.gids, perm.perUser);
2288                }
2289            }
2290
2291            ArrayMap<String, String> libConfig = systemConfig.getSharedLibraries();
2292            final int builtInLibCount = libConfig.size();
2293            for (int i = 0; i < builtInLibCount; i++) {
2294                String name = libConfig.keyAt(i);
2295                String path = libConfig.valueAt(i);
2296                addSharedLibraryLPw(path, null, name, SharedLibraryInfo.VERSION_UNDEFINED,
2297                        SharedLibraryInfo.TYPE_BUILTIN, PLATFORM_PACKAGE_NAME, 0);
2298            }
2299
2300            mFoundPolicyFile = SELinuxMMAC.readInstallPolicy();
2301
2302            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "read user settings");
2303            mFirstBoot = !mSettings.readLPw(sUserManager.getUsers(false));
2304            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2305
2306            // Clean up orphaned packages for which the code path doesn't exist
2307            // and they are an update to a system app - caused by bug/32321269
2308            final int packageSettingCount = mSettings.mPackages.size();
2309            for (int i = packageSettingCount - 1; i >= 0; i--) {
2310                PackageSetting ps = mSettings.mPackages.valueAt(i);
2311                if (!isExternal(ps) && (ps.codePath == null || !ps.codePath.exists())
2312                        && mSettings.getDisabledSystemPkgLPr(ps.name) != null) {
2313                    mSettings.mPackages.removeAt(i);
2314                    mSettings.enableSystemPackageLPw(ps.name);
2315                }
2316            }
2317
2318            if (mFirstBoot) {
2319                requestCopyPreoptedFiles();
2320            }
2321
2322            String customResolverActivity = Resources.getSystem().getString(
2323                    R.string.config_customResolverActivity);
2324            if (TextUtils.isEmpty(customResolverActivity)) {
2325                customResolverActivity = null;
2326            } else {
2327                mCustomResolverComponentName = ComponentName.unflattenFromString(
2328                        customResolverActivity);
2329            }
2330
2331            long startTime = SystemClock.uptimeMillis();
2332
2333            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START,
2334                    startTime);
2335
2336            final String bootClassPath = System.getenv("BOOTCLASSPATH");
2337            final String systemServerClassPath = System.getenv("SYSTEMSERVERCLASSPATH");
2338
2339            if (bootClassPath == null) {
2340                Slog.w(TAG, "No BOOTCLASSPATH found!");
2341            }
2342
2343            if (systemServerClassPath == null) {
2344                Slog.w(TAG, "No SYSTEMSERVERCLASSPATH found!");
2345            }
2346
2347            final List<String> allInstructionSets = InstructionSets.getAllInstructionSets();
2348            final String[] dexCodeInstructionSets =
2349                    getDexCodeInstructionSets(
2350                            allInstructionSets.toArray(new String[allInstructionSets.size()]));
2351
2352            /**
2353             * Ensure all external libraries have had dexopt run on them.
2354             */
2355            if (mSharedLibraries.size() > 0) {
2356                Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
2357                // NOTE: For now, we're compiling these system "shared libraries"
2358                // (and framework jars) into all available architectures. It's possible
2359                // to compile them only when we come across an app that uses them (there's
2360                // already logic for that in scanPackageLI) but that adds some complexity.
2361                for (String dexCodeInstructionSet : dexCodeInstructionSets) {
2362                    final int libCount = mSharedLibraries.size();
2363                    for (int i = 0; i < libCount; i++) {
2364                        SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.valueAt(i);
2365                        final int versionCount = versionedLib.size();
2366                        for (int j = 0; j < versionCount; j++) {
2367                            SharedLibraryEntry libEntry = versionedLib.valueAt(j);
2368                            final String libPath = libEntry.path != null
2369                                    ? libEntry.path : libEntry.apk;
2370                            if (libPath == null) {
2371                                continue;
2372                            }
2373                            try {
2374                                // Shared libraries do not have profiles so we perform a full
2375                                // AOT compilation (if needed).
2376                                int dexoptNeeded = DexFile.getDexOptNeeded(
2377                                        libPath, dexCodeInstructionSet,
2378                                        getCompilerFilterForReason(REASON_SHARED_APK),
2379                                        false /* newProfile */);
2380                                if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) {
2381                                    mInstaller.dexopt(libPath, Process.SYSTEM_UID, "*",
2382                                            dexCodeInstructionSet, dexoptNeeded, null,
2383                                            DEXOPT_PUBLIC,
2384                                            getCompilerFilterForReason(REASON_SHARED_APK),
2385                                            StorageManager.UUID_PRIVATE_INTERNAL,
2386                                            SKIP_SHARED_LIBRARY_CHECK);
2387                                }
2388                            } catch (FileNotFoundException e) {
2389                                Slog.w(TAG, "Library not found: " + libPath);
2390                            } catch (IOException | InstallerException e) {
2391                                Slog.w(TAG, "Cannot dexopt " + libPath + "; is it an APK or JAR? "
2392                                        + e.getMessage());
2393                            }
2394                        }
2395                    }
2396                }
2397                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2398            }
2399
2400            File frameworkDir = new File(Environment.getRootDirectory(), "framework");
2401
2402            final VersionInfo ver = mSettings.getInternalVersion();
2403            mIsUpgrade = !Build.FINGERPRINT.equals(ver.fingerprint);
2404
2405            // when upgrading from pre-M, promote system app permissions from install to runtime
2406            mPromoteSystemApps =
2407                    mIsUpgrade && ver.sdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1;
2408
2409            // When upgrading from pre-N, we need to handle package extraction like first boot,
2410            // as there is no profiling data available.
2411            mIsPreNUpgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N;
2412
2413            mIsPreNMR1Upgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N_MR1;
2414
2415            // save off the names of pre-existing system packages prior to scanning; we don't
2416            // want to automatically grant runtime permissions for new system apps
2417            if (mPromoteSystemApps) {
2418                Iterator<PackageSetting> pkgSettingIter = mSettings.mPackages.values().iterator();
2419                while (pkgSettingIter.hasNext()) {
2420                    PackageSetting ps = pkgSettingIter.next();
2421                    if (isSystemApp(ps)) {
2422                        mExistingSystemPackages.add(ps.name);
2423                    }
2424                }
2425            }
2426
2427            mCacheDir = preparePackageParserCache(mIsUpgrade);
2428
2429            // Set flag to monitor and not change apk file paths when
2430            // scanning install directories.
2431            int scanFlags = SCAN_BOOTING | SCAN_INITIAL;
2432
2433            if (mIsUpgrade || mFirstBoot) {
2434                scanFlags = scanFlags | SCAN_FIRST_BOOT_OR_UPGRADE;
2435            }
2436
2437            // Collect vendor overlay packages. (Do this before scanning any apps.)
2438            // For security and version matching reason, only consider
2439            // overlay packages if they reside in the right directory.
2440            String overlayThemeDir = SystemProperties.get(VENDOR_OVERLAY_THEME_PERSIST_PROPERTY);
2441            if (overlayThemeDir.isEmpty()) {
2442                overlayThemeDir = SystemProperties.get(VENDOR_OVERLAY_THEME_PROPERTY);
2443            }
2444            if (!overlayThemeDir.isEmpty()) {
2445                scanDirTracedLI(new File(VENDOR_OVERLAY_DIR, overlayThemeDir), mDefParseFlags
2446                        | PackageParser.PARSE_IS_SYSTEM
2447                        | PackageParser.PARSE_IS_SYSTEM_DIR
2448                        | PackageParser.PARSE_TRUSTED_OVERLAY, scanFlags | SCAN_TRUSTED_OVERLAY, 0);
2449            }
2450            scanDirTracedLI(new File(VENDOR_OVERLAY_DIR), mDefParseFlags
2451                    | PackageParser.PARSE_IS_SYSTEM
2452                    | PackageParser.PARSE_IS_SYSTEM_DIR
2453                    | PackageParser.PARSE_TRUSTED_OVERLAY, scanFlags | SCAN_TRUSTED_OVERLAY, 0);
2454
2455            // Find base frameworks (resource packages without code).
2456            scanDirTracedLI(frameworkDir, mDefParseFlags
2457                    | PackageParser.PARSE_IS_SYSTEM
2458                    | PackageParser.PARSE_IS_SYSTEM_DIR
2459                    | PackageParser.PARSE_IS_PRIVILEGED,
2460                    scanFlags | SCAN_NO_DEX, 0);
2461
2462            // Collected privileged system packages.
2463            final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app");
2464            scanDirTracedLI(privilegedAppDir, mDefParseFlags
2465                    | PackageParser.PARSE_IS_SYSTEM
2466                    | PackageParser.PARSE_IS_SYSTEM_DIR
2467                    | PackageParser.PARSE_IS_PRIVILEGED, scanFlags, 0);
2468
2469            // Collect ordinary system packages.
2470            final File systemAppDir = new File(Environment.getRootDirectory(), "app");
2471            scanDirTracedLI(systemAppDir, mDefParseFlags
2472                    | PackageParser.PARSE_IS_SYSTEM
2473                    | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
2474
2475            // Collect all vendor packages.
2476            File vendorAppDir = new File("/vendor/app");
2477            try {
2478                vendorAppDir = vendorAppDir.getCanonicalFile();
2479            } catch (IOException e) {
2480                // failed to look up canonical path, continue with original one
2481            }
2482            scanDirTracedLI(vendorAppDir, mDefParseFlags
2483                    | PackageParser.PARSE_IS_SYSTEM
2484                    | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
2485
2486            // Collect all OEM packages.
2487            final File oemAppDir = new File(Environment.getOemDirectory(), "app");
2488            scanDirTracedLI(oemAppDir, mDefParseFlags
2489                    | PackageParser.PARSE_IS_SYSTEM
2490                    | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
2491
2492            // Prune any system packages that no longer exist.
2493            final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<String>();
2494            if (!mOnlyCore) {
2495                Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
2496                while (psit.hasNext()) {
2497                    PackageSetting ps = psit.next();
2498
2499                    /*
2500                     * If this is not a system app, it can't be a
2501                     * disable system app.
2502                     */
2503                    if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
2504                        continue;
2505                    }
2506
2507                    /*
2508                     * If the package is scanned, it's not erased.
2509                     */
2510                    final PackageParser.Package scannedPkg = mPackages.get(ps.name);
2511                    if (scannedPkg != null) {
2512                        /*
2513                         * If the system app is both scanned and in the
2514                         * disabled packages list, then it must have been
2515                         * added via OTA. Remove it from the currently
2516                         * scanned package so the previously user-installed
2517                         * application can be scanned.
2518                         */
2519                        if (mSettings.isDisabledSystemPackageLPr(ps.name)) {
2520                            logCriticalInfo(Log.WARN, "Expecting better updated system app for "
2521                                    + ps.name + "; removing system app.  Last known codePath="
2522                                    + ps.codePathString + ", installStatus=" + ps.installStatus
2523                                    + ", versionCode=" + ps.versionCode + "; scanned versionCode="
2524                                    + scannedPkg.mVersionCode);
2525                            removePackageLI(scannedPkg, true);
2526                            mExpectingBetter.put(ps.name, ps.codePath);
2527                        }
2528
2529                        continue;
2530                    }
2531
2532                    if (!mSettings.isDisabledSystemPackageLPr(ps.name)) {
2533                        psit.remove();
2534                        logCriticalInfo(Log.WARN, "System package " + ps.name
2535                                + " no longer exists; it's data will be wiped");
2536                        // Actual deletion of code and data will be handled by later
2537                        // reconciliation step
2538                    } else {
2539                        final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(ps.name);
2540                        if (disabledPs.codePath == null || !disabledPs.codePath.exists()) {
2541                            possiblyDeletedUpdatedSystemApps.add(ps.name);
2542                        }
2543                    }
2544                }
2545            }
2546
2547            //look for any incomplete package installations
2548            ArrayList<PackageSetting> deletePkgsList = mSettings.getListOfIncompleteInstallPackagesLPr();
2549            for (int i = 0; i < deletePkgsList.size(); i++) {
2550                // Actual deletion of code and data will be handled by later
2551                // reconciliation step
2552                final String packageName = deletePkgsList.get(i).name;
2553                logCriticalInfo(Log.WARN, "Cleaning up incompletely installed app: " + packageName);
2554                synchronized (mPackages) {
2555                    mSettings.removePackageLPw(packageName);
2556                }
2557            }
2558
2559            //delete tmp files
2560            deleteTempPackageFiles();
2561
2562            // Remove any shared userIDs that have no associated packages
2563            mSettings.pruneSharedUsersLPw();
2564
2565            if (!mOnlyCore) {
2566                EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,
2567                        SystemClock.uptimeMillis());
2568                scanDirTracedLI(mAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0);
2569
2570                scanDirTracedLI(mDrmAppPrivateInstallDir, mDefParseFlags
2571                        | PackageParser.PARSE_FORWARD_LOCK,
2572                        scanFlags | SCAN_REQUIRE_KNOWN, 0);
2573
2574                scanDirLI(mEphemeralInstallDir, mDefParseFlags
2575                        | PackageParser.PARSE_IS_EPHEMERAL,
2576                        scanFlags | SCAN_REQUIRE_KNOWN, 0);
2577
2578                /**
2579                 * Remove disable package settings for any updated system
2580                 * apps that were removed via an OTA. If they're not a
2581                 * previously-updated app, remove them completely.
2582                 * Otherwise, just revoke their system-level permissions.
2583                 */
2584                for (String deletedAppName : possiblyDeletedUpdatedSystemApps) {
2585                    PackageParser.Package deletedPkg = mPackages.get(deletedAppName);
2586                    mSettings.removeDisabledSystemPackageLPw(deletedAppName);
2587
2588                    String msg;
2589                    if (deletedPkg == null) {
2590                        msg = "Updated system package " + deletedAppName
2591                                + " no longer exists; it's data will be wiped";
2592                        // Actual deletion of code and data will be handled by later
2593                        // reconciliation step
2594                    } else {
2595                        msg = "Updated system app + " + deletedAppName
2596                                + " no longer present; removing system privileges for "
2597                                + deletedAppName;
2598
2599                        deletedPkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM;
2600
2601                        PackageSetting deletedPs = mSettings.mPackages.get(deletedAppName);
2602                        deletedPs.pkgFlags &= ~ApplicationInfo.FLAG_SYSTEM;
2603                    }
2604                    logCriticalInfo(Log.WARN, msg);
2605                }
2606
2607                /**
2608                 * Make sure all system apps that we expected to appear on
2609                 * the userdata partition actually showed up. If they never
2610                 * appeared, crawl back and revive the system version.
2611                 */
2612                for (int i = 0; i < mExpectingBetter.size(); i++) {
2613                    final String packageName = mExpectingBetter.keyAt(i);
2614                    if (!mPackages.containsKey(packageName)) {
2615                        final File scanFile = mExpectingBetter.valueAt(i);
2616
2617                        logCriticalInfo(Log.WARN, "Expected better " + packageName
2618                                + " but never showed up; reverting to system");
2619
2620                        int reparseFlags = mDefParseFlags;
2621                        if (FileUtils.contains(privilegedAppDir, scanFile)) {
2622                            reparseFlags = PackageParser.PARSE_IS_SYSTEM
2623                                    | PackageParser.PARSE_IS_SYSTEM_DIR
2624                                    | PackageParser.PARSE_IS_PRIVILEGED;
2625                        } else if (FileUtils.contains(systemAppDir, scanFile)) {
2626                            reparseFlags = PackageParser.PARSE_IS_SYSTEM
2627                                    | PackageParser.PARSE_IS_SYSTEM_DIR;
2628                        } else if (FileUtils.contains(vendorAppDir, scanFile)) {
2629                            reparseFlags = PackageParser.PARSE_IS_SYSTEM
2630                                    | PackageParser.PARSE_IS_SYSTEM_DIR;
2631                        } else if (FileUtils.contains(oemAppDir, scanFile)) {
2632                            reparseFlags = PackageParser.PARSE_IS_SYSTEM
2633                                    | PackageParser.PARSE_IS_SYSTEM_DIR;
2634                        } else {
2635                            Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile);
2636                            continue;
2637                        }
2638
2639                        mSettings.enableSystemPackageLPw(packageName);
2640
2641                        try {
2642                            scanPackageTracedLI(scanFile, reparseFlags, scanFlags, 0, null);
2643                        } catch (PackageManagerException e) {
2644                            Slog.e(TAG, "Failed to parse original system package: "
2645                                    + e.getMessage());
2646                        }
2647                    }
2648                }
2649            }
2650            mExpectingBetter.clear();
2651
2652            // Resolve the storage manager.
2653            mStorageManagerPackage = getStorageManagerPackageName();
2654
2655            // Resolve protected action filters. Only the setup wizard is allowed to
2656            // have a high priority filter for these actions.
2657            mSetupWizardPackage = getSetupWizardPackageName();
2658            if (mProtectedFilters.size() > 0) {
2659                if (DEBUG_FILTERS && mSetupWizardPackage == null) {
2660                    Slog.i(TAG, "No setup wizard;"
2661                        + " All protected intents capped to priority 0");
2662                }
2663                for (ActivityIntentInfo filter : mProtectedFilters) {
2664                    if (filter.activity.info.packageName.equals(mSetupWizardPackage)) {
2665                        if (DEBUG_FILTERS) {
2666                            Slog.i(TAG, "Found setup wizard;"
2667                                + " allow priority " + filter.getPriority() + ";"
2668                                + " package: " + filter.activity.info.packageName
2669                                + " activity: " + filter.activity.className
2670                                + " priority: " + filter.getPriority());
2671                        }
2672                        // skip setup wizard; allow it to keep the high priority filter
2673                        continue;
2674                    }
2675                    Slog.w(TAG, "Protected action; cap priority to 0;"
2676                            + " package: " + filter.activity.info.packageName
2677                            + " activity: " + filter.activity.className
2678                            + " origPrio: " + filter.getPriority());
2679                    filter.setPriority(0);
2680                }
2681            }
2682            mDeferProtectedFilters = false;
2683            mProtectedFilters.clear();
2684
2685            // Now that we know all of the shared libraries, update all clients to have
2686            // the correct library paths.
2687            updateAllSharedLibrariesLPw(null);
2688
2689            for (SharedUserSetting setting : mSettings.getAllSharedUsersLPw()) {
2690                // NOTE: We ignore potential failures here during a system scan (like
2691                // the rest of the commands above) because there's precious little we
2692                // can do about it. A settings error is reported, though.
2693                adjustCpuAbisForSharedUserLPw(setting.packages, null /*scannedPackage*/);
2694            }
2695
2696            // Now that we know all the packages we are keeping,
2697            // read and update their last usage times.
2698            mPackageUsage.read(mPackages);
2699            mCompilerStats.read();
2700
2701            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END,
2702                    SystemClock.uptimeMillis());
2703            Slog.i(TAG, "Time to scan packages: "
2704                    + ((SystemClock.uptimeMillis()-startTime)/1000f)
2705                    + " seconds");
2706
2707            // If the platform SDK has changed since the last time we booted,
2708            // we need to re-grant app permission to catch any new ones that
2709            // appear.  This is really a hack, and means that apps can in some
2710            // cases get permissions that the user didn't initially explicitly
2711            // allow...  it would be nice to have some better way to handle
2712            // this situation.
2713            int updateFlags = UPDATE_PERMISSIONS_ALL;
2714            if (ver.sdkVersion != mSdkVersion) {
2715                Slog.i(TAG, "Platform changed from " + ver.sdkVersion + " to "
2716                        + mSdkVersion + "; regranting permissions for internal storage");
2717                updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
2718            }
2719            updatePermissionsLPw(null, null, StorageManager.UUID_PRIVATE_INTERNAL, updateFlags);
2720            ver.sdkVersion = mSdkVersion;
2721
2722            // If this is the first boot or an update from pre-M, and it is a normal
2723            // boot, then we need to initialize the default preferred apps across
2724            // all defined users.
2725            if (!onlyCore && (mPromoteSystemApps || mFirstBoot)) {
2726                for (UserInfo user : sUserManager.getUsers(true)) {
2727                    mSettings.applyDefaultPreferredAppsLPw(this, user.id);
2728                    applyFactoryDefaultBrowserLPw(user.id);
2729                    primeDomainVerificationsLPw(user.id);
2730                }
2731            }
2732
2733            // Prepare storage for system user really early during boot,
2734            // since core system apps like SettingsProvider and SystemUI
2735            // can't wait for user to start
2736            final int storageFlags;
2737            if (StorageManager.isFileEncryptedNativeOrEmulated()) {
2738                storageFlags = StorageManager.FLAG_STORAGE_DE;
2739            } else {
2740                storageFlags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
2741            }
2742            reconcileAppsDataLI(StorageManager.UUID_PRIVATE_INTERNAL, UserHandle.USER_SYSTEM,
2743                    storageFlags, true /* migrateAppData */);
2744
2745            // If this is first boot after an OTA, and a normal boot, then
2746            // we need to clear code cache directories.
2747            // Note that we do *not* clear the application profiles. These remain valid
2748            // across OTAs and are used to drive profile verification (post OTA) and
2749            // profile compilation (without waiting to collect a fresh set of profiles).
2750            if (mIsUpgrade && !onlyCore) {
2751                Slog.i(TAG, "Build fingerprint changed; clearing code caches");
2752                for (int i = 0; i < mSettings.mPackages.size(); i++) {
2753                    final PackageSetting ps = mSettings.mPackages.valueAt(i);
2754                    if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, ps.volumeUuid)) {
2755                        // No apps are running this early, so no need to freeze
2756                        clearAppDataLIF(ps.pkg, UserHandle.USER_ALL,
2757                                StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE
2758                                        | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
2759                    }
2760                }
2761                ver.fingerprint = Build.FINGERPRINT;
2762            }
2763
2764            checkDefaultBrowser();
2765
2766            // clear only after permissions and other defaults have been updated
2767            mExistingSystemPackages.clear();
2768            mPromoteSystemApps = false;
2769
2770            // All the changes are done during package scanning.
2771            ver.databaseVersion = Settings.CURRENT_DATABASE_VERSION;
2772
2773            // can downgrade to reader
2774            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "write settings");
2775            mSettings.writeLPr();
2776            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2777
2778            // Perform dexopt on all apps that mark themselves as coreApps. We do this pretty
2779            // early on (before the package manager declares itself as early) because other
2780            // components in the system server might ask for package contexts for these apps.
2781            //
2782            // Note that "onlyCore" in this context means the system is encrypted or encrypting
2783            // (i.e, that the data partition is unavailable).
2784            if ((isFirstBoot() || isUpgrade() || VMRuntime.didPruneDalvikCache()) && !onlyCore) {
2785                long start = System.nanoTime();
2786                List<PackageParser.Package> coreApps = new ArrayList<>();
2787                for (PackageParser.Package pkg : mPackages.values()) {
2788                    if (pkg.coreApp) {
2789                        coreApps.add(pkg);
2790                    }
2791                }
2792
2793                int[] stats = performDexOptUpgrade(coreApps, false,
2794                        getCompilerFilterForReason(REASON_CORE_APP));
2795
2796                final int elapsedTimeSeconds =
2797                        (int) TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - start);
2798                MetricsLogger.histogram(mContext, "opt_coreapps_time_s", elapsedTimeSeconds);
2799
2800                if (DEBUG_DEXOPT) {
2801                    Slog.i(TAG, "Dex-opt core apps took : " + elapsedTimeSeconds + " seconds (" +
2802                            stats[0] + ", " + stats[1] + ", " + stats[2] + ")");
2803                }
2804
2805
2806                // TODO: Should we log these stats to tron too ?
2807                // MetricsLogger.histogram(mContext, "opt_coreapps_num_dexopted", stats[0]);
2808                // MetricsLogger.histogram(mContext, "opt_coreapps_num_skipped", stats[1]);
2809                // MetricsLogger.histogram(mContext, "opt_coreapps_num_failed", stats[2]);
2810                // MetricsLogger.histogram(mContext, "opt_coreapps_num_total", coreApps.size());
2811            }
2812
2813            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY,
2814                    SystemClock.uptimeMillis());
2815
2816            if (!mOnlyCore) {
2817                mRequiredVerifierPackage = getRequiredButNotReallyRequiredVerifierLPr();
2818                mRequiredInstallerPackage = getRequiredInstallerLPr();
2819                mRequiredUninstallerPackage = getRequiredUninstallerLPr();
2820                mIntentFilterVerifierComponent = getIntentFilterVerifierComponentNameLPr();
2821                mIntentFilterVerifier = new IntentVerifierProxy(mContext,
2822                        mIntentFilterVerifierComponent);
2823                mServicesSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr(
2824                        PackageManager.SYSTEM_SHARED_LIBRARY_SERVICES,
2825                        SharedLibraryInfo.VERSION_UNDEFINED);
2826                mSharedSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr(
2827                        PackageManager.SYSTEM_SHARED_LIBRARY_SHARED,
2828                        SharedLibraryInfo.VERSION_UNDEFINED);
2829            } else {
2830                mRequiredVerifierPackage = null;
2831                mRequiredInstallerPackage = null;
2832                mRequiredUninstallerPackage = null;
2833                mIntentFilterVerifierComponent = null;
2834                mIntentFilterVerifier = null;
2835                mServicesSystemSharedLibraryPackageName = null;
2836                mSharedSystemSharedLibraryPackageName = null;
2837            }
2838
2839            mInstallerService = new PackageInstallerService(context, this);
2840
2841            final ComponentName ephemeralResolverComponent = getEphemeralResolverLPr();
2842            if (ephemeralResolverComponent != null) {
2843                if (DEBUG_EPHEMERAL) {
2844                    Slog.i(TAG, "Ephemeral resolver: " + ephemeralResolverComponent);
2845                }
2846                mEphemeralResolverConnection =
2847                        new EphemeralResolverConnection(mContext, ephemeralResolverComponent);
2848            } else {
2849                mEphemeralResolverConnection = null;
2850            }
2851            mEphemeralInstallerComponent = getEphemeralInstallerLPr();
2852            if (mEphemeralInstallerComponent != null) {
2853                if (DEBUG_EPHEMERAL) {
2854                    Slog.i(TAG, "Ephemeral installer: " + mEphemeralInstallerComponent);
2855                }
2856                setUpEphemeralInstallerActivityLP(mEphemeralInstallerComponent);
2857            }
2858
2859            // Read and update the usage of dex files.
2860            // Do this at the end of PM init so that all the packages have their
2861            // data directory reconciled.
2862            // At this point we know the code paths of the packages, so we can validate
2863            // the disk file and build the internal cache.
2864            // The usage file is expected to be small so loading and verifying it
2865            // should take a fairly small time compare to the other activities (e.g. package
2866            // scanning).
2867            final Map<Integer, List<PackageInfo>> userPackages = new HashMap<>();
2868            final int[] currentUserIds = UserManagerService.getInstance().getUserIds();
2869            for (int userId : currentUserIds) {
2870                userPackages.put(userId, getInstalledPackages(/*flags*/ 0, userId).getList());
2871            }
2872            mDexManager.load(userPackages);
2873        } // synchronized (mPackages)
2874        } // synchronized (mInstallLock)
2875
2876        // Now after opening every single application zip, make sure they
2877        // are all flushed.  Not really needed, but keeps things nice and
2878        // tidy.
2879        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "GC");
2880        Runtime.getRuntime().gc();
2881        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2882
2883        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "loadFallbacks");
2884        FallbackCategoryProvider.loadFallbacks();
2885        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2886
2887        // The initial scanning above does many calls into installd while
2888        // holding the mPackages lock, but we're mostly interested in yelling
2889        // once we have a booted system.
2890        mInstaller.setWarnIfHeld(mPackages);
2891
2892        // Expose private service for system components to use.
2893        LocalServices.addService(PackageManagerInternal.class, new PackageManagerInternalImpl());
2894        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2895    }
2896
2897    private static File preparePackageParserCache(boolean isUpgrade) {
2898        if (!DEFAULT_PACKAGE_PARSER_CACHE_ENABLED) {
2899            return null;
2900        }
2901
2902        // Disable package parsing on eng builds to allow for faster incremental development.
2903        if ("eng".equals(Build.TYPE)) {
2904            return null;
2905        }
2906
2907        if (SystemProperties.getBoolean("pm.boot.disable_package_cache", false)) {
2908            Slog.i(TAG, "Disabling package parser cache due to system property.");
2909            return null;
2910        }
2911
2912        // The base directory for the package parser cache lives under /data/system/.
2913        final File cacheBaseDir = FileUtils.createDir(Environment.getDataSystemDirectory(),
2914                "package_cache");
2915        if (cacheBaseDir == null) {
2916            return null;
2917        }
2918
2919        // If this is a system upgrade scenario, delete the contents of the package cache dir.
2920        // This also serves to "GC" unused entries when the package cache version changes (which
2921        // can only happen during upgrades).
2922        if (isUpgrade) {
2923            FileUtils.deleteContents(cacheBaseDir);
2924        }
2925
2926
2927        // Return the versioned package cache directory. This is something like
2928        // "/data/system/package_cache/1"
2929        File cacheDir = FileUtils.createDir(cacheBaseDir, PACKAGE_PARSER_CACHE_VERSION);
2930
2931        // The following is a workaround to aid development on non-numbered userdebug
2932        // builds or cases where "adb sync" is used on userdebug builds. If we detect that
2933        // the system partition is newer.
2934        //
2935        // NOTE: When no BUILD_NUMBER is set by the build system, it defaults to a build
2936        // that starts with "eng." to signify that this is an engineering build and not
2937        // destined for release.
2938        if ("userdebug".equals(Build.TYPE) && Build.VERSION.INCREMENTAL.startsWith("eng.")) {
2939            Slog.w(TAG, "Wiping cache directory because the system partition changed.");
2940
2941            // Heuristic: If the /system directory has been modified recently due to an "adb sync"
2942            // or a regular make, then blow away the cache. Note that mtimes are *NOT* reliable
2943            // in general and should not be used for production changes. In this specific case,
2944            // we know that they will work.
2945            File frameworkDir = new File(Environment.getRootDirectory(), "framework");
2946            if (cacheDir.lastModified() < frameworkDir.lastModified()) {
2947                FileUtils.deleteContents(cacheBaseDir);
2948                cacheDir = FileUtils.createDir(cacheBaseDir, PACKAGE_PARSER_CACHE_VERSION);
2949            }
2950        }
2951
2952        return cacheDir;
2953    }
2954
2955    @Override
2956    public boolean isFirstBoot() {
2957        return mFirstBoot;
2958    }
2959
2960    @Override
2961    public boolean isOnlyCoreApps() {
2962        return mOnlyCore;
2963    }
2964
2965    @Override
2966    public boolean isUpgrade() {
2967        return mIsUpgrade;
2968    }
2969
2970    private @Nullable String getRequiredButNotReallyRequiredVerifierLPr() {
2971        final Intent intent = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
2972
2973        final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE,
2974                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
2975                UserHandle.USER_SYSTEM);
2976        if (matches.size() == 1) {
2977            return matches.get(0).getComponentInfo().packageName;
2978        } else if (matches.size() == 0) {
2979            Log.e(TAG, "There should probably be a verifier, but, none were found");
2980            return null;
2981        }
2982        throw new RuntimeException("There must be exactly one verifier; found " + matches);
2983    }
2984
2985    private @NonNull String getRequiredSharedLibraryLPr(String name, int version) {
2986        synchronized (mPackages) {
2987            SharedLibraryEntry libraryEntry = getSharedLibraryEntryLPr(name, version);
2988            if (libraryEntry == null) {
2989                throw new IllegalStateException("Missing required shared library:" + name);
2990            }
2991            return libraryEntry.apk;
2992        }
2993    }
2994
2995    private @NonNull String getRequiredInstallerLPr() {
2996        final Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
2997        intent.addCategory(Intent.CATEGORY_DEFAULT);
2998        intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE);
2999
3000        final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
3001                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3002                UserHandle.USER_SYSTEM);
3003        if (matches.size() == 1) {
3004            ResolveInfo resolveInfo = matches.get(0);
3005            if (!resolveInfo.activityInfo.applicationInfo.isPrivilegedApp()) {
3006                throw new RuntimeException("The installer must be a privileged app");
3007            }
3008            return matches.get(0).getComponentInfo().packageName;
3009        } else {
3010            throw new RuntimeException("There must be exactly one installer; found " + matches);
3011        }
3012    }
3013
3014    private @NonNull String getRequiredUninstallerLPr() {
3015        final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE);
3016        intent.addCategory(Intent.CATEGORY_DEFAULT);
3017        intent.setData(Uri.fromParts(PACKAGE_SCHEME, "foo.bar", null));
3018
3019        final ResolveInfo resolveInfo = resolveIntent(intent, null,
3020                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3021                UserHandle.USER_SYSTEM);
3022        if (resolveInfo == null ||
3023                mResolveActivity.name.equals(resolveInfo.getComponentInfo().name)) {
3024            throw new RuntimeException("There must be exactly one uninstaller; found "
3025                    + resolveInfo);
3026        }
3027        return resolveInfo.getComponentInfo().packageName;
3028    }
3029
3030    private @NonNull ComponentName getIntentFilterVerifierComponentNameLPr() {
3031        final Intent intent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION);
3032
3033        final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE,
3034                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3035                UserHandle.USER_SYSTEM);
3036        ResolveInfo best = null;
3037        final int N = matches.size();
3038        for (int i = 0; i < N; i++) {
3039            final ResolveInfo cur = matches.get(i);
3040            final String packageName = cur.getComponentInfo().packageName;
3041            if (checkPermission(android.Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT,
3042                    packageName, UserHandle.USER_SYSTEM) != PackageManager.PERMISSION_GRANTED) {
3043                continue;
3044            }
3045
3046            if (best == null || cur.priority > best.priority) {
3047                best = cur;
3048            }
3049        }
3050
3051        if (best != null) {
3052            return best.getComponentInfo().getComponentName();
3053        } else {
3054            throw new RuntimeException("There must be at least one intent filter verifier");
3055        }
3056    }
3057
3058    private @Nullable ComponentName getEphemeralResolverLPr() {
3059        final String[] packageArray =
3060                mContext.getResources().getStringArray(R.array.config_ephemeralResolverPackage);
3061        if (packageArray.length == 0 && !Build.IS_DEBUGGABLE) {
3062            if (DEBUG_EPHEMERAL) {
3063                Slog.d(TAG, "Ephemeral resolver NOT found; empty package list");
3064            }
3065            return null;
3066        }
3067
3068        final int resolveFlags =
3069                MATCH_DIRECT_BOOT_AWARE
3070                | MATCH_DIRECT_BOOT_UNAWARE
3071                | (!Build.IS_DEBUGGABLE ? MATCH_SYSTEM_ONLY : 0);
3072        final Intent resolverIntent = new Intent(Intent.ACTION_RESOLVE_EPHEMERAL_PACKAGE);
3073        final List<ResolveInfo> resolvers = queryIntentServicesInternal(resolverIntent, null,
3074                resolveFlags, UserHandle.USER_SYSTEM);
3075
3076        final int N = resolvers.size();
3077        if (N == 0) {
3078            if (DEBUG_EPHEMERAL) {
3079                Slog.d(TAG, "Ephemeral resolver NOT found; no matching intent filters");
3080            }
3081            return null;
3082        }
3083
3084        final Set<String> possiblePackages = new ArraySet<>(Arrays.asList(packageArray));
3085        for (int i = 0; i < N; i++) {
3086            final ResolveInfo info = resolvers.get(i);
3087
3088            if (info.serviceInfo == null) {
3089                continue;
3090            }
3091
3092            final String packageName = info.serviceInfo.packageName;
3093            if (!possiblePackages.contains(packageName) && !Build.IS_DEBUGGABLE) {
3094                if (DEBUG_EPHEMERAL) {
3095                    Slog.d(TAG, "Ephemeral resolver not in allowed package list;"
3096                            + " pkg: " + packageName + ", info:" + info);
3097                }
3098                continue;
3099            }
3100
3101            if (DEBUG_EPHEMERAL) {
3102                Slog.v(TAG, "Ephemeral resolver found;"
3103                        + " pkg: " + packageName + ", info:" + info);
3104            }
3105            return new ComponentName(packageName, info.serviceInfo.name);
3106        }
3107        if (DEBUG_EPHEMERAL) {
3108            Slog.v(TAG, "Ephemeral resolver NOT found");
3109        }
3110        return null;
3111    }
3112
3113    private @Nullable ComponentName getEphemeralInstallerLPr() {
3114        final Intent intent = new Intent(Intent.ACTION_INSTALL_EPHEMERAL_PACKAGE);
3115        intent.addCategory(Intent.CATEGORY_DEFAULT);
3116        intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE);
3117
3118        final int resolveFlags =
3119                MATCH_DIRECT_BOOT_AWARE
3120                | MATCH_DIRECT_BOOT_UNAWARE
3121                | (!Build.IS_DEBUGGABLE ? MATCH_SYSTEM_ONLY : 0);
3122        final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
3123                resolveFlags, UserHandle.USER_SYSTEM);
3124        Iterator<ResolveInfo> iter = matches.iterator();
3125        while (iter.hasNext()) {
3126            final ResolveInfo rInfo = iter.next();
3127            final PackageSetting ps = mSettings.mPackages.get(rInfo.activityInfo.packageName);
3128            if (ps != null) {
3129                final PermissionsState permissionsState = ps.getPermissionsState();
3130                if (permissionsState.hasPermission(Manifest.permission.INSTALL_PACKAGES, 0)) {
3131                    continue;
3132                }
3133            }
3134            iter.remove();
3135        }
3136        if (matches.size() == 0) {
3137            return null;
3138        } else if (matches.size() == 1) {
3139            return matches.get(0).getComponentInfo().getComponentName();
3140        } else {
3141            throw new RuntimeException(
3142                    "There must be at most one ephemeral installer; found " + matches);
3143        }
3144    }
3145
3146    private void primeDomainVerificationsLPw(int userId) {
3147        if (DEBUG_DOMAIN_VERIFICATION) {
3148            Slog.d(TAG, "Priming domain verifications in user " + userId);
3149        }
3150
3151        SystemConfig systemConfig = SystemConfig.getInstance();
3152        ArraySet<String> packages = systemConfig.getLinkedApps();
3153
3154        for (String packageName : packages) {
3155            PackageParser.Package pkg = mPackages.get(packageName);
3156            if (pkg != null) {
3157                if (!pkg.isSystemApp()) {
3158                    Slog.w(TAG, "Non-system app '" + packageName + "' in sysconfig <app-link>");
3159                    continue;
3160                }
3161
3162                ArraySet<String> domains = null;
3163                for (PackageParser.Activity a : pkg.activities) {
3164                    for (ActivityIntentInfo filter : a.intents) {
3165                        if (hasValidDomains(filter)) {
3166                            if (domains == null) {
3167                                domains = new ArraySet<String>();
3168                            }
3169                            domains.addAll(filter.getHostsList());
3170                        }
3171                    }
3172                }
3173
3174                if (domains != null && domains.size() > 0) {
3175                    if (DEBUG_DOMAIN_VERIFICATION) {
3176                        Slog.v(TAG, "      + " + packageName);
3177                    }
3178                    // 'Undefined' in the global IntentFilterVerificationInfo, i.e. the usual
3179                    // state w.r.t. the formal app-linkage "no verification attempted" state;
3180                    // and then 'always' in the per-user state actually used for intent resolution.
3181                    final IntentFilterVerificationInfo ivi;
3182                    ivi = mSettings.createIntentFilterVerificationIfNeededLPw(packageName, domains);
3183                    ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED);
3184                    mSettings.updateIntentFilterVerificationStatusLPw(packageName,
3185                            INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS, userId);
3186                } else {
3187                    Slog.w(TAG, "Sysconfig <app-link> package '" + packageName
3188                            + "' does not handle web links");
3189                }
3190            } else {
3191                Slog.w(TAG, "Unknown package " + packageName + " in sysconfig <app-link>");
3192            }
3193        }
3194
3195        scheduleWritePackageRestrictionsLocked(userId);
3196        scheduleWriteSettingsLocked();
3197    }
3198
3199    private void applyFactoryDefaultBrowserLPw(int userId) {
3200        // The default browser app's package name is stored in a string resource,
3201        // with a product-specific overlay used for vendor customization.
3202        String browserPkg = mContext.getResources().getString(
3203                com.android.internal.R.string.default_browser);
3204        if (!TextUtils.isEmpty(browserPkg)) {
3205            // non-empty string => required to be a known package
3206            PackageSetting ps = mSettings.mPackages.get(browserPkg);
3207            if (ps == null) {
3208                Slog.e(TAG, "Product default browser app does not exist: " + browserPkg);
3209                browserPkg = null;
3210            } else {
3211                mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId);
3212            }
3213        }
3214
3215        // Nothing valid explicitly set? Make the factory-installed browser the explicit
3216        // default.  If there's more than one, just leave everything alone.
3217        if (browserPkg == null) {
3218            calculateDefaultBrowserLPw(userId);
3219        }
3220    }
3221
3222    private void calculateDefaultBrowserLPw(int userId) {
3223        List<String> allBrowsers = resolveAllBrowserApps(userId);
3224        final String browserPkg = (allBrowsers.size() == 1) ? allBrowsers.get(0) : null;
3225        mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId);
3226    }
3227
3228    private List<String> resolveAllBrowserApps(int userId) {
3229        // Resolve the canonical browser intent and check that the handleAllWebDataURI boolean is set
3230        List<ResolveInfo> list = queryIntentActivitiesInternal(sBrowserIntent, null,
3231                PackageManager.MATCH_ALL, userId);
3232
3233        final int count = list.size();
3234        List<String> result = new ArrayList<String>(count);
3235        for (int i=0; i<count; i++) {
3236            ResolveInfo info = list.get(i);
3237            if (info.activityInfo == null
3238                    || !info.handleAllWebDataURI
3239                    || (info.activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0
3240                    || result.contains(info.activityInfo.packageName)) {
3241                continue;
3242            }
3243            result.add(info.activityInfo.packageName);
3244        }
3245
3246        return result;
3247    }
3248
3249    private boolean packageIsBrowser(String packageName, int userId) {
3250        List<ResolveInfo> list = queryIntentActivitiesInternal(sBrowserIntent, null,
3251                PackageManager.MATCH_ALL, userId);
3252        final int N = list.size();
3253        for (int i = 0; i < N; i++) {
3254            ResolveInfo info = list.get(i);
3255            if (packageName.equals(info.activityInfo.packageName)) {
3256                return true;
3257            }
3258        }
3259        return false;
3260    }
3261
3262    private void checkDefaultBrowser() {
3263        final int myUserId = UserHandle.myUserId();
3264        final String packageName = getDefaultBrowserPackageName(myUserId);
3265        if (packageName != null) {
3266            PackageInfo info = getPackageInfo(packageName, 0, myUserId);
3267            if (info == null) {
3268                Slog.w(TAG, "Default browser no longer installed: " + packageName);
3269                synchronized (mPackages) {
3270                    applyFactoryDefaultBrowserLPw(myUserId);    // leaves ambiguous when > 1
3271                }
3272            }
3273        }
3274    }
3275
3276    @Override
3277    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
3278            throws RemoteException {
3279        try {
3280            return super.onTransact(code, data, reply, flags);
3281        } catch (RuntimeException e) {
3282            if (!(e instanceof SecurityException) && !(e instanceof IllegalArgumentException)) {
3283                Slog.wtf(TAG, "Package Manager Crash", e);
3284            }
3285            throw e;
3286        }
3287    }
3288
3289    static int[] appendInts(int[] cur, int[] add) {
3290        if (add == null) return cur;
3291        if (cur == null) return add;
3292        final int N = add.length;
3293        for (int i=0; i<N; i++) {
3294            cur = appendInt(cur, add[i]);
3295        }
3296        return cur;
3297    }
3298
3299    private PackageInfo generatePackageInfo(PackageSetting ps, int flags, int userId) {
3300        if (!sUserManager.exists(userId)) return null;
3301        if (ps == null) {
3302            return null;
3303        }
3304        final PackageParser.Package p = ps.pkg;
3305        if (p == null) {
3306            return null;
3307        }
3308        // Filter out ephemeral app metadata:
3309        //   * The system/shell/root can see metadata for any app
3310        //   * An installed app can see metadata for 1) other installed apps
3311        //     and 2) ephemeral apps that have explicitly interacted with it
3312        //   * Ephemeral apps can only see their own metadata
3313        //   * Holding a signature permission allows seeing instant apps
3314        final int callingAppId = UserHandle.getAppId(Binder.getCallingUid());
3315        if (callingAppId != Process.SYSTEM_UID
3316                && callingAppId != Process.SHELL_UID
3317                && callingAppId != Process.ROOT_UID
3318                && checkUidPermission(Manifest.permission.ACCESS_INSTANT_APPS,
3319                        Binder.getCallingUid()) != PackageManager.PERMISSION_GRANTED) {
3320            final String ephemeralPackageName = getEphemeralPackageName(Binder.getCallingUid());
3321            if (ephemeralPackageName != null) {
3322                // ephemeral apps can only get information on themselves
3323                if (!ephemeralPackageName.equals(p.packageName)) {
3324                    return null;
3325                }
3326            } else {
3327                if (p.applicationInfo.isInstantApp()) {
3328                    // only get access to the ephemeral app if we've been granted access
3329                    if (!mInstantAppRegistry.isInstantAccessGranted(
3330                            userId, callingAppId, ps.appId)) {
3331                        return null;
3332                    }
3333                }
3334            }
3335        }
3336
3337        final PermissionsState permissionsState = ps.getPermissionsState();
3338
3339        // Compute GIDs only if requested
3340        final int[] gids = (flags & PackageManager.GET_GIDS) == 0
3341                ? EMPTY_INT_ARRAY : permissionsState.computeGids(userId);
3342        // Compute granted permissions only if package has requested permissions
3343        final Set<String> permissions = ArrayUtils.isEmpty(p.requestedPermissions)
3344                ? Collections.<String>emptySet() : permissionsState.getPermissions(userId);
3345        final PackageUserState state = ps.readUserState(userId);
3346
3347        if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0
3348                && ps.isSystem()) {
3349            flags |= MATCH_ANY_USER;
3350        }
3351
3352        PackageInfo packageInfo = PackageParser.generatePackageInfo(p, gids, flags,
3353                ps.firstInstallTime, ps.lastUpdateTime, permissions, state, userId);
3354
3355        if (packageInfo == null) {
3356            return null;
3357        }
3358
3359        packageInfo.packageName = packageInfo.applicationInfo.packageName =
3360                resolveExternalPackageNameLPr(p);
3361
3362        return packageInfo;
3363    }
3364
3365    @Override
3366    public void checkPackageStartable(String packageName, int userId) {
3367        final boolean userKeyUnlocked = StorageManager.isUserKeyUnlocked(userId);
3368
3369        synchronized (mPackages) {
3370            final PackageSetting ps = mSettings.mPackages.get(packageName);
3371            if (ps == null) {
3372                throw new SecurityException("Package " + packageName + " was not found!");
3373            }
3374
3375            if (!ps.getInstalled(userId)) {
3376                throw new SecurityException(
3377                        "Package " + packageName + " was not installed for user " + userId + "!");
3378            }
3379
3380            if (mSafeMode && !ps.isSystem()) {
3381                throw new SecurityException("Package " + packageName + " not a system app!");
3382            }
3383
3384            if (mFrozenPackages.contains(packageName)) {
3385                throw new SecurityException("Package " + packageName + " is currently frozen!");
3386            }
3387
3388            if (!userKeyUnlocked && !(ps.pkg.applicationInfo.isDirectBootAware()
3389                    || ps.pkg.applicationInfo.isPartiallyDirectBootAware())) {
3390                throw new SecurityException("Package " + packageName + " is not encryption aware!");
3391            }
3392        }
3393    }
3394
3395    @Override
3396    public boolean isPackageAvailable(String packageName, int userId) {
3397        if (!sUserManager.exists(userId)) return false;
3398        enforceCrossUserPermission(Binder.getCallingUid(), userId,
3399                false /* requireFullPermission */, false /* checkShell */, "is package available");
3400        synchronized (mPackages) {
3401            PackageParser.Package p = mPackages.get(packageName);
3402            if (p != null) {
3403                final PackageSetting ps = (PackageSetting) p.mExtras;
3404                if (ps != null) {
3405                    final PackageUserState state = ps.readUserState(userId);
3406                    if (state != null) {
3407                        return PackageParser.isAvailable(state);
3408                    }
3409                }
3410            }
3411        }
3412        return false;
3413    }
3414
3415    @Override
3416    public PackageInfo getPackageInfo(String packageName, int flags, int userId) {
3417        return getPackageInfoInternal(packageName, PackageManager.VERSION_CODE_HIGHEST,
3418                flags, userId);
3419    }
3420
3421    @Override
3422    public PackageInfo getPackageInfoVersioned(VersionedPackage versionedPackage,
3423            int flags, int userId) {
3424        return getPackageInfoInternal(versionedPackage.getPackageName(),
3425                // TODO: We will change version code to long, so in the new API it is long
3426                (int) versionedPackage.getVersionCode(), flags, userId);
3427    }
3428
3429    private PackageInfo getPackageInfoInternal(String packageName, int versionCode,
3430            int flags, int userId) {
3431        if (!sUserManager.exists(userId)) return null;
3432        flags = updateFlagsForPackage(flags, userId, packageName);
3433        enforceCrossUserPermission(Binder.getCallingUid(), userId,
3434                false /* requireFullPermission */, false /* checkShell */, "get package info");
3435
3436        // reader
3437        synchronized (mPackages) {
3438            // Normalize package name to handle renamed packages and static libs
3439            packageName = resolveInternalPackageNameLPr(packageName, versionCode);
3440
3441            final boolean matchFactoryOnly = (flags & MATCH_FACTORY_ONLY) != 0;
3442            if (matchFactoryOnly) {
3443                final PackageSetting ps = mSettings.getDisabledSystemPkgLPr(packageName);
3444                if (ps != null) {
3445                    if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId)) {
3446                        return null;
3447                    }
3448                    return generatePackageInfo(ps, flags, userId);
3449                }
3450            }
3451
3452            PackageParser.Package p = mPackages.get(packageName);
3453            if (matchFactoryOnly && p != null && !isSystemApp(p)) {
3454                return null;
3455            }
3456            if (DEBUG_PACKAGE_INFO)
3457                Log.v(TAG, "getPackageInfo " + packageName + ": " + p);
3458            if (p != null) {
3459                if (filterSharedLibPackageLPr((PackageSetting) p.mExtras,
3460                        Binder.getCallingUid(), userId)) {
3461                    return null;
3462                }
3463                return generatePackageInfo((PackageSetting)p.mExtras, flags, userId);
3464            }
3465            if (!matchFactoryOnly && (flags & MATCH_KNOWN_PACKAGES) != 0) {
3466                final PackageSetting ps = mSettings.mPackages.get(packageName);
3467                if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId)) {
3468                    return null;
3469                }
3470                return generatePackageInfo(ps, flags, userId);
3471            }
3472        }
3473        return null;
3474    }
3475
3476
3477    private boolean filterSharedLibPackageLPr(@Nullable PackageSetting ps, int uid, int userId) {
3478        // System/shell/root get to see all static libs
3479        final int appId = UserHandle.getAppId(uid);
3480        if (appId == Process.SYSTEM_UID || appId == Process.SHELL_UID
3481                || appId == Process.ROOT_UID) {
3482            return false;
3483        }
3484
3485        // No package means no static lib as it is always on internal storage
3486        if (ps == null || ps.pkg == null || !ps.pkg.applicationInfo.isStaticSharedLibrary()) {
3487            return false;
3488        }
3489
3490        final SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(ps.pkg.staticSharedLibName,
3491                ps.pkg.staticSharedLibVersion);
3492        if (libEntry == null) {
3493            return false;
3494        }
3495
3496        final int resolvedUid = UserHandle.getUid(userId, UserHandle.getAppId(uid));
3497        final String[] uidPackageNames = getPackagesForUid(resolvedUid);
3498        if (uidPackageNames == null) {
3499            return true;
3500        }
3501
3502        for (String uidPackageName : uidPackageNames) {
3503            if (ps.name.equals(uidPackageName)) {
3504                return false;
3505            }
3506            PackageSetting uidPs = mSettings.getPackageLPr(uidPackageName);
3507            if (uidPs != null) {
3508                final int index = ArrayUtils.indexOf(uidPs.usesStaticLibraries,
3509                        libEntry.info.getName());
3510                if (index < 0) {
3511                    continue;
3512                }
3513                if (uidPs.pkg.usesStaticLibrariesVersions[index] == libEntry.info.getVersion()) {
3514                    return false;
3515                }
3516            }
3517        }
3518        return true;
3519    }
3520
3521    @Override
3522    public String[] currentToCanonicalPackageNames(String[] names) {
3523        String[] out = new String[names.length];
3524        // reader
3525        synchronized (mPackages) {
3526            for (int i=names.length-1; i>=0; i--) {
3527                PackageSetting ps = mSettings.mPackages.get(names[i]);
3528                out[i] = ps != null && ps.realName != null ? ps.realName : names[i];
3529            }
3530        }
3531        return out;
3532    }
3533
3534    @Override
3535    public String[] canonicalToCurrentPackageNames(String[] names) {
3536        String[] out = new String[names.length];
3537        // reader
3538        synchronized (mPackages) {
3539            for (int i=names.length-1; i>=0; i--) {
3540                String cur = mSettings.getRenamedPackageLPr(names[i]);
3541                out[i] = cur != null ? cur : names[i];
3542            }
3543        }
3544        return out;
3545    }
3546
3547    @Override
3548    public int getPackageUid(String packageName, int flags, int userId) {
3549        if (!sUserManager.exists(userId)) return -1;
3550        flags = updateFlagsForPackage(flags, userId, packageName);
3551        enforceCrossUserPermission(Binder.getCallingUid(), userId,
3552                false /* requireFullPermission */, false /* checkShell */, "get package uid");
3553
3554        // reader
3555        synchronized (mPackages) {
3556            final PackageParser.Package p = mPackages.get(packageName);
3557            if (p != null && p.isMatch(flags)) {
3558                return UserHandle.getUid(userId, p.applicationInfo.uid);
3559            }
3560            if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
3561                final PackageSetting ps = mSettings.mPackages.get(packageName);
3562                if (ps != null && ps.isMatch(flags)) {
3563                    return UserHandle.getUid(userId, ps.appId);
3564                }
3565            }
3566        }
3567
3568        return -1;
3569    }
3570
3571    @Override
3572    public int[] getPackageGids(String packageName, int flags, int userId) {
3573        if (!sUserManager.exists(userId)) return null;
3574        flags = updateFlagsForPackage(flags, userId, packageName);
3575        enforceCrossUserPermission(Binder.getCallingUid(), userId,
3576                false /* requireFullPermission */, false /* checkShell */,
3577                "getPackageGids");
3578
3579        // reader
3580        synchronized (mPackages) {
3581            final PackageParser.Package p = mPackages.get(packageName);
3582            if (p != null && p.isMatch(flags)) {
3583                PackageSetting ps = (PackageSetting) p.mExtras;
3584                // TODO: Shouldn't this be checking for package installed state for userId and
3585                // return null?
3586                return ps.getPermissionsState().computeGids(userId);
3587            }
3588            if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
3589                final PackageSetting ps = mSettings.mPackages.get(packageName);
3590                if (ps != null && ps.isMatch(flags)) {
3591                    return ps.getPermissionsState().computeGids(userId);
3592                }
3593            }
3594        }
3595
3596        return null;
3597    }
3598
3599    static PermissionInfo generatePermissionInfo(BasePermission bp, int flags) {
3600        if (bp.perm != null) {
3601            return PackageParser.generatePermissionInfo(bp.perm, flags);
3602        }
3603        PermissionInfo pi = new PermissionInfo();
3604        pi.name = bp.name;
3605        pi.packageName = bp.sourcePackage;
3606        pi.nonLocalizedLabel = bp.name;
3607        pi.protectionLevel = bp.protectionLevel;
3608        return pi;
3609    }
3610
3611    @Override
3612    public PermissionInfo getPermissionInfo(String name, int flags) {
3613        // reader
3614        synchronized (mPackages) {
3615            final BasePermission p = mSettings.mPermissions.get(name);
3616            if (p != null) {
3617                return generatePermissionInfo(p, flags);
3618            }
3619            return null;
3620        }
3621    }
3622
3623    @Override
3624    public @Nullable ParceledListSlice<PermissionInfo> queryPermissionsByGroup(String group,
3625            int flags) {
3626        // reader
3627        synchronized (mPackages) {
3628            if (group != null && !mPermissionGroups.containsKey(group)) {
3629                // This is thrown as NameNotFoundException
3630                return null;
3631            }
3632
3633            ArrayList<PermissionInfo> out = new ArrayList<PermissionInfo>(10);
3634            for (BasePermission p : mSettings.mPermissions.values()) {
3635                if (group == null) {
3636                    if (p.perm == null || p.perm.info.group == null) {
3637                        out.add(generatePermissionInfo(p, flags));
3638                    }
3639                } else {
3640                    if (p.perm != null && group.equals(p.perm.info.group)) {
3641                        out.add(PackageParser.generatePermissionInfo(p.perm, flags));
3642                    }
3643                }
3644            }
3645            return new ParceledListSlice<>(out);
3646        }
3647    }
3648
3649    @Override
3650    public PermissionGroupInfo getPermissionGroupInfo(String name, int flags) {
3651        // reader
3652        synchronized (mPackages) {
3653            return PackageParser.generatePermissionGroupInfo(
3654                    mPermissionGroups.get(name), flags);
3655        }
3656    }
3657
3658    @Override
3659    public @NonNull ParceledListSlice<PermissionGroupInfo> getAllPermissionGroups(int flags) {
3660        // reader
3661        synchronized (mPackages) {
3662            final int N = mPermissionGroups.size();
3663            ArrayList<PermissionGroupInfo> out
3664                    = new ArrayList<PermissionGroupInfo>(N);
3665            for (PackageParser.PermissionGroup pg : mPermissionGroups.values()) {
3666                out.add(PackageParser.generatePermissionGroupInfo(pg, flags));
3667            }
3668            return new ParceledListSlice<>(out);
3669        }
3670    }
3671
3672    private ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName, int flags,
3673            int uid, int userId) {
3674        if (!sUserManager.exists(userId)) return null;
3675        PackageSetting ps = mSettings.mPackages.get(packageName);
3676        if (ps != null) {
3677            if (filterSharedLibPackageLPr(ps, uid, userId)) {
3678                return null;
3679            }
3680            if (ps.pkg == null) {
3681                final PackageInfo pInfo = generatePackageInfo(ps, flags, userId);
3682                if (pInfo != null) {
3683                    return pInfo.applicationInfo;
3684                }
3685                return null;
3686            }
3687            ApplicationInfo ai = PackageParser.generateApplicationInfo(ps.pkg, flags,
3688                    ps.readUserState(userId), userId);
3689            if (ai != null) {
3690                ai.packageName = resolveExternalPackageNameLPr(ps.pkg);
3691            }
3692            return ai;
3693        }
3694        return null;
3695    }
3696
3697    @Override
3698    public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) {
3699        if (!sUserManager.exists(userId)) return null;
3700        flags = updateFlagsForApplication(flags, userId, packageName);
3701        enforceCrossUserPermission(Binder.getCallingUid(), userId,
3702                false /* requireFullPermission */, false /* checkShell */, "get application info");
3703
3704        // writer
3705        synchronized (mPackages) {
3706            // Normalize package name to handle renamed packages and static libs
3707            packageName = resolveInternalPackageNameLPr(packageName,
3708                    PackageManager.VERSION_CODE_HIGHEST);
3709
3710            PackageParser.Package p = mPackages.get(packageName);
3711            if (DEBUG_PACKAGE_INFO) Log.v(
3712                    TAG, "getApplicationInfo " + packageName
3713                    + ": " + p);
3714            if (p != null) {
3715                PackageSetting ps = mSettings.mPackages.get(packageName);
3716                if (ps == null) return null;
3717                if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId)) {
3718                    return null;
3719                }
3720                // Note: isEnabledLP() does not apply here - always return info
3721                ApplicationInfo ai = PackageParser.generateApplicationInfo(
3722                        p, flags, ps.readUserState(userId), userId);
3723                if (ai != null) {
3724                    ai.packageName = resolveExternalPackageNameLPr(p);
3725                }
3726                return ai;
3727            }
3728            if ("android".equals(packageName)||"system".equals(packageName)) {
3729                return mAndroidApplication;
3730            }
3731            if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
3732                // Already generates the external package name
3733                return generateApplicationInfoFromSettingsLPw(packageName,
3734                        Binder.getCallingUid(), flags, userId);
3735            }
3736        }
3737        return null;
3738    }
3739
3740    private String normalizePackageNameLPr(String packageName) {
3741        String normalizedPackageName = mSettings.getRenamedPackageLPr(packageName);
3742        return normalizedPackageName != null ? normalizedPackageName : packageName;
3743    }
3744
3745    @Override
3746    public void freeStorageAndNotify(final String volumeUuid, final long freeStorageSize,
3747            final IPackageDataObserver observer) {
3748        mContext.enforceCallingOrSelfPermission(
3749                android.Manifest.permission.CLEAR_APP_CACHE, null);
3750        // Queue up an async operation since clearing cache may take a little while.
3751        mHandler.post(new Runnable() {
3752            public void run() {
3753                mHandler.removeCallbacks(this);
3754                boolean success = true;
3755                synchronized (mInstallLock) {
3756                    try {
3757                        mInstaller.freeCache(volumeUuid, freeStorageSize, 0);
3758                    } catch (InstallerException e) {
3759                        Slog.w(TAG, "Couldn't clear application caches: " + e);
3760                        success = false;
3761                    }
3762                }
3763                if (observer != null) {
3764                    try {
3765                        observer.onRemoveCompleted(null, success);
3766                    } catch (RemoteException e) {
3767                        Slog.w(TAG, "RemoveException when invoking call back");
3768                    }
3769                }
3770            }
3771        });
3772    }
3773
3774    @Override
3775    public void freeStorage(final String volumeUuid, final long freeStorageSize,
3776            final IntentSender pi) {
3777        mContext.enforceCallingOrSelfPermission(
3778                android.Manifest.permission.CLEAR_APP_CACHE, null);
3779        // Queue up an async operation since clearing cache may take a little while.
3780        mHandler.post(new Runnable() {
3781            public void run() {
3782                mHandler.removeCallbacks(this);
3783                boolean success = true;
3784                synchronized (mInstallLock) {
3785                    try {
3786                        mInstaller.freeCache(volumeUuid, freeStorageSize, 0);
3787                    } catch (InstallerException e) {
3788                        Slog.w(TAG, "Couldn't clear application caches: " + e);
3789                        success = false;
3790                    }
3791                }
3792                if(pi != null) {
3793                    try {
3794                        // Callback via pending intent
3795                        int code = success ? 1 : 0;
3796                        pi.sendIntent(null, code, null,
3797                                null, null);
3798                    } catch (SendIntentException e1) {
3799                        Slog.i(TAG, "Failed to send pending intent");
3800                    }
3801                }
3802            }
3803        });
3804    }
3805
3806    void freeStorage(String volumeUuid, long freeStorageSize) throws IOException {
3807        synchronized (mInstallLock) {
3808            try {
3809                mInstaller.freeCache(volumeUuid, freeStorageSize, 0);
3810            } catch (InstallerException e) {
3811                throw new IOException("Failed to free enough space", e);
3812            }
3813        }
3814    }
3815
3816    /**
3817     * Update given flags based on encryption status of current user.
3818     */
3819    private int updateFlags(int flags, int userId) {
3820        if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
3821                | PackageManager.MATCH_DIRECT_BOOT_AWARE)) != 0) {
3822            // Caller expressed an explicit opinion about what encryption
3823            // aware/unaware components they want to see, so fall through and
3824            // give them what they want
3825        } else {
3826            // Caller expressed no opinion, so match based on user state
3827            if (getUserManagerInternal().isUserUnlockingOrUnlocked(userId)) {
3828                flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE;
3829            } else {
3830                flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE;
3831            }
3832        }
3833        return flags;
3834    }
3835
3836    private UserManagerInternal getUserManagerInternal() {
3837        if (mUserManagerInternal == null) {
3838            mUserManagerInternal = LocalServices.getService(UserManagerInternal.class);
3839        }
3840        return mUserManagerInternal;
3841    }
3842
3843    /**
3844     * Update given flags when being used to request {@link PackageInfo}.
3845     */
3846    private int updateFlagsForPackage(int flags, int userId, Object cookie) {
3847        final boolean isCallerSystemUser = UserHandle.getCallingUserId() == UserHandle.USER_SYSTEM;
3848        boolean triaged = true;
3849        if ((flags & (PackageManager.GET_ACTIVITIES | PackageManager.GET_RECEIVERS
3850                | PackageManager.GET_SERVICES | PackageManager.GET_PROVIDERS)) != 0) {
3851            // Caller is asking for component details, so they'd better be
3852            // asking for specific encryption matching behavior, or be triaged
3853            if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
3854                    | PackageManager.MATCH_DIRECT_BOOT_AWARE
3855                    | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
3856                triaged = false;
3857            }
3858        }
3859        if ((flags & (PackageManager.MATCH_UNINSTALLED_PACKAGES
3860                | PackageManager.MATCH_SYSTEM_ONLY
3861                | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
3862            triaged = false;
3863        }
3864        if ((flags & PackageManager.MATCH_ANY_USER) != 0) {
3865            enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false,
3866                    "MATCH_ANY_USER flag requires INTERACT_ACROSS_USERS permission at "
3867                    + Debug.getCallers(5));
3868        } else if ((flags & PackageManager.MATCH_UNINSTALLED_PACKAGES) != 0 && isCallerSystemUser
3869                && sUserManager.hasManagedProfile(UserHandle.USER_SYSTEM)) {
3870            // If the caller wants all packages and has a restricted profile associated with it,
3871            // then match all users. This is to make sure that launchers that need to access work
3872            // profile apps don't start breaking. TODO: Remove this hack when launchers stop using
3873            // MATCH_UNINSTALLED_PACKAGES to query apps in other profiles. b/31000380
3874            flags |= PackageManager.MATCH_ANY_USER;
3875        }
3876        if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) {
3877            Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie
3878                    + " with flags 0x" + Integer.toHexString(flags), new Throwable());
3879        }
3880        return updateFlags(flags, userId);
3881    }
3882
3883    /**
3884     * Update given flags when being used to request {@link ApplicationInfo}.
3885     */
3886    private int updateFlagsForApplication(int flags, int userId, Object cookie) {
3887        return updateFlagsForPackage(flags, userId, cookie);
3888    }
3889
3890    /**
3891     * Update given flags when being used to request {@link ComponentInfo}.
3892     */
3893    private int updateFlagsForComponent(int flags, int userId, Object cookie) {
3894        if (cookie instanceof Intent) {
3895            if ((((Intent) cookie).getFlags() & Intent.FLAG_DEBUG_TRIAGED_MISSING) != 0) {
3896                flags |= PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
3897            }
3898        }
3899
3900        boolean triaged = true;
3901        // Caller is asking for component details, so they'd better be
3902        // asking for specific encryption matching behavior, or be triaged
3903        if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
3904                | PackageManager.MATCH_DIRECT_BOOT_AWARE
3905                | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
3906            triaged = false;
3907        }
3908        if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) {
3909            Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie
3910                    + " with flags 0x" + Integer.toHexString(flags), new Throwable());
3911        }
3912
3913        return updateFlags(flags, userId);
3914    }
3915
3916    /**
3917     * Update given intent when being used to request {@link ResolveInfo}.
3918     */
3919    private Intent updateIntentForResolve(Intent intent) {
3920        if (intent.getSelector() != null) {
3921            intent = intent.getSelector();
3922        }
3923        if (DEBUG_PREFERRED) {
3924            intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION);
3925        }
3926        return intent;
3927    }
3928
3929    /**
3930     * Update given flags when being used to request {@link ResolveInfo}.
3931     */
3932    int updateFlagsForResolve(int flags, int userId, Object cookie) {
3933        // Safe mode means we shouldn't match any third-party components
3934        if (mSafeMode) {
3935            flags |= PackageManager.MATCH_SYSTEM_ONLY;
3936        }
3937        final int callingUid = Binder.getCallingUid();
3938        if (callingUid == Process.SYSTEM_UID || callingUid == 0) {
3939            // The system sees all components
3940            flags |= PackageManager.MATCH_EPHEMERAL;
3941        } else if (getEphemeralPackageName(callingUid) != null) {
3942            // But, ephemeral apps see both ephemeral and exposed, non-ephemeral components
3943            flags |= PackageManager.MATCH_VISIBLE_TO_EPHEMERAL_ONLY;
3944            flags |= PackageManager.MATCH_EPHEMERAL;
3945        } else {
3946            // Otherwise, prevent leaking ephemeral components
3947            flags &= ~PackageManager.MATCH_VISIBLE_TO_EPHEMERAL_ONLY;
3948            flags &= ~PackageManager.MATCH_EPHEMERAL;
3949        }
3950        return updateFlagsForComponent(flags, userId, cookie);
3951    }
3952
3953    @Override
3954    public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) {
3955        if (!sUserManager.exists(userId)) return null;
3956        flags = updateFlagsForComponent(flags, userId, component);
3957        enforceCrossUserPermission(Binder.getCallingUid(), userId,
3958                false /* requireFullPermission */, false /* checkShell */, "get activity info");
3959        synchronized (mPackages) {
3960            PackageParser.Activity a = mActivities.mActivities.get(component);
3961
3962            if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a);
3963            if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) {
3964                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
3965                if (ps == null) return null;
3966                return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId),
3967                        userId);
3968            }
3969            if (mResolveComponentName.equals(component)) {
3970                return PackageParser.generateActivityInfo(mResolveActivity, flags,
3971                        new PackageUserState(), userId);
3972            }
3973        }
3974        return null;
3975    }
3976
3977    @Override
3978    public boolean activitySupportsIntent(ComponentName component, Intent intent,
3979            String resolvedType) {
3980        synchronized (mPackages) {
3981            if (component.equals(mResolveComponentName)) {
3982                // The resolver supports EVERYTHING!
3983                return true;
3984            }
3985            PackageParser.Activity a = mActivities.mActivities.get(component);
3986            if (a == null) {
3987                return false;
3988            }
3989            for (int i=0; i<a.intents.size(); i++) {
3990                if (a.intents.get(i).match(intent.getAction(), resolvedType, intent.getScheme(),
3991                        intent.getData(), intent.getCategories(), TAG) >= 0) {
3992                    return true;
3993                }
3994            }
3995            return false;
3996        }
3997    }
3998
3999    @Override
4000    public ActivityInfo getReceiverInfo(ComponentName component, int flags, int userId) {
4001        if (!sUserManager.exists(userId)) return null;
4002        flags = updateFlagsForComponent(flags, userId, component);
4003        enforceCrossUserPermission(Binder.getCallingUid(), userId,
4004                false /* requireFullPermission */, false /* checkShell */, "get receiver info");
4005        synchronized (mPackages) {
4006            PackageParser.Activity a = mReceivers.mActivities.get(component);
4007            if (DEBUG_PACKAGE_INFO) Log.v(
4008                TAG, "getReceiverInfo " + component + ": " + a);
4009            if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) {
4010                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
4011                if (ps == null) return null;
4012                return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId),
4013                        userId);
4014            }
4015        }
4016        return null;
4017    }
4018
4019    @Override
4020    public ParceledListSlice<SharedLibraryInfo> getSharedLibraries(int flags, int userId) {
4021        if (!sUserManager.exists(userId)) return null;
4022        Preconditions.checkArgumentNonnegative(userId, "userId must be >= 0");
4023
4024        flags = updateFlagsForPackage(flags, userId, null);
4025
4026        final boolean canSeeStaticLibraries =
4027                mContext.checkCallingOrSelfPermission(INSTALL_PACKAGES)
4028                        == PERMISSION_GRANTED
4029                || mContext.checkCallingOrSelfPermission(DELETE_PACKAGES)
4030                        == PERMISSION_GRANTED
4031                || mContext.checkCallingOrSelfPermission(REQUEST_INSTALL_PACKAGES)
4032                        == PERMISSION_GRANTED
4033                || mContext.checkCallingOrSelfPermission(REQUEST_DELETE_PACKAGES)
4034                        == PERMISSION_GRANTED;
4035
4036        synchronized (mPackages) {
4037            List<SharedLibraryInfo> result = null;
4038
4039            final int libCount = mSharedLibraries.size();
4040            for (int i = 0; i < libCount; i++) {
4041                SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.valueAt(i);
4042                if (versionedLib == null) {
4043                    continue;
4044                }
4045
4046                final int versionCount = versionedLib.size();
4047                for (int j = 0; j < versionCount; j++) {
4048                    SharedLibraryInfo libInfo = versionedLib.valueAt(j).info;
4049                    if (!canSeeStaticLibraries && libInfo.isStatic()) {
4050                        break;
4051                    }
4052                    final long identity = Binder.clearCallingIdentity();
4053                    try {
4054                        // TODO: We will change version code to long, so in the new API it is long
4055                        PackageInfo packageInfo = getPackageInfoVersioned(
4056                                libInfo.getDeclaringPackage(), flags, userId);
4057                        if (packageInfo == null) {
4058                            continue;
4059                        }
4060                    } finally {
4061                        Binder.restoreCallingIdentity(identity);
4062                    }
4063
4064                    SharedLibraryInfo resLibInfo = new SharedLibraryInfo(libInfo.getName(),
4065                            libInfo.getVersion(), libInfo.getType(), libInfo.getDeclaringPackage(),
4066                            getPackagesUsingSharedLibraryLPr(libInfo, flags, userId));
4067
4068                    if (result == null) {
4069                        result = new ArrayList<>();
4070                    }
4071                    result.add(resLibInfo);
4072                }
4073            }
4074
4075            return result != null ? new ParceledListSlice<>(result) : null;
4076        }
4077    }
4078
4079    private List<VersionedPackage> getPackagesUsingSharedLibraryLPr(
4080            SharedLibraryInfo libInfo, int flags, int userId) {
4081        List<VersionedPackage> versionedPackages = null;
4082        final int packageCount = mSettings.mPackages.size();
4083        for (int i = 0; i < packageCount; i++) {
4084            PackageSetting ps = mSettings.mPackages.valueAt(i);
4085
4086            if (ps == null) {
4087                continue;
4088            }
4089
4090            if (!ps.getUserState().get(userId).isAvailable(flags)) {
4091                continue;
4092            }
4093
4094            final String libName = libInfo.getName();
4095            if (libInfo.isStatic()) {
4096                final int libIdx = ArrayUtils.indexOf(ps.usesStaticLibraries, libName);
4097                if (libIdx < 0) {
4098                    continue;
4099                }
4100                if (ps.usesStaticLibrariesVersions[libIdx] != libInfo.getVersion()) {
4101                    continue;
4102                }
4103                if (versionedPackages == null) {
4104                    versionedPackages = new ArrayList<>();
4105                }
4106                // If the dependent is a static shared lib, use the public package name
4107                String dependentPackageName = ps.name;
4108                if (ps.pkg != null && ps.pkg.applicationInfo.isStaticSharedLibrary()) {
4109                    dependentPackageName = ps.pkg.manifestPackageName;
4110                }
4111                versionedPackages.add(new VersionedPackage(dependentPackageName, ps.versionCode));
4112            } else if (ps.pkg != null) {
4113                if (ArrayUtils.contains(ps.pkg.usesLibraries, libName)
4114                        || ArrayUtils.contains(ps.pkg.usesOptionalLibraries, libName)) {
4115                    if (versionedPackages == null) {
4116                        versionedPackages = new ArrayList<>();
4117                    }
4118                    versionedPackages.add(new VersionedPackage(ps.name, ps.versionCode));
4119                }
4120            }
4121        }
4122
4123        return versionedPackages;
4124    }
4125
4126    @Override
4127    public ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) {
4128        if (!sUserManager.exists(userId)) return null;
4129        flags = updateFlagsForComponent(flags, userId, component);
4130        enforceCrossUserPermission(Binder.getCallingUid(), userId,
4131                false /* requireFullPermission */, false /* checkShell */, "get service info");
4132        synchronized (mPackages) {
4133            PackageParser.Service s = mServices.mServices.get(component);
4134            if (DEBUG_PACKAGE_INFO) Log.v(
4135                TAG, "getServiceInfo " + component + ": " + s);
4136            if (s != null && mSettings.isEnabledAndMatchLPr(s.info, flags, userId)) {
4137                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
4138                if (ps == null) return null;
4139                return PackageParser.generateServiceInfo(s, flags, ps.readUserState(userId),
4140                        userId);
4141            }
4142        }
4143        return null;
4144    }
4145
4146    @Override
4147    public ProviderInfo getProviderInfo(ComponentName component, int flags, int userId) {
4148        if (!sUserManager.exists(userId)) return null;
4149        flags = updateFlagsForComponent(flags, userId, component);
4150        enforceCrossUserPermission(Binder.getCallingUid(), userId,
4151                false /* requireFullPermission */, false /* checkShell */, "get provider info");
4152        synchronized (mPackages) {
4153            PackageParser.Provider p = mProviders.mProviders.get(component);
4154            if (DEBUG_PACKAGE_INFO) Log.v(
4155                TAG, "getProviderInfo " + component + ": " + p);
4156            if (p != null && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) {
4157                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
4158                if (ps == null) return null;
4159                return PackageParser.generateProviderInfo(p, flags, ps.readUserState(userId),
4160                        userId);
4161            }
4162        }
4163        return null;
4164    }
4165
4166    @Override
4167    public String[] getSystemSharedLibraryNames() {
4168        synchronized (mPackages) {
4169            Set<String> libs = null;
4170            final int libCount = mSharedLibraries.size();
4171            for (int i = 0; i < libCount; i++) {
4172                SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.valueAt(i);
4173                if (versionedLib == null) {
4174                    continue;
4175                }
4176                final int versionCount = versionedLib.size();
4177                for (int j = 0; j < versionCount; j++) {
4178                    SharedLibraryEntry libEntry = versionedLib.valueAt(j);
4179                    if (!libEntry.info.isStatic()) {
4180                        if (libs == null) {
4181                            libs = new ArraySet<>();
4182                        }
4183                        libs.add(libEntry.info.getName());
4184                        break;
4185                    }
4186                    PackageSetting ps = mSettings.getPackageLPr(libEntry.apk);
4187                    if (ps != null && !filterSharedLibPackageLPr(ps, Binder.getCallingUid(),
4188                            UserHandle.getUserId(Binder.getCallingUid()))) {
4189                        if (libs == null) {
4190                            libs = new ArraySet<>();
4191                        }
4192                        libs.add(libEntry.info.getName());
4193                        break;
4194                    }
4195                }
4196            }
4197
4198            if (libs != null) {
4199                String[] libsArray = new String[libs.size()];
4200                libs.toArray(libsArray);
4201                return libsArray;
4202            }
4203
4204            return null;
4205        }
4206    }
4207
4208    @Override
4209    public @NonNull String getServicesSystemSharedLibraryPackageName() {
4210        synchronized (mPackages) {
4211            return mServicesSystemSharedLibraryPackageName;
4212        }
4213    }
4214
4215    @Override
4216    public @NonNull String getSharedSystemSharedLibraryPackageName() {
4217        synchronized (mPackages) {
4218            return mSharedSystemSharedLibraryPackageName;
4219        }
4220    }
4221
4222    @Override
4223    public @NonNull ParceledListSlice<FeatureInfo> getSystemAvailableFeatures() {
4224        ArrayList<FeatureInfo> res;
4225        synchronized (mAvailableFeatures) {
4226            res = new ArrayList<>(mAvailableFeatures.size() + 1);
4227            res.addAll(mAvailableFeatures.values());
4228        }
4229        final FeatureInfo fi = new FeatureInfo();
4230        fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version",
4231                FeatureInfo.GL_ES_VERSION_UNDEFINED);
4232        res.add(fi);
4233
4234        return new ParceledListSlice<>(res);
4235    }
4236
4237    @Override
4238    public boolean hasSystemFeature(String name, int version) {
4239        synchronized (mAvailableFeatures) {
4240            final FeatureInfo feat = mAvailableFeatures.get(name);
4241            if (feat == null) {
4242                return false;
4243            } else {
4244                return feat.version >= version;
4245            }
4246        }
4247    }
4248
4249    @Override
4250    public int checkPermission(String permName, String pkgName, int userId) {
4251        if (!sUserManager.exists(userId)) {
4252            return PackageManager.PERMISSION_DENIED;
4253        }
4254
4255        synchronized (mPackages) {
4256            final PackageParser.Package p = mPackages.get(pkgName);
4257            if (p != null && p.mExtras != null) {
4258                final PackageSetting ps = (PackageSetting) p.mExtras;
4259                final PermissionsState permissionsState = ps.getPermissionsState();
4260                if (permissionsState.hasPermission(permName, userId)) {
4261                    return PackageManager.PERMISSION_GRANTED;
4262                }
4263                // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION
4264                if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState
4265                        .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) {
4266                    return PackageManager.PERMISSION_GRANTED;
4267                }
4268            }
4269        }
4270
4271        return PackageManager.PERMISSION_DENIED;
4272    }
4273
4274    @Override
4275    public int checkUidPermission(String permName, int uid) {
4276        final int userId = UserHandle.getUserId(uid);
4277
4278        if (!sUserManager.exists(userId)) {
4279            return PackageManager.PERMISSION_DENIED;
4280        }
4281
4282        synchronized (mPackages) {
4283            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
4284            if (obj != null) {
4285                final SettingBase ps = (SettingBase) obj;
4286                final PermissionsState permissionsState = ps.getPermissionsState();
4287                if (permissionsState.hasPermission(permName, userId)) {
4288                    return PackageManager.PERMISSION_GRANTED;
4289                }
4290                // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION
4291                if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState
4292                        .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) {
4293                    return PackageManager.PERMISSION_GRANTED;
4294                }
4295            } else {
4296                ArraySet<String> perms = mSystemPermissions.get(uid);
4297                if (perms != null) {
4298                    if (perms.contains(permName)) {
4299                        return PackageManager.PERMISSION_GRANTED;
4300                    }
4301                    if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && perms
4302                            .contains(Manifest.permission.ACCESS_FINE_LOCATION)) {
4303                        return PackageManager.PERMISSION_GRANTED;
4304                    }
4305                }
4306            }
4307        }
4308
4309        return PackageManager.PERMISSION_DENIED;
4310    }
4311
4312    @Override
4313    public boolean isPermissionRevokedByPolicy(String permission, String packageName, int userId) {
4314        if (UserHandle.getCallingUserId() != userId) {
4315            mContext.enforceCallingPermission(
4316                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
4317                    "isPermissionRevokedByPolicy for user " + userId);
4318        }
4319
4320        if (checkPermission(permission, packageName, userId)
4321                == PackageManager.PERMISSION_GRANTED) {
4322            return false;
4323        }
4324
4325        final long identity = Binder.clearCallingIdentity();
4326        try {
4327            final int flags = getPermissionFlags(permission, packageName, userId);
4328            return (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0;
4329        } finally {
4330            Binder.restoreCallingIdentity(identity);
4331        }
4332    }
4333
4334    @Override
4335    public String getPermissionControllerPackageName() {
4336        synchronized (mPackages) {
4337            return mRequiredInstallerPackage;
4338        }
4339    }
4340
4341    /**
4342     * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS
4343     * or INTERACT_ACROSS_USERS_FULL permissions, if the userid is not for the caller.
4344     * @param checkShell whether to prevent shell from access if there's a debugging restriction
4345     * @param message the message to log on security exception
4346     */
4347    void enforceCrossUserPermission(int callingUid, int userId, boolean requireFullPermission,
4348            boolean checkShell, String message) {
4349        if (userId < 0) {
4350            throw new IllegalArgumentException("Invalid userId " + userId);
4351        }
4352        if (checkShell) {
4353            enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId);
4354        }
4355        if (userId == UserHandle.getUserId(callingUid)) return;
4356        if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
4357            if (requireFullPermission) {
4358                mContext.enforceCallingOrSelfPermission(
4359                        android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
4360            } else {
4361                try {
4362                    mContext.enforceCallingOrSelfPermission(
4363                            android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
4364                } catch (SecurityException se) {
4365                    mContext.enforceCallingOrSelfPermission(
4366                            android.Manifest.permission.INTERACT_ACROSS_USERS, message);
4367                }
4368            }
4369        }
4370    }
4371
4372    void enforceShellRestriction(String restriction, int callingUid, int userHandle) {
4373        if (callingUid == Process.SHELL_UID) {
4374            if (userHandle >= 0
4375                    && sUserManager.hasUserRestriction(restriction, userHandle)) {
4376                throw new SecurityException("Shell does not have permission to access user "
4377                        + userHandle);
4378            } else if (userHandle < 0) {
4379                Slog.e(TAG, "Unable to check shell permission for user " + userHandle + "\n\t"
4380                        + Debug.getCallers(3));
4381            }
4382        }
4383    }
4384
4385    private BasePermission findPermissionTreeLP(String permName) {
4386        for(BasePermission bp : mSettings.mPermissionTrees.values()) {
4387            if (permName.startsWith(bp.name) &&
4388                    permName.length() > bp.name.length() &&
4389                    permName.charAt(bp.name.length()) == '.') {
4390                return bp;
4391            }
4392        }
4393        return null;
4394    }
4395
4396    private BasePermission checkPermissionTreeLP(String permName) {
4397        if (permName != null) {
4398            BasePermission bp = findPermissionTreeLP(permName);
4399            if (bp != null) {
4400                if (bp.uid == UserHandle.getAppId(Binder.getCallingUid())) {
4401                    return bp;
4402                }
4403                throw new SecurityException("Calling uid "
4404                        + Binder.getCallingUid()
4405                        + " is not allowed to add to permission tree "
4406                        + bp.name + " owned by uid " + bp.uid);
4407            }
4408        }
4409        throw new SecurityException("No permission tree found for " + permName);
4410    }
4411
4412    static boolean compareStrings(CharSequence s1, CharSequence s2) {
4413        if (s1 == null) {
4414            return s2 == null;
4415        }
4416        if (s2 == null) {
4417            return false;
4418        }
4419        if (s1.getClass() != s2.getClass()) {
4420            return false;
4421        }
4422        return s1.equals(s2);
4423    }
4424
4425    static boolean comparePermissionInfos(PermissionInfo pi1, PermissionInfo pi2) {
4426        if (pi1.icon != pi2.icon) return false;
4427        if (pi1.logo != pi2.logo) return false;
4428        if (pi1.protectionLevel != pi2.protectionLevel) return false;
4429        if (!compareStrings(pi1.name, pi2.name)) return false;
4430        if (!compareStrings(pi1.nonLocalizedLabel, pi2.nonLocalizedLabel)) return false;
4431        // We'll take care of setting this one.
4432        if (!compareStrings(pi1.packageName, pi2.packageName)) return false;
4433        // These are not currently stored in settings.
4434        //if (!compareStrings(pi1.group, pi2.group)) return false;
4435        //if (!compareStrings(pi1.nonLocalizedDescription, pi2.nonLocalizedDescription)) return false;
4436        //if (pi1.labelRes != pi2.labelRes) return false;
4437        //if (pi1.descriptionRes != pi2.descriptionRes) return false;
4438        return true;
4439    }
4440
4441    int permissionInfoFootprint(PermissionInfo info) {
4442        int size = info.name.length();
4443        if (info.nonLocalizedLabel != null) size += info.nonLocalizedLabel.length();
4444        if (info.nonLocalizedDescription != null) size += info.nonLocalizedDescription.length();
4445        return size;
4446    }
4447
4448    int calculateCurrentPermissionFootprintLocked(BasePermission tree) {
4449        int size = 0;
4450        for (BasePermission perm : mSettings.mPermissions.values()) {
4451            if (perm.uid == tree.uid) {
4452                size += perm.name.length() + permissionInfoFootprint(perm.perm.info);
4453            }
4454        }
4455        return size;
4456    }
4457
4458    void enforcePermissionCapLocked(PermissionInfo info, BasePermission tree) {
4459        // We calculate the max size of permissions defined by this uid and throw
4460        // if that plus the size of 'info' would exceed our stated maximum.
4461        if (tree.uid != Process.SYSTEM_UID) {
4462            final int curTreeSize = calculateCurrentPermissionFootprintLocked(tree);
4463            if (curTreeSize + permissionInfoFootprint(info) > MAX_PERMISSION_TREE_FOOTPRINT) {
4464                throw new SecurityException("Permission tree size cap exceeded");
4465            }
4466        }
4467    }
4468
4469    boolean addPermissionLocked(PermissionInfo info, boolean async) {
4470        if (info.labelRes == 0 && info.nonLocalizedLabel == null) {
4471            throw new SecurityException("Label must be specified in permission");
4472        }
4473        BasePermission tree = checkPermissionTreeLP(info.name);
4474        BasePermission bp = mSettings.mPermissions.get(info.name);
4475        boolean added = bp == null;
4476        boolean changed = true;
4477        int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel);
4478        if (added) {
4479            enforcePermissionCapLocked(info, tree);
4480            bp = new BasePermission(info.name, tree.sourcePackage,
4481                    BasePermission.TYPE_DYNAMIC);
4482        } else if (bp.type != BasePermission.TYPE_DYNAMIC) {
4483            throw new SecurityException(
4484                    "Not allowed to modify non-dynamic permission "
4485                    + info.name);
4486        } else {
4487            if (bp.protectionLevel == fixedLevel
4488                    && bp.perm.owner.equals(tree.perm.owner)
4489                    && bp.uid == tree.uid
4490                    && comparePermissionInfos(bp.perm.info, info)) {
4491                changed = false;
4492            }
4493        }
4494        bp.protectionLevel = fixedLevel;
4495        info = new PermissionInfo(info);
4496        info.protectionLevel = fixedLevel;
4497        bp.perm = new PackageParser.Permission(tree.perm.owner, info);
4498        bp.perm.info.packageName = tree.perm.info.packageName;
4499        bp.uid = tree.uid;
4500        if (added) {
4501            mSettings.mPermissions.put(info.name, bp);
4502        }
4503        if (changed) {
4504            if (!async) {
4505                mSettings.writeLPr();
4506            } else {
4507                scheduleWriteSettingsLocked();
4508            }
4509        }
4510        return added;
4511    }
4512
4513    @Override
4514    public boolean addPermission(PermissionInfo info) {
4515        synchronized (mPackages) {
4516            return addPermissionLocked(info, false);
4517        }
4518    }
4519
4520    @Override
4521    public boolean addPermissionAsync(PermissionInfo info) {
4522        synchronized (mPackages) {
4523            return addPermissionLocked(info, true);
4524        }
4525    }
4526
4527    @Override
4528    public void removePermission(String name) {
4529        synchronized (mPackages) {
4530            checkPermissionTreeLP(name);
4531            BasePermission bp = mSettings.mPermissions.get(name);
4532            if (bp != null) {
4533                if (bp.type != BasePermission.TYPE_DYNAMIC) {
4534                    throw new SecurityException(
4535                            "Not allowed to modify non-dynamic permission "
4536                            + name);
4537                }
4538                mSettings.mPermissions.remove(name);
4539                mSettings.writeLPr();
4540            }
4541        }
4542    }
4543
4544    private static void enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(PackageParser.Package pkg,
4545            BasePermission bp) {
4546        int index = pkg.requestedPermissions.indexOf(bp.name);
4547        if (index == -1) {
4548            throw new SecurityException("Package " + pkg.packageName
4549                    + " has not requested permission " + bp.name);
4550        }
4551        if (!bp.isRuntime() && !bp.isDevelopment()) {
4552            throw new SecurityException("Permission " + bp.name
4553                    + " is not a changeable permission type");
4554        }
4555    }
4556
4557    @Override
4558    public void grantRuntimePermission(String packageName, String name, final int userId) {
4559        grantRuntimePermission(packageName, name, userId, false /* Only if not fixed by policy */);
4560    }
4561
4562    private void grantRuntimePermission(String packageName, String name, final int userId,
4563            boolean overridePolicy) {
4564        if (!sUserManager.exists(userId)) {
4565            Log.e(TAG, "No such user:" + userId);
4566            return;
4567        }
4568
4569        mContext.enforceCallingOrSelfPermission(
4570                android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
4571                "grantRuntimePermission");
4572
4573        enforceCrossUserPermission(Binder.getCallingUid(), userId,
4574                true /* requireFullPermission */, true /* checkShell */,
4575                "grantRuntimePermission");
4576
4577        final int uid;
4578        final SettingBase sb;
4579
4580        synchronized (mPackages) {
4581            final PackageParser.Package pkg = mPackages.get(packageName);
4582            if (pkg == null) {
4583                throw new IllegalArgumentException("Unknown package: " + packageName);
4584            }
4585
4586            final BasePermission bp = mSettings.mPermissions.get(name);
4587            if (bp == null) {
4588                throw new IllegalArgumentException("Unknown permission: " + name);
4589            }
4590
4591            enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(pkg, bp);
4592
4593            // If a permission review is required for legacy apps we represent
4594            // their permissions as always granted runtime ones since we need
4595            // to keep the review required permission flag per user while an
4596            // install permission's state is shared across all users.
4597            if (mPermissionReviewRequired
4598                    && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
4599                    && bp.isRuntime()) {
4600                return;
4601            }
4602
4603            uid = UserHandle.getUid(userId, pkg.applicationInfo.uid);
4604            sb = (SettingBase) pkg.mExtras;
4605            if (sb == null) {
4606                throw new IllegalArgumentException("Unknown package: " + packageName);
4607            }
4608
4609            final PermissionsState permissionsState = sb.getPermissionsState();
4610
4611            final int flags = permissionsState.getPermissionFlags(name, userId);
4612            if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
4613                throw new SecurityException("Cannot grant system fixed permission "
4614                        + name + " for package " + packageName);
4615            }
4616            if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
4617                throw new SecurityException("Cannot grant policy fixed permission "
4618                        + name + " for package " + packageName);
4619            }
4620
4621            if (bp.isDevelopment()) {
4622                // Development permissions must be handled specially, since they are not
4623                // normal runtime permissions.  For now they apply to all users.
4624                if (permissionsState.grantInstallPermission(bp) !=
4625                        PermissionsState.PERMISSION_OPERATION_FAILURE) {
4626                    scheduleWriteSettingsLocked();
4627                }
4628                return;
4629            }
4630
4631            if (pkg.applicationInfo.isInstantApp() && !bp.isInstant()) {
4632                throw new SecurityException("Cannot grant non-ephemeral permission"
4633                        + name + " for package " + packageName);
4634            }
4635
4636            if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
4637                Slog.w(TAG, "Cannot grant runtime permission to a legacy app");
4638                return;
4639            }
4640
4641            final int result = permissionsState.grantRuntimePermission(bp, userId);
4642            switch (result) {
4643                case PermissionsState.PERMISSION_OPERATION_FAILURE: {
4644                    return;
4645                }
4646
4647                case PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
4648                    final int appId = UserHandle.getAppId(pkg.applicationInfo.uid);
4649                    mHandler.post(new Runnable() {
4650                        @Override
4651                        public void run() {
4652                            killUid(appId, userId, KILL_APP_REASON_GIDS_CHANGED);
4653                        }
4654                    });
4655                }
4656                break;
4657            }
4658
4659            if (bp.isRuntime()) {
4660                logPermissionGranted(mContext, name, packageName);
4661            }
4662
4663            mOnPermissionChangeListeners.onPermissionsChanged(uid);
4664
4665            // Not critical if that is lost - app has to request again.
4666            mSettings.writeRuntimePermissionsForUserLPr(userId, false);
4667        }
4668
4669        // Only need to do this if user is initialized. Otherwise it's a new user
4670        // and there are no processes running as the user yet and there's no need
4671        // to make an expensive call to remount processes for the changed permissions.
4672        if (READ_EXTERNAL_STORAGE.equals(name)
4673                || WRITE_EXTERNAL_STORAGE.equals(name)) {
4674            final long token = Binder.clearCallingIdentity();
4675            try {
4676                if (sUserManager.isInitialized(userId)) {
4677                    StorageManagerInternal storageManagerInternal = LocalServices.getService(
4678                            StorageManagerInternal.class);
4679                    storageManagerInternal.onExternalStoragePolicyChanged(uid, packageName);
4680                }
4681            } finally {
4682                Binder.restoreCallingIdentity(token);
4683            }
4684        }
4685    }
4686
4687    @Override
4688    public void revokeRuntimePermission(String packageName, String name, int userId) {
4689        revokeRuntimePermission(packageName, name, userId, false /* Only if not fixed by policy */);
4690    }
4691
4692    private void revokeRuntimePermission(String packageName, String name, int userId,
4693            boolean overridePolicy) {
4694        if (!sUserManager.exists(userId)) {
4695            Log.e(TAG, "No such user:" + userId);
4696            return;
4697        }
4698
4699        mContext.enforceCallingOrSelfPermission(
4700                android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
4701                "revokeRuntimePermission");
4702
4703        enforceCrossUserPermission(Binder.getCallingUid(), userId,
4704                true /* requireFullPermission */, true /* checkShell */,
4705                "revokeRuntimePermission");
4706
4707        final int appId;
4708
4709        synchronized (mPackages) {
4710            final PackageParser.Package pkg = mPackages.get(packageName);
4711            if (pkg == null) {
4712                throw new IllegalArgumentException("Unknown package: " + packageName);
4713            }
4714
4715            final BasePermission bp = mSettings.mPermissions.get(name);
4716            if (bp == null) {
4717                throw new IllegalArgumentException("Unknown permission: " + name);
4718            }
4719
4720            enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(pkg, bp);
4721
4722            // If a permission review is required for legacy apps we represent
4723            // their permissions as always granted runtime ones since we need
4724            // to keep the review required permission flag per user while an
4725            // install permission's state is shared across all users.
4726            if (mPermissionReviewRequired
4727                    && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
4728                    && bp.isRuntime()) {
4729                return;
4730            }
4731
4732            SettingBase sb = (SettingBase) pkg.mExtras;
4733            if (sb == null) {
4734                throw new IllegalArgumentException("Unknown package: " + packageName);
4735            }
4736
4737            final PermissionsState permissionsState = sb.getPermissionsState();
4738
4739            final int flags = permissionsState.getPermissionFlags(name, userId);
4740            if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
4741                throw new SecurityException("Cannot revoke system fixed permission "
4742                        + name + " for package " + packageName);
4743            }
4744            if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
4745                throw new SecurityException("Cannot revoke policy fixed permission "
4746                        + name + " for package " + packageName);
4747            }
4748
4749            if (bp.isDevelopment()) {
4750                // Development permissions must be handled specially, since they are not
4751                // normal runtime permissions.  For now they apply to all users.
4752                if (permissionsState.revokeInstallPermission(bp) !=
4753                        PermissionsState.PERMISSION_OPERATION_FAILURE) {
4754                    scheduleWriteSettingsLocked();
4755                }
4756                return;
4757            }
4758
4759            if (permissionsState.revokeRuntimePermission(bp, userId) ==
4760                    PermissionsState.PERMISSION_OPERATION_FAILURE) {
4761                return;
4762            }
4763
4764            if (bp.isRuntime()) {
4765                logPermissionRevoked(mContext, name, packageName);
4766            }
4767
4768            mOnPermissionChangeListeners.onPermissionsChanged(pkg.applicationInfo.uid);
4769
4770            // Critical, after this call app should never have the permission.
4771            mSettings.writeRuntimePermissionsForUserLPr(userId, true);
4772
4773            appId = UserHandle.getAppId(pkg.applicationInfo.uid);
4774        }
4775
4776        killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED);
4777    }
4778
4779    /**
4780     * Get the first event id for the permission.
4781     *
4782     * <p>There are four events for each permission: <ul>
4783     *     <li>Request permission: first id + 0</li>
4784     *     <li>Grant permission: first id + 1</li>
4785     *     <li>Request for permission denied: first id + 2</li>
4786     *     <li>Revoke permission: first id + 3</li>
4787     * </ul></p>
4788     *
4789     * @param name name of the permission
4790     *
4791     * @return The first event id for the permission
4792     */
4793    private static int getBaseEventId(@NonNull String name) {
4794        int eventIdIndex = ALL_DANGEROUS_PERMISSIONS.indexOf(name);
4795
4796        if (eventIdIndex == -1) {
4797            if (AppOpsManager.permissionToOpCode(name) == AppOpsManager.OP_NONE
4798                    || "user".equals(Build.TYPE)) {
4799                Log.i(TAG, "Unknown permission " + name);
4800
4801                return MetricsEvent.ACTION_PERMISSION_REQUEST_UNKNOWN;
4802            } else {
4803                // Most likely #ALL_DANGEROUS_PERMISSIONS needs to be updated.
4804                //
4805                // Also update
4806                // - EventLogger#ALL_DANGEROUS_PERMISSIONS
4807                // - metrics_constants.proto
4808                throw new IllegalStateException("Unknown permission " + name);
4809            }
4810        }
4811
4812        return MetricsEvent.ACTION_PERMISSION_REQUEST_READ_CALENDAR + eventIdIndex * 4;
4813    }
4814
4815    /**
4816     * Log that a permission was revoked.
4817     *
4818     * @param context Context of the caller
4819     * @param name name of the permission
4820     * @param packageName package permission if for
4821     */
4822    private static void logPermissionRevoked(@NonNull Context context, @NonNull String name,
4823            @NonNull String packageName) {
4824        MetricsLogger.action(context, getBaseEventId(name) + 3, packageName);
4825    }
4826
4827    /**
4828     * Log that a permission request was granted.
4829     *
4830     * @param context Context of the caller
4831     * @param name name of the permission
4832     * @param packageName package permission if for
4833     */
4834    private static void logPermissionGranted(@NonNull Context context, @NonNull String name,
4835            @NonNull String packageName) {
4836        MetricsLogger.action(context, getBaseEventId(name) + 1, packageName);
4837    }
4838
4839    @Override
4840    public void resetRuntimePermissions() {
4841        mContext.enforceCallingOrSelfPermission(
4842                android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
4843                "revokeRuntimePermission");
4844
4845        int callingUid = Binder.getCallingUid();
4846        if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
4847            mContext.enforceCallingOrSelfPermission(
4848                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
4849                    "resetRuntimePermissions");
4850        }
4851
4852        synchronized (mPackages) {
4853            updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL);
4854            for (int userId : UserManagerService.getInstance().getUserIds()) {
4855                final int packageCount = mPackages.size();
4856                for (int i = 0; i < packageCount; i++) {
4857                    PackageParser.Package pkg = mPackages.valueAt(i);
4858                    if (!(pkg.mExtras instanceof PackageSetting)) {
4859                        continue;
4860                    }
4861                    PackageSetting ps = (PackageSetting) pkg.mExtras;
4862                    resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
4863                }
4864            }
4865        }
4866    }
4867
4868    @Override
4869    public int getPermissionFlags(String name, String packageName, int userId) {
4870        if (!sUserManager.exists(userId)) {
4871            return 0;
4872        }
4873
4874        enforceGrantRevokeRuntimePermissionPermissions("getPermissionFlags");
4875
4876        enforceCrossUserPermission(Binder.getCallingUid(), userId,
4877                true /* requireFullPermission */, false /* checkShell */,
4878                "getPermissionFlags");
4879
4880        synchronized (mPackages) {
4881            final PackageParser.Package pkg = mPackages.get(packageName);
4882            if (pkg == null) {
4883                return 0;
4884            }
4885
4886            final BasePermission bp = mSettings.mPermissions.get(name);
4887            if (bp == null) {
4888                return 0;
4889            }
4890
4891            SettingBase sb = (SettingBase) pkg.mExtras;
4892            if (sb == null) {
4893                return 0;
4894            }
4895
4896            PermissionsState permissionsState = sb.getPermissionsState();
4897            return permissionsState.getPermissionFlags(name, userId);
4898        }
4899    }
4900
4901    @Override
4902    public void updatePermissionFlags(String name, String packageName, int flagMask,
4903            int flagValues, int userId) {
4904        if (!sUserManager.exists(userId)) {
4905            return;
4906        }
4907
4908        enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlags");
4909
4910        enforceCrossUserPermission(Binder.getCallingUid(), userId,
4911                true /* requireFullPermission */, true /* checkShell */,
4912                "updatePermissionFlags");
4913
4914        // Only the system can change these flags and nothing else.
4915        if (getCallingUid() != Process.SYSTEM_UID) {
4916            flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
4917            flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
4918            flagMask &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
4919            flagValues &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
4920            flagValues &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
4921        }
4922
4923        synchronized (mPackages) {
4924            final PackageParser.Package pkg = mPackages.get(packageName);
4925            if (pkg == null) {
4926                throw new IllegalArgumentException("Unknown package: " + packageName);
4927            }
4928
4929            final BasePermission bp = mSettings.mPermissions.get(name);
4930            if (bp == null) {
4931                throw new IllegalArgumentException("Unknown permission: " + name);
4932            }
4933
4934            SettingBase sb = (SettingBase) pkg.mExtras;
4935            if (sb == null) {
4936                throw new IllegalArgumentException("Unknown package: " + packageName);
4937            }
4938
4939            PermissionsState permissionsState = sb.getPermissionsState();
4940
4941            boolean hadState = permissionsState.getRuntimePermissionState(name, userId) != null;
4942
4943            if (permissionsState.updatePermissionFlags(bp, userId, flagMask, flagValues)) {
4944                // Install and runtime permissions are stored in different places,
4945                // so figure out what permission changed and persist the change.
4946                if (permissionsState.getInstallPermissionState(name) != null) {
4947                    scheduleWriteSettingsLocked();
4948                } else if (permissionsState.getRuntimePermissionState(name, userId) != null
4949                        || hadState) {
4950                    mSettings.writeRuntimePermissionsForUserLPr(userId, false);
4951                }
4952            }
4953        }
4954    }
4955
4956    /**
4957     * Update the permission flags for all packages and runtime permissions of a user in order
4958     * to allow device or profile owner to remove POLICY_FIXED.
4959     */
4960    @Override
4961    public void updatePermissionFlagsForAllApps(int flagMask, int flagValues, int userId) {
4962        if (!sUserManager.exists(userId)) {
4963            return;
4964        }
4965
4966        enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlagsForAllApps");
4967
4968        enforceCrossUserPermission(Binder.getCallingUid(), userId,
4969                true /* requireFullPermission */, true /* checkShell */,
4970                "updatePermissionFlagsForAllApps");
4971
4972        // Only the system can change system fixed flags.
4973        if (getCallingUid() != Process.SYSTEM_UID) {
4974            flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
4975            flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
4976        }
4977
4978        synchronized (mPackages) {
4979            boolean changed = false;
4980            final int packageCount = mPackages.size();
4981            for (int pkgIndex = 0; pkgIndex < packageCount; pkgIndex++) {
4982                final PackageParser.Package pkg = mPackages.valueAt(pkgIndex);
4983                SettingBase sb = (SettingBase) pkg.mExtras;
4984                if (sb == null) {
4985                    continue;
4986                }
4987                PermissionsState permissionsState = sb.getPermissionsState();
4988                changed |= permissionsState.updatePermissionFlagsForAllPermissions(
4989                        userId, flagMask, flagValues);
4990            }
4991            if (changed) {
4992                mSettings.writeRuntimePermissionsForUserLPr(userId, false);
4993            }
4994        }
4995    }
4996
4997    private void enforceGrantRevokeRuntimePermissionPermissions(String message) {
4998        if (mContext.checkCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS)
4999                != PackageManager.PERMISSION_GRANTED
5000            && mContext.checkCallingOrSelfPermission(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS)
5001                != PackageManager.PERMISSION_GRANTED) {
5002            throw new SecurityException(message + " requires "
5003                    + Manifest.permission.GRANT_RUNTIME_PERMISSIONS + " or "
5004                    + Manifest.permission.REVOKE_RUNTIME_PERMISSIONS);
5005        }
5006    }
5007
5008    @Override
5009    public boolean shouldShowRequestPermissionRationale(String permissionName,
5010            String packageName, int userId) {
5011        if (UserHandle.getCallingUserId() != userId) {
5012            mContext.enforceCallingPermission(
5013                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
5014                    "canShowRequestPermissionRationale for user " + userId);
5015        }
5016
5017        final int uid = getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
5018        if (UserHandle.getAppId(getCallingUid()) != UserHandle.getAppId(uid)) {
5019            return false;
5020        }
5021
5022        if (checkPermission(permissionName, packageName, userId)
5023                == PackageManager.PERMISSION_GRANTED) {
5024            return false;
5025        }
5026
5027        final int flags;
5028
5029        final long identity = Binder.clearCallingIdentity();
5030        try {
5031            flags = getPermissionFlags(permissionName,
5032                    packageName, userId);
5033        } finally {
5034            Binder.restoreCallingIdentity(identity);
5035        }
5036
5037        final int fixedFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
5038                | PackageManager.FLAG_PERMISSION_POLICY_FIXED
5039                | PackageManager.FLAG_PERMISSION_USER_FIXED;
5040
5041        if ((flags & fixedFlags) != 0) {
5042            return false;
5043        }
5044
5045        return (flags & PackageManager.FLAG_PERMISSION_USER_SET) != 0;
5046    }
5047
5048    @Override
5049    public void addOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
5050        mContext.enforceCallingOrSelfPermission(
5051                Manifest.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS,
5052                "addOnPermissionsChangeListener");
5053
5054        synchronized (mPackages) {
5055            mOnPermissionChangeListeners.addListenerLocked(listener);
5056        }
5057    }
5058
5059    @Override
5060    public void removeOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
5061        synchronized (mPackages) {
5062            mOnPermissionChangeListeners.removeListenerLocked(listener);
5063        }
5064    }
5065
5066    @Override
5067    public boolean isProtectedBroadcast(String actionName) {
5068        synchronized (mPackages) {
5069            if (mProtectedBroadcasts.contains(actionName)) {
5070                return true;
5071            } else if (actionName != null) {
5072                // TODO: remove these terrible hacks
5073                if (actionName.startsWith("android.net.netmon.lingerExpired")
5074                        || actionName.startsWith("com.android.server.sip.SipWakeupTimer")
5075                        || actionName.startsWith("com.android.internal.telephony.data-reconnect")
5076                        || actionName.startsWith("android.net.netmon.launchCaptivePortalApp")) {
5077                    return true;
5078                }
5079            }
5080        }
5081        return false;
5082    }
5083
5084    @Override
5085    public int checkSignatures(String pkg1, String pkg2) {
5086        synchronized (mPackages) {
5087            final PackageParser.Package p1 = mPackages.get(pkg1);
5088            final PackageParser.Package p2 = mPackages.get(pkg2);
5089            if (p1 == null || p1.mExtras == null
5090                    || p2 == null || p2.mExtras == null) {
5091                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5092            }
5093            return compareSignatures(p1.mSignatures, p2.mSignatures);
5094        }
5095    }
5096
5097    @Override
5098    public int checkUidSignatures(int uid1, int uid2) {
5099        // Map to base uids.
5100        uid1 = UserHandle.getAppId(uid1);
5101        uid2 = UserHandle.getAppId(uid2);
5102        // reader
5103        synchronized (mPackages) {
5104            Signature[] s1;
5105            Signature[] s2;
5106            Object obj = mSettings.getUserIdLPr(uid1);
5107            if (obj != null) {
5108                if (obj instanceof SharedUserSetting) {
5109                    s1 = ((SharedUserSetting)obj).signatures.mSignatures;
5110                } else if (obj instanceof PackageSetting) {
5111                    s1 = ((PackageSetting)obj).signatures.mSignatures;
5112                } else {
5113                    return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5114                }
5115            } else {
5116                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5117            }
5118            obj = mSettings.getUserIdLPr(uid2);
5119            if (obj != null) {
5120                if (obj instanceof SharedUserSetting) {
5121                    s2 = ((SharedUserSetting)obj).signatures.mSignatures;
5122                } else if (obj instanceof PackageSetting) {
5123                    s2 = ((PackageSetting)obj).signatures.mSignatures;
5124                } else {
5125                    return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5126                }
5127            } else {
5128                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5129            }
5130            return compareSignatures(s1, s2);
5131        }
5132    }
5133
5134    /**
5135     * This method should typically only be used when granting or revoking
5136     * permissions, since the app may immediately restart after this call.
5137     * <p>
5138     * If you're doing surgery on app code/data, use {@link PackageFreezer} to
5139     * guard your work against the app being relaunched.
5140     */
5141    private void killUid(int appId, int userId, String reason) {
5142        final long identity = Binder.clearCallingIdentity();
5143        try {
5144            IActivityManager am = ActivityManager.getService();
5145            if (am != null) {
5146                try {
5147                    am.killUid(appId, userId, reason);
5148                } catch (RemoteException e) {
5149                    /* ignore - same process */
5150                }
5151            }
5152        } finally {
5153            Binder.restoreCallingIdentity(identity);
5154        }
5155    }
5156
5157    /**
5158     * Compares two sets of signatures. Returns:
5159     * <br />
5160     * {@link PackageManager#SIGNATURE_NEITHER_SIGNED}: if both signature sets are null,
5161     * <br />
5162     * {@link PackageManager#SIGNATURE_FIRST_NOT_SIGNED}: if the first signature set is null,
5163     * <br />
5164     * {@link PackageManager#SIGNATURE_SECOND_NOT_SIGNED}: if the second signature set is null,
5165     * <br />
5166     * {@link PackageManager#SIGNATURE_MATCH}: if the two signature sets are identical,
5167     * <br />
5168     * {@link PackageManager#SIGNATURE_NO_MATCH}: if the two signature sets differ.
5169     */
5170    static int compareSignatures(Signature[] s1, Signature[] s2) {
5171        if (s1 == null) {
5172            return s2 == null
5173                    ? PackageManager.SIGNATURE_NEITHER_SIGNED
5174                    : PackageManager.SIGNATURE_FIRST_NOT_SIGNED;
5175        }
5176
5177        if (s2 == null) {
5178            return PackageManager.SIGNATURE_SECOND_NOT_SIGNED;
5179        }
5180
5181        if (s1.length != s2.length) {
5182            return PackageManager.SIGNATURE_NO_MATCH;
5183        }
5184
5185        // Since both signature sets are of size 1, we can compare without HashSets.
5186        if (s1.length == 1) {
5187            return s1[0].equals(s2[0]) ?
5188                    PackageManager.SIGNATURE_MATCH :
5189                    PackageManager.SIGNATURE_NO_MATCH;
5190        }
5191
5192        ArraySet<Signature> set1 = new ArraySet<Signature>();
5193        for (Signature sig : s1) {
5194            set1.add(sig);
5195        }
5196        ArraySet<Signature> set2 = new ArraySet<Signature>();
5197        for (Signature sig : s2) {
5198            set2.add(sig);
5199        }
5200        // Make sure s2 contains all signatures in s1.
5201        if (set1.equals(set2)) {
5202            return PackageManager.SIGNATURE_MATCH;
5203        }
5204        return PackageManager.SIGNATURE_NO_MATCH;
5205    }
5206
5207    /**
5208     * If the database version for this type of package (internal storage or
5209     * external storage) is less than the version where package signatures
5210     * were updated, return true.
5211     */
5212    private boolean isCompatSignatureUpdateNeeded(PackageParser.Package scannedPkg) {
5213        final VersionInfo ver = getSettingsVersionForPackage(scannedPkg);
5214        return ver.databaseVersion < DatabaseVersion.SIGNATURE_END_ENTITY;
5215    }
5216
5217    /**
5218     * Used for backward compatibility to make sure any packages with
5219     * certificate chains get upgraded to the new style. {@code existingSigs}
5220     * will be in the old format (since they were stored on disk from before the
5221     * system upgrade) and {@code scannedSigs} will be in the newer format.
5222     */
5223    private int compareSignaturesCompat(PackageSignatures existingSigs,
5224            PackageParser.Package scannedPkg) {
5225        if (!isCompatSignatureUpdateNeeded(scannedPkg)) {
5226            return PackageManager.SIGNATURE_NO_MATCH;
5227        }
5228
5229        ArraySet<Signature> existingSet = new ArraySet<Signature>();
5230        for (Signature sig : existingSigs.mSignatures) {
5231            existingSet.add(sig);
5232        }
5233        ArraySet<Signature> scannedCompatSet = new ArraySet<Signature>();
5234        for (Signature sig : scannedPkg.mSignatures) {
5235            try {
5236                Signature[] chainSignatures = sig.getChainSignatures();
5237                for (Signature chainSig : chainSignatures) {
5238                    scannedCompatSet.add(chainSig);
5239                }
5240            } catch (CertificateEncodingException e) {
5241                scannedCompatSet.add(sig);
5242            }
5243        }
5244        /*
5245         * Make sure the expanded scanned set contains all signatures in the
5246         * existing one.
5247         */
5248        if (scannedCompatSet.equals(existingSet)) {
5249            // Migrate the old signatures to the new scheme.
5250            existingSigs.assignSignatures(scannedPkg.mSignatures);
5251            // The new KeySets will be re-added later in the scanning process.
5252            synchronized (mPackages) {
5253                mSettings.mKeySetManagerService.removeAppKeySetDataLPw(scannedPkg.packageName);
5254            }
5255            return PackageManager.SIGNATURE_MATCH;
5256        }
5257        return PackageManager.SIGNATURE_NO_MATCH;
5258    }
5259
5260    private boolean isRecoverSignatureUpdateNeeded(PackageParser.Package scannedPkg) {
5261        final VersionInfo ver = getSettingsVersionForPackage(scannedPkg);
5262        return ver.databaseVersion < DatabaseVersion.SIGNATURE_MALFORMED_RECOVER;
5263    }
5264
5265    private int compareSignaturesRecover(PackageSignatures existingSigs,
5266            PackageParser.Package scannedPkg) {
5267        if (!isRecoverSignatureUpdateNeeded(scannedPkg)) {
5268            return PackageManager.SIGNATURE_NO_MATCH;
5269        }
5270
5271        String msg = null;
5272        try {
5273            if (Signature.areEffectiveMatch(existingSigs.mSignatures, scannedPkg.mSignatures)) {
5274                logCriticalInfo(Log.INFO, "Recovered effectively matching certificates for "
5275                        + scannedPkg.packageName);
5276                return PackageManager.SIGNATURE_MATCH;
5277            }
5278        } catch (CertificateException e) {
5279            msg = e.getMessage();
5280        }
5281
5282        logCriticalInfo(Log.INFO,
5283                "Failed to recover certificates for " + scannedPkg.packageName + ": " + msg);
5284        return PackageManager.SIGNATURE_NO_MATCH;
5285    }
5286
5287    @Override
5288    public List<String> getAllPackages() {
5289        synchronized (mPackages) {
5290            return new ArrayList<String>(mPackages.keySet());
5291        }
5292    }
5293
5294    @Override
5295    public String[] getPackagesForUid(int uid) {
5296        final int userId = UserHandle.getUserId(uid);
5297        uid = UserHandle.getAppId(uid);
5298        // reader
5299        synchronized (mPackages) {
5300            Object obj = mSettings.getUserIdLPr(uid);
5301            if (obj instanceof SharedUserSetting) {
5302                final SharedUserSetting sus = (SharedUserSetting) obj;
5303                final int N = sus.packages.size();
5304                String[] res = new String[N];
5305                final Iterator<PackageSetting> it = sus.packages.iterator();
5306                int i = 0;
5307                while (it.hasNext()) {
5308                    PackageSetting ps = it.next();
5309                    if (ps.getInstalled(userId)) {
5310                        res[i++] = ps.name;
5311                    } else {
5312                        res = ArrayUtils.removeElement(String.class, res, res[i]);
5313                    }
5314                }
5315                return res;
5316            } else if (obj instanceof PackageSetting) {
5317                final PackageSetting ps = (PackageSetting) obj;
5318                if (ps.getInstalled(userId)) {
5319                    return new String[]{ps.name};
5320                }
5321            }
5322        }
5323        return null;
5324    }
5325
5326    @Override
5327    public String getNameForUid(int uid) {
5328        // reader
5329        synchronized (mPackages) {
5330            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
5331            if (obj instanceof SharedUserSetting) {
5332                final SharedUserSetting sus = (SharedUserSetting) obj;
5333                return sus.name + ":" + sus.userId;
5334            } else if (obj instanceof PackageSetting) {
5335                final PackageSetting ps = (PackageSetting) obj;
5336                return ps.name;
5337            }
5338        }
5339        return null;
5340    }
5341
5342    @Override
5343    public int getUidForSharedUser(String sharedUserName) {
5344        if(sharedUserName == null) {
5345            return -1;
5346        }
5347        // reader
5348        synchronized (mPackages) {
5349            SharedUserSetting suid;
5350            try {
5351                suid = mSettings.getSharedUserLPw(sharedUserName, 0, 0, false);
5352                if (suid != null) {
5353                    return suid.userId;
5354                }
5355            } catch (PackageManagerException ignore) {
5356                // can't happen, but, still need to catch it
5357            }
5358            return -1;
5359        }
5360    }
5361
5362    @Override
5363    public int getFlagsForUid(int uid) {
5364        synchronized (mPackages) {
5365            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
5366            if (obj instanceof SharedUserSetting) {
5367                final SharedUserSetting sus = (SharedUserSetting) obj;
5368                return sus.pkgFlags;
5369            } else if (obj instanceof PackageSetting) {
5370                final PackageSetting ps = (PackageSetting) obj;
5371                return ps.pkgFlags;
5372            }
5373        }
5374        return 0;
5375    }
5376
5377    @Override
5378    public int getPrivateFlagsForUid(int uid) {
5379        synchronized (mPackages) {
5380            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
5381            if (obj instanceof SharedUserSetting) {
5382                final SharedUserSetting sus = (SharedUserSetting) obj;
5383                return sus.pkgPrivateFlags;
5384            } else if (obj instanceof PackageSetting) {
5385                final PackageSetting ps = (PackageSetting) obj;
5386                return ps.pkgPrivateFlags;
5387            }
5388        }
5389        return 0;
5390    }
5391
5392    @Override
5393    public boolean isUidPrivileged(int uid) {
5394        uid = UserHandle.getAppId(uid);
5395        // reader
5396        synchronized (mPackages) {
5397            Object obj = mSettings.getUserIdLPr(uid);
5398            if (obj instanceof SharedUserSetting) {
5399                final SharedUserSetting sus = (SharedUserSetting) obj;
5400                final Iterator<PackageSetting> it = sus.packages.iterator();
5401                while (it.hasNext()) {
5402                    if (it.next().isPrivileged()) {
5403                        return true;
5404                    }
5405                }
5406            } else if (obj instanceof PackageSetting) {
5407                final PackageSetting ps = (PackageSetting) obj;
5408                return ps.isPrivileged();
5409            }
5410        }
5411        return false;
5412    }
5413
5414    @Override
5415    public String[] getAppOpPermissionPackages(String permissionName) {
5416        synchronized (mPackages) {
5417            ArraySet<String> pkgs = mAppOpPermissionPackages.get(permissionName);
5418            if (pkgs == null) {
5419                return null;
5420            }
5421            return pkgs.toArray(new String[pkgs.size()]);
5422        }
5423    }
5424
5425    @Override
5426    public ResolveInfo resolveIntent(Intent intent, String resolvedType,
5427            int flags, int userId) {
5428        try {
5429            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveIntent");
5430
5431            if (!sUserManager.exists(userId)) return null;
5432            flags = updateFlagsForResolve(flags, userId, intent);
5433            enforceCrossUserPermission(Binder.getCallingUid(), userId,
5434                    false /*requireFullPermission*/, false /*checkShell*/, "resolve intent");
5435
5436            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities");
5437            final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType,
5438                    flags, userId);
5439            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
5440
5441            final ResolveInfo bestChoice =
5442                    chooseBestActivity(intent, resolvedType, flags, query, userId);
5443            return bestChoice;
5444        } finally {
5445            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
5446        }
5447    }
5448
5449    @Override
5450    public ResolveInfo findPersistentPreferredActivity(Intent intent, int userId) {
5451        if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.SYSTEM_UID)) {
5452            throw new SecurityException(
5453                    "findPersistentPreferredActivity can only be run by the system");
5454        }
5455        if (!sUserManager.exists(userId)) {
5456            return null;
5457        }
5458        intent = updateIntentForResolve(intent);
5459        final String resolvedType = intent.resolveTypeIfNeeded(mContext.getContentResolver());
5460        final int flags = updateFlagsForResolve(0, userId, intent);
5461        final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
5462                userId);
5463        synchronized (mPackages) {
5464            return findPersistentPreferredActivityLP(intent, resolvedType, flags, query, false,
5465                    userId);
5466        }
5467    }
5468
5469    @Override
5470    public void setLastChosenActivity(Intent intent, String resolvedType, int flags,
5471            IntentFilter filter, int match, ComponentName activity) {
5472        final int userId = UserHandle.getCallingUserId();
5473        if (DEBUG_PREFERRED) {
5474            Log.v(TAG, "setLastChosenActivity intent=" + intent
5475                + " resolvedType=" + resolvedType
5476                + " flags=" + flags
5477                + " filter=" + filter
5478                + " match=" + match
5479                + " activity=" + activity);
5480            filter.dump(new PrintStreamPrinter(System.out), "    ");
5481        }
5482        intent.setComponent(null);
5483        final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
5484                userId);
5485        // Find any earlier preferred or last chosen entries and nuke them
5486        findPreferredActivity(intent, resolvedType,
5487                flags, query, 0, false, true, false, userId);
5488        // Add the new activity as the last chosen for this filter
5489        addPreferredActivityInternal(filter, match, null, activity, false, userId,
5490                "Setting last chosen");
5491    }
5492
5493    @Override
5494    public ResolveInfo getLastChosenActivity(Intent intent, String resolvedType, int flags) {
5495        final int userId = UserHandle.getCallingUserId();
5496        if (DEBUG_PREFERRED) Log.v(TAG, "Querying last chosen activity for " + intent);
5497        final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
5498                userId);
5499        return findPreferredActivity(intent, resolvedType, flags, query, 0,
5500                false, false, false, userId);
5501    }
5502
5503    private boolean isEphemeralDisabled() {
5504        // ephemeral apps have been disabled across the board
5505        if (DISABLE_EPHEMERAL_APPS) {
5506            return true;
5507        }
5508        // system isn't up yet; can't read settings, so, assume no ephemeral apps
5509        if (!mSystemReady) {
5510            return true;
5511        }
5512        // we can't get a content resolver until the system is ready; these checks must happen last
5513        final ContentResolver resolver = mContext.getContentResolver();
5514        if (Global.getInt(resolver, Global.ENABLE_EPHEMERAL_FEATURE, 1) == 0) {
5515            return true;
5516        }
5517        return Secure.getInt(resolver, Secure.WEB_ACTION_ENABLED, 1) == 0;
5518    }
5519
5520    private boolean isEphemeralAllowed(
5521            Intent intent, List<ResolveInfo> resolvedActivities, int userId,
5522            boolean skipPackageCheck) {
5523        // Short circuit and return early if possible.
5524        if (isEphemeralDisabled()) {
5525            return false;
5526        }
5527        final int callingUser = UserHandle.getCallingUserId();
5528        if (callingUser != UserHandle.USER_SYSTEM) {
5529            return false;
5530        }
5531        if (mEphemeralResolverConnection == null) {
5532            return false;
5533        }
5534        if (mEphemeralInstallerComponent == null) {
5535            return false;
5536        }
5537        if (intent.getComponent() != null) {
5538            return false;
5539        }
5540        if ((intent.getFlags() & Intent.FLAG_IGNORE_EPHEMERAL) != 0) {
5541            return false;
5542        }
5543        if (!skipPackageCheck && intent.getPackage() != null) {
5544            return false;
5545        }
5546        final boolean isWebUri = hasWebURI(intent);
5547        if (!isWebUri || intent.getData().getHost() == null) {
5548            return false;
5549        }
5550        // Deny ephemeral apps if the user chose _ALWAYS or _ALWAYS_ASK for intent resolution.
5551        synchronized (mPackages) {
5552            final int count = (resolvedActivities == null ? 0 : resolvedActivities.size());
5553            for (int n = 0; n < count; n++) {
5554                ResolveInfo info = resolvedActivities.get(n);
5555                String packageName = info.activityInfo.packageName;
5556                PackageSetting ps = mSettings.mPackages.get(packageName);
5557                if (ps != null) {
5558                    // Try to get the status from User settings first
5559                    long packedStatus = getDomainVerificationStatusLPr(ps, userId);
5560                    int status = (int) (packedStatus >> 32);
5561                    if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS
5562                            || status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
5563                        if (DEBUG_EPHEMERAL) {
5564                            Slog.v(TAG, "DENY ephemeral apps;"
5565                                + " pkg: " + packageName + ", status: " + status);
5566                        }
5567                        return false;
5568                    }
5569                }
5570            }
5571        }
5572        // We've exhausted all ways to deny ephemeral application; let the system look for them.
5573        return true;
5574    }
5575
5576    private void requestEphemeralResolutionPhaseTwo(EphemeralResponse responseObj,
5577            Intent origIntent, String resolvedType, Intent launchIntent, String callingPackage,
5578            int userId) {
5579        final Message msg = mHandler.obtainMessage(EPHEMERAL_RESOLUTION_PHASE_TWO,
5580                new EphemeralRequest(responseObj, origIntent, resolvedType, launchIntent,
5581                        callingPackage, userId));
5582        mHandler.sendMessage(msg);
5583    }
5584
5585    private ResolveInfo chooseBestActivity(Intent intent, String resolvedType,
5586            int flags, List<ResolveInfo> query, int userId) {
5587        if (query != null) {
5588            final int N = query.size();
5589            if (N == 1) {
5590                return query.get(0);
5591            } else if (N > 1) {
5592                final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
5593                // If there is more than one activity with the same priority,
5594                // then let the user decide between them.
5595                ResolveInfo r0 = query.get(0);
5596                ResolveInfo r1 = query.get(1);
5597                if (DEBUG_INTENT_MATCHING || debug) {
5598                    Slog.v(TAG, r0.activityInfo.name + "=" + r0.priority + " vs "
5599                            + r1.activityInfo.name + "=" + r1.priority);
5600                }
5601                // If the first activity has a higher priority, or a different
5602                // default, then it is always desirable to pick it.
5603                if (r0.priority != r1.priority
5604                        || r0.preferredOrder != r1.preferredOrder
5605                        || r0.isDefault != r1.isDefault) {
5606                    return query.get(0);
5607                }
5608                // If we have saved a preference for a preferred activity for
5609                // this Intent, use that.
5610                ResolveInfo ri = findPreferredActivity(intent, resolvedType,
5611                        flags, query, r0.priority, true, false, debug, userId);
5612                if (ri != null) {
5613                    return ri;
5614                }
5615                ri = new ResolveInfo(mResolveInfo);
5616                ri.activityInfo = new ActivityInfo(ri.activityInfo);
5617                ri.activityInfo.labelRes = ResolverActivity.getLabelRes(intent.getAction());
5618                // If all of the options come from the same package, show the application's
5619                // label and icon instead of the generic resolver's.
5620                // Some calls like Intent.resolveActivityInfo query the ResolveInfo from here
5621                // and then throw away the ResolveInfo itself, meaning that the caller loses
5622                // the resolvePackageName. Therefore the activityInfo.labelRes above provides
5623                // a fallback for this case; we only set the target package's resources on
5624                // the ResolveInfo, not the ActivityInfo.
5625                final String intentPackage = intent.getPackage();
5626                if (!TextUtils.isEmpty(intentPackage) && allHavePackage(query, intentPackage)) {
5627                    final ApplicationInfo appi = query.get(0).activityInfo.applicationInfo;
5628                    ri.resolvePackageName = intentPackage;
5629                    if (userNeedsBadging(userId)) {
5630                        ri.noResourceId = true;
5631                    } else {
5632                        ri.icon = appi.icon;
5633                    }
5634                    ri.iconResourceId = appi.icon;
5635                    ri.labelRes = appi.labelRes;
5636                }
5637                ri.activityInfo.applicationInfo = new ApplicationInfo(
5638                        ri.activityInfo.applicationInfo);
5639                if (userId != 0) {
5640                    ri.activityInfo.applicationInfo.uid = UserHandle.getUid(userId,
5641                            UserHandle.getAppId(ri.activityInfo.applicationInfo.uid));
5642                }
5643                // Make sure that the resolver is displayable in car mode
5644                if (ri.activityInfo.metaData == null) ri.activityInfo.metaData = new Bundle();
5645                ri.activityInfo.metaData.putBoolean(Intent.METADATA_DOCK_HOME, true);
5646                return ri;
5647            }
5648        }
5649        return null;
5650    }
5651
5652    /**
5653     * Return true if the given list is not empty and all of its contents have
5654     * an activityInfo with the given package name.
5655     */
5656    private boolean allHavePackage(List<ResolveInfo> list, String packageName) {
5657        if (ArrayUtils.isEmpty(list)) {
5658            return false;
5659        }
5660        for (int i = 0, N = list.size(); i < N; i++) {
5661            final ResolveInfo ri = list.get(i);
5662            final ActivityInfo ai = ri != null ? ri.activityInfo : null;
5663            if (ai == null || !packageName.equals(ai.packageName)) {
5664                return false;
5665            }
5666        }
5667        return true;
5668    }
5669
5670    private ResolveInfo findPersistentPreferredActivityLP(Intent intent, String resolvedType,
5671            int flags, List<ResolveInfo> query, boolean debug, int userId) {
5672        final int N = query.size();
5673        PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
5674                .get(userId);
5675        // Get the list of persistent preferred activities that handle the intent
5676        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for presistent preferred activities...");
5677        List<PersistentPreferredActivity> pprefs = ppir != null
5678                ? ppir.queryIntent(intent, resolvedType,
5679                        (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
5680                        (flags & PackageManager.MATCH_VISIBLE_TO_EPHEMERAL_ONLY) != 0,
5681                        (flags & PackageManager.MATCH_EPHEMERAL) != 0, userId)
5682                : null;
5683        if (pprefs != null && pprefs.size() > 0) {
5684            final int M = pprefs.size();
5685            for (int i=0; i<M; i++) {
5686                final PersistentPreferredActivity ppa = pprefs.get(i);
5687                if (DEBUG_PREFERRED || debug) {
5688                    Slog.v(TAG, "Checking PersistentPreferredActivity ds="
5689                            + (ppa.countDataSchemes() > 0 ? ppa.getDataScheme(0) : "<none>")
5690                            + "\n  component=" + ppa.mComponent);
5691                    ppa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
5692                }
5693                final ActivityInfo ai = getActivityInfo(ppa.mComponent,
5694                        flags | MATCH_DISABLED_COMPONENTS, userId);
5695                if (DEBUG_PREFERRED || debug) {
5696                    Slog.v(TAG, "Found persistent preferred activity:");
5697                    if (ai != null) {
5698                        ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
5699                    } else {
5700                        Slog.v(TAG, "  null");
5701                    }
5702                }
5703                if (ai == null) {
5704                    // This previously registered persistent preferred activity
5705                    // component is no longer known. Ignore it and do NOT remove it.
5706                    continue;
5707                }
5708                for (int j=0; j<N; j++) {
5709                    final ResolveInfo ri = query.get(j);
5710                    if (!ri.activityInfo.applicationInfo.packageName
5711                            .equals(ai.applicationInfo.packageName)) {
5712                        continue;
5713                    }
5714                    if (!ri.activityInfo.name.equals(ai.name)) {
5715                        continue;
5716                    }
5717                    //  Found a persistent preference that can handle the intent.
5718                    if (DEBUG_PREFERRED || debug) {
5719                        Slog.v(TAG, "Returning persistent preferred activity: " +
5720                                ri.activityInfo.packageName + "/" + ri.activityInfo.name);
5721                    }
5722                    return ri;
5723                }
5724            }
5725        }
5726        return null;
5727    }
5728
5729    // TODO: handle preferred activities missing while user has amnesia
5730    ResolveInfo findPreferredActivity(Intent intent, String resolvedType, int flags,
5731            List<ResolveInfo> query, int priority, boolean always,
5732            boolean removeMatches, boolean debug, int userId) {
5733        if (!sUserManager.exists(userId)) return null;
5734        flags = updateFlagsForResolve(flags, userId, intent);
5735        intent = updateIntentForResolve(intent);
5736        // writer
5737        synchronized (mPackages) {
5738            // Try to find a matching persistent preferred activity.
5739            ResolveInfo pri = findPersistentPreferredActivityLP(intent, resolvedType, flags, query,
5740                    debug, userId);
5741
5742            // If a persistent preferred activity matched, use it.
5743            if (pri != null) {
5744                return pri;
5745            }
5746
5747            PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
5748            // Get the list of preferred activities that handle the intent
5749            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for preferred activities...");
5750            List<PreferredActivity> prefs = pir != null
5751                    ? pir.queryIntent(intent, resolvedType,
5752                            (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
5753                            (flags & PackageManager.MATCH_VISIBLE_TO_EPHEMERAL_ONLY) != 0,
5754                            (flags & PackageManager.MATCH_EPHEMERAL) != 0, userId)
5755                    : null;
5756            if (prefs != null && prefs.size() > 0) {
5757                boolean changed = false;
5758                try {
5759                    // First figure out how good the original match set is.
5760                    // We will only allow preferred activities that came
5761                    // from the same match quality.
5762                    int match = 0;
5763
5764                    if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Figuring out best match...");
5765
5766                    final int N = query.size();
5767                    for (int j=0; j<N; j++) {
5768                        final ResolveInfo ri = query.get(j);
5769                        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Match for " + ri.activityInfo
5770                                + ": 0x" + Integer.toHexString(match));
5771                        if (ri.match > match) {
5772                            match = ri.match;
5773                        }
5774                    }
5775
5776                    if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Best match: 0x"
5777                            + Integer.toHexString(match));
5778
5779                    match &= IntentFilter.MATCH_CATEGORY_MASK;
5780                    final int M = prefs.size();
5781                    for (int i=0; i<M; i++) {
5782                        final PreferredActivity pa = prefs.get(i);
5783                        if (DEBUG_PREFERRED || debug) {
5784                            Slog.v(TAG, "Checking PreferredActivity ds="
5785                                    + (pa.countDataSchemes() > 0 ? pa.getDataScheme(0) : "<none>")
5786                                    + "\n  component=" + pa.mPref.mComponent);
5787                            pa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
5788                        }
5789                        if (pa.mPref.mMatch != match) {
5790                            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping bad match "
5791                                    + Integer.toHexString(pa.mPref.mMatch));
5792                            continue;
5793                        }
5794                        // If it's not an "always" type preferred activity and that's what we're
5795                        // looking for, skip it.
5796                        if (always && !pa.mPref.mAlways) {
5797                            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping mAlways=false entry");
5798                            continue;
5799                        }
5800                        final ActivityInfo ai = getActivityInfo(
5801                                pa.mPref.mComponent, flags | MATCH_DISABLED_COMPONENTS
5802                                        | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
5803                                userId);
5804                        if (DEBUG_PREFERRED || debug) {
5805                            Slog.v(TAG, "Found preferred activity:");
5806                            if (ai != null) {
5807                                ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
5808                            } else {
5809                                Slog.v(TAG, "  null");
5810                            }
5811                        }
5812                        if (ai == null) {
5813                            // This previously registered preferred activity
5814                            // component is no longer known.  Most likely an update
5815                            // to the app was installed and in the new version this
5816                            // component no longer exists.  Clean it up by removing
5817                            // it from the preferred activities list, and skip it.
5818                            Slog.w(TAG, "Removing dangling preferred activity: "
5819                                    + pa.mPref.mComponent);
5820                            pir.removeFilter(pa);
5821                            changed = true;
5822                            continue;
5823                        }
5824                        for (int j=0; j<N; j++) {
5825                            final ResolveInfo ri = query.get(j);
5826                            if (!ri.activityInfo.applicationInfo.packageName
5827                                    .equals(ai.applicationInfo.packageName)) {
5828                                continue;
5829                            }
5830                            if (!ri.activityInfo.name.equals(ai.name)) {
5831                                continue;
5832                            }
5833
5834                            if (removeMatches) {
5835                                pir.removeFilter(pa);
5836                                changed = true;
5837                                if (DEBUG_PREFERRED) {
5838                                    Slog.v(TAG, "Removing match " + pa.mPref.mComponent);
5839                                }
5840                                break;
5841                            }
5842
5843                            // Okay we found a previously set preferred or last chosen app.
5844                            // If the result set is different from when this
5845                            // was created, we need to clear it and re-ask the
5846                            // user their preference, if we're looking for an "always" type entry.
5847                            if (always && !pa.mPref.sameSet(query)) {
5848                                Slog.i(TAG, "Result set changed, dropping preferred activity for "
5849                                        + intent + " type " + resolvedType);
5850                                if (DEBUG_PREFERRED) {
5851                                    Slog.v(TAG, "Removing preferred activity since set changed "
5852                                            + pa.mPref.mComponent);
5853                                }
5854                                pir.removeFilter(pa);
5855                                // Re-add the filter as a "last chosen" entry (!always)
5856                                PreferredActivity lastChosen = new PreferredActivity(
5857                                        pa, pa.mPref.mMatch, null, pa.mPref.mComponent, false);
5858                                pir.addFilter(lastChosen);
5859                                changed = true;
5860                                return null;
5861                            }
5862
5863                            // Yay! Either the set matched or we're looking for the last chosen
5864                            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Returning preferred activity: "
5865                                    + ri.activityInfo.packageName + "/" + ri.activityInfo.name);
5866                            return ri;
5867                        }
5868                    }
5869                } finally {
5870                    if (changed) {
5871                        if (DEBUG_PREFERRED) {
5872                            Slog.v(TAG, "Preferred activity bookkeeping changed; writing restrictions");
5873                        }
5874                        scheduleWritePackageRestrictionsLocked(userId);
5875                    }
5876                }
5877            }
5878        }
5879        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "No preferred activity to return");
5880        return null;
5881    }
5882
5883    /*
5884     * Returns if intent can be forwarded from the sourceUserId to the targetUserId
5885     */
5886    @Override
5887    public boolean canForwardTo(Intent intent, String resolvedType, int sourceUserId,
5888            int targetUserId) {
5889        mContext.enforceCallingOrSelfPermission(
5890                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
5891        List<CrossProfileIntentFilter> matches =
5892                getMatchingCrossProfileIntentFilters(intent, resolvedType, sourceUserId);
5893        if (matches != null) {
5894            int size = matches.size();
5895            for (int i = 0; i < size; i++) {
5896                if (matches.get(i).getTargetUserId() == targetUserId) return true;
5897            }
5898        }
5899        if (hasWebURI(intent)) {
5900            // cross-profile app linking works only towards the parent.
5901            final UserInfo parent = getProfileParent(sourceUserId);
5902            synchronized(mPackages) {
5903                int flags = updateFlagsForResolve(0, parent.id, intent);
5904                CrossProfileDomainInfo xpDomainInfo = getCrossProfileDomainPreferredLpr(
5905                        intent, resolvedType, flags, sourceUserId, parent.id);
5906                return xpDomainInfo != null;
5907            }
5908        }
5909        return false;
5910    }
5911
5912    private UserInfo getProfileParent(int userId) {
5913        final long identity = Binder.clearCallingIdentity();
5914        try {
5915            return sUserManager.getProfileParent(userId);
5916        } finally {
5917            Binder.restoreCallingIdentity(identity);
5918        }
5919    }
5920
5921    private List<CrossProfileIntentFilter> getMatchingCrossProfileIntentFilters(Intent intent,
5922            String resolvedType, int userId) {
5923        CrossProfileIntentResolver resolver = mSettings.mCrossProfileIntentResolvers.get(userId);
5924        if (resolver != null) {
5925            return resolver.queryIntent(intent, resolvedType, false /*defaultOnly*/,
5926                    false /*visibleToEphemeral*/, false /*isInstant*/, userId);
5927        }
5928        return null;
5929    }
5930
5931    @Override
5932    public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivities(Intent intent,
5933            String resolvedType, int flags, int userId) {
5934        try {
5935            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities");
5936
5937            return new ParceledListSlice<>(
5938                    queryIntentActivitiesInternal(intent, resolvedType, flags, userId));
5939        } finally {
5940            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
5941        }
5942    }
5943
5944    /**
5945     * Returns the package name of the calling Uid if it's an ephemeral app. If it isn't
5946     * ephemeral, returns {@code null}.
5947     */
5948    private String getEphemeralPackageName(int callingUid) {
5949        final int appId = UserHandle.getAppId(callingUid);
5950        synchronized (mPackages) {
5951            final Object obj = mSettings.getUserIdLPr(appId);
5952            if (obj instanceof PackageSetting) {
5953                final PackageSetting ps = (PackageSetting) obj;
5954                return ps.pkg.applicationInfo.isInstantApp() ? ps.pkg.packageName : null;
5955            }
5956        }
5957        return null;
5958    }
5959
5960    private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
5961            String resolvedType, int flags, int userId) {
5962        if (!sUserManager.exists(userId)) return Collections.emptyList();
5963        final String ephemeralPkgName = getEphemeralPackageName(Binder.getCallingUid());
5964        flags = updateFlagsForResolve(flags, userId, intent);
5965        enforceCrossUserPermission(Binder.getCallingUid(), userId,
5966                false /* requireFullPermission */, false /* checkShell */,
5967                "query intent activities");
5968        ComponentName comp = intent.getComponent();
5969        if (comp == null) {
5970            if (intent.getSelector() != null) {
5971                intent = intent.getSelector();
5972                comp = intent.getComponent();
5973            }
5974        }
5975
5976        if (comp != null) {
5977            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
5978            final ActivityInfo ai = getActivityInfo(comp, flags, userId);
5979            if (ai != null) {
5980                // When specifying an explicit component, we prevent the activity from being
5981                // used when either 1) the calling package is normal and the activity is within
5982                // an ephemeral application or 2) the calling package is ephemeral and the
5983                // activity is not visible to ephemeral applications.
5984                boolean matchEphemeral =
5985                        (flags & PackageManager.MATCH_EPHEMERAL) != 0;
5986                boolean ephemeralVisibleOnly =
5987                        (flags & PackageManager.MATCH_VISIBLE_TO_EPHEMERAL_ONLY) != 0;
5988                boolean blockResolution =
5989                        (!matchEphemeral && ephemeralPkgName == null
5990                                && (ai.applicationInfo.privateFlags
5991                                        & ApplicationInfo.PRIVATE_FLAG_EPHEMERAL) != 0)
5992                        || (ephemeralVisibleOnly && ephemeralPkgName != null
5993                                && (ai.flags & ActivityInfo.FLAG_VISIBLE_TO_EPHEMERAL) == 0);
5994                if (!blockResolution) {
5995                    final ResolveInfo ri = new ResolveInfo();
5996                    ri.activityInfo = ai;
5997                    list.add(ri);
5998                }
5999            }
6000            return list;
6001        }
6002
6003        // reader
6004        boolean sortResult = false;
6005        boolean addEphemeral = false;
6006        List<ResolveInfo> result;
6007        final String pkgName = intent.getPackage();
6008        synchronized (mPackages) {
6009            if (pkgName == null) {
6010                List<CrossProfileIntentFilter> matchingFilters =
6011                        getMatchingCrossProfileIntentFilters(intent, resolvedType, userId);
6012                // Check for results that need to skip the current profile.
6013                ResolveInfo xpResolveInfo  = querySkipCurrentProfileIntents(matchingFilters, intent,
6014                        resolvedType, flags, userId);
6015                if (xpResolveInfo != null) {
6016                    List<ResolveInfo> xpResult = new ArrayList<ResolveInfo>(1);
6017                    xpResult.add(xpResolveInfo);
6018                    return filterForEphemeral(
6019                            filterIfNotSystemUser(xpResult, userId), ephemeralPkgName);
6020                }
6021
6022                // Check for results in the current profile.
6023                result = filterIfNotSystemUser(mActivities.queryIntent(
6024                        intent, resolvedType, flags, userId), userId);
6025                addEphemeral =
6026                        isEphemeralAllowed(intent, result, userId, false /*skipPackageCheck*/);
6027
6028                // Check for cross profile results.
6029                boolean hasNonNegativePriorityResult = hasNonNegativePriority(result);
6030                xpResolveInfo = queryCrossProfileIntents(
6031                        matchingFilters, intent, resolvedType, flags, userId,
6032                        hasNonNegativePriorityResult);
6033                if (xpResolveInfo != null && isUserEnabled(xpResolveInfo.targetUserId)) {
6034                    boolean isVisibleToUser = filterIfNotSystemUser(
6035                            Collections.singletonList(xpResolveInfo), userId).size() > 0;
6036                    if (isVisibleToUser) {
6037                        result.add(xpResolveInfo);
6038                        sortResult = true;
6039                    }
6040                }
6041                if (hasWebURI(intent)) {
6042                    CrossProfileDomainInfo xpDomainInfo = null;
6043                    final UserInfo parent = getProfileParent(userId);
6044                    if (parent != null) {
6045                        xpDomainInfo = getCrossProfileDomainPreferredLpr(intent, resolvedType,
6046                                flags, userId, parent.id);
6047                    }
6048                    if (xpDomainInfo != null) {
6049                        if (xpResolveInfo != null) {
6050                            // If we didn't remove it, the cross-profile ResolveInfo would be twice
6051                            // in the result.
6052                            result.remove(xpResolveInfo);
6053                        }
6054                        if (result.size() == 0 && !addEphemeral) {
6055                            // No result in current profile, but found candidate in parent user.
6056                            // And we are not going to add emphemeral app, so we can return the
6057                            // result straight away.
6058                            result.add(xpDomainInfo.resolveInfo);
6059                            return filterForEphemeral(result, ephemeralPkgName);
6060                        }
6061                    } else if (result.size() <= 1 && !addEphemeral) {
6062                        // No result in parent user and <= 1 result in current profile, and we
6063                        // are not going to add emphemeral app, so we can return the result without
6064                        // further processing.
6065                        return filterForEphemeral(result, ephemeralPkgName);
6066                    }
6067                    // We have more than one candidate (combining results from current and parent
6068                    // profile), so we need filtering and sorting.
6069                    result = filterCandidatesWithDomainPreferredActivitiesLPr(
6070                            intent, flags, result, xpDomainInfo, userId);
6071                    sortResult = true;
6072                }
6073            } else {
6074                final PackageParser.Package pkg = mPackages.get(pkgName);
6075                if (pkg != null) {
6076                    result = filterForEphemeral(filterIfNotSystemUser(
6077                            mActivities.queryIntentForPackage(
6078                                    intent, resolvedType, flags, pkg.activities, userId),
6079                            userId), ephemeralPkgName);
6080                } else {
6081                    // the caller wants to resolve for a particular package; however, there
6082                    // were no installed results, so, try to find an ephemeral result
6083                    addEphemeral = isEphemeralAllowed(
6084                            intent, null /*result*/, userId, true /*skipPackageCheck*/);
6085                    result = new ArrayList<ResolveInfo>();
6086                }
6087            }
6088        }
6089        if (addEphemeral) {
6090            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveEphemeral");
6091            final EphemeralRequest requestObject = new EphemeralRequest(
6092                    null /*responseObj*/, intent /*origIntent*/, resolvedType,
6093                    null /*launchIntent*/, null /*callingPackage*/, userId);
6094            final EphemeralResponse intentInfo = EphemeralResolver.doEphemeralResolutionPhaseOne(
6095                    mContext, mEphemeralResolverConnection, requestObject);
6096            if (intentInfo != null) {
6097                if (DEBUG_EPHEMERAL) {
6098                    Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
6099                }
6100                final ResolveInfo ephemeralInstaller = new ResolveInfo(mEphemeralInstallerInfo);
6101                ephemeralInstaller.ephemeralResponse = intentInfo;
6102                // make sure this resolver is the default
6103                ephemeralInstaller.isDefault = true;
6104                ephemeralInstaller.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
6105                        | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
6106                // add a non-generic filter
6107                ephemeralInstaller.filter = new IntentFilter(intent.getAction());
6108                ephemeralInstaller.filter.addDataPath(
6109                        intent.getData().getPath(), PatternMatcher.PATTERN_LITERAL);
6110                result.add(ephemeralInstaller);
6111            }
6112            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
6113        }
6114        if (sortResult) {
6115            Collections.sort(result, mResolvePrioritySorter);
6116        }
6117        return filterForEphemeral(result, ephemeralPkgName);
6118    }
6119
6120    private static class CrossProfileDomainInfo {
6121        /* ResolveInfo for IntentForwarderActivity to send the intent to the other profile */
6122        ResolveInfo resolveInfo;
6123        /* Best domain verification status of the activities found in the other profile */
6124        int bestDomainVerificationStatus;
6125    }
6126
6127    private CrossProfileDomainInfo getCrossProfileDomainPreferredLpr(Intent intent,
6128            String resolvedType, int flags, int sourceUserId, int parentUserId) {
6129        if (!sUserManager.hasUserRestriction(UserManager.ALLOW_PARENT_PROFILE_APP_LINKING,
6130                sourceUserId)) {
6131            return null;
6132        }
6133        List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent,
6134                resolvedType, flags, parentUserId);
6135
6136        if (resultTargetUser == null || resultTargetUser.isEmpty()) {
6137            return null;
6138        }
6139        CrossProfileDomainInfo result = null;
6140        int size = resultTargetUser.size();
6141        for (int i = 0; i < size; i++) {
6142            ResolveInfo riTargetUser = resultTargetUser.get(i);
6143            // Intent filter verification is only for filters that specify a host. So don't return
6144            // those that handle all web uris.
6145            if (riTargetUser.handleAllWebDataURI) {
6146                continue;
6147            }
6148            String packageName = riTargetUser.activityInfo.packageName;
6149            PackageSetting ps = mSettings.mPackages.get(packageName);
6150            if (ps == null) {
6151                continue;
6152            }
6153            long verificationState = getDomainVerificationStatusLPr(ps, parentUserId);
6154            int status = (int)(verificationState >> 32);
6155            if (result == null) {
6156                result = new CrossProfileDomainInfo();
6157                result.resolveInfo = createForwardingResolveInfoUnchecked(new IntentFilter(),
6158                        sourceUserId, parentUserId);
6159                result.bestDomainVerificationStatus = status;
6160            } else {
6161                result.bestDomainVerificationStatus = bestDomainVerificationStatus(status,
6162                        result.bestDomainVerificationStatus);
6163            }
6164        }
6165        // Don't consider matches with status NEVER across profiles.
6166        if (result != null && result.bestDomainVerificationStatus
6167                == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
6168            return null;
6169        }
6170        return result;
6171    }
6172
6173    /**
6174     * Verification statuses are ordered from the worse to the best, except for
6175     * INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER, which is the worse.
6176     */
6177    private int bestDomainVerificationStatus(int status1, int status2) {
6178        if (status1 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
6179            return status2;
6180        }
6181        if (status2 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
6182            return status1;
6183        }
6184        return (int) MathUtils.max(status1, status2);
6185    }
6186
6187    private boolean isUserEnabled(int userId) {
6188        long callingId = Binder.clearCallingIdentity();
6189        try {
6190            UserInfo userInfo = sUserManager.getUserInfo(userId);
6191            return userInfo != null && userInfo.isEnabled();
6192        } finally {
6193            Binder.restoreCallingIdentity(callingId);
6194        }
6195    }
6196
6197    /**
6198     * Filter out activities with systemUserOnly flag set, when current user is not System.
6199     *
6200     * @return filtered list
6201     */
6202    private List<ResolveInfo> filterIfNotSystemUser(List<ResolveInfo> resolveInfos, int userId) {
6203        if (userId == UserHandle.USER_SYSTEM) {
6204            return resolveInfos;
6205        }
6206        for (int i = resolveInfos.size() - 1; i >= 0; i--) {
6207            ResolveInfo info = resolveInfos.get(i);
6208            if ((info.activityInfo.flags & ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
6209                resolveInfos.remove(i);
6210            }
6211        }
6212        return resolveInfos;
6213    }
6214
6215    /**
6216     * Filters out ephemeral activities.
6217     * <p>When resolving for an ephemeral app, only activities that 1) are defined in the
6218     * ephemeral app or 2) marked with {@code visibleToEphemeral} are returned.
6219     *
6220     * @param resolveInfos The pre-filtered list of resolved activities
6221     * @param ephemeralPkgName The ephemeral package name. If {@code null}, no filtering
6222     *          is performed.
6223     * @return A filtered list of resolved activities.
6224     */
6225    private List<ResolveInfo> filterForEphemeral(List<ResolveInfo> resolveInfos,
6226            String ephemeralPkgName) {
6227        if (ephemeralPkgName == null) {
6228            return resolveInfos;
6229        }
6230        for (int i = resolveInfos.size() - 1; i >= 0; i--) {
6231            ResolveInfo info = resolveInfos.get(i);
6232            final boolean isEphemeralApp = info.activityInfo.applicationInfo.isInstantApp();
6233            // allow activities that are defined in the provided package
6234            if (isEphemeralApp && ephemeralPkgName.equals(info.activityInfo.packageName)) {
6235                continue;
6236            }
6237            // allow activities that have been explicitly exposed to ephemeral apps
6238            if (!isEphemeralApp
6239                    && ((info.activityInfo.flags & ActivityInfo.FLAG_VISIBLE_TO_EPHEMERAL) != 0)) {
6240                continue;
6241            }
6242            resolveInfos.remove(i);
6243        }
6244        return resolveInfos;
6245    }
6246
6247    /**
6248     * @param resolveInfos list of resolve infos in descending priority order
6249     * @return if the list contains a resolve info with non-negative priority
6250     */
6251    private boolean hasNonNegativePriority(List<ResolveInfo> resolveInfos) {
6252        return resolveInfos.size() > 0 && resolveInfos.get(0).priority >= 0;
6253    }
6254
6255    private static boolean hasWebURI(Intent intent) {
6256        if (intent.getData() == null) {
6257            return false;
6258        }
6259        final String scheme = intent.getScheme();
6260        if (TextUtils.isEmpty(scheme)) {
6261            return false;
6262        }
6263        return scheme.equals(IntentFilter.SCHEME_HTTP) || scheme.equals(IntentFilter.SCHEME_HTTPS);
6264    }
6265
6266    private List<ResolveInfo> filterCandidatesWithDomainPreferredActivitiesLPr(Intent intent,
6267            int matchFlags, List<ResolveInfo> candidates, CrossProfileDomainInfo xpDomainInfo,
6268            int userId) {
6269        final boolean debug = (intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0;
6270
6271        if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) {
6272            Slog.v(TAG, "Filtering results with preferred activities. Candidates count: " +
6273                    candidates.size());
6274        }
6275
6276        ArrayList<ResolveInfo> result = new ArrayList<ResolveInfo>();
6277        ArrayList<ResolveInfo> alwaysList = new ArrayList<ResolveInfo>();
6278        ArrayList<ResolveInfo> undefinedList = new ArrayList<ResolveInfo>();
6279        ArrayList<ResolveInfo> alwaysAskList = new ArrayList<ResolveInfo>();
6280        ArrayList<ResolveInfo> neverList = new ArrayList<ResolveInfo>();
6281        ArrayList<ResolveInfo> matchAllList = new ArrayList<ResolveInfo>();
6282
6283        synchronized (mPackages) {
6284            final int count = candidates.size();
6285            // First, try to use linked apps. Partition the candidates into four lists:
6286            // one for the final results, one for the "do not use ever", one for "undefined status"
6287            // and finally one for "browser app type".
6288            for (int n=0; n<count; n++) {
6289                ResolveInfo info = candidates.get(n);
6290                String packageName = info.activityInfo.packageName;
6291                PackageSetting ps = mSettings.mPackages.get(packageName);
6292                if (ps != null) {
6293                    // Add to the special match all list (Browser use case)
6294                    if (info.handleAllWebDataURI) {
6295                        matchAllList.add(info);
6296                        continue;
6297                    }
6298                    // Try to get the status from User settings first
6299                    long packedStatus = getDomainVerificationStatusLPr(ps, userId);
6300                    int status = (int)(packedStatus >> 32);
6301                    int linkGeneration = (int)(packedStatus & 0xFFFFFFFF);
6302                    if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) {
6303                        if (DEBUG_DOMAIN_VERIFICATION || debug) {
6304                            Slog.i(TAG, "  + always: " + info.activityInfo.packageName
6305                                    + " : linkgen=" + linkGeneration);
6306                        }
6307                        // Use link-enabled generation as preferredOrder, i.e.
6308                        // prefer newly-enabled over earlier-enabled.
6309                        info.preferredOrder = linkGeneration;
6310                        alwaysList.add(info);
6311                    } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
6312                        if (DEBUG_DOMAIN_VERIFICATION || debug) {
6313                            Slog.i(TAG, "  + never: " + info.activityInfo.packageName);
6314                        }
6315                        neverList.add(info);
6316                    } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
6317                        if (DEBUG_DOMAIN_VERIFICATION || debug) {
6318                            Slog.i(TAG, "  + always-ask: " + info.activityInfo.packageName);
6319                        }
6320                        alwaysAskList.add(info);
6321                    } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED ||
6322                            status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK) {
6323                        if (DEBUG_DOMAIN_VERIFICATION || debug) {
6324                            Slog.i(TAG, "  + ask: " + info.activityInfo.packageName);
6325                        }
6326                        undefinedList.add(info);
6327                    }
6328                }
6329            }
6330
6331            // We'll want to include browser possibilities in a few cases
6332            boolean includeBrowser = false;
6333
6334            // First try to add the "always" resolution(s) for the current user, if any
6335            if (alwaysList.size() > 0) {
6336                result.addAll(alwaysList);
6337            } else {
6338                // Add all undefined apps as we want them to appear in the disambiguation dialog.
6339                result.addAll(undefinedList);
6340                // Maybe add one for the other profile.
6341                if (xpDomainInfo != null && (
6342                        xpDomainInfo.bestDomainVerificationStatus
6343                        != INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER)) {
6344                    result.add(xpDomainInfo.resolveInfo);
6345                }
6346                includeBrowser = true;
6347            }
6348
6349            // The presence of any 'always ask' alternatives means we'll also offer browsers.
6350            // If there were 'always' entries their preferred order has been set, so we also
6351            // back that off to make the alternatives equivalent
6352            if (alwaysAskList.size() > 0) {
6353                for (ResolveInfo i : result) {
6354                    i.preferredOrder = 0;
6355                }
6356                result.addAll(alwaysAskList);
6357                includeBrowser = true;
6358            }
6359
6360            if (includeBrowser) {
6361                // Also add browsers (all of them or only the default one)
6362                if (DEBUG_DOMAIN_VERIFICATION) {
6363                    Slog.v(TAG, "   ...including browsers in candidate set");
6364                }
6365                if ((matchFlags & MATCH_ALL) != 0) {
6366                    result.addAll(matchAllList);
6367                } else {
6368                    // Browser/generic handling case.  If there's a default browser, go straight
6369                    // to that (but only if there is no other higher-priority match).
6370                    final String defaultBrowserPackageName = getDefaultBrowserPackageName(userId);
6371                    int maxMatchPrio = 0;
6372                    ResolveInfo defaultBrowserMatch = null;
6373                    final int numCandidates = matchAllList.size();
6374                    for (int n = 0; n < numCandidates; n++) {
6375                        ResolveInfo info = matchAllList.get(n);
6376                        // track the highest overall match priority...
6377                        if (info.priority > maxMatchPrio) {
6378                            maxMatchPrio = info.priority;
6379                        }
6380                        // ...and the highest-priority default browser match
6381                        if (info.activityInfo.packageName.equals(defaultBrowserPackageName)) {
6382                            if (defaultBrowserMatch == null
6383                                    || (defaultBrowserMatch.priority < info.priority)) {
6384                                if (debug) {
6385                                    Slog.v(TAG, "Considering default browser match " + info);
6386                                }
6387                                defaultBrowserMatch = info;
6388                            }
6389                        }
6390                    }
6391                    if (defaultBrowserMatch != null
6392                            && defaultBrowserMatch.priority >= maxMatchPrio
6393                            && !TextUtils.isEmpty(defaultBrowserPackageName))
6394                    {
6395                        if (debug) {
6396                            Slog.v(TAG, "Default browser match " + defaultBrowserMatch);
6397                        }
6398                        result.add(defaultBrowserMatch);
6399                    } else {
6400                        result.addAll(matchAllList);
6401                    }
6402                }
6403
6404                // If there is nothing selected, add all candidates and remove the ones that the user
6405                // has explicitly put into the INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER state
6406                if (result.size() == 0) {
6407                    result.addAll(candidates);
6408                    result.removeAll(neverList);
6409                }
6410            }
6411        }
6412        if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) {
6413            Slog.v(TAG, "Filtered results with preferred activities. New candidates count: " +
6414                    result.size());
6415            for (ResolveInfo info : result) {
6416                Slog.v(TAG, "  + " + info.activityInfo);
6417            }
6418        }
6419        return result;
6420    }
6421
6422    // Returns a packed value as a long:
6423    //
6424    // high 'int'-sized word: link status: undefined/ask/never/always.
6425    // low 'int'-sized word: relative priority among 'always' results.
6426    private long getDomainVerificationStatusLPr(PackageSetting ps, int userId) {
6427        long result = ps.getDomainVerificationStatusForUser(userId);
6428        // if none available, get the master status
6429        if (result >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) {
6430            if (ps.getIntentFilterVerificationInfo() != null) {
6431                result = ((long)ps.getIntentFilterVerificationInfo().getStatus()) << 32;
6432            }
6433        }
6434        return result;
6435    }
6436
6437    private ResolveInfo querySkipCurrentProfileIntents(
6438            List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
6439            int flags, int sourceUserId) {
6440        if (matchingFilters != null) {
6441            int size = matchingFilters.size();
6442            for (int i = 0; i < size; i ++) {
6443                CrossProfileIntentFilter filter = matchingFilters.get(i);
6444                if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0) {
6445                    // Checking if there are activities in the target user that can handle the
6446                    // intent.
6447                    ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent,
6448                            resolvedType, flags, sourceUserId);
6449                    if (resolveInfo != null) {
6450                        return resolveInfo;
6451                    }
6452                }
6453            }
6454        }
6455        return null;
6456    }
6457
6458    // Return matching ResolveInfo in target user if any.
6459    private ResolveInfo queryCrossProfileIntents(
6460            List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
6461            int flags, int sourceUserId, boolean matchInCurrentProfile) {
6462        if (matchingFilters != null) {
6463            // Two {@link CrossProfileIntentFilter}s can have the same targetUserId and
6464            // match the same intent. For performance reasons, it is better not to
6465            // run queryIntent twice for the same userId
6466            SparseBooleanArray alreadyTriedUserIds = new SparseBooleanArray();
6467            int size = matchingFilters.size();
6468            for (int i = 0; i < size; i++) {
6469                CrossProfileIntentFilter filter = matchingFilters.get(i);
6470                int targetUserId = filter.getTargetUserId();
6471                boolean skipCurrentProfile =
6472                        (filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0;
6473                boolean skipCurrentProfileIfNoMatchFound =
6474                        (filter.getFlags() & PackageManager.ONLY_IF_NO_MATCH_FOUND) != 0;
6475                if (!skipCurrentProfile && !alreadyTriedUserIds.get(targetUserId)
6476                        && (!skipCurrentProfileIfNoMatchFound || !matchInCurrentProfile)) {
6477                    // Checking if there are activities in the target user that can handle the
6478                    // intent.
6479                    ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent,
6480                            resolvedType, flags, sourceUserId);
6481                    if (resolveInfo != null) return resolveInfo;
6482                    alreadyTriedUserIds.put(targetUserId, true);
6483                }
6484            }
6485        }
6486        return null;
6487    }
6488
6489    /**
6490     * If the filter's target user can handle the intent and is enabled: returns a ResolveInfo that
6491     * will forward the intent to the filter's target user.
6492     * Otherwise, returns null.
6493     */
6494    private ResolveInfo createForwardingResolveInfo(CrossProfileIntentFilter filter, Intent intent,
6495            String resolvedType, int flags, int sourceUserId) {
6496        int targetUserId = filter.getTargetUserId();
6497        List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent,
6498                resolvedType, flags, targetUserId);
6499        if (resultTargetUser != null && isUserEnabled(targetUserId)) {
6500            // If all the matches in the target profile are suspended, return null.
6501            for (int i = resultTargetUser.size() - 1; i >= 0; i--) {
6502                if ((resultTargetUser.get(i).activityInfo.applicationInfo.flags
6503                        & ApplicationInfo.FLAG_SUSPENDED) == 0) {
6504                    return createForwardingResolveInfoUnchecked(filter, sourceUserId,
6505                            targetUserId);
6506                }
6507            }
6508        }
6509        return null;
6510    }
6511
6512    private ResolveInfo createForwardingResolveInfoUnchecked(IntentFilter filter,
6513            int sourceUserId, int targetUserId) {
6514        ResolveInfo forwardingResolveInfo = new ResolveInfo();
6515        long ident = Binder.clearCallingIdentity();
6516        boolean targetIsProfile;
6517        try {
6518            targetIsProfile = sUserManager.getUserInfo(targetUserId).isManagedProfile();
6519        } finally {
6520            Binder.restoreCallingIdentity(ident);
6521        }
6522        String className;
6523        if (targetIsProfile) {
6524            className = FORWARD_INTENT_TO_MANAGED_PROFILE;
6525        } else {
6526            className = FORWARD_INTENT_TO_PARENT;
6527        }
6528        ComponentName forwardingActivityComponentName = new ComponentName(
6529                mAndroidApplication.packageName, className);
6530        ActivityInfo forwardingActivityInfo = getActivityInfo(forwardingActivityComponentName, 0,
6531                sourceUserId);
6532        if (!targetIsProfile) {
6533            forwardingActivityInfo.showUserIcon = targetUserId;
6534            forwardingResolveInfo.noResourceId = true;
6535        }
6536        forwardingResolveInfo.activityInfo = forwardingActivityInfo;
6537        forwardingResolveInfo.priority = 0;
6538        forwardingResolveInfo.preferredOrder = 0;
6539        forwardingResolveInfo.match = 0;
6540        forwardingResolveInfo.isDefault = true;
6541        forwardingResolveInfo.filter = filter;
6542        forwardingResolveInfo.targetUserId = targetUserId;
6543        return forwardingResolveInfo;
6544    }
6545
6546    @Override
6547    public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivityOptions(ComponentName caller,
6548            Intent[] specifics, String[] specificTypes, Intent intent,
6549            String resolvedType, int flags, int userId) {
6550        return new ParceledListSlice<>(queryIntentActivityOptionsInternal(caller, specifics,
6551                specificTypes, intent, resolvedType, flags, userId));
6552    }
6553
6554    private @NonNull List<ResolveInfo> queryIntentActivityOptionsInternal(ComponentName caller,
6555            Intent[] specifics, String[] specificTypes, Intent intent,
6556            String resolvedType, int flags, int userId) {
6557        if (!sUserManager.exists(userId)) return Collections.emptyList();
6558        flags = updateFlagsForResolve(flags, userId, intent);
6559        enforceCrossUserPermission(Binder.getCallingUid(), userId,
6560                false /* requireFullPermission */, false /* checkShell */,
6561                "query intent activity options");
6562        final String resultsAction = intent.getAction();
6563
6564        final List<ResolveInfo> results = queryIntentActivitiesInternal(intent, resolvedType, flags
6565                | PackageManager.GET_RESOLVED_FILTER, userId);
6566
6567        if (DEBUG_INTENT_MATCHING) {
6568            Log.v(TAG, "Query " + intent + ": " + results);
6569        }
6570
6571        int specificsPos = 0;
6572        int N;
6573
6574        // todo: note that the algorithm used here is O(N^2).  This
6575        // isn't a problem in our current environment, but if we start running
6576        // into situations where we have more than 5 or 10 matches then this
6577        // should probably be changed to something smarter...
6578
6579        // First we go through and resolve each of the specific items
6580        // that were supplied, taking care of removing any corresponding
6581        // duplicate items in the generic resolve list.
6582        if (specifics != null) {
6583            for (int i=0; i<specifics.length; i++) {
6584                final Intent sintent = specifics[i];
6585                if (sintent == null) {
6586                    continue;
6587                }
6588
6589                if (DEBUG_INTENT_MATCHING) {
6590                    Log.v(TAG, "Specific #" + i + ": " + sintent);
6591                }
6592
6593                String action = sintent.getAction();
6594                if (resultsAction != null && resultsAction.equals(action)) {
6595                    // If this action was explicitly requested, then don't
6596                    // remove things that have it.
6597                    action = null;
6598                }
6599
6600                ResolveInfo ri = null;
6601                ActivityInfo ai = null;
6602
6603                ComponentName comp = sintent.getComponent();
6604                if (comp == null) {
6605                    ri = resolveIntent(
6606                        sintent,
6607                        specificTypes != null ? specificTypes[i] : null,
6608                            flags, userId);
6609                    if (ri == null) {
6610                        continue;
6611                    }
6612                    if (ri == mResolveInfo) {
6613                        // ACK!  Must do something better with this.
6614                    }
6615                    ai = ri.activityInfo;
6616                    comp = new ComponentName(ai.applicationInfo.packageName,
6617                            ai.name);
6618                } else {
6619                    ai = getActivityInfo(comp, flags, userId);
6620                    if (ai == null) {
6621                        continue;
6622                    }
6623                }
6624
6625                // Look for any generic query activities that are duplicates
6626                // of this specific one, and remove them from the results.
6627                if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Specific #" + i + ": " + ai);
6628                N = results.size();
6629                int j;
6630                for (j=specificsPos; j<N; j++) {
6631                    ResolveInfo sri = results.get(j);
6632                    if ((sri.activityInfo.name.equals(comp.getClassName())
6633                            && sri.activityInfo.applicationInfo.packageName.equals(
6634                                    comp.getPackageName()))
6635                        || (action != null && sri.filter.matchAction(action))) {
6636                        results.remove(j);
6637                        if (DEBUG_INTENT_MATCHING) Log.v(
6638                            TAG, "Removing duplicate item from " + j
6639                            + " due to specific " + specificsPos);
6640                        if (ri == null) {
6641                            ri = sri;
6642                        }
6643                        j--;
6644                        N--;
6645                    }
6646                }
6647
6648                // Add this specific item to its proper place.
6649                if (ri == null) {
6650                    ri = new ResolveInfo();
6651                    ri.activityInfo = ai;
6652                }
6653                results.add(specificsPos, ri);
6654                ri.specificIndex = i;
6655                specificsPos++;
6656            }
6657        }
6658
6659        // Now we go through the remaining generic results and remove any
6660        // duplicate actions that are found here.
6661        N = results.size();
6662        for (int i=specificsPos; i<N-1; i++) {
6663            final ResolveInfo rii = results.get(i);
6664            if (rii.filter == null) {
6665                continue;
6666            }
6667
6668            // Iterate over all of the actions of this result's intent
6669            // filter...  typically this should be just one.
6670            final Iterator<String> it = rii.filter.actionsIterator();
6671            if (it == null) {
6672                continue;
6673            }
6674            while (it.hasNext()) {
6675                final String action = it.next();
6676                if (resultsAction != null && resultsAction.equals(action)) {
6677                    // If this action was explicitly requested, then don't
6678                    // remove things that have it.
6679                    continue;
6680                }
6681                for (int j=i+1; j<N; j++) {
6682                    final ResolveInfo rij = results.get(j);
6683                    if (rij.filter != null && rij.filter.hasAction(action)) {
6684                        results.remove(j);
6685                        if (DEBUG_INTENT_MATCHING) Log.v(
6686                            TAG, "Removing duplicate item from " + j
6687                            + " due to action " + action + " at " + i);
6688                        j--;
6689                        N--;
6690                    }
6691                }
6692            }
6693
6694            // If the caller didn't request filter information, drop it now
6695            // so we don't have to marshall/unmarshall it.
6696            if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
6697                rii.filter = null;
6698            }
6699        }
6700
6701        // Filter out the caller activity if so requested.
6702        if (caller != null) {
6703            N = results.size();
6704            for (int i=0; i<N; i++) {
6705                ActivityInfo ainfo = results.get(i).activityInfo;
6706                if (caller.getPackageName().equals(ainfo.applicationInfo.packageName)
6707                        && caller.getClassName().equals(ainfo.name)) {
6708                    results.remove(i);
6709                    break;
6710                }
6711            }
6712        }
6713
6714        // If the caller didn't request filter information,
6715        // drop them now so we don't have to
6716        // marshall/unmarshall it.
6717        if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
6718            N = results.size();
6719            for (int i=0; i<N; i++) {
6720                results.get(i).filter = null;
6721            }
6722        }
6723
6724        if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Result: " + results);
6725        return results;
6726    }
6727
6728    @Override
6729    public @NonNull ParceledListSlice<ResolveInfo> queryIntentReceivers(Intent intent,
6730            String resolvedType, int flags, int userId) {
6731        return new ParceledListSlice<>(
6732                queryIntentReceiversInternal(intent, resolvedType, flags, userId));
6733    }
6734
6735    private @NonNull List<ResolveInfo> queryIntentReceiversInternal(Intent intent,
6736            String resolvedType, int flags, int userId) {
6737        if (!sUserManager.exists(userId)) return Collections.emptyList();
6738        flags = updateFlagsForResolve(flags, userId, intent);
6739        ComponentName comp = intent.getComponent();
6740        if (comp == null) {
6741            if (intent.getSelector() != null) {
6742                intent = intent.getSelector();
6743                comp = intent.getComponent();
6744            }
6745        }
6746        if (comp != null) {
6747            List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
6748            ActivityInfo ai = getReceiverInfo(comp, flags, userId);
6749            if (ai != null) {
6750                ResolveInfo ri = new ResolveInfo();
6751                ri.activityInfo = ai;
6752                list.add(ri);
6753            }
6754            return list;
6755        }
6756
6757        // reader
6758        synchronized (mPackages) {
6759            String pkgName = intent.getPackage();
6760            if (pkgName == null) {
6761                return mReceivers.queryIntent(intent, resolvedType, flags, userId);
6762            }
6763            final PackageParser.Package pkg = mPackages.get(pkgName);
6764            if (pkg != null) {
6765                return mReceivers.queryIntentForPackage(intent, resolvedType, flags, pkg.receivers,
6766                        userId);
6767            }
6768            return Collections.emptyList();
6769        }
6770    }
6771
6772    @Override
6773    public ResolveInfo resolveService(Intent intent, String resolvedType, int flags, int userId) {
6774        if (!sUserManager.exists(userId)) return null;
6775        flags = updateFlagsForResolve(flags, userId, intent);
6776        List<ResolveInfo> query = queryIntentServicesInternal(intent, resolvedType, flags, userId);
6777        if (query != null) {
6778            if (query.size() >= 1) {
6779                // If there is more than one service with the same priority,
6780                // just arbitrarily pick the first one.
6781                return query.get(0);
6782            }
6783        }
6784        return null;
6785    }
6786
6787    @Override
6788    public @NonNull ParceledListSlice<ResolveInfo> queryIntentServices(Intent intent,
6789            String resolvedType, int flags, int userId) {
6790        return new ParceledListSlice<>(
6791                queryIntentServicesInternal(intent, resolvedType, flags, userId));
6792    }
6793
6794    private @NonNull List<ResolveInfo> queryIntentServicesInternal(Intent intent,
6795            String resolvedType, int flags, int userId) {
6796        if (!sUserManager.exists(userId)) return Collections.emptyList();
6797        flags = updateFlagsForResolve(flags, userId, intent);
6798        ComponentName comp = intent.getComponent();
6799        if (comp == null) {
6800            if (intent.getSelector() != null) {
6801                intent = intent.getSelector();
6802                comp = intent.getComponent();
6803            }
6804        }
6805        if (comp != null) {
6806            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
6807            final ServiceInfo si = getServiceInfo(comp, flags, userId);
6808            if (si != null) {
6809                final ResolveInfo ri = new ResolveInfo();
6810                ri.serviceInfo = si;
6811                list.add(ri);
6812            }
6813            return list;
6814        }
6815
6816        // reader
6817        synchronized (mPackages) {
6818            String pkgName = intent.getPackage();
6819            if (pkgName == null) {
6820                return mServices.queryIntent(intent, resolvedType, flags, userId);
6821            }
6822            final PackageParser.Package pkg = mPackages.get(pkgName);
6823            if (pkg != null) {
6824                return mServices.queryIntentForPackage(intent, resolvedType, flags, pkg.services,
6825                        userId);
6826            }
6827            return Collections.emptyList();
6828        }
6829    }
6830
6831    @Override
6832    public @NonNull ParceledListSlice<ResolveInfo> queryIntentContentProviders(Intent intent,
6833            String resolvedType, int flags, int userId) {
6834        return new ParceledListSlice<>(
6835                queryIntentContentProvidersInternal(intent, resolvedType, flags, userId));
6836    }
6837
6838    private @NonNull List<ResolveInfo> queryIntentContentProvidersInternal(
6839            Intent intent, String resolvedType, int flags, int userId) {
6840        if (!sUserManager.exists(userId)) return Collections.emptyList();
6841        flags = updateFlagsForResolve(flags, userId, intent);
6842        ComponentName comp = intent.getComponent();
6843        if (comp == null) {
6844            if (intent.getSelector() != null) {
6845                intent = intent.getSelector();
6846                comp = intent.getComponent();
6847            }
6848        }
6849        if (comp != null) {
6850            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
6851            final ProviderInfo pi = getProviderInfo(comp, flags, userId);
6852            if (pi != null) {
6853                final ResolveInfo ri = new ResolveInfo();
6854                ri.providerInfo = pi;
6855                list.add(ri);
6856            }
6857            return list;
6858        }
6859
6860        // reader
6861        synchronized (mPackages) {
6862            String pkgName = intent.getPackage();
6863            if (pkgName == null) {
6864                return mProviders.queryIntent(intent, resolvedType, flags, userId);
6865            }
6866            final PackageParser.Package pkg = mPackages.get(pkgName);
6867            if (pkg != null) {
6868                return mProviders.queryIntentForPackage(
6869                        intent, resolvedType, flags, pkg.providers, userId);
6870            }
6871            return Collections.emptyList();
6872        }
6873    }
6874
6875    @Override
6876    public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) {
6877        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
6878        flags = updateFlagsForPackage(flags, userId, null);
6879        final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
6880        enforceCrossUserPermission(Binder.getCallingUid(), userId,
6881                true /* requireFullPermission */, false /* checkShell */,
6882                "get installed packages");
6883
6884        // writer
6885        synchronized (mPackages) {
6886            ArrayList<PackageInfo> list;
6887            if (listUninstalled) {
6888                list = new ArrayList<>(mSettings.mPackages.size());
6889                for (PackageSetting ps : mSettings.mPackages.values()) {
6890                    if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId)) {
6891                        continue;
6892                    }
6893                    final PackageInfo pi = generatePackageInfo(ps, flags, userId);
6894                    if (pi != null) {
6895                        list.add(pi);
6896                    }
6897                }
6898            } else {
6899                list = new ArrayList<>(mPackages.size());
6900                for (PackageParser.Package p : mPackages.values()) {
6901                    if (filterSharedLibPackageLPr((PackageSetting) p.mExtras,
6902                            Binder.getCallingUid(), userId)) {
6903                        continue;
6904                    }
6905                    final PackageInfo pi = generatePackageInfo((PackageSetting)
6906                            p.mExtras, flags, userId);
6907                    if (pi != null) {
6908                        list.add(pi);
6909                    }
6910                }
6911            }
6912
6913            return new ParceledListSlice<>(list);
6914        }
6915    }
6916
6917    private void addPackageHoldingPermissions(ArrayList<PackageInfo> list, PackageSetting ps,
6918            String[] permissions, boolean[] tmp, int flags, int userId) {
6919        int numMatch = 0;
6920        final PermissionsState permissionsState = ps.getPermissionsState();
6921        for (int i=0; i<permissions.length; i++) {
6922            final String permission = permissions[i];
6923            if (permissionsState.hasPermission(permission, userId)) {
6924                tmp[i] = true;
6925                numMatch++;
6926            } else {
6927                tmp[i] = false;
6928            }
6929        }
6930        if (numMatch == 0) {
6931            return;
6932        }
6933        final PackageInfo pi = generatePackageInfo(ps, flags, userId);
6934
6935        // The above might return null in cases of uninstalled apps or install-state
6936        // skew across users/profiles.
6937        if (pi != null) {
6938            if ((flags&PackageManager.GET_PERMISSIONS) == 0) {
6939                if (numMatch == permissions.length) {
6940                    pi.requestedPermissions = permissions;
6941                } else {
6942                    pi.requestedPermissions = new String[numMatch];
6943                    numMatch = 0;
6944                    for (int i=0; i<permissions.length; i++) {
6945                        if (tmp[i]) {
6946                            pi.requestedPermissions[numMatch] = permissions[i];
6947                            numMatch++;
6948                        }
6949                    }
6950                }
6951            }
6952            list.add(pi);
6953        }
6954    }
6955
6956    @Override
6957    public ParceledListSlice<PackageInfo> getPackagesHoldingPermissions(
6958            String[] permissions, int flags, int userId) {
6959        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
6960        flags = updateFlagsForPackage(flags, userId, permissions);
6961        enforceCrossUserPermission(Binder.getCallingUid(), userId,
6962                true /* requireFullPermission */, false /* checkShell */,
6963                "get packages holding permissions");
6964        final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
6965
6966        // writer
6967        synchronized (mPackages) {
6968            ArrayList<PackageInfo> list = new ArrayList<PackageInfo>();
6969            boolean[] tmpBools = new boolean[permissions.length];
6970            if (listUninstalled) {
6971                for (PackageSetting ps : mSettings.mPackages.values()) {
6972                    addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags,
6973                            userId);
6974                }
6975            } else {
6976                for (PackageParser.Package pkg : mPackages.values()) {
6977                    PackageSetting ps = (PackageSetting)pkg.mExtras;
6978                    if (ps != null) {
6979                        addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags,
6980                                userId);
6981                    }
6982                }
6983            }
6984
6985            return new ParceledListSlice<PackageInfo>(list);
6986        }
6987    }
6988
6989    @Override
6990    public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags, int userId) {
6991        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
6992        flags = updateFlagsForApplication(flags, userId, null);
6993        final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
6994
6995        // writer
6996        synchronized (mPackages) {
6997            ArrayList<ApplicationInfo> list;
6998            if (listUninstalled) {
6999                list = new ArrayList<>(mSettings.mPackages.size());
7000                for (PackageSetting ps : mSettings.mPackages.values()) {
7001                    ApplicationInfo ai;
7002                    int effectiveFlags = flags;
7003                    if (ps.isSystem()) {
7004                        effectiveFlags |= PackageManager.MATCH_ANY_USER;
7005                    }
7006                    if (ps.pkg != null) {
7007                        if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId)) {
7008                            continue;
7009                        }
7010                        ai = PackageParser.generateApplicationInfo(ps.pkg, effectiveFlags,
7011                                ps.readUserState(userId), userId);
7012                        if (ai != null) {
7013                            ai.packageName = resolveExternalPackageNameLPr(ps.pkg);
7014                        }
7015                    } else {
7016                        // Shared lib filtering done in generateApplicationInfoFromSettingsLPw
7017                        // and already converts to externally visible package name
7018                        ai = generateApplicationInfoFromSettingsLPw(ps.name,
7019                                Binder.getCallingUid(), effectiveFlags, userId);
7020                    }
7021                    if (ai != null) {
7022                        list.add(ai);
7023                    }
7024                }
7025            } else {
7026                list = new ArrayList<>(mPackages.size());
7027                for (PackageParser.Package p : mPackages.values()) {
7028                    if (p.mExtras != null) {
7029                        PackageSetting ps = (PackageSetting) p.mExtras;
7030                        if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId)) {
7031                            continue;
7032                        }
7033                        ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
7034                                ps.readUserState(userId), userId);
7035                        if (ai != null) {
7036                            ai.packageName = resolveExternalPackageNameLPr(p);
7037                            list.add(ai);
7038                        }
7039                    }
7040                }
7041            }
7042
7043            return new ParceledListSlice<>(list);
7044        }
7045    }
7046
7047    @Override
7048    public ParceledListSlice<InstantAppInfo> getInstantApps(int userId) {
7049        if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
7050            return null;
7051        }
7052
7053        mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_INSTANT_APPS,
7054                "getEphemeralApplications");
7055        enforceCrossUserPermission(Binder.getCallingUid(), userId,
7056                true /* requireFullPermission */, false /* checkShell */,
7057                "getEphemeralApplications");
7058        synchronized (mPackages) {
7059            List<InstantAppInfo> instantApps = mInstantAppRegistry
7060                    .getInstantAppsLPr(userId);
7061            if (instantApps != null) {
7062                return new ParceledListSlice<>(instantApps);
7063            }
7064        }
7065        return null;
7066    }
7067
7068    @Override
7069    public boolean isInstantApp(String packageName, int userId) {
7070        enforceCrossUserPermission(Binder.getCallingUid(), userId,
7071                true /* requireFullPermission */, false /* checkShell */,
7072                "isInstantApp");
7073        if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
7074            return false;
7075        }
7076
7077        if (!isCallerSameApp(packageName)) {
7078            return false;
7079        }
7080        synchronized (mPackages) {
7081            PackageParser.Package pkg = mPackages.get(packageName);
7082            if (pkg != null) {
7083                return pkg.applicationInfo.isInstantApp();
7084            }
7085        }
7086        return false;
7087    }
7088
7089    @Override
7090    public byte[] getInstantAppCookie(String packageName, int userId) {
7091        if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
7092            return null;
7093        }
7094
7095        enforceCrossUserPermission(Binder.getCallingUid(), userId,
7096                true /* requireFullPermission */, false /* checkShell */,
7097                "getInstantAppCookie");
7098        if (!isCallerSameApp(packageName)) {
7099            return null;
7100        }
7101        synchronized (mPackages) {
7102            return mInstantAppRegistry.getInstantAppCookieLPw(
7103                    packageName, userId);
7104        }
7105    }
7106
7107    @Override
7108    public boolean setInstantAppCookie(String packageName, byte[] cookie, int userId) {
7109        if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
7110            return true;
7111        }
7112
7113        enforceCrossUserPermission(Binder.getCallingUid(), userId,
7114                true /* requireFullPermission */, true /* checkShell */,
7115                "setInstantAppCookie");
7116        if (!isCallerSameApp(packageName)) {
7117            return false;
7118        }
7119        synchronized (mPackages) {
7120            return mInstantAppRegistry.setInstantAppCookieLPw(
7121                    packageName, cookie, userId);
7122        }
7123    }
7124
7125    @Override
7126    public Bitmap getInstantAppIcon(String packageName, int userId) {
7127        if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
7128            return null;
7129        }
7130
7131        mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_INSTANT_APPS,
7132                "getInstantAppIcon");
7133
7134        enforceCrossUserPermission(Binder.getCallingUid(), userId,
7135                true /* requireFullPermission */, false /* checkShell */,
7136                "getInstantAppIcon");
7137
7138        synchronized (mPackages) {
7139            return mInstantAppRegistry.getInstantAppIconLPw(
7140                    packageName, userId);
7141        }
7142    }
7143
7144    private boolean isCallerSameApp(String packageName) {
7145        PackageParser.Package pkg = mPackages.get(packageName);
7146        return pkg != null
7147                && UserHandle.getAppId(Binder.getCallingUid()) == pkg.applicationInfo.uid;
7148    }
7149
7150    @Override
7151    public @NonNull ParceledListSlice<ApplicationInfo> getPersistentApplications(int flags) {
7152        return new ParceledListSlice<>(getPersistentApplicationsInternal(flags));
7153    }
7154
7155    private @NonNull List<ApplicationInfo> getPersistentApplicationsInternal(int flags) {
7156        final ArrayList<ApplicationInfo> finalList = new ArrayList<ApplicationInfo>();
7157
7158        // reader
7159        synchronized (mPackages) {
7160            final Iterator<PackageParser.Package> i = mPackages.values().iterator();
7161            final int userId = UserHandle.getCallingUserId();
7162            while (i.hasNext()) {
7163                final PackageParser.Package p = i.next();
7164                if (p.applicationInfo == null) continue;
7165
7166                final boolean matchesUnaware = ((flags & MATCH_DIRECT_BOOT_UNAWARE) != 0)
7167                        && !p.applicationInfo.isDirectBootAware();
7168                final boolean matchesAware = ((flags & MATCH_DIRECT_BOOT_AWARE) != 0)
7169                        && p.applicationInfo.isDirectBootAware();
7170
7171                if ((p.applicationInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0
7172                        && (!mSafeMode || isSystemApp(p))
7173                        && (matchesUnaware || matchesAware)) {
7174                    PackageSetting ps = mSettings.mPackages.get(p.packageName);
7175                    if (ps != null) {
7176                        ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
7177                                ps.readUserState(userId), userId);
7178                        if (ai != null) {
7179                            finalList.add(ai);
7180                        }
7181                    }
7182                }
7183            }
7184        }
7185
7186        return finalList;
7187    }
7188
7189    @Override
7190    public ProviderInfo resolveContentProvider(String name, int flags, int userId) {
7191        if (!sUserManager.exists(userId)) return null;
7192        flags = updateFlagsForComponent(flags, userId, name);
7193        // reader
7194        synchronized (mPackages) {
7195            final PackageParser.Provider provider = mProvidersByAuthority.get(name);
7196            PackageSetting ps = provider != null
7197                    ? mSettings.mPackages.get(provider.owner.packageName)
7198                    : null;
7199            return ps != null
7200                    && mSettings.isEnabledAndMatchLPr(provider.info, flags, userId)
7201                    ? PackageParser.generateProviderInfo(provider, flags,
7202                            ps.readUserState(userId), userId)
7203                    : null;
7204        }
7205    }
7206
7207    /**
7208     * @deprecated
7209     */
7210    @Deprecated
7211    public void querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo) {
7212        // reader
7213        synchronized (mPackages) {
7214            final Iterator<Map.Entry<String, PackageParser.Provider>> i = mProvidersByAuthority
7215                    .entrySet().iterator();
7216            final int userId = UserHandle.getCallingUserId();
7217            while (i.hasNext()) {
7218                Map.Entry<String, PackageParser.Provider> entry = i.next();
7219                PackageParser.Provider p = entry.getValue();
7220                PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
7221
7222                if (ps != null && p.syncable
7223                        && (!mSafeMode || (p.info.applicationInfo.flags
7224                                &ApplicationInfo.FLAG_SYSTEM) != 0)) {
7225                    ProviderInfo info = PackageParser.generateProviderInfo(p, 0,
7226                            ps.readUserState(userId), userId);
7227                    if (info != null) {
7228                        outNames.add(entry.getKey());
7229                        outInfo.add(info);
7230                    }
7231                }
7232            }
7233        }
7234    }
7235
7236    @Override
7237    public @NonNull ParceledListSlice<ProviderInfo> queryContentProviders(String processName,
7238            int uid, int flags) {
7239        final int userId = processName != null ? UserHandle.getUserId(uid)
7240                : UserHandle.getCallingUserId();
7241        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
7242        flags = updateFlagsForComponent(flags, userId, processName);
7243
7244        ArrayList<ProviderInfo> finalList = null;
7245        // reader
7246        synchronized (mPackages) {
7247            final Iterator<PackageParser.Provider> i = mProviders.mProviders.values().iterator();
7248            while (i.hasNext()) {
7249                final PackageParser.Provider p = i.next();
7250                PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
7251                if (ps != null && p.info.authority != null
7252                        && (processName == null
7253                                || (p.info.processName.equals(processName)
7254                                        && UserHandle.isSameApp(p.info.applicationInfo.uid, uid)))
7255                        && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) {
7256                    if (finalList == null) {
7257                        finalList = new ArrayList<ProviderInfo>(3);
7258                    }
7259                    ProviderInfo info = PackageParser.generateProviderInfo(p, flags,
7260                            ps.readUserState(userId), userId);
7261                    if (info != null) {
7262                        finalList.add(info);
7263                    }
7264                }
7265            }
7266        }
7267
7268        if (finalList != null) {
7269            Collections.sort(finalList, mProviderInitOrderSorter);
7270            return new ParceledListSlice<ProviderInfo>(finalList);
7271        }
7272
7273        return ParceledListSlice.emptyList();
7274    }
7275
7276    @Override
7277    public InstrumentationInfo getInstrumentationInfo(ComponentName name, int flags) {
7278        // reader
7279        synchronized (mPackages) {
7280            final PackageParser.Instrumentation i = mInstrumentation.get(name);
7281            return PackageParser.generateInstrumentationInfo(i, flags);
7282        }
7283    }
7284
7285    @Override
7286    public @NonNull ParceledListSlice<InstrumentationInfo> queryInstrumentation(
7287            String targetPackage, int flags) {
7288        return new ParceledListSlice<>(queryInstrumentationInternal(targetPackage, flags));
7289    }
7290
7291    private @NonNull List<InstrumentationInfo> queryInstrumentationInternal(String targetPackage,
7292            int flags) {
7293        ArrayList<InstrumentationInfo> finalList = new ArrayList<InstrumentationInfo>();
7294
7295        // reader
7296        synchronized (mPackages) {
7297            final Iterator<PackageParser.Instrumentation> i = mInstrumentation.values().iterator();
7298            while (i.hasNext()) {
7299                final PackageParser.Instrumentation p = i.next();
7300                if (targetPackage == null
7301                        || targetPackage.equals(p.info.targetPackage)) {
7302                    InstrumentationInfo ii = PackageParser.generateInstrumentationInfo(p,
7303                            flags);
7304                    if (ii != null) {
7305                        finalList.add(ii);
7306                    }
7307                }
7308            }
7309        }
7310
7311        return finalList;
7312    }
7313
7314    private void createIdmapsForPackageLI(PackageParser.Package pkg) {
7315        ArrayMap<String, PackageParser.Package> overlays = mOverlays.get(pkg.packageName);
7316        if (overlays == null) {
7317            Slog.w(TAG, "Unable to create idmap for " + pkg.packageName + ": no overlay packages");
7318            return;
7319        }
7320        for (PackageParser.Package opkg : overlays.values()) {
7321            // Not much to do if idmap fails: we already logged the error
7322            // and we certainly don't want to abort installation of pkg simply
7323            // because an overlay didn't fit properly. For these reasons,
7324            // ignore the return value of createIdmapForPackagePairLI.
7325            createIdmapForPackagePairLI(pkg, opkg);
7326        }
7327    }
7328
7329    private boolean createIdmapForPackagePairLI(PackageParser.Package pkg,
7330            PackageParser.Package opkg) {
7331        if (!opkg.mTrustedOverlay) {
7332            Slog.w(TAG, "Skipping target and overlay pair " + pkg.baseCodePath + " and " +
7333                    opkg.baseCodePath + ": overlay not trusted");
7334            return false;
7335        }
7336        ArrayMap<String, PackageParser.Package> overlaySet = mOverlays.get(pkg.packageName);
7337        if (overlaySet == null) {
7338            Slog.e(TAG, "was about to create idmap for " + pkg.baseCodePath + " and " +
7339                    opkg.baseCodePath + " but target package has no known overlays");
7340            return false;
7341        }
7342        final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
7343        // TODO: generate idmap for split APKs
7344        try {
7345            mInstaller.idmap(pkg.baseCodePath, opkg.baseCodePath, sharedGid);
7346        } catch (InstallerException e) {
7347            Slog.e(TAG, "Failed to generate idmap for " + pkg.baseCodePath + " and "
7348                    + opkg.baseCodePath);
7349            return false;
7350        }
7351        PackageParser.Package[] overlayArray =
7352            overlaySet.values().toArray(new PackageParser.Package[0]);
7353        Comparator<PackageParser.Package> cmp = new Comparator<PackageParser.Package>() {
7354            public int compare(PackageParser.Package p1, PackageParser.Package p2) {
7355                return p1.mOverlayPriority - p2.mOverlayPriority;
7356            }
7357        };
7358        Arrays.sort(overlayArray, cmp);
7359
7360        pkg.applicationInfo.resourceDirs = new String[overlayArray.length];
7361        int i = 0;
7362        for (PackageParser.Package p : overlayArray) {
7363            pkg.applicationInfo.resourceDirs[i++] = p.baseCodePath;
7364        }
7365        return true;
7366    }
7367
7368    private void scanDirTracedLI(File dir, final int parseFlags, int scanFlags, long currentTime) {
7369        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanDir [" + dir.getAbsolutePath() + "]");
7370        try {
7371            scanDirLI(dir, parseFlags, scanFlags, currentTime);
7372        } finally {
7373            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
7374        }
7375    }
7376
7377    private void scanDirLI(File dir, int parseFlags, int scanFlags, long currentTime) {
7378        final File[] files = dir.listFiles();
7379        if (ArrayUtils.isEmpty(files)) {
7380            Log.d(TAG, "No files in app dir " + dir);
7381            return;
7382        }
7383
7384        if (DEBUG_PACKAGE_SCANNING) {
7385            Log.d(TAG, "Scanning app dir " + dir + " scanFlags=" + scanFlags
7386                    + " flags=0x" + Integer.toHexString(parseFlags));
7387        }
7388        ParallelPackageParser parallelPackageParser = new ParallelPackageParser(
7389                mSeparateProcesses, mOnlyCore, mMetrics, mCacheDir);
7390
7391        // Submit files for parsing in parallel
7392        int fileCount = 0;
7393        for (File file : files) {
7394            final boolean isPackage = (isApkFile(file) || file.isDirectory())
7395                    && !PackageInstallerService.isStageName(file.getName());
7396            if (!isPackage) {
7397                // Ignore entries which are not packages
7398                continue;
7399            }
7400            parallelPackageParser.submit(file, parseFlags);
7401            fileCount++;
7402        }
7403
7404        // Process results one by one
7405        for (; fileCount > 0; fileCount--) {
7406            ParallelPackageParser.ParseResult parseResult = parallelPackageParser.take();
7407            Throwable throwable = parseResult.throwable;
7408            int errorCode = PackageManager.INSTALL_SUCCEEDED;
7409
7410            if (throwable == null) {
7411                // Static shared libraries have synthetic package names
7412                if (parseResult.pkg.applicationInfo.isStaticSharedLibrary()) {
7413                    renameStaticSharedLibraryPackage(parseResult.pkg);
7414                }
7415                try {
7416                    if (errorCode == PackageManager.INSTALL_SUCCEEDED) {
7417                        scanPackageLI(parseResult.pkg, parseResult.scanFile, parseFlags, scanFlags,
7418                                currentTime, null);
7419                    }
7420                } catch (PackageManagerException e) {
7421                    errorCode = e.error;
7422                    Slog.w(TAG, "Failed to scan " + parseResult.scanFile + ": " + e.getMessage());
7423                }
7424            } else if (throwable instanceof PackageParser.PackageParserException) {
7425                PackageParser.PackageParserException e = (PackageParser.PackageParserException)
7426                        throwable;
7427                errorCode = e.error;
7428                Slog.w(TAG, "Failed to parse " + parseResult.scanFile + ": " + e.getMessage());
7429            } else {
7430                throw new IllegalStateException("Unexpected exception occurred while parsing "
7431                        + parseResult.scanFile, throwable);
7432            }
7433
7434            // Delete invalid userdata apps
7435            if ((parseFlags & PackageParser.PARSE_IS_SYSTEM) == 0 &&
7436                    errorCode == PackageManager.INSTALL_FAILED_INVALID_APK) {
7437                logCriticalInfo(Log.WARN,
7438                        "Deleting invalid package at " + parseResult.scanFile);
7439                removeCodePathLI(parseResult.scanFile);
7440            }
7441        }
7442        parallelPackageParser.close();
7443    }
7444
7445    private static File getSettingsProblemFile() {
7446        File dataDir = Environment.getDataDirectory();
7447        File systemDir = new File(dataDir, "system");
7448        File fname = new File(systemDir, "uiderrors.txt");
7449        return fname;
7450    }
7451
7452    static void reportSettingsProblem(int priority, String msg) {
7453        logCriticalInfo(priority, msg);
7454    }
7455
7456    static void logCriticalInfo(int priority, String msg) {
7457        Slog.println(priority, TAG, msg);
7458        EventLogTags.writePmCriticalInfo(msg);
7459        try {
7460            File fname = getSettingsProblemFile();
7461            FileOutputStream out = new FileOutputStream(fname, true);
7462            PrintWriter pw = new FastPrintWriter(out);
7463            SimpleDateFormat formatter = new SimpleDateFormat();
7464            String dateString = formatter.format(new Date(System.currentTimeMillis()));
7465            pw.println(dateString + ": " + msg);
7466            pw.close();
7467            FileUtils.setPermissions(
7468                    fname.toString(),
7469                    FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IROTH,
7470                    -1, -1);
7471        } catch (java.io.IOException e) {
7472        }
7473    }
7474
7475    private long getLastModifiedTime(PackageParser.Package pkg, File srcFile) {
7476        if (srcFile.isDirectory()) {
7477            final File baseFile = new File(pkg.baseCodePath);
7478            long maxModifiedTime = baseFile.lastModified();
7479            if (pkg.splitCodePaths != null) {
7480                for (int i = pkg.splitCodePaths.length - 1; i >=0; --i) {
7481                    final File splitFile = new File(pkg.splitCodePaths[i]);
7482                    maxModifiedTime = Math.max(maxModifiedTime, splitFile.lastModified());
7483                }
7484            }
7485            return maxModifiedTime;
7486        }
7487        return srcFile.lastModified();
7488    }
7489
7490    private void collectCertificatesLI(PackageSetting ps, PackageParser.Package pkg, File srcFile,
7491            final int policyFlags) throws PackageManagerException {
7492        // When upgrading from pre-N MR1, verify the package time stamp using the package
7493        // directory and not the APK file.
7494        final long lastModifiedTime = mIsPreNMR1Upgrade
7495                ? new File(pkg.codePath).lastModified() : getLastModifiedTime(pkg, srcFile);
7496        if (ps != null
7497                && ps.codePath.equals(srcFile)
7498                && ps.timeStamp == lastModifiedTime
7499                && !isCompatSignatureUpdateNeeded(pkg)
7500                && !isRecoverSignatureUpdateNeeded(pkg)) {
7501            long mSigningKeySetId = ps.keySetData.getProperSigningKeySet();
7502            KeySetManagerService ksms = mSettings.mKeySetManagerService;
7503            ArraySet<PublicKey> signingKs;
7504            synchronized (mPackages) {
7505                signingKs = ksms.getPublicKeysFromKeySetLPr(mSigningKeySetId);
7506            }
7507            if (ps.signatures.mSignatures != null
7508                    && ps.signatures.mSignatures.length != 0
7509                    && signingKs != null) {
7510                // Optimization: reuse the existing cached certificates
7511                // if the package appears to be unchanged.
7512                pkg.mSignatures = ps.signatures.mSignatures;
7513                pkg.mSigningKeys = signingKs;
7514                return;
7515            }
7516
7517            Slog.w(TAG, "PackageSetting for " + ps.name
7518                    + " is missing signatures.  Collecting certs again to recover them.");
7519        } else {
7520            Slog.i(TAG, srcFile.toString() + " changed; collecting certs");
7521        }
7522
7523        try {
7524            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "collectCertificates");
7525            PackageParser.collectCertificates(pkg, policyFlags);
7526        } catch (PackageParserException e) {
7527            throw PackageManagerException.from(e);
7528        } finally {
7529            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
7530        }
7531    }
7532
7533    /**
7534     *  Traces a package scan.
7535     *  @see #scanPackageLI(File, int, int, long, UserHandle)
7536     */
7537    private PackageParser.Package scanPackageTracedLI(File scanFile, final int parseFlags,
7538            int scanFlags, long currentTime, UserHandle user) throws PackageManagerException {
7539        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage [" + scanFile.toString() + "]");
7540        try {
7541            return scanPackageLI(scanFile, parseFlags, scanFlags, currentTime, user);
7542        } finally {
7543            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
7544        }
7545    }
7546
7547    /**
7548     *  Scans a package and returns the newly parsed package.
7549     *  Returns {@code null} in case of errors and the error code is stored in mLastScanError
7550     */
7551    private PackageParser.Package scanPackageLI(File scanFile, int parseFlags, int scanFlags,
7552            long currentTime, UserHandle user) throws PackageManagerException {
7553        if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanFile);
7554        PackageParser pp = new PackageParser();
7555        pp.setSeparateProcesses(mSeparateProcesses);
7556        pp.setOnlyCoreApps(mOnlyCore);
7557        pp.setDisplayMetrics(mMetrics);
7558
7559        if ((scanFlags & SCAN_TRUSTED_OVERLAY) != 0) {
7560            parseFlags |= PackageParser.PARSE_TRUSTED_OVERLAY;
7561        }
7562
7563        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
7564        final PackageParser.Package pkg;
7565        try {
7566            pkg = pp.parsePackage(scanFile, parseFlags);
7567        } catch (PackageParserException e) {
7568            throw PackageManagerException.from(e);
7569        } finally {
7570            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
7571        }
7572
7573        // Static shared libraries have synthetic package names
7574        if (pkg.applicationInfo.isStaticSharedLibrary()) {
7575            renameStaticSharedLibraryPackage(pkg);
7576        }
7577
7578        return scanPackageLI(pkg, scanFile, parseFlags, scanFlags, currentTime, user);
7579    }
7580
7581    /**
7582     *  Scans a package and returns the newly parsed package.
7583     *  @throws PackageManagerException on a parse error.
7584     */
7585    private PackageParser.Package scanPackageLI(PackageParser.Package pkg, File scanFile,
7586            final int policyFlags, int scanFlags, long currentTime, UserHandle user)
7587            throws PackageManagerException {
7588        // If the package has children and this is the first dive in the function
7589        // we scan the package with the SCAN_CHECK_ONLY flag set to see whether all
7590        // packages (parent and children) would be successfully scanned before the
7591        // actual scan since scanning mutates internal state and we want to atomically
7592        // install the package and its children.
7593        if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
7594            if (pkg.childPackages != null && pkg.childPackages.size() > 0) {
7595                scanFlags |= SCAN_CHECK_ONLY;
7596            }
7597        } else {
7598            scanFlags &= ~SCAN_CHECK_ONLY;
7599        }
7600
7601        // Scan the parent
7602        PackageParser.Package scannedPkg = scanPackageInternalLI(pkg, scanFile, policyFlags,
7603                scanFlags, currentTime, user);
7604
7605        // Scan the children
7606        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
7607        for (int i = 0; i < childCount; i++) {
7608            PackageParser.Package childPackage = pkg.childPackages.get(i);
7609            scanPackageInternalLI(childPackage, scanFile, policyFlags, scanFlags,
7610                    currentTime, user);
7611        }
7612
7613
7614        if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
7615            return scanPackageLI(pkg, scanFile, policyFlags, scanFlags, currentTime, user);
7616        }
7617
7618        return scannedPkg;
7619    }
7620
7621    /**
7622     *  Scans a package and returns the newly parsed package.
7623     *  @throws PackageManagerException on a parse error.
7624     */
7625    private PackageParser.Package scanPackageInternalLI(PackageParser.Package pkg, File scanFile,
7626            int policyFlags, int scanFlags, long currentTime, UserHandle user)
7627            throws PackageManagerException {
7628        PackageSetting ps = null;
7629        PackageSetting updatedPkg;
7630        // reader
7631        synchronized (mPackages) {
7632            // Look to see if we already know about this package.
7633            String oldName = mSettings.getRenamedPackageLPr(pkg.packageName);
7634            if (pkg.mOriginalPackages != null && pkg.mOriginalPackages.contains(oldName)) {
7635                // This package has been renamed to its original name.  Let's
7636                // use that.
7637                ps = mSettings.getPackageLPr(oldName);
7638            }
7639            // If there was no original package, see one for the real package name.
7640            if (ps == null) {
7641                ps = mSettings.getPackageLPr(pkg.packageName);
7642            }
7643            // Check to see if this package could be hiding/updating a system
7644            // package.  Must look for it either under the original or real
7645            // package name depending on our state.
7646            updatedPkg = mSettings.getDisabledSystemPkgLPr(ps != null ? ps.name : pkg.packageName);
7647            if (DEBUG_INSTALL && updatedPkg != null) Slog.d(TAG, "updatedPkg = " + updatedPkg);
7648
7649            // If this is a package we don't know about on the system partition, we
7650            // may need to remove disabled child packages on the system partition
7651            // or may need to not add child packages if the parent apk is updated
7652            // on the data partition and no longer defines this child package.
7653            if ((policyFlags & PackageParser.PARSE_IS_SYSTEM) != 0) {
7654                // If this is a parent package for an updated system app and this system
7655                // app got an OTA update which no longer defines some of the child packages
7656                // we have to prune them from the disabled system packages.
7657                PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(pkg.packageName);
7658                if (disabledPs != null) {
7659                    final int scannedChildCount = (pkg.childPackages != null)
7660                            ? pkg.childPackages.size() : 0;
7661                    final int disabledChildCount = disabledPs.childPackageNames != null
7662                            ? disabledPs.childPackageNames.size() : 0;
7663                    for (int i = 0; i < disabledChildCount; i++) {
7664                        String disabledChildPackageName = disabledPs.childPackageNames.get(i);
7665                        boolean disabledPackageAvailable = false;
7666                        for (int j = 0; j < scannedChildCount; j++) {
7667                            PackageParser.Package childPkg = pkg.childPackages.get(j);
7668                            if (childPkg.packageName.equals(disabledChildPackageName)) {
7669                                disabledPackageAvailable = true;
7670                                break;
7671                            }
7672                         }
7673                         if (!disabledPackageAvailable) {
7674                             mSettings.removeDisabledSystemPackageLPw(disabledChildPackageName);
7675                         }
7676                    }
7677                }
7678            }
7679        }
7680
7681        boolean updatedPkgBetter = false;
7682        // First check if this is a system package that may involve an update
7683        if (updatedPkg != null && (policyFlags & PackageParser.PARSE_IS_SYSTEM) != 0) {
7684            // If new package is not located in "/system/priv-app" (e.g. due to an OTA),
7685            // it needs to drop FLAG_PRIVILEGED.
7686            if (locationIsPrivileged(scanFile)) {
7687                updatedPkg.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
7688            } else {
7689                updatedPkg.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
7690            }
7691
7692            if (ps != null && !ps.codePath.equals(scanFile)) {
7693                // The path has changed from what was last scanned...  check the
7694                // version of the new path against what we have stored to determine
7695                // what to do.
7696                if (DEBUG_INSTALL) Slog.d(TAG, "Path changing from " + ps.codePath);
7697                if (pkg.mVersionCode <= ps.versionCode) {
7698                    // The system package has been updated and the code path does not match
7699                    // Ignore entry. Skip it.
7700                    if (DEBUG_INSTALL) Slog.i(TAG, "Package " + ps.name + " at " + scanFile
7701                            + " ignored: updated version " + ps.versionCode
7702                            + " better than this " + pkg.mVersionCode);
7703                    if (!updatedPkg.codePath.equals(scanFile)) {
7704                        Slog.w(PackageManagerService.TAG, "Code path for hidden system pkg "
7705                                + ps.name + " changing from " + updatedPkg.codePathString
7706                                + " to " + scanFile);
7707                        updatedPkg.codePath = scanFile;
7708                        updatedPkg.codePathString = scanFile.toString();
7709                        updatedPkg.resourcePath = scanFile;
7710                        updatedPkg.resourcePathString = scanFile.toString();
7711                    }
7712                    updatedPkg.pkg = pkg;
7713                    updatedPkg.versionCode = pkg.mVersionCode;
7714
7715                    // Update the disabled system child packages to point to the package too.
7716                    final int childCount = updatedPkg.childPackageNames != null
7717                            ? updatedPkg.childPackageNames.size() : 0;
7718                    for (int i = 0; i < childCount; i++) {
7719                        String childPackageName = updatedPkg.childPackageNames.get(i);
7720                        PackageSetting updatedChildPkg = mSettings.getDisabledSystemPkgLPr(
7721                                childPackageName);
7722                        if (updatedChildPkg != null) {
7723                            updatedChildPkg.pkg = pkg;
7724                            updatedChildPkg.versionCode = pkg.mVersionCode;
7725                        }
7726                    }
7727
7728                    throw new PackageManagerException(Log.WARN, "Package " + ps.name + " at "
7729                            + scanFile + " ignored: updated version " + ps.versionCode
7730                            + " better than this " + pkg.mVersionCode);
7731                } else {
7732                    // The current app on the system partition is better than
7733                    // what we have updated to on the data partition; switch
7734                    // back to the system partition version.
7735                    // At this point, its safely assumed that package installation for
7736                    // apps in system partition will go through. If not there won't be a working
7737                    // version of the app
7738                    // writer
7739                    synchronized (mPackages) {
7740                        // Just remove the loaded entries from package lists.
7741                        mPackages.remove(ps.name);
7742                    }
7743
7744                    logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile
7745                            + " reverting from " + ps.codePathString
7746                            + ": new version " + pkg.mVersionCode
7747                            + " better than installed " + ps.versionCode);
7748
7749                    InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
7750                            ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
7751                    synchronized (mInstallLock) {
7752                        args.cleanUpResourcesLI();
7753                    }
7754                    synchronized (mPackages) {
7755                        mSettings.enableSystemPackageLPw(ps.name);
7756                    }
7757                    updatedPkgBetter = true;
7758                }
7759            }
7760        }
7761
7762        if (updatedPkg != null) {
7763            // An updated system app will not have the PARSE_IS_SYSTEM flag set
7764            // initially
7765            policyFlags |= PackageParser.PARSE_IS_SYSTEM;
7766
7767            // An updated privileged app will not have the PARSE_IS_PRIVILEGED
7768            // flag set initially
7769            if ((updatedPkg.pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0) {
7770                policyFlags |= PackageParser.PARSE_IS_PRIVILEGED;
7771            }
7772        }
7773
7774        // Verify certificates against what was last scanned
7775        collectCertificatesLI(ps, pkg, scanFile, policyFlags);
7776
7777        /*
7778         * A new system app appeared, but we already had a non-system one of the
7779         * same name installed earlier.
7780         */
7781        boolean shouldHideSystemApp = false;
7782        if (updatedPkg == null && ps != null
7783                && (policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0 && !isSystemApp(ps)) {
7784            /*
7785             * Check to make sure the signatures match first. If they don't,
7786             * wipe the installed application and its data.
7787             */
7788            if (compareSignatures(ps.signatures.mSignatures, pkg.mSignatures)
7789                    != PackageManager.SIGNATURE_MATCH) {
7790                logCriticalInfo(Log.WARN, "Package " + ps.name + " appeared on system, but"
7791                        + " signatures don't match existing userdata copy; removing");
7792                try (PackageFreezer freezer = freezePackage(pkg.packageName,
7793                        "scanPackageInternalLI")) {
7794                    deletePackageLIF(pkg.packageName, null, true, null, 0, null, false, null);
7795                }
7796                ps = null;
7797            } else {
7798                /*
7799                 * If the newly-added system app is an older version than the
7800                 * already installed version, hide it. It will be scanned later
7801                 * and re-added like an update.
7802                 */
7803                if (pkg.mVersionCode <= ps.versionCode) {
7804                    shouldHideSystemApp = true;
7805                    logCriticalInfo(Log.INFO, "Package " + ps.name + " appeared at " + scanFile
7806                            + " but new version " + pkg.mVersionCode + " better than installed "
7807                            + ps.versionCode + "; hiding system");
7808                } else {
7809                    /*
7810                     * The newly found system app is a newer version that the
7811                     * one previously installed. Simply remove the
7812                     * already-installed application and replace it with our own
7813                     * while keeping the application data.
7814                     */
7815                    logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile
7816                            + " reverting from " + ps.codePathString + ": new version "
7817                            + pkg.mVersionCode + " better than installed " + ps.versionCode);
7818                    InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
7819                            ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
7820                    synchronized (mInstallLock) {
7821                        args.cleanUpResourcesLI();
7822                    }
7823                }
7824            }
7825        }
7826
7827        // The apk is forward locked (not public) if its code and resources
7828        // are kept in different files. (except for app in either system or
7829        // vendor path).
7830        // TODO grab this value from PackageSettings
7831        if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
7832            if (ps != null && !ps.codePath.equals(ps.resourcePath)) {
7833                policyFlags |= PackageParser.PARSE_FORWARD_LOCK;
7834            }
7835        }
7836
7837        // TODO: extend to support forward-locked splits
7838        String resourcePath = null;
7839        String baseResourcePath = null;
7840        if ((policyFlags & PackageParser.PARSE_FORWARD_LOCK) != 0 && !updatedPkgBetter) {
7841            if (ps != null && ps.resourcePathString != null) {
7842                resourcePath = ps.resourcePathString;
7843                baseResourcePath = ps.resourcePathString;
7844            } else {
7845                // Should not happen at all. Just log an error.
7846                Slog.e(TAG, "Resource path not set for package " + pkg.packageName);
7847            }
7848        } else {
7849            resourcePath = pkg.codePath;
7850            baseResourcePath = pkg.baseCodePath;
7851        }
7852
7853        // Set application objects path explicitly.
7854        pkg.setApplicationVolumeUuid(pkg.volumeUuid);
7855        pkg.setApplicationInfoCodePath(pkg.codePath);
7856        pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
7857        pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
7858        pkg.setApplicationInfoResourcePath(resourcePath);
7859        pkg.setApplicationInfoBaseResourcePath(baseResourcePath);
7860        pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
7861
7862        // Note that we invoke the following method only if we are about to unpack an application
7863        PackageParser.Package scannedPkg = scanPackageLI(pkg, policyFlags, scanFlags
7864                | SCAN_UPDATE_SIGNATURE, currentTime, user);
7865
7866        /*
7867         * If the system app should be overridden by a previously installed
7868         * data, hide the system app now and let the /data/app scan pick it up
7869         * again.
7870         */
7871        if (shouldHideSystemApp) {
7872            synchronized (mPackages) {
7873                mSettings.disableSystemPackageLPw(pkg.packageName, true);
7874            }
7875        }
7876
7877        return scannedPkg;
7878    }
7879
7880    private void renameStaticSharedLibraryPackage(PackageParser.Package pkg) {
7881        // Derive the new package synthetic package name
7882        pkg.setPackageName(pkg.packageName + STATIC_SHARED_LIB_DELIMITER
7883                + pkg.staticSharedLibVersion);
7884    }
7885
7886    private static String fixProcessName(String defProcessName,
7887            String processName) {
7888        if (processName == null) {
7889            return defProcessName;
7890        }
7891        return processName;
7892    }
7893
7894    private void verifySignaturesLP(PackageSetting pkgSetting, PackageParser.Package pkg)
7895            throws PackageManagerException {
7896        if (pkgSetting.signatures.mSignatures != null) {
7897            // Already existing package. Make sure signatures match
7898            boolean match = compareSignatures(pkgSetting.signatures.mSignatures, pkg.mSignatures)
7899                    == PackageManager.SIGNATURE_MATCH;
7900            if (!match) {
7901                match = compareSignaturesCompat(pkgSetting.signatures, pkg)
7902                        == PackageManager.SIGNATURE_MATCH;
7903            }
7904            if (!match) {
7905                match = compareSignaturesRecover(pkgSetting.signatures, pkg)
7906                        == PackageManager.SIGNATURE_MATCH;
7907            }
7908            if (!match) {
7909                throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
7910                        + pkg.packageName + " signatures do not match the "
7911                        + "previously installed version; ignoring!");
7912            }
7913        }
7914
7915        // Check for shared user signatures
7916        if (pkgSetting.sharedUser != null && pkgSetting.sharedUser.signatures.mSignatures != null) {
7917            // Already existing package. Make sure signatures match
7918            boolean match = compareSignatures(pkgSetting.sharedUser.signatures.mSignatures,
7919                    pkg.mSignatures) == PackageManager.SIGNATURE_MATCH;
7920            if (!match) {
7921                match = compareSignaturesCompat(pkgSetting.sharedUser.signatures, pkg)
7922                        == PackageManager.SIGNATURE_MATCH;
7923            }
7924            if (!match) {
7925                match = compareSignaturesRecover(pkgSetting.sharedUser.signatures, pkg)
7926                        == PackageManager.SIGNATURE_MATCH;
7927            }
7928            if (!match) {
7929                throw new PackageManagerException(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
7930                        "Package " + pkg.packageName
7931                        + " has no signatures that match those in shared user "
7932                        + pkgSetting.sharedUser.name + "; ignoring!");
7933            }
7934        }
7935    }
7936
7937    /**
7938     * Enforces that only the system UID or root's UID can call a method exposed
7939     * via Binder.
7940     *
7941     * @param message used as message if SecurityException is thrown
7942     * @throws SecurityException if the caller is not system or root
7943     */
7944    private static final void enforceSystemOrRoot(String message) {
7945        final int uid = Binder.getCallingUid();
7946        if (uid != Process.SYSTEM_UID && uid != 0) {
7947            throw new SecurityException(message);
7948        }
7949    }
7950
7951    @Override
7952    public void performFstrimIfNeeded() {
7953        enforceSystemOrRoot("Only the system can request fstrim");
7954
7955        // Before everything else, see whether we need to fstrim.
7956        try {
7957            IStorageManager sm = PackageHelper.getStorageManager();
7958            if (sm != null) {
7959                boolean doTrim = false;
7960                final long interval = android.provider.Settings.Global.getLong(
7961                        mContext.getContentResolver(),
7962                        android.provider.Settings.Global.FSTRIM_MANDATORY_INTERVAL,
7963                        DEFAULT_MANDATORY_FSTRIM_INTERVAL);
7964                if (interval > 0) {
7965                    final long timeSinceLast = System.currentTimeMillis() - sm.lastMaintenance();
7966                    if (timeSinceLast > interval) {
7967                        doTrim = true;
7968                        Slog.w(TAG, "No disk maintenance in " + timeSinceLast
7969                                + "; running immediately");
7970                    }
7971                }
7972                if (doTrim) {
7973                    final boolean dexOptDialogShown;
7974                    synchronized (mPackages) {
7975                        dexOptDialogShown = mDexOptDialogShown;
7976                    }
7977                    if (!isFirstBoot() && dexOptDialogShown) {
7978                        try {
7979                            ActivityManager.getService().showBootMessage(
7980                                    mContext.getResources().getString(
7981                                            R.string.android_upgrading_fstrim), true);
7982                        } catch (RemoteException e) {
7983                        }
7984                    }
7985                    sm.runMaintenance();
7986                }
7987            } else {
7988                Slog.e(TAG, "storageManager service unavailable!");
7989            }
7990        } catch (RemoteException e) {
7991            // Can't happen; StorageManagerService is local
7992        }
7993    }
7994
7995    @Override
7996    public void updatePackagesIfNeeded() {
7997        enforceSystemOrRoot("Only the system can request package update");
7998
7999        // We need to re-extract after an OTA.
8000        boolean causeUpgrade = isUpgrade();
8001
8002        // First boot or factory reset.
8003        // Note: we also handle devices that are upgrading to N right now as if it is their
8004        //       first boot, as they do not have profile data.
8005        boolean causeFirstBoot = isFirstBoot() || mIsPreNUpgrade;
8006
8007        // We need to re-extract after a pruned cache, as AoT-ed files will be out of date.
8008        boolean causePrunedCache = VMRuntime.didPruneDalvikCache();
8009
8010        if (!causeUpgrade && !causeFirstBoot && !causePrunedCache) {
8011            return;
8012        }
8013
8014        List<PackageParser.Package> pkgs;
8015        synchronized (mPackages) {
8016            pkgs = PackageManagerServiceUtils.getPackagesForDexopt(mPackages.values(), this);
8017        }
8018
8019        final long startTime = System.nanoTime();
8020        final int[] stats = performDexOptUpgrade(pkgs, mIsPreNUpgrade /* showDialog */,
8021                    getCompilerFilterForReason(causeFirstBoot ? REASON_FIRST_BOOT : REASON_BOOT));
8022
8023        final int elapsedTimeSeconds =
8024                (int) TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - startTime);
8025
8026        MetricsLogger.histogram(mContext, "opt_dialog_num_dexopted", stats[0]);
8027        MetricsLogger.histogram(mContext, "opt_dialog_num_skipped", stats[1]);
8028        MetricsLogger.histogram(mContext, "opt_dialog_num_failed", stats[2]);
8029        MetricsLogger.histogram(mContext, "opt_dialog_num_total", getOptimizablePackages().size());
8030        MetricsLogger.histogram(mContext, "opt_dialog_time_s", elapsedTimeSeconds);
8031    }
8032
8033    /**
8034     * Performs dexopt on the set of packages in {@code packages} and returns an int array
8035     * containing statistics about the invocation. The array consists of three elements,
8036     * which are (in order) {@code numberOfPackagesOptimized}, {@code numberOfPackagesSkipped}
8037     * and {@code numberOfPackagesFailed}.
8038     */
8039    private int[] performDexOptUpgrade(List<PackageParser.Package> pkgs, boolean showDialog,
8040            String compilerFilter) {
8041
8042        int numberOfPackagesVisited = 0;
8043        int numberOfPackagesOptimized = 0;
8044        int numberOfPackagesSkipped = 0;
8045        int numberOfPackagesFailed = 0;
8046        final int numberOfPackagesToDexopt = pkgs.size();
8047
8048        for (PackageParser.Package pkg : pkgs) {
8049            numberOfPackagesVisited++;
8050
8051            if (!PackageDexOptimizer.canOptimizePackage(pkg)) {
8052                if (DEBUG_DEXOPT) {
8053                    Log.i(TAG, "Skipping update of of non-optimizable app " + pkg.packageName);
8054                }
8055                numberOfPackagesSkipped++;
8056                continue;
8057            }
8058
8059            if (DEBUG_DEXOPT) {
8060                Log.i(TAG, "Updating app " + numberOfPackagesVisited + " of " +
8061                        numberOfPackagesToDexopt + ": " + pkg.packageName);
8062            }
8063
8064            if (showDialog) {
8065                try {
8066                    ActivityManager.getService().showBootMessage(
8067                            mContext.getResources().getString(R.string.android_upgrading_apk,
8068                                    numberOfPackagesVisited, numberOfPackagesToDexopt), true);
8069                } catch (RemoteException e) {
8070                }
8071                synchronized (mPackages) {
8072                    mDexOptDialogShown = true;
8073                }
8074            }
8075
8076            // If the OTA updates a system app which was previously preopted to a non-preopted state
8077            // the app might end up being verified at runtime. That's because by default the apps
8078            // are verify-profile but for preopted apps there's no profile.
8079            // Do a hacky check to ensure that if we have no profiles (a reasonable indication
8080            // that before the OTA the app was preopted) the app gets compiled with a non-profile
8081            // filter (by default interpret-only).
8082            // Note that at this stage unused apps are already filtered.
8083            if (isSystemApp(pkg) &&
8084                    DexFile.isProfileGuidedCompilerFilter(compilerFilter) &&
8085                    !Environment.getReferenceProfile(pkg.packageName).exists()) {
8086                compilerFilter = getNonProfileGuidedCompilerFilter(compilerFilter);
8087            }
8088
8089            // checkProfiles is false to avoid merging profiles during boot which
8090            // might interfere with background compilation (b/28612421).
8091            // Unfortunately this will also means that "pm.dexopt.boot=speed-profile" will
8092            // behave differently than "pm.dexopt.bg-dexopt=speed-profile" but that's a
8093            // trade-off worth doing to save boot time work.
8094            int dexOptStatus = performDexOptTraced(pkg.packageName,
8095                    false /* checkProfiles */,
8096                    compilerFilter,
8097                    false /* force */);
8098            switch (dexOptStatus) {
8099                case PackageDexOptimizer.DEX_OPT_PERFORMED:
8100                    numberOfPackagesOptimized++;
8101                    break;
8102                case PackageDexOptimizer.DEX_OPT_SKIPPED:
8103                    numberOfPackagesSkipped++;
8104                    break;
8105                case PackageDexOptimizer.DEX_OPT_FAILED:
8106                    numberOfPackagesFailed++;
8107                    break;
8108                default:
8109                    Log.e(TAG, "Unexpected dexopt return code " + dexOptStatus);
8110                    break;
8111            }
8112        }
8113
8114        return new int[] { numberOfPackagesOptimized, numberOfPackagesSkipped,
8115                numberOfPackagesFailed };
8116    }
8117
8118    @Override
8119    public void notifyPackageUse(String packageName, int reason) {
8120        synchronized (mPackages) {
8121            PackageParser.Package p = mPackages.get(packageName);
8122            if (p == null) {
8123                return;
8124            }
8125            p.mLastPackageUsageTimeInMills[reason] = System.currentTimeMillis();
8126        }
8127    }
8128
8129    @Override
8130    public void notifyDexLoad(String loadingPackageName, List<String> dexPaths, String loaderIsa) {
8131        int userId = UserHandle.getCallingUserId();
8132        ApplicationInfo ai = getApplicationInfo(loadingPackageName, /*flags*/ 0, userId);
8133        if (ai == null) {
8134            Slog.w(TAG, "Loading a package that does not exist for the calling user. package="
8135                + loadingPackageName + ", user=" + userId);
8136            return;
8137        }
8138        mDexManager.notifyDexLoad(ai, dexPaths, loaderIsa, userId);
8139    }
8140
8141    // TODO: this is not used nor needed. Delete it.
8142    @Override
8143    public boolean performDexOptIfNeeded(String packageName) {
8144        int dexOptStatus = performDexOptTraced(packageName,
8145                false /* checkProfiles */, getFullCompilerFilter(), false /* force */);
8146        return dexOptStatus != PackageDexOptimizer.DEX_OPT_FAILED;
8147    }
8148
8149    @Override
8150    public boolean performDexOpt(String packageName,
8151            boolean checkProfiles, int compileReason, boolean force) {
8152        int dexOptStatus = performDexOptTraced(packageName, checkProfiles,
8153                getCompilerFilterForReason(compileReason), force);
8154        return dexOptStatus != PackageDexOptimizer.DEX_OPT_FAILED;
8155    }
8156
8157    @Override
8158    public boolean performDexOptMode(String packageName,
8159            boolean checkProfiles, String targetCompilerFilter, boolean force) {
8160        int dexOptStatus = performDexOptTraced(packageName, checkProfiles,
8161                targetCompilerFilter, force);
8162        return dexOptStatus != PackageDexOptimizer.DEX_OPT_FAILED;
8163    }
8164
8165    private int performDexOptTraced(String packageName,
8166                boolean checkProfiles, String targetCompilerFilter, boolean force) {
8167        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
8168        try {
8169            return performDexOptInternal(packageName, checkProfiles,
8170                    targetCompilerFilter, force);
8171        } finally {
8172            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8173        }
8174    }
8175
8176    // Run dexopt on a given package. Returns true if dexopt did not fail, i.e.
8177    // if the package can now be considered up to date for the given filter.
8178    private int performDexOptInternal(String packageName,
8179                boolean checkProfiles, String targetCompilerFilter, boolean force) {
8180        PackageParser.Package p;
8181        synchronized (mPackages) {
8182            p = mPackages.get(packageName);
8183            if (p == null) {
8184                // Package could not be found. Report failure.
8185                return PackageDexOptimizer.DEX_OPT_FAILED;
8186            }
8187            mPackageUsage.maybeWriteAsync(mPackages);
8188            mCompilerStats.maybeWriteAsync();
8189        }
8190        long callingId = Binder.clearCallingIdentity();
8191        try {
8192            synchronized (mInstallLock) {
8193                return performDexOptInternalWithDependenciesLI(p, checkProfiles,
8194                        targetCompilerFilter, force);
8195            }
8196        } finally {
8197            Binder.restoreCallingIdentity(callingId);
8198        }
8199    }
8200
8201    public ArraySet<String> getOptimizablePackages() {
8202        ArraySet<String> pkgs = new ArraySet<String>();
8203        synchronized (mPackages) {
8204            for (PackageParser.Package p : mPackages.values()) {
8205                if (PackageDexOptimizer.canOptimizePackage(p)) {
8206                    pkgs.add(p.packageName);
8207                }
8208            }
8209        }
8210        return pkgs;
8211    }
8212
8213    private int performDexOptInternalWithDependenciesLI(PackageParser.Package p,
8214            boolean checkProfiles, String targetCompilerFilter,
8215            boolean force) {
8216        // Select the dex optimizer based on the force parameter.
8217        // Note: The force option is rarely used (cmdline input for testing, mostly), so it's OK to
8218        //       allocate an object here.
8219        PackageDexOptimizer pdo = force
8220                ? new PackageDexOptimizer.ForcedUpdatePackageDexOptimizer(mPackageDexOptimizer)
8221                : mPackageDexOptimizer;
8222
8223        // Optimize all dependencies first. Note: we ignore the return value and march on
8224        // on errors.
8225        Collection<PackageParser.Package> deps = findSharedNonSystemLibraries(p);
8226        final String[] instructionSets = getAppDexInstructionSets(p.applicationInfo);
8227        if (!deps.isEmpty()) {
8228            for (PackageParser.Package depPackage : deps) {
8229                // TODO: Analyze and investigate if we (should) profile libraries.
8230                // Currently this will do a full compilation of the library by default.
8231                pdo.performDexOpt(depPackage, null /* sharedLibraries */, instructionSets,
8232                        false /* checkProfiles */,
8233                        getCompilerFilterForReason(REASON_NON_SYSTEM_LIBRARY),
8234                        getOrCreateCompilerPackageStats(depPackage));
8235            }
8236        }
8237        return pdo.performDexOpt(p, p.usesLibraryFiles, instructionSets, checkProfiles,
8238                targetCompilerFilter, getOrCreateCompilerPackageStats(p));
8239    }
8240
8241    // Performs dexopt on the used secondary dex files belonging to the given package.
8242    // Returns true if all dex files were process successfully (which could mean either dexopt or
8243    // skip). Returns false if any of the files caused errors.
8244    @Override
8245    public boolean performDexOptSecondary(String packageName, String compilerFilter,
8246            boolean force) {
8247        return mDexManager.dexoptSecondaryDex(packageName, compilerFilter, force);
8248    }
8249
8250    /**
8251     * Reconcile the information we have about the secondary dex files belonging to
8252     * {@code packagName} and the actual dex files. For all dex files that were
8253     * deleted, update the internal records and delete the generated oat files.
8254     */
8255    @Override
8256    public void reconcileSecondaryDexFiles(String packageName) {
8257        mDexManager.reconcileSecondaryDexFiles(packageName);
8258    }
8259
8260    // TODO(calin): this is only needed for BackgroundDexOptService. Find a cleaner way to inject
8261    // a reference there.
8262    /*package*/ DexManager getDexManager() {
8263        return mDexManager;
8264    }
8265
8266    /**
8267     * Execute the background dexopt job immediately.
8268     */
8269    @Override
8270    public boolean runBackgroundDexoptJob() {
8271        return BackgroundDexOptService.runIdleOptimizationsNow(this, mContext);
8272    }
8273
8274    List<PackageParser.Package> findSharedNonSystemLibraries(PackageParser.Package p) {
8275        if (p.usesLibraries != null || p.usesOptionalLibraries != null
8276                || p.usesStaticLibraries != null) {
8277            ArrayList<PackageParser.Package> retValue = new ArrayList<>();
8278            Set<String> collectedNames = new HashSet<>();
8279            findSharedNonSystemLibrariesRecursive(p, retValue, collectedNames);
8280
8281            retValue.remove(p);
8282
8283            return retValue;
8284        } else {
8285            return Collections.emptyList();
8286        }
8287    }
8288
8289    private void findSharedNonSystemLibrariesRecursive(PackageParser.Package p,
8290            ArrayList<PackageParser.Package> collected, Set<String> collectedNames) {
8291        if (!collectedNames.contains(p.packageName)) {
8292            collectedNames.add(p.packageName);
8293            collected.add(p);
8294
8295            if (p.usesLibraries != null) {
8296                findSharedNonSystemLibrariesRecursive(p.usesLibraries,
8297                        null, collected, collectedNames);
8298            }
8299            if (p.usesOptionalLibraries != null) {
8300                findSharedNonSystemLibrariesRecursive(p.usesOptionalLibraries,
8301                        null, collected, collectedNames);
8302            }
8303            if (p.usesStaticLibraries != null) {
8304                findSharedNonSystemLibrariesRecursive(p.usesStaticLibraries,
8305                        p.usesStaticLibrariesVersions, collected, collectedNames);
8306            }
8307        }
8308    }
8309
8310    private void findSharedNonSystemLibrariesRecursive(ArrayList<String> libs, int[] versions,
8311            ArrayList<PackageParser.Package> collected, Set<String> collectedNames) {
8312        final int libNameCount = libs.size();
8313        for (int i = 0; i < libNameCount; i++) {
8314            String libName = libs.get(i);
8315            int version = (versions != null && versions.length == libNameCount)
8316                    ? versions[i] : PackageManager.VERSION_CODE_HIGHEST;
8317            PackageParser.Package libPkg = findSharedNonSystemLibrary(libName, version);
8318            if (libPkg != null) {
8319                findSharedNonSystemLibrariesRecursive(libPkg, collected, collectedNames);
8320            }
8321        }
8322    }
8323
8324    private PackageParser.Package findSharedNonSystemLibrary(String name, int version) {
8325        synchronized (mPackages) {
8326            SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(name, version);
8327            if (libEntry != null) {
8328                return mPackages.get(libEntry.apk);
8329            }
8330            return null;
8331        }
8332    }
8333
8334    private SharedLibraryEntry getSharedLibraryEntryLPr(String name, int version) {
8335        SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(name);
8336        if (versionedLib == null) {
8337            return null;
8338        }
8339        return versionedLib.get(version);
8340    }
8341
8342    private SharedLibraryEntry getLatestSharedLibraVersionLPr(PackageParser.Package pkg) {
8343        SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(
8344                pkg.staticSharedLibName);
8345        if (versionedLib == null) {
8346            return null;
8347        }
8348        int previousLibVersion = -1;
8349        final int versionCount = versionedLib.size();
8350        for (int i = 0; i < versionCount; i++) {
8351            final int libVersion = versionedLib.keyAt(i);
8352            if (libVersion < pkg.staticSharedLibVersion) {
8353                previousLibVersion = Math.max(previousLibVersion, libVersion);
8354            }
8355        }
8356        if (previousLibVersion >= 0) {
8357            return versionedLib.get(previousLibVersion);
8358        }
8359        return null;
8360    }
8361
8362    public void shutdown() {
8363        mPackageUsage.writeNow(mPackages);
8364        mCompilerStats.writeNow();
8365    }
8366
8367    @Override
8368    public void dumpProfiles(String packageName) {
8369        PackageParser.Package pkg;
8370        synchronized (mPackages) {
8371            pkg = mPackages.get(packageName);
8372            if (pkg == null) {
8373                throw new IllegalArgumentException("Unknown package: " + packageName);
8374            }
8375        }
8376        /* Only the shell, root, or the app user should be able to dump profiles. */
8377        int callingUid = Binder.getCallingUid();
8378        if (callingUid != Process.SHELL_UID &&
8379            callingUid != Process.ROOT_UID &&
8380            callingUid != pkg.applicationInfo.uid) {
8381            throw new SecurityException("dumpProfiles");
8382        }
8383
8384        synchronized (mInstallLock) {
8385            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dump profiles");
8386            final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
8387            try {
8388                List<String> allCodePaths = pkg.getAllCodePathsExcludingResourceOnly();
8389                String codePaths = TextUtils.join(";", allCodePaths);
8390                mInstaller.dumpProfiles(sharedGid, packageName, codePaths);
8391            } catch (InstallerException e) {
8392                Slog.w(TAG, "Failed to dump profiles", e);
8393            }
8394            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8395        }
8396    }
8397
8398    @Override
8399    public void forceDexOpt(String packageName) {
8400        enforceSystemOrRoot("forceDexOpt");
8401
8402        PackageParser.Package pkg;
8403        synchronized (mPackages) {
8404            pkg = mPackages.get(packageName);
8405            if (pkg == null) {
8406                throw new IllegalArgumentException("Unknown package: " + packageName);
8407            }
8408        }
8409
8410        synchronized (mInstallLock) {
8411            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
8412
8413            // Whoever is calling forceDexOpt wants a fully compiled package.
8414            // Don't use profiles since that may cause compilation to be skipped.
8415            final int res = performDexOptInternalWithDependenciesLI(pkg,
8416                    false /* checkProfiles */, getCompilerFilterForReason(REASON_FORCED_DEXOPT),
8417                    true /* force */);
8418
8419            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8420            if (res != PackageDexOptimizer.DEX_OPT_PERFORMED) {
8421                throw new IllegalStateException("Failed to dexopt: " + res);
8422            }
8423        }
8424    }
8425
8426    private boolean verifyPackageUpdateLPr(PackageSetting oldPkg, PackageParser.Package newPkg) {
8427        if ((oldPkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8428            Slog.w(TAG, "Unable to update from " + oldPkg.name
8429                    + " to " + newPkg.packageName
8430                    + ": old package not in system partition");
8431            return false;
8432        } else if (mPackages.get(oldPkg.name) != null) {
8433            Slog.w(TAG, "Unable to update from " + oldPkg.name
8434                    + " to " + newPkg.packageName
8435                    + ": old package still exists");
8436            return false;
8437        }
8438        return true;
8439    }
8440
8441    void removeCodePathLI(File codePath) {
8442        if (codePath.isDirectory()) {
8443            try {
8444                mInstaller.rmPackageDir(codePath.getAbsolutePath());
8445            } catch (InstallerException e) {
8446                Slog.w(TAG, "Failed to remove code path", e);
8447            }
8448        } else {
8449            codePath.delete();
8450        }
8451    }
8452
8453    private int[] resolveUserIds(int userId) {
8454        return (userId == UserHandle.USER_ALL) ? sUserManager.getUserIds() : new int[] { userId };
8455    }
8456
8457    private void clearAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
8458        if (pkg == null) {
8459            Slog.wtf(TAG, "Package was null!", new Throwable());
8460            return;
8461        }
8462        clearAppDataLeafLIF(pkg, userId, flags);
8463        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
8464        for (int i = 0; i < childCount; i++) {
8465            clearAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
8466        }
8467    }
8468
8469    private void clearAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
8470        final PackageSetting ps;
8471        synchronized (mPackages) {
8472            ps = mSettings.mPackages.get(pkg.packageName);
8473        }
8474        for (int realUserId : resolveUserIds(userId)) {
8475            final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0;
8476            try {
8477                mInstaller.clearAppData(pkg.volumeUuid, pkg.packageName, realUserId, flags,
8478                        ceDataInode);
8479            } catch (InstallerException e) {
8480                Slog.w(TAG, String.valueOf(e));
8481            }
8482        }
8483    }
8484
8485    private void destroyAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
8486        if (pkg == null) {
8487            Slog.wtf(TAG, "Package was null!", new Throwable());
8488            return;
8489        }
8490        destroyAppDataLeafLIF(pkg, userId, flags);
8491        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
8492        for (int i = 0; i < childCount; i++) {
8493            destroyAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
8494        }
8495    }
8496
8497    private void destroyAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
8498        final PackageSetting ps;
8499        synchronized (mPackages) {
8500            ps = mSettings.mPackages.get(pkg.packageName);
8501        }
8502        for (int realUserId : resolveUserIds(userId)) {
8503            final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0;
8504            try {
8505                mInstaller.destroyAppData(pkg.volumeUuid, pkg.packageName, realUserId, flags,
8506                        ceDataInode);
8507            } catch (InstallerException e) {
8508                Slog.w(TAG, String.valueOf(e));
8509            }
8510        }
8511    }
8512
8513    private void destroyAppProfilesLIF(PackageParser.Package pkg, int userId) {
8514        if (pkg == null) {
8515            Slog.wtf(TAG, "Package was null!", new Throwable());
8516            return;
8517        }
8518        destroyAppProfilesLeafLIF(pkg);
8519        destroyAppReferenceProfileLeafLIF(pkg, userId, true /* removeBaseMarker */);
8520        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
8521        for (int i = 0; i < childCount; i++) {
8522            destroyAppProfilesLeafLIF(pkg.childPackages.get(i));
8523            destroyAppReferenceProfileLeafLIF(pkg.childPackages.get(i), userId,
8524                    true /* removeBaseMarker */);
8525        }
8526    }
8527
8528    private void destroyAppReferenceProfileLeafLIF(PackageParser.Package pkg, int userId,
8529            boolean removeBaseMarker) {
8530        if (pkg.isForwardLocked()) {
8531            return;
8532        }
8533
8534        for (String path : pkg.getAllCodePathsExcludingResourceOnly()) {
8535            try {
8536                path = PackageManagerServiceUtils.realpath(new File(path));
8537            } catch (IOException e) {
8538                // TODO: Should we return early here ?
8539                Slog.w(TAG, "Failed to get canonical path", e);
8540                continue;
8541            }
8542
8543            final String useMarker = path.replace('/', '@');
8544            for (int realUserId : resolveUserIds(userId)) {
8545                File profileDir = Environment.getDataProfilesDeForeignDexDirectory(realUserId);
8546                if (removeBaseMarker) {
8547                    File foreignUseMark = new File(profileDir, useMarker);
8548                    if (foreignUseMark.exists()) {
8549                        if (!foreignUseMark.delete()) {
8550                            Slog.w(TAG, "Unable to delete foreign user mark for package: "
8551                                    + pkg.packageName);
8552                        }
8553                    }
8554                }
8555
8556                File[] markers = profileDir.listFiles();
8557                if (markers != null) {
8558                    final String searchString = "@" + pkg.packageName + "@";
8559                    // We also delete all markers that contain the package name we're
8560                    // uninstalling. These are associated with secondary dex-files belonging
8561                    // to the package. Reconstructing the path of these dex files is messy
8562                    // in general.
8563                    for (File marker : markers) {
8564                        if (marker.getName().indexOf(searchString) > 0) {
8565                            if (!marker.delete()) {
8566                                Slog.w(TAG, "Unable to delete foreign user mark for package: "
8567                                    + pkg.packageName);
8568                            }
8569                        }
8570                    }
8571                }
8572            }
8573        }
8574    }
8575
8576    private void destroyAppProfilesLeafLIF(PackageParser.Package pkg) {
8577        try {
8578            mInstaller.destroyAppProfiles(pkg.packageName);
8579        } catch (InstallerException e) {
8580            Slog.w(TAG, String.valueOf(e));
8581        }
8582    }
8583
8584    private void clearAppProfilesLIF(PackageParser.Package pkg, int userId) {
8585        if (pkg == null) {
8586            Slog.wtf(TAG, "Package was null!", new Throwable());
8587            return;
8588        }
8589        clearAppProfilesLeafLIF(pkg);
8590        // We don't remove the base foreign use marker when clearing profiles because
8591        // we will rename it when the app is updated. Unlike the actual profile contents,
8592        // the foreign use marker is good across installs.
8593        destroyAppReferenceProfileLeafLIF(pkg, userId, false /* removeBaseMarker */);
8594        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
8595        for (int i = 0; i < childCount; i++) {
8596            clearAppProfilesLeafLIF(pkg.childPackages.get(i));
8597        }
8598    }
8599
8600    private void clearAppProfilesLeafLIF(PackageParser.Package pkg) {
8601        try {
8602            mInstaller.clearAppProfiles(pkg.packageName);
8603        } catch (InstallerException e) {
8604            Slog.w(TAG, String.valueOf(e));
8605        }
8606    }
8607
8608    private void setInstallAndUpdateTime(PackageParser.Package pkg, long firstInstallTime,
8609            long lastUpdateTime) {
8610        // Set parent install/update time
8611        PackageSetting ps = (PackageSetting) pkg.mExtras;
8612        if (ps != null) {
8613            ps.firstInstallTime = firstInstallTime;
8614            ps.lastUpdateTime = lastUpdateTime;
8615        }
8616        // Set children install/update time
8617        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
8618        for (int i = 0; i < childCount; i++) {
8619            PackageParser.Package childPkg = pkg.childPackages.get(i);
8620            ps = (PackageSetting) childPkg.mExtras;
8621            if (ps != null) {
8622                ps.firstInstallTime = firstInstallTime;
8623                ps.lastUpdateTime = lastUpdateTime;
8624            }
8625        }
8626    }
8627
8628    private void addSharedLibraryLPr(ArraySet<String> usesLibraryFiles, SharedLibraryEntry file,
8629            PackageParser.Package changingLib) {
8630        if (file.path != null) {
8631            usesLibraryFiles.add(file.path);
8632            return;
8633        }
8634        PackageParser.Package p = mPackages.get(file.apk);
8635        if (changingLib != null && changingLib.packageName.equals(file.apk)) {
8636            // If we are doing this while in the middle of updating a library apk,
8637            // then we need to make sure to use that new apk for determining the
8638            // dependencies here.  (We haven't yet finished committing the new apk
8639            // to the package manager state.)
8640            if (p == null || p.packageName.equals(changingLib.packageName)) {
8641                p = changingLib;
8642            }
8643        }
8644        if (p != null) {
8645            usesLibraryFiles.addAll(p.getAllCodePaths());
8646        }
8647    }
8648
8649    private void updateSharedLibrariesLPr(PackageParser.Package pkg,
8650            PackageParser.Package changingLib) throws PackageManagerException {
8651        if (pkg == null) {
8652            return;
8653        }
8654        ArraySet<String> usesLibraryFiles = null;
8655        if (pkg.usesLibraries != null) {
8656            usesLibraryFiles = addSharedLibrariesLPw(pkg.usesLibraries,
8657                    null, null, pkg.packageName, changingLib, true, null);
8658        }
8659        if (pkg.usesStaticLibraries != null) {
8660            usesLibraryFiles = addSharedLibrariesLPw(pkg.usesStaticLibraries,
8661                    pkg.usesStaticLibrariesVersions, pkg.usesStaticLibrariesCertDigests,
8662                    pkg.packageName, changingLib, true, usesLibraryFiles);
8663        }
8664        if (pkg.usesOptionalLibraries != null) {
8665            usesLibraryFiles = addSharedLibrariesLPw(pkg.usesOptionalLibraries,
8666                    null, null, pkg.packageName, changingLib, false, usesLibraryFiles);
8667        }
8668        if (!ArrayUtils.isEmpty(usesLibraryFiles)) {
8669            pkg.usesLibraryFiles = usesLibraryFiles.toArray(new String[usesLibraryFiles.size()]);
8670        } else {
8671            pkg.usesLibraryFiles = null;
8672        }
8673    }
8674
8675    private ArraySet<String> addSharedLibrariesLPw(@NonNull List<String> requestedLibraries,
8676            @Nullable int[] requiredVersions, @Nullable String[] requiredCertDigests,
8677            @NonNull String packageName, @Nullable PackageParser.Package changingLib,
8678            boolean required, @Nullable ArraySet<String> outUsedLibraries)
8679            throws PackageManagerException {
8680        final int libCount = requestedLibraries.size();
8681        for (int i = 0; i < libCount; i++) {
8682            final String libName = requestedLibraries.get(i);
8683            final int libVersion = requiredVersions != null ? requiredVersions[i]
8684                    : SharedLibraryInfo.VERSION_UNDEFINED;
8685            final SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(libName, libVersion);
8686            if (libEntry == null) {
8687                if (required) {
8688                    throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
8689                            "Package " + packageName + " requires unavailable shared library "
8690                                    + libName + "; failing!");
8691                } else {
8692                    Slog.w(TAG, "Package " + packageName
8693                            + " desires unavailable shared library "
8694                            + libName + "; ignoring!");
8695                }
8696            } else {
8697                if (requiredVersions != null && requiredCertDigests != null) {
8698                    if (libEntry.info.getVersion() != requiredVersions[i]) {
8699                        throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
8700                            "Package " + packageName + " requires unavailable static shared"
8701                                    + " library " + libName + " version "
8702                                    + libEntry.info.getVersion() + "; failing!");
8703                    }
8704
8705                    PackageParser.Package libPkg = mPackages.get(libEntry.apk);
8706                    if (libPkg == null) {
8707                        throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
8708                                "Package " + packageName + " requires unavailable static shared"
8709                                        + " library; failing!");
8710                    }
8711
8712                    String expectedCertDigest = requiredCertDigests[i];
8713                    String libCertDigest = PackageUtils.computeCertSha256Digest(
8714                                libPkg.mSignatures[0]);
8715                    if (!libCertDigest.equalsIgnoreCase(expectedCertDigest)) {
8716                        throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
8717                                "Package " + packageName + " requires differently signed" +
8718                                        " static shared library; failing!");
8719                    }
8720                }
8721
8722                if (outUsedLibraries == null) {
8723                    outUsedLibraries = new ArraySet<>();
8724                }
8725                addSharedLibraryLPr(outUsedLibraries, libEntry, changingLib);
8726            }
8727        }
8728        return outUsedLibraries;
8729    }
8730
8731    private static boolean hasString(List<String> list, List<String> which) {
8732        if (list == null) {
8733            return false;
8734        }
8735        for (int i=list.size()-1; i>=0; i--) {
8736            for (int j=which.size()-1; j>=0; j--) {
8737                if (which.get(j).equals(list.get(i))) {
8738                    return true;
8739                }
8740            }
8741        }
8742        return false;
8743    }
8744
8745    private ArrayList<PackageParser.Package> updateAllSharedLibrariesLPw(
8746            PackageParser.Package changingPkg) {
8747        ArrayList<PackageParser.Package> res = null;
8748        for (PackageParser.Package pkg : mPackages.values()) {
8749            if (changingPkg != null
8750                    && !hasString(pkg.usesLibraries, changingPkg.libraryNames)
8751                    && !hasString(pkg.usesOptionalLibraries, changingPkg.libraryNames)
8752                    && !ArrayUtils.contains(pkg.usesStaticLibraries,
8753                            changingPkg.staticSharedLibName)) {
8754                return null;
8755            }
8756            if (res == null) {
8757                res = new ArrayList<>();
8758            }
8759            res.add(pkg);
8760            try {
8761                updateSharedLibrariesLPr(pkg, changingPkg);
8762            } catch (PackageManagerException e) {
8763                // If a system app update or an app and a required lib missing we
8764                // delete the package and for updated system apps keep the data as
8765                // it is better for the user to reinstall than to be in an limbo
8766                // state. Also libs disappearing under an app should never happen
8767                // - just in case.
8768                if (!pkg.isSystemApp() || pkg.isUpdatedSystemApp()) {
8769                    final int flags = pkg.isUpdatedSystemApp()
8770                            ? PackageManager.DELETE_KEEP_DATA : 0;
8771                    deletePackageLIF(pkg.packageName, null, true, sUserManager.getUserIds(),
8772                            flags , null, true, null);
8773                }
8774                Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
8775            }
8776        }
8777        return res;
8778    }
8779
8780    /**
8781     * Derive the value of the {@code cpuAbiOverride} based on the provided
8782     * value and an optional stored value from the package settings.
8783     */
8784    private static String deriveAbiOverride(String abiOverride, PackageSetting settings) {
8785        String cpuAbiOverride = null;
8786
8787        if (NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(abiOverride)) {
8788            cpuAbiOverride = null;
8789        } else if (abiOverride != null) {
8790            cpuAbiOverride = abiOverride;
8791        } else if (settings != null) {
8792            cpuAbiOverride = settings.cpuAbiOverrideString;
8793        }
8794
8795        return cpuAbiOverride;
8796    }
8797
8798    private PackageParser.Package scanPackageTracedLI(PackageParser.Package pkg,
8799            final int policyFlags, int scanFlags, long currentTime, UserHandle user)
8800                    throws PackageManagerException {
8801        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage");
8802        // If the package has children and this is the first dive in the function
8803        // we recursively scan the package with the SCAN_CHECK_ONLY flag set to see
8804        // whether all packages (parent and children) would be successfully scanned
8805        // before the actual scan since scanning mutates internal state and we want
8806        // to atomically install the package and its children.
8807        if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
8808            if (pkg.childPackages != null && pkg.childPackages.size() > 0) {
8809                scanFlags |= SCAN_CHECK_ONLY;
8810            }
8811        } else {
8812            scanFlags &= ~SCAN_CHECK_ONLY;
8813        }
8814
8815        final PackageParser.Package scannedPkg;
8816        try {
8817            // Scan the parent
8818            scannedPkg = scanPackageLI(pkg, policyFlags, scanFlags, currentTime, user);
8819            // Scan the children
8820            final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
8821            for (int i = 0; i < childCount; i++) {
8822                PackageParser.Package childPkg = pkg.childPackages.get(i);
8823                scanPackageLI(childPkg, policyFlags,
8824                        scanFlags, currentTime, user);
8825            }
8826        } finally {
8827            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8828        }
8829
8830        if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
8831            return scanPackageTracedLI(pkg, policyFlags, scanFlags, currentTime, user);
8832        }
8833
8834        return scannedPkg;
8835    }
8836
8837    private PackageParser.Package scanPackageLI(PackageParser.Package pkg, final int policyFlags,
8838            int scanFlags, long currentTime, UserHandle user) throws PackageManagerException {
8839        boolean success = false;
8840        try {
8841            final PackageParser.Package res = scanPackageDirtyLI(pkg, policyFlags, scanFlags,
8842                    currentTime, user);
8843            success = true;
8844            return res;
8845        } finally {
8846            if (!success && (scanFlags & SCAN_DELETE_DATA_ON_FAILURES) != 0) {
8847                // DELETE_DATA_ON_FAILURES is only used by frozen paths
8848                destroyAppDataLIF(pkg, UserHandle.USER_ALL,
8849                        StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
8850                destroyAppProfilesLIF(pkg, UserHandle.USER_ALL);
8851            }
8852        }
8853    }
8854
8855    /**
8856     * Returns {@code true} if the given file contains code. Otherwise {@code false}.
8857     */
8858    private static boolean apkHasCode(String fileName) {
8859        StrictJarFile jarFile = null;
8860        try {
8861            jarFile = new StrictJarFile(fileName,
8862                    false /*verify*/, false /*signatureSchemeRollbackProtectionsEnforced*/);
8863            return jarFile.findEntry("classes.dex") != null;
8864        } catch (IOException ignore) {
8865        } finally {
8866            try {
8867                if (jarFile != null) {
8868                    jarFile.close();
8869                }
8870            } catch (IOException ignore) {}
8871        }
8872        return false;
8873    }
8874
8875    /**
8876     * Enforces code policy for the package. This ensures that if an APK has
8877     * declared hasCode="true" in its manifest that the APK actually contains
8878     * code.
8879     *
8880     * @throws PackageManagerException If bytecode could not be found when it should exist
8881     */
8882    private static void assertCodePolicy(PackageParser.Package pkg)
8883            throws PackageManagerException {
8884        final boolean shouldHaveCode =
8885                (pkg.applicationInfo.flags & ApplicationInfo.FLAG_HAS_CODE) != 0;
8886        if (shouldHaveCode && !apkHasCode(pkg.baseCodePath)) {
8887            throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
8888                    "Package " + pkg.baseCodePath + " code is missing");
8889        }
8890
8891        if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) {
8892            for (int i = 0; i < pkg.splitCodePaths.length; i++) {
8893                final boolean splitShouldHaveCode =
8894                        (pkg.splitFlags[i] & ApplicationInfo.FLAG_HAS_CODE) != 0;
8895                if (splitShouldHaveCode && !apkHasCode(pkg.splitCodePaths[i])) {
8896                    throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
8897                            "Package " + pkg.splitCodePaths[i] + " code is missing");
8898                }
8899            }
8900        }
8901    }
8902
8903    private PackageParser.Package scanPackageDirtyLI(PackageParser.Package pkg,
8904            final int policyFlags, final int scanFlags, long currentTime, UserHandle user)
8905                    throws PackageManagerException {
8906        if (DEBUG_PACKAGE_SCANNING) {
8907            if ((policyFlags & PackageParser.PARSE_CHATTY) != 0)
8908                Log.d(TAG, "Scanning package " + pkg.packageName);
8909        }
8910
8911        applyPolicy(pkg, policyFlags);
8912
8913        assertPackageIsValid(pkg, policyFlags, scanFlags);
8914
8915        // Initialize package source and resource directories
8916        final File scanFile = new File(pkg.codePath);
8917        final File destCodeFile = new File(pkg.applicationInfo.getCodePath());
8918        final File destResourceFile = new File(pkg.applicationInfo.getResourcePath());
8919
8920        SharedUserSetting suid = null;
8921        PackageSetting pkgSetting = null;
8922
8923        // Getting the package setting may have a side-effect, so if we
8924        // are only checking if scan would succeed, stash a copy of the
8925        // old setting to restore at the end.
8926        PackageSetting nonMutatedPs = null;
8927
8928        // We keep references to the derived CPU Abis from settings in oder to reuse
8929        // them in the case where we're not upgrading or booting for the first time.
8930        String primaryCpuAbiFromSettings = null;
8931        String secondaryCpuAbiFromSettings = null;
8932
8933        // writer
8934        synchronized (mPackages) {
8935            if (pkg.mSharedUserId != null) {
8936                // SIDE EFFECTS; may potentially allocate a new shared user
8937                suid = mSettings.getSharedUserLPw(
8938                        pkg.mSharedUserId, 0 /*pkgFlags*/, 0 /*pkgPrivateFlags*/, true /*create*/);
8939                if (DEBUG_PACKAGE_SCANNING) {
8940                    if ((policyFlags & PackageParser.PARSE_CHATTY) != 0)
8941                        Log.d(TAG, "Shared UserID " + pkg.mSharedUserId + " (uid=" + suid.userId
8942                                + "): packages=" + suid.packages);
8943                }
8944            }
8945
8946            // Check if we are renaming from an original package name.
8947            PackageSetting origPackage = null;
8948            String realName = null;
8949            if (pkg.mOriginalPackages != null) {
8950                // This package may need to be renamed to a previously
8951                // installed name.  Let's check on that...
8952                final String renamed = mSettings.getRenamedPackageLPr(pkg.mRealPackage);
8953                if (pkg.mOriginalPackages.contains(renamed)) {
8954                    // This package had originally been installed as the
8955                    // original name, and we have already taken care of
8956                    // transitioning to the new one.  Just update the new
8957                    // one to continue using the old name.
8958                    realName = pkg.mRealPackage;
8959                    if (!pkg.packageName.equals(renamed)) {
8960                        // Callers into this function may have already taken
8961                        // care of renaming the package; only do it here if
8962                        // it is not already done.
8963                        pkg.setPackageName(renamed);
8964                    }
8965                } else {
8966                    for (int i=pkg.mOriginalPackages.size()-1; i>=0; i--) {
8967                        if ((origPackage = mSettings.getPackageLPr(
8968                                pkg.mOriginalPackages.get(i))) != null) {
8969                            // We do have the package already installed under its
8970                            // original name...  should we use it?
8971                            if (!verifyPackageUpdateLPr(origPackage, pkg)) {
8972                                // New package is not compatible with original.
8973                                origPackage = null;
8974                                continue;
8975                            } else if (origPackage.sharedUser != null) {
8976                                // Make sure uid is compatible between packages.
8977                                if (!origPackage.sharedUser.name.equals(pkg.mSharedUserId)) {
8978                                    Slog.w(TAG, "Unable to migrate data from " + origPackage.name
8979                                            + " to " + pkg.packageName + ": old uid "
8980                                            + origPackage.sharedUser.name
8981                                            + " differs from " + pkg.mSharedUserId);
8982                                    origPackage = null;
8983                                    continue;
8984                                }
8985                                // TODO: Add case when shared user id is added [b/28144775]
8986                            } else {
8987                                if (DEBUG_UPGRADE) Log.v(TAG, "Renaming new package "
8988                                        + pkg.packageName + " to old name " + origPackage.name);
8989                            }
8990                            break;
8991                        }
8992                    }
8993                }
8994            }
8995
8996            if (mTransferedPackages.contains(pkg.packageName)) {
8997                Slog.w(TAG, "Package " + pkg.packageName
8998                        + " was transferred to another, but its .apk remains");
8999            }
9000
9001            // See comments in nonMutatedPs declaration
9002            if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
9003                PackageSetting foundPs = mSettings.getPackageLPr(pkg.packageName);
9004                if (foundPs != null) {
9005                    nonMutatedPs = new PackageSetting(foundPs);
9006                }
9007            }
9008
9009            if ((scanFlags & SCAN_FIRST_BOOT_OR_UPGRADE) == 0) {
9010                PackageSetting foundPs = mSettings.getPackageLPr(pkg.packageName);
9011                if (foundPs != null) {
9012                    primaryCpuAbiFromSettings = foundPs.primaryCpuAbiString;
9013                    secondaryCpuAbiFromSettings = foundPs.secondaryCpuAbiString;
9014                }
9015            }
9016
9017            pkgSetting = mSettings.getPackageLPr(pkg.packageName);
9018            if (pkgSetting != null && pkgSetting.sharedUser != suid) {
9019                PackageManagerService.reportSettingsProblem(Log.WARN,
9020                        "Package " + pkg.packageName + " shared user changed from "
9021                                + (pkgSetting.sharedUser != null
9022                                        ? pkgSetting.sharedUser.name : "<nothing>")
9023                                + " to "
9024                                + (suid != null ? suid.name : "<nothing>")
9025                                + "; replacing with new");
9026                pkgSetting = null;
9027            }
9028            final PackageSetting oldPkgSetting =
9029                    pkgSetting == null ? null : new PackageSetting(pkgSetting);
9030            final PackageSetting disabledPkgSetting =
9031                    mSettings.getDisabledSystemPkgLPr(pkg.packageName);
9032
9033            String[] usesStaticLibraries = null;
9034            if (pkg.usesStaticLibraries != null) {
9035                usesStaticLibraries = new String[pkg.usesStaticLibraries.size()];
9036                pkg.usesStaticLibraries.toArray(usesStaticLibraries);
9037            }
9038
9039            if (pkgSetting == null) {
9040                final String parentPackageName = (pkg.parentPackage != null)
9041                        ? pkg.parentPackage.packageName : null;
9042
9043                // REMOVE SharedUserSetting from method; update in a separate call
9044                pkgSetting = Settings.createNewSetting(pkg.packageName, origPackage,
9045                        disabledPkgSetting, realName, suid, destCodeFile, destResourceFile,
9046                        pkg.applicationInfo.nativeLibraryRootDir, pkg.applicationInfo.primaryCpuAbi,
9047                        pkg.applicationInfo.secondaryCpuAbi, pkg.mVersionCode,
9048                        pkg.applicationInfo.flags, pkg.applicationInfo.privateFlags, user,
9049                        true /*allowInstall*/, parentPackageName, pkg.getChildPackageNames(),
9050                        UserManagerService.getInstance(), usesStaticLibraries,
9051                        pkg.usesStaticLibrariesVersions);
9052                // SIDE EFFECTS; updates system state; move elsewhere
9053                if (origPackage != null) {
9054                    mSettings.addRenamedPackageLPw(pkg.packageName, origPackage.name);
9055                }
9056                mSettings.addUserToSettingLPw(pkgSetting);
9057            } else {
9058                // REMOVE SharedUserSetting from method; update in a separate call.
9059                //
9060                // TODO(narayan): This update is bogus. nativeLibraryDir & primaryCpuAbi,
9061                // secondaryCpuAbi are not known at this point so we always update them
9062                // to null here, only to reset them at a later point.
9063                Settings.updatePackageSetting(pkgSetting, disabledPkgSetting, suid, destCodeFile,
9064                        pkg.applicationInfo.nativeLibraryDir, pkg.applicationInfo.primaryCpuAbi,
9065                        pkg.applicationInfo.secondaryCpuAbi, pkg.applicationInfo.flags,
9066                        pkg.applicationInfo.privateFlags, pkg.getChildPackageNames(),
9067                        UserManagerService.getInstance(), usesStaticLibraries,
9068                        pkg.usesStaticLibrariesVersions);
9069            }
9070            // SIDE EFFECTS; persists system state to files on disk; move elsewhere
9071            mSettings.writeUserRestrictionsLPw(pkgSetting, oldPkgSetting);
9072
9073            // SIDE EFFECTS; modifies system state; move elsewhere
9074            if (pkgSetting.origPackage != null) {
9075                // If we are first transitioning from an original package,
9076                // fix up the new package's name now.  We need to do this after
9077                // looking up the package under its new name, so getPackageLP
9078                // can take care of fiddling things correctly.
9079                pkg.setPackageName(origPackage.name);
9080
9081                // File a report about this.
9082                String msg = "New package " + pkgSetting.realName
9083                        + " renamed to replace old package " + pkgSetting.name;
9084                reportSettingsProblem(Log.WARN, msg);
9085
9086                // Make a note of it.
9087                if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
9088                    mTransferedPackages.add(origPackage.name);
9089                }
9090
9091                // No longer need to retain this.
9092                pkgSetting.origPackage = null;
9093            }
9094
9095            // SIDE EFFECTS; modifies system state; move elsewhere
9096            if ((scanFlags & SCAN_CHECK_ONLY) == 0 && realName != null) {
9097                // Make a note of it.
9098                mTransferedPackages.add(pkg.packageName);
9099            }
9100
9101            if (mSettings.isDisabledSystemPackageLPr(pkg.packageName)) {
9102                pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
9103            }
9104
9105            if ((scanFlags & SCAN_BOOTING) == 0
9106                    && (policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
9107                // Check all shared libraries and map to their actual file path.
9108                // We only do this here for apps not on a system dir, because those
9109                // are the only ones that can fail an install due to this.  We
9110                // will take care of the system apps by updating all of their
9111                // library paths after the scan is done. Also during the initial
9112                // scan don't update any libs as we do this wholesale after all
9113                // apps are scanned to avoid dependency based scanning.
9114                updateSharedLibrariesLPr(pkg, null);
9115            }
9116
9117            if (mFoundPolicyFile) {
9118                SELinuxMMAC.assignSeinfoValue(pkg);
9119            }
9120
9121            pkg.applicationInfo.uid = pkgSetting.appId;
9122            pkg.mExtras = pkgSetting;
9123
9124
9125            // Static shared libs have same package with different versions where
9126            // we internally use a synthetic package name to allow multiple versions
9127            // of the same package, therefore we need to compare signatures against
9128            // the package setting for the latest library version.
9129            PackageSetting signatureCheckPs = pkgSetting;
9130            if (pkg.applicationInfo.isStaticSharedLibrary()) {
9131                SharedLibraryEntry libraryEntry = getLatestSharedLibraVersionLPr(pkg);
9132                if (libraryEntry != null) {
9133                    signatureCheckPs = mSettings.getPackageLPr(libraryEntry.apk);
9134                }
9135            }
9136
9137            if (shouldCheckUpgradeKeySetLP(signatureCheckPs, scanFlags)) {
9138                if (checkUpgradeKeySetLP(signatureCheckPs, pkg)) {
9139                    // We just determined the app is signed correctly, so bring
9140                    // over the latest parsed certs.
9141                    pkgSetting.signatures.mSignatures = pkg.mSignatures;
9142                } else {
9143                    if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
9144                        throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
9145                                "Package " + pkg.packageName + " upgrade keys do not match the "
9146                                + "previously installed version");
9147                    } else {
9148                        pkgSetting.signatures.mSignatures = pkg.mSignatures;
9149                        String msg = "System package " + pkg.packageName
9150                                + " signature changed; retaining data.";
9151                        reportSettingsProblem(Log.WARN, msg);
9152                    }
9153                }
9154            } else {
9155                try {
9156                    // SIDE EFFECTS; compareSignaturesCompat() changes KeysetManagerService
9157                    verifySignaturesLP(signatureCheckPs, pkg);
9158                    // We just determined the app is signed correctly, so bring
9159                    // over the latest parsed certs.
9160                    pkgSetting.signatures.mSignatures = pkg.mSignatures;
9161                } catch (PackageManagerException e) {
9162                    if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
9163                        throw e;
9164                    }
9165                    // The signature has changed, but this package is in the system
9166                    // image...  let's recover!
9167                    pkgSetting.signatures.mSignatures = pkg.mSignatures;
9168                    // However...  if this package is part of a shared user, but it
9169                    // doesn't match the signature of the shared user, let's fail.
9170                    // What this means is that you can't change the signatures
9171                    // associated with an overall shared user, which doesn't seem all
9172                    // that unreasonable.
9173                    if (signatureCheckPs.sharedUser != null) {
9174                        if (compareSignatures(signatureCheckPs.sharedUser.signatures.mSignatures,
9175                                pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) {
9176                            throw new PackageManagerException(
9177                                    INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES,
9178                                    "Signature mismatch for shared user: "
9179                                            + pkgSetting.sharedUser);
9180                        }
9181                    }
9182                    // File a report about this.
9183                    String msg = "System package " + pkg.packageName
9184                            + " signature changed; retaining data.";
9185                    reportSettingsProblem(Log.WARN, msg);
9186                }
9187            }
9188
9189            if ((scanFlags & SCAN_CHECK_ONLY) == 0 && pkg.mAdoptPermissions != null) {
9190                // This package wants to adopt ownership of permissions from
9191                // another package.
9192                for (int i = pkg.mAdoptPermissions.size() - 1; i >= 0; i--) {
9193                    final String origName = pkg.mAdoptPermissions.get(i);
9194                    final PackageSetting orig = mSettings.getPackageLPr(origName);
9195                    if (orig != null) {
9196                        if (verifyPackageUpdateLPr(orig, pkg)) {
9197                            Slog.i(TAG, "Adopting permissions from " + origName + " to "
9198                                    + pkg.packageName);
9199                            // SIDE EFFECTS; updates permissions system state; move elsewhere
9200                            mSettings.transferPermissionsLPw(origName, pkg.packageName);
9201                        }
9202                    }
9203                }
9204            }
9205        }
9206
9207        pkg.applicationInfo.processName = fixProcessName(
9208                pkg.applicationInfo.packageName,
9209                pkg.applicationInfo.processName);
9210
9211        if (pkg != mPlatformPackage) {
9212            // Get all of our default paths setup
9213            pkg.applicationInfo.initForUser(UserHandle.USER_SYSTEM);
9214        }
9215
9216        final String cpuAbiOverride = deriveAbiOverride(pkg.cpuAbiOverride, pkgSetting);
9217
9218        if ((scanFlags & SCAN_NEW_INSTALL) == 0) {
9219            if ((scanFlags & SCAN_FIRST_BOOT_OR_UPGRADE) != 0) {
9220                Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "derivePackageAbi");
9221                derivePackageAbi(
9222                        pkg, scanFile, cpuAbiOverride, true /*extractLibs*/, mAppLib32InstallDir);
9223                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9224
9225                // Some system apps still use directory structure for native libraries
9226                // in which case we might end up not detecting abi solely based on apk
9227                // structure. Try to detect abi based on directory structure.
9228                if (isSystemApp(pkg) && !pkg.isUpdatedSystemApp() &&
9229                        pkg.applicationInfo.primaryCpuAbi == null) {
9230                    setBundledAppAbisAndRoots(pkg, pkgSetting);
9231                    setNativeLibraryPaths(pkg, mAppLib32InstallDir);
9232                }
9233            } else {
9234                // This is not a first boot or an upgrade, don't bother deriving the
9235                // ABI during the scan. Instead, trust the value that was stored in the
9236                // package setting.
9237                pkg.applicationInfo.primaryCpuAbi = primaryCpuAbiFromSettings;
9238                pkg.applicationInfo.secondaryCpuAbi = secondaryCpuAbiFromSettings;
9239
9240                setNativeLibraryPaths(pkg, mAppLib32InstallDir);
9241
9242                if (DEBUG_ABI_SELECTION) {
9243                    Slog.i(TAG, "Using ABIS and native lib paths from settings : " +
9244                        pkg.packageName + " " + pkg.applicationInfo.primaryCpuAbi + ", " +
9245                        pkg.applicationInfo.secondaryCpuAbi);
9246                }
9247            }
9248        } else {
9249            if ((scanFlags & SCAN_MOVE) != 0) {
9250                // We haven't run dex-opt for this move (since we've moved the compiled output too)
9251                // but we already have this packages package info in the PackageSetting. We just
9252                // use that and derive the native library path based on the new codepath.
9253                pkg.applicationInfo.primaryCpuAbi = pkgSetting.primaryCpuAbiString;
9254                pkg.applicationInfo.secondaryCpuAbi = pkgSetting.secondaryCpuAbiString;
9255            }
9256
9257            // Set native library paths again. For moves, the path will be updated based on the
9258            // ABIs we've determined above. For non-moves, the path will be updated based on the
9259            // ABIs we determined during compilation, but the path will depend on the final
9260            // package path (after the rename away from the stage path).
9261            setNativeLibraryPaths(pkg, mAppLib32InstallDir);
9262        }
9263
9264        // This is a special case for the "system" package, where the ABI is
9265        // dictated by the zygote configuration (and init.rc). We should keep track
9266        // of this ABI so that we can deal with "normal" applications that run under
9267        // the same UID correctly.
9268        if (mPlatformPackage == pkg) {
9269            pkg.applicationInfo.primaryCpuAbi = VMRuntime.getRuntime().is64Bit() ?
9270                    Build.SUPPORTED_64_BIT_ABIS[0] : Build.SUPPORTED_32_BIT_ABIS[0];
9271        }
9272
9273        // If there's a mismatch between the abi-override in the package setting
9274        // and the abiOverride specified for the install. Warn about this because we
9275        // would've already compiled the app without taking the package setting into
9276        // account.
9277        if ((scanFlags & SCAN_NO_DEX) == 0 && (scanFlags & SCAN_NEW_INSTALL) != 0) {
9278            if (cpuAbiOverride == null && pkgSetting.cpuAbiOverrideString != null) {
9279                Slog.w(TAG, "Ignoring persisted ABI override " + cpuAbiOverride +
9280                        " for package " + pkg.packageName);
9281            }
9282        }
9283
9284        pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
9285        pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
9286        pkgSetting.cpuAbiOverrideString = cpuAbiOverride;
9287
9288        // Copy the derived override back to the parsed package, so that we can
9289        // update the package settings accordingly.
9290        pkg.cpuAbiOverride = cpuAbiOverride;
9291
9292        if (DEBUG_ABI_SELECTION) {
9293            Slog.d(TAG, "Resolved nativeLibraryRoot for " + pkg.applicationInfo.packageName
9294                    + " to root=" + pkg.applicationInfo.nativeLibraryRootDir + ", isa="
9295                    + pkg.applicationInfo.nativeLibraryRootRequiresIsa);
9296        }
9297
9298        // Push the derived path down into PackageSettings so we know what to
9299        // clean up at uninstall time.
9300        pkgSetting.legacyNativeLibraryPathString = pkg.applicationInfo.nativeLibraryRootDir;
9301
9302        if (DEBUG_ABI_SELECTION) {
9303            Log.d(TAG, "Abis for package[" + pkg.packageName + "] are" +
9304                    " primary=" + pkg.applicationInfo.primaryCpuAbi +
9305                    " secondary=" + pkg.applicationInfo.secondaryCpuAbi);
9306        }
9307
9308        // SIDE EFFECTS; removes DEX files from disk; move elsewhere
9309        if ((scanFlags & SCAN_BOOTING) == 0 && pkgSetting.sharedUser != null) {
9310            // We don't do this here during boot because we can do it all
9311            // at once after scanning all existing packages.
9312            //
9313            // We also do this *before* we perform dexopt on this package, so that
9314            // we can avoid redundant dexopts, and also to make sure we've got the
9315            // code and package path correct.
9316            adjustCpuAbisForSharedUserLPw(pkgSetting.sharedUser.packages, pkg);
9317        }
9318
9319        if (mFactoryTest && pkg.requestedPermissions.contains(
9320                android.Manifest.permission.FACTORY_TEST)) {
9321            pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST;
9322        }
9323
9324        if (isSystemApp(pkg)) {
9325            pkgSetting.isOrphaned = true;
9326        }
9327
9328        // Take care of first install / last update times.
9329        final long scanFileTime = getLastModifiedTime(pkg, scanFile);
9330        if (currentTime != 0) {
9331            if (pkgSetting.firstInstallTime == 0) {
9332                pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = currentTime;
9333            } else if ((scanFlags & SCAN_UPDATE_TIME) != 0) {
9334                pkgSetting.lastUpdateTime = currentTime;
9335            }
9336        } else if (pkgSetting.firstInstallTime == 0) {
9337            // We need *something*.  Take time time stamp of the file.
9338            pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = scanFileTime;
9339        } else if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0) {
9340            if (scanFileTime != pkgSetting.timeStamp) {
9341                // A package on the system image has changed; consider this
9342                // to be an update.
9343                pkgSetting.lastUpdateTime = scanFileTime;
9344            }
9345        }
9346        pkgSetting.setTimeStamp(scanFileTime);
9347
9348        if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
9349            if (nonMutatedPs != null) {
9350                synchronized (mPackages) {
9351                    mSettings.mPackages.put(nonMutatedPs.name, nonMutatedPs);
9352                }
9353            }
9354        } else {
9355            // Modify state for the given package setting
9356            commitPackageSettings(pkg, pkgSetting, user, scanFlags,
9357                    (policyFlags & PackageParser.PARSE_CHATTY) != 0 /*chatty*/);
9358            if (isEphemeral(pkg)) {
9359                final int userId = user == null ? 0 : user.getIdentifier();
9360                mInstantAppRegistry.addInstantAppLPw(userId, pkgSetting.appId);
9361            }
9362        }
9363        return pkg;
9364    }
9365
9366    /**
9367     * Applies policy to the parsed package based upon the given policy flags.
9368     * Ensures the package is in a good state.
9369     * <p>
9370     * Implementation detail: This method must NOT have any side effect. It would
9371     * ideally be static, but, it requires locks to read system state.
9372     */
9373    private void applyPolicy(PackageParser.Package pkg, int policyFlags) {
9374        if ((policyFlags&PackageParser.PARSE_IS_SYSTEM) != 0) {
9375            pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
9376            if (pkg.applicationInfo.isDirectBootAware()) {
9377                // we're direct boot aware; set for all components
9378                for (PackageParser.Service s : pkg.services) {
9379                    s.info.encryptionAware = s.info.directBootAware = true;
9380                }
9381                for (PackageParser.Provider p : pkg.providers) {
9382                    p.info.encryptionAware = p.info.directBootAware = true;
9383                }
9384                for (PackageParser.Activity a : pkg.activities) {
9385                    a.info.encryptionAware = a.info.directBootAware = true;
9386                }
9387                for (PackageParser.Activity r : pkg.receivers) {
9388                    r.info.encryptionAware = r.info.directBootAware = true;
9389                }
9390            }
9391        } else {
9392            // Only allow system apps to be flagged as core apps.
9393            pkg.coreApp = false;
9394            // clear flags not applicable to regular apps
9395            pkg.applicationInfo.privateFlags &=
9396                    ~ApplicationInfo.PRIVATE_FLAG_DEFAULT_TO_DEVICE_PROTECTED_STORAGE;
9397            pkg.applicationInfo.privateFlags &=
9398                    ~ApplicationInfo.PRIVATE_FLAG_DIRECT_BOOT_AWARE;
9399        }
9400        pkg.mTrustedOverlay = (policyFlags&PackageParser.PARSE_TRUSTED_OVERLAY) != 0;
9401
9402        if ((policyFlags&PackageParser.PARSE_IS_PRIVILEGED) != 0) {
9403            pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
9404        }
9405
9406        if (!isSystemApp(pkg)) {
9407            // Only system apps can use these features.
9408            pkg.mOriginalPackages = null;
9409            pkg.mRealPackage = null;
9410            pkg.mAdoptPermissions = null;
9411        }
9412    }
9413
9414    /**
9415     * Asserts the parsed package is valid according to the given policy. If the
9416     * package is invalid, for whatever reason, throws {@link PackgeManagerException}.
9417     * <p>
9418     * Implementation detail: This method must NOT have any side effects. It would
9419     * ideally be static, but, it requires locks to read system state.
9420     *
9421     * @throws PackageManagerException If the package fails any of the validation checks
9422     */
9423    private void assertPackageIsValid(PackageParser.Package pkg, int policyFlags, int scanFlags)
9424            throws PackageManagerException {
9425        if ((policyFlags & PackageParser.PARSE_ENFORCE_CODE) != 0) {
9426            assertCodePolicy(pkg);
9427        }
9428
9429        if (pkg.applicationInfo.getCodePath() == null ||
9430                pkg.applicationInfo.getResourcePath() == null) {
9431            // Bail out. The resource and code paths haven't been set.
9432            throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
9433                    "Code and resource paths haven't been set correctly");
9434        }
9435
9436        // Make sure we're not adding any bogus keyset info
9437        KeySetManagerService ksms = mSettings.mKeySetManagerService;
9438        ksms.assertScannedPackageValid(pkg);
9439
9440        synchronized (mPackages) {
9441            // The special "android" package can only be defined once
9442            if (pkg.packageName.equals("android")) {
9443                if (mAndroidApplication != null) {
9444                    Slog.w(TAG, "*************************************************");
9445                    Slog.w(TAG, "Core android package being redefined.  Skipping.");
9446                    Slog.w(TAG, " codePath=" + pkg.codePath);
9447                    Slog.w(TAG, "*************************************************");
9448                    throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
9449                            "Core android package being redefined.  Skipping.");
9450                }
9451            }
9452
9453            // A package name must be unique; don't allow duplicates
9454            if (mPackages.containsKey(pkg.packageName)) {
9455                throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
9456                        "Application package " + pkg.packageName
9457                        + " already installed.  Skipping duplicate.");
9458            }
9459
9460            if (pkg.applicationInfo.isStaticSharedLibrary()) {
9461                // Static libs have a synthetic package name containing the version
9462                // but we still want the base name to be unique.
9463                if (mPackages.containsKey(pkg.manifestPackageName)) {
9464                    throw new PackageManagerException(
9465                            "Duplicate static shared lib provider package");
9466                }
9467
9468                // Static shared libraries should have at least O target SDK
9469                if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.O) {
9470                    throw new PackageManagerException(
9471                            "Packages declaring static-shared libs must target O SDK or higher");
9472                }
9473
9474                // Package declaring static a shared lib cannot be ephemeral
9475                if (pkg.applicationInfo.isInstantApp()) {
9476                    throw new PackageManagerException(
9477                            "Packages declaring static-shared libs cannot be ephemeral");
9478                }
9479
9480                // Package declaring static a shared lib cannot be renamed since the package
9481                // name is synthetic and apps can't code around package manager internals.
9482                if (!ArrayUtils.isEmpty(pkg.mOriginalPackages)) {
9483                    throw new PackageManagerException(
9484                            "Packages declaring static-shared libs cannot be renamed");
9485                }
9486
9487                // Package declaring static a shared lib cannot declare child packages
9488                if (!ArrayUtils.isEmpty(pkg.childPackages)) {
9489                    throw new PackageManagerException(
9490                            "Packages declaring static-shared libs cannot have child packages");
9491                }
9492
9493                // Package declaring static a shared lib cannot declare dynamic libs
9494                if (!ArrayUtils.isEmpty(pkg.libraryNames)) {
9495                    throw new PackageManagerException(
9496                            "Packages declaring static-shared libs cannot declare dynamic libs");
9497                }
9498
9499                // Package declaring static a shared lib cannot declare shared users
9500                if (pkg.mSharedUserId != null) {
9501                    throw new PackageManagerException(
9502                            "Packages declaring static-shared libs cannot declare shared users");
9503                }
9504
9505                // Static shared libs cannot declare activities
9506                if (!pkg.activities.isEmpty()) {
9507                    throw new PackageManagerException(
9508                            "Static shared libs cannot declare activities");
9509                }
9510
9511                // Static shared libs cannot declare services
9512                if (!pkg.services.isEmpty()) {
9513                    throw new PackageManagerException(
9514                            "Static shared libs cannot declare services");
9515                }
9516
9517                // Static shared libs cannot declare providers
9518                if (!pkg.providers.isEmpty()) {
9519                    throw new PackageManagerException(
9520                            "Static shared libs cannot declare content providers");
9521                }
9522
9523                // Static shared libs cannot declare receivers
9524                if (!pkg.receivers.isEmpty()) {
9525                    throw new PackageManagerException(
9526                            "Static shared libs cannot declare broadcast receivers");
9527                }
9528
9529                // Static shared libs cannot declare permission groups
9530                if (!pkg.permissionGroups.isEmpty()) {
9531                    throw new PackageManagerException(
9532                            "Static shared libs cannot declare permission groups");
9533                }
9534
9535                // Static shared libs cannot declare permissions
9536                if (!pkg.permissions.isEmpty()) {
9537                    throw new PackageManagerException(
9538                            "Static shared libs cannot declare permissions");
9539                }
9540
9541                // Static shared libs cannot declare protected broadcasts
9542                if (pkg.protectedBroadcasts != null) {
9543                    throw new PackageManagerException(
9544                            "Static shared libs cannot declare protected broadcasts");
9545                }
9546
9547                // Static shared libs cannot be overlay targets
9548                if (pkg.mOverlayTarget != null) {
9549                    throw new PackageManagerException(
9550                            "Static shared libs cannot be overlay targets");
9551                }
9552
9553                // The version codes must be ordered as lib versions
9554                int minVersionCode = Integer.MIN_VALUE;
9555                int maxVersionCode = Integer.MAX_VALUE;
9556
9557                SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(
9558                        pkg.staticSharedLibName);
9559                if (versionedLib != null) {
9560                    final int versionCount = versionedLib.size();
9561                    for (int i = 0; i < versionCount; i++) {
9562                        SharedLibraryInfo libInfo = versionedLib.valueAt(i).info;
9563                        // TODO: We will change version code to long, so in the new API it is long
9564                        final int libVersionCode = (int) libInfo.getDeclaringPackage()
9565                                .getVersionCode();
9566                        if (libInfo.getVersion() <  pkg.staticSharedLibVersion) {
9567                            minVersionCode = Math.max(minVersionCode, libVersionCode + 1);
9568                        } else if (libInfo.getVersion() >  pkg.staticSharedLibVersion) {
9569                            maxVersionCode = Math.min(maxVersionCode, libVersionCode - 1);
9570                        } else {
9571                            minVersionCode = maxVersionCode = libVersionCode;
9572                            break;
9573                        }
9574                    }
9575                }
9576                if (pkg.mVersionCode < minVersionCode || pkg.mVersionCode > maxVersionCode) {
9577                    throw new PackageManagerException("Static shared"
9578                            + " lib version codes must be ordered as lib versions");
9579                }
9580            }
9581
9582            // Only privileged apps and updated privileged apps can add child packages.
9583            if (pkg.childPackages != null && !pkg.childPackages.isEmpty()) {
9584                if ((policyFlags & PARSE_IS_PRIVILEGED) == 0) {
9585                    throw new PackageManagerException("Only privileged apps can add child "
9586                            + "packages. Ignoring package " + pkg.packageName);
9587                }
9588                final int childCount = pkg.childPackages.size();
9589                for (int i = 0; i < childCount; i++) {
9590                    PackageParser.Package childPkg = pkg.childPackages.get(i);
9591                    if (mSettings.hasOtherDisabledSystemPkgWithChildLPr(pkg.packageName,
9592                            childPkg.packageName)) {
9593                        throw new PackageManagerException("Can't override child of "
9594                                + "another disabled app. Ignoring package " + pkg.packageName);
9595                    }
9596                }
9597            }
9598
9599            // If we're only installing presumed-existing packages, require that the
9600            // scanned APK is both already known and at the path previously established
9601            // for it.  Previously unknown packages we pick up normally, but if we have an
9602            // a priori expectation about this package's install presence, enforce it.
9603            // With a singular exception for new system packages. When an OTA contains
9604            // a new system package, we allow the codepath to change from a system location
9605            // to the user-installed location. If we don't allow this change, any newer,
9606            // user-installed version of the application will be ignored.
9607            if ((scanFlags & SCAN_REQUIRE_KNOWN) != 0) {
9608                if (mExpectingBetter.containsKey(pkg.packageName)) {
9609                    logCriticalInfo(Log.WARN,
9610                            "Relax SCAN_REQUIRE_KNOWN requirement for package " + pkg.packageName);
9611                } else {
9612                    PackageSetting known = mSettings.getPackageLPr(pkg.packageName);
9613                    if (known != null) {
9614                        if (DEBUG_PACKAGE_SCANNING) {
9615                            Log.d(TAG, "Examining " + pkg.codePath
9616                                    + " and requiring known paths " + known.codePathString
9617                                    + " & " + known.resourcePathString);
9618                        }
9619                        if (!pkg.applicationInfo.getCodePath().equals(known.codePathString)
9620                                || !pkg.applicationInfo.getResourcePath().equals(
9621                                        known.resourcePathString)) {
9622                            throw new PackageManagerException(INSTALL_FAILED_PACKAGE_CHANGED,
9623                                    "Application package " + pkg.packageName
9624                                    + " found at " + pkg.applicationInfo.getCodePath()
9625                                    + " but expected at " + known.codePathString
9626                                    + "; ignoring.");
9627                        }
9628                    }
9629                }
9630            }
9631
9632            // Verify that this new package doesn't have any content providers
9633            // that conflict with existing packages.  Only do this if the
9634            // package isn't already installed, since we don't want to break
9635            // things that are installed.
9636            if ((scanFlags & SCAN_NEW_INSTALL) != 0) {
9637                final int N = pkg.providers.size();
9638                int i;
9639                for (i=0; i<N; i++) {
9640                    PackageParser.Provider p = pkg.providers.get(i);
9641                    if (p.info.authority != null) {
9642                        String names[] = p.info.authority.split(";");
9643                        for (int j = 0; j < names.length; j++) {
9644                            if (mProvidersByAuthority.containsKey(names[j])) {
9645                                PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
9646                                final String otherPackageName =
9647                                        ((other != null && other.getComponentName() != null) ?
9648                                                other.getComponentName().getPackageName() : "?");
9649                                throw new PackageManagerException(
9650                                        INSTALL_FAILED_CONFLICTING_PROVIDER,
9651                                        "Can't install because provider name " + names[j]
9652                                                + " (in package " + pkg.applicationInfo.packageName
9653                                                + ") is already used by " + otherPackageName);
9654                            }
9655                        }
9656                    }
9657                }
9658            }
9659        }
9660    }
9661
9662    private boolean addSharedLibraryLPw(String path, String apk, String name, int version,
9663            int type, String declaringPackageName, int declaringVersionCode) {
9664        SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(name);
9665        if (versionedLib == null) {
9666            versionedLib = new SparseArray<>();
9667            mSharedLibraries.put(name, versionedLib);
9668            if (type == SharedLibraryInfo.TYPE_STATIC) {
9669                mStaticLibsByDeclaringPackage.put(declaringPackageName, versionedLib);
9670            }
9671        } else if (versionedLib.indexOfKey(version) >= 0) {
9672            return false;
9673        }
9674        SharedLibraryEntry libEntry = new SharedLibraryEntry(path, apk, name,
9675                version, type, declaringPackageName, declaringVersionCode);
9676        versionedLib.put(version, libEntry);
9677        return true;
9678    }
9679
9680    private boolean removeSharedLibraryLPw(String name, int version) {
9681        SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(name);
9682        if (versionedLib == null) {
9683            return false;
9684        }
9685        final int libIdx = versionedLib.indexOfKey(version);
9686        if (libIdx < 0) {
9687            return false;
9688        }
9689        SharedLibraryEntry libEntry = versionedLib.valueAt(libIdx);
9690        versionedLib.remove(version);
9691        if (versionedLib.size() <= 0) {
9692            mSharedLibraries.remove(name);
9693            if (libEntry.info.getType() == SharedLibraryInfo.TYPE_STATIC) {
9694                mStaticLibsByDeclaringPackage.remove(libEntry.info.getDeclaringPackage()
9695                        .getPackageName());
9696            }
9697        }
9698        return true;
9699    }
9700
9701    /**
9702     * Adds a scanned package to the system. When this method is finished, the package will
9703     * be available for query, resolution, etc...
9704     */
9705    private void commitPackageSettings(PackageParser.Package pkg, PackageSetting pkgSetting,
9706            UserHandle user, int scanFlags, boolean chatty) throws PackageManagerException {
9707        final String pkgName = pkg.packageName;
9708        if (mCustomResolverComponentName != null &&
9709                mCustomResolverComponentName.getPackageName().equals(pkg.packageName)) {
9710            setUpCustomResolverActivity(pkg);
9711        }
9712
9713        if (pkg.packageName.equals("android")) {
9714            synchronized (mPackages) {
9715                if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
9716                    // Set up information for our fall-back user intent resolution activity.
9717                    mPlatformPackage = pkg;
9718                    pkg.mVersionCode = mSdkVersion;
9719                    mAndroidApplication = pkg.applicationInfo;
9720
9721                    if (!mResolverReplaced) {
9722                        mResolveActivity.applicationInfo = mAndroidApplication;
9723                        mResolveActivity.name = ResolverActivity.class.getName();
9724                        mResolveActivity.packageName = mAndroidApplication.packageName;
9725                        mResolveActivity.processName = "system:ui";
9726                        mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
9727                        mResolveActivity.documentLaunchMode = ActivityInfo.DOCUMENT_LAUNCH_NEVER;
9728                        mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS;
9729                        mResolveActivity.theme = R.style.Theme_Material_Dialog_Alert;
9730                        mResolveActivity.exported = true;
9731                        mResolveActivity.enabled = true;
9732                        mResolveActivity.resizeMode = ActivityInfo.RESIZE_MODE_RESIZEABLE;
9733                        mResolveActivity.configChanges = ActivityInfo.CONFIG_SCREEN_SIZE
9734                                | ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE
9735                                | ActivityInfo.CONFIG_SCREEN_LAYOUT
9736                                | ActivityInfo.CONFIG_ORIENTATION
9737                                | ActivityInfo.CONFIG_KEYBOARD
9738                                | ActivityInfo.CONFIG_KEYBOARD_HIDDEN;
9739                        mResolveInfo.activityInfo = mResolveActivity;
9740                        mResolveInfo.priority = 0;
9741                        mResolveInfo.preferredOrder = 0;
9742                        mResolveInfo.match = 0;
9743                        mResolveComponentName = new ComponentName(
9744                                mAndroidApplication.packageName, mResolveActivity.name);
9745                    }
9746                }
9747            }
9748        }
9749
9750        ArrayList<PackageParser.Package> clientLibPkgs = null;
9751        // writer
9752        synchronized (mPackages) {
9753            boolean hasStaticSharedLibs = false;
9754
9755            // Any app can add new static shared libraries
9756            if (pkg.staticSharedLibName != null) {
9757                // Static shared libs don't allow renaming as they have synthetic package
9758                // names to allow install of multiple versions, so use name from manifest.
9759                if (addSharedLibraryLPw(null, pkg.packageName, pkg.staticSharedLibName,
9760                        pkg.staticSharedLibVersion, SharedLibraryInfo.TYPE_STATIC,
9761                        pkg.manifestPackageName, pkg.mVersionCode)) {
9762                    hasStaticSharedLibs = true;
9763                } else {
9764                    Slog.w(TAG, "Package " + pkg.packageName + " library "
9765                                + pkg.staticSharedLibName + " already exists; skipping");
9766                }
9767                // Static shared libs cannot be updated once installed since they
9768                // use synthetic package name which includes the version code, so
9769                // not need to update other packages's shared lib dependencies.
9770            }
9771
9772            if (!hasStaticSharedLibs
9773                    && (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
9774                // Only system apps can add new dynamic shared libraries.
9775                if (pkg.libraryNames != null) {
9776                    for (int i = 0; i < pkg.libraryNames.size(); i++) {
9777                        String name = pkg.libraryNames.get(i);
9778                        boolean allowed = false;
9779                        if (pkg.isUpdatedSystemApp()) {
9780                            // New library entries can only be added through the
9781                            // system image.  This is important to get rid of a lot
9782                            // of nasty edge cases: for example if we allowed a non-
9783                            // system update of the app to add a library, then uninstalling
9784                            // the update would make the library go away, and assumptions
9785                            // we made such as through app install filtering would now
9786                            // have allowed apps on the device which aren't compatible
9787                            // with it.  Better to just have the restriction here, be
9788                            // conservative, and create many fewer cases that can negatively
9789                            // impact the user experience.
9790                            final PackageSetting sysPs = mSettings
9791                                    .getDisabledSystemPkgLPr(pkg.packageName);
9792                            if (sysPs.pkg != null && sysPs.pkg.libraryNames != null) {
9793                                for (int j = 0; j < sysPs.pkg.libraryNames.size(); j++) {
9794                                    if (name.equals(sysPs.pkg.libraryNames.get(j))) {
9795                                        allowed = true;
9796                                        break;
9797                                    }
9798                                }
9799                            }
9800                        } else {
9801                            allowed = true;
9802                        }
9803                        if (allowed) {
9804                            if (!addSharedLibraryLPw(null, pkg.packageName, name,
9805                                    SharedLibraryInfo.VERSION_UNDEFINED,
9806                                    SharedLibraryInfo.TYPE_DYNAMIC,
9807                                    pkg.packageName, pkg.mVersionCode)) {
9808                                Slog.w(TAG, "Package " + pkg.packageName + " library "
9809                                        + name + " already exists; skipping");
9810                            }
9811                        } else {
9812                            Slog.w(TAG, "Package " + pkg.packageName + " declares lib "
9813                                    + name + " that is not declared on system image; skipping");
9814                        }
9815                    }
9816
9817                    if ((scanFlags & SCAN_BOOTING) == 0) {
9818                        // If we are not booting, we need to update any applications
9819                        // that are clients of our shared library.  If we are booting,
9820                        // this will all be done once the scan is complete.
9821                        clientLibPkgs = updateAllSharedLibrariesLPw(pkg);
9822                    }
9823                }
9824            }
9825        }
9826
9827        if ((scanFlags & SCAN_BOOTING) != 0) {
9828            // No apps can run during boot scan, so they don't need to be frozen
9829        } else if ((scanFlags & SCAN_DONT_KILL_APP) != 0) {
9830            // Caller asked to not kill app, so it's probably not frozen
9831        } else if ((scanFlags & SCAN_IGNORE_FROZEN) != 0) {
9832            // Caller asked us to ignore frozen check for some reason; they
9833            // probably didn't know the package name
9834        } else {
9835            // We're doing major surgery on this package, so it better be frozen
9836            // right now to keep it from launching
9837            checkPackageFrozen(pkgName);
9838        }
9839
9840        // Also need to kill any apps that are dependent on the library.
9841        if (clientLibPkgs != null) {
9842            for (int i=0; i<clientLibPkgs.size(); i++) {
9843                PackageParser.Package clientPkg = clientLibPkgs.get(i);
9844                killApplication(clientPkg.applicationInfo.packageName,
9845                        clientPkg.applicationInfo.uid, "update lib");
9846            }
9847        }
9848
9849        // writer
9850        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");
9851
9852        boolean createIdmapFailed = false;
9853        synchronized (mPackages) {
9854            // We don't expect installation to fail beyond this point
9855
9856            if (pkgSetting.pkg != null) {
9857                // Note that |user| might be null during the initial boot scan. If a codePath
9858                // for an app has changed during a boot scan, it's due to an app update that's
9859                // part of the system partition and marker changes must be applied to all users.
9860                final int userId = ((user != null) ? user : UserHandle.ALL).getIdentifier();
9861                final int[] userIds = resolveUserIds(userId);
9862                maybeRenameForeignDexMarkers(pkgSetting.pkg, pkg, userIds);
9863            }
9864
9865            // Add the new setting to mSettings
9866            mSettings.insertPackageSettingLPw(pkgSetting, pkg);
9867            // Add the new setting to mPackages
9868            mPackages.put(pkg.applicationInfo.packageName, pkg);
9869            // Make sure we don't accidentally delete its data.
9870            final Iterator<PackageCleanItem> iter = mSettings.mPackagesToBeCleaned.iterator();
9871            while (iter.hasNext()) {
9872                PackageCleanItem item = iter.next();
9873                if (pkgName.equals(item.packageName)) {
9874                    iter.remove();
9875                }
9876            }
9877
9878            // Add the package's KeySets to the global KeySetManagerService
9879            KeySetManagerService ksms = mSettings.mKeySetManagerService;
9880            ksms.addScannedPackageLPw(pkg);
9881
9882            int N = pkg.providers.size();
9883            StringBuilder r = null;
9884            int i;
9885            for (i=0; i<N; i++) {
9886                PackageParser.Provider p = pkg.providers.get(i);
9887                p.info.processName = fixProcessName(pkg.applicationInfo.processName,
9888                        p.info.processName);
9889                mProviders.addProvider(p);
9890                p.syncable = p.info.isSyncable;
9891                if (p.info.authority != null) {
9892                    String names[] = p.info.authority.split(";");
9893                    p.info.authority = null;
9894                    for (int j = 0; j < names.length; j++) {
9895                        if (j == 1 && p.syncable) {
9896                            // We only want the first authority for a provider to possibly be
9897                            // syncable, so if we already added this provider using a different
9898                            // authority clear the syncable flag. We copy the provider before
9899                            // changing it because the mProviders object contains a reference
9900                            // to a provider that we don't want to change.
9901                            // Only do this for the second authority since the resulting provider
9902                            // object can be the same for all future authorities for this provider.
9903                            p = new PackageParser.Provider(p);
9904                            p.syncable = false;
9905                        }
9906                        if (!mProvidersByAuthority.containsKey(names[j])) {
9907                            mProvidersByAuthority.put(names[j], p);
9908                            if (p.info.authority == null) {
9909                                p.info.authority = names[j];
9910                            } else {
9911                                p.info.authority = p.info.authority + ";" + names[j];
9912                            }
9913                            if (DEBUG_PACKAGE_SCANNING) {
9914                                if (chatty)
9915                                    Log.d(TAG, "Registered content provider: " + names[j]
9916                                            + ", className = " + p.info.name + ", isSyncable = "
9917                                            + p.info.isSyncable);
9918                            }
9919                        } else {
9920                            PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
9921                            Slog.w(TAG, "Skipping provider name " + names[j] +
9922                                    " (in package " + pkg.applicationInfo.packageName +
9923                                    "): name already used by "
9924                                    + ((other != null && other.getComponentName() != null)
9925                                            ? other.getComponentName().getPackageName() : "?"));
9926                        }
9927                    }
9928                }
9929                if (chatty) {
9930                    if (r == null) {
9931                        r = new StringBuilder(256);
9932                    } else {
9933                        r.append(' ');
9934                    }
9935                    r.append(p.info.name);
9936                }
9937            }
9938            if (r != null) {
9939                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Providers: " + r);
9940            }
9941
9942            N = pkg.services.size();
9943            r = null;
9944            for (i=0; i<N; i++) {
9945                PackageParser.Service s = pkg.services.get(i);
9946                s.info.processName = fixProcessName(pkg.applicationInfo.processName,
9947                        s.info.processName);
9948                mServices.addService(s);
9949                if (chatty) {
9950                    if (r == null) {
9951                        r = new StringBuilder(256);
9952                    } else {
9953                        r.append(' ');
9954                    }
9955                    r.append(s.info.name);
9956                }
9957            }
9958            if (r != null) {
9959                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Services: " + r);
9960            }
9961
9962            N = pkg.receivers.size();
9963            r = null;
9964            for (i=0; i<N; i++) {
9965                PackageParser.Activity a = pkg.receivers.get(i);
9966                a.info.processName = fixProcessName(pkg.applicationInfo.processName,
9967                        a.info.processName);
9968                mReceivers.addActivity(a, "receiver");
9969                if (chatty) {
9970                    if (r == null) {
9971                        r = new StringBuilder(256);
9972                    } else {
9973                        r.append(' ');
9974                    }
9975                    r.append(a.info.name);
9976                }
9977            }
9978            if (r != null) {
9979                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Receivers: " + r);
9980            }
9981
9982            N = pkg.activities.size();
9983            r = null;
9984            for (i=0; i<N; i++) {
9985                PackageParser.Activity a = pkg.activities.get(i);
9986                a.info.processName = fixProcessName(pkg.applicationInfo.processName,
9987                        a.info.processName);
9988                mActivities.addActivity(a, "activity");
9989                if (chatty) {
9990                    if (r == null) {
9991                        r = new StringBuilder(256);
9992                    } else {
9993                        r.append(' ');
9994                    }
9995                    r.append(a.info.name);
9996                }
9997            }
9998            if (r != null) {
9999                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Activities: " + r);
10000            }
10001
10002            N = pkg.permissionGroups.size();
10003            r = null;
10004            for (i=0; i<N; i++) {
10005                PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i);
10006                PackageParser.PermissionGroup cur = mPermissionGroups.get(pg.info.name);
10007                final String curPackageName = cur == null ? null : cur.info.packageName;
10008                // Dont allow ephemeral apps to define new permission groups.
10009                if (pkg.applicationInfo.isInstantApp()) {
10010                    Slog.w(TAG, "Permission group " + pg.info.name + " from package "
10011                            + pg.info.packageName
10012                            + " ignored: ephemeral apps cannot define new permission groups.");
10013                    continue;
10014                }
10015                final boolean isPackageUpdate = pg.info.packageName.equals(curPackageName);
10016                if (cur == null || isPackageUpdate) {
10017                    mPermissionGroups.put(pg.info.name, pg);
10018                    if (chatty) {
10019                        if (r == null) {
10020                            r = new StringBuilder(256);
10021                        } else {
10022                            r.append(' ');
10023                        }
10024                        if (isPackageUpdate) {
10025                            r.append("UPD:");
10026                        }
10027                        r.append(pg.info.name);
10028                    }
10029                } else {
10030                    Slog.w(TAG, "Permission group " + pg.info.name + " from package "
10031                            + pg.info.packageName + " ignored: original from "
10032                            + cur.info.packageName);
10033                    if (chatty) {
10034                        if (r == null) {
10035                            r = new StringBuilder(256);
10036                        } else {
10037                            r.append(' ');
10038                        }
10039                        r.append("DUP:");
10040                        r.append(pg.info.name);
10041                    }
10042                }
10043            }
10044            if (r != null) {
10045                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Permission Groups: " + r);
10046            }
10047
10048            N = pkg.permissions.size();
10049            r = null;
10050            for (i=0; i<N; i++) {
10051                PackageParser.Permission p = pkg.permissions.get(i);
10052
10053                // Dont allow ephemeral apps to define new permissions.
10054                if (pkg.applicationInfo.isInstantApp()) {
10055                    Slog.w(TAG, "Permission " + p.info.name + " from package "
10056                            + p.info.packageName
10057                            + " ignored: ephemeral apps cannot define new permissions.");
10058                    continue;
10059                }
10060
10061                // Assume by default that we did not install this permission into the system.
10062                p.info.flags &= ~PermissionInfo.FLAG_INSTALLED;
10063
10064                // Now that permission groups have a special meaning, we ignore permission
10065                // groups for legacy apps to prevent unexpected behavior. In particular,
10066                // permissions for one app being granted to someone just becase they happen
10067                // to be in a group defined by another app (before this had no implications).
10068                if (pkg.applicationInfo.targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1) {
10069                    p.group = mPermissionGroups.get(p.info.group);
10070                    // Warn for a permission in an unknown group.
10071                    if (p.info.group != null && p.group == null) {
10072                        Slog.w(TAG, "Permission " + p.info.name + " from package "
10073                                + p.info.packageName + " in an unknown group " + p.info.group);
10074                    }
10075                }
10076
10077                ArrayMap<String, BasePermission> permissionMap =
10078                        p.tree ? mSettings.mPermissionTrees
10079                                : mSettings.mPermissions;
10080                BasePermission bp = permissionMap.get(p.info.name);
10081
10082                // Allow system apps to redefine non-system permissions
10083                if (bp != null && !Objects.equals(bp.sourcePackage, p.info.packageName)) {
10084                    final boolean currentOwnerIsSystem = (bp.perm != null
10085                            && isSystemApp(bp.perm.owner));
10086                    if (isSystemApp(p.owner)) {
10087                        if (bp.type == BasePermission.TYPE_BUILTIN && bp.perm == null) {
10088                            // It's a built-in permission and no owner, take ownership now
10089                            bp.packageSetting = pkgSetting;
10090                            bp.perm = p;
10091                            bp.uid = pkg.applicationInfo.uid;
10092                            bp.sourcePackage = p.info.packageName;
10093                            p.info.flags |= PermissionInfo.FLAG_INSTALLED;
10094                        } else if (!currentOwnerIsSystem) {
10095                            String msg = "New decl " + p.owner + " of permission  "
10096                                    + p.info.name + " is system; overriding " + bp.sourcePackage;
10097                            reportSettingsProblem(Log.WARN, msg);
10098                            bp = null;
10099                        }
10100                    }
10101                }
10102
10103                if (bp == null) {
10104                    bp = new BasePermission(p.info.name, p.info.packageName,
10105                            BasePermission.TYPE_NORMAL);
10106                    permissionMap.put(p.info.name, bp);
10107                }
10108
10109                if (bp.perm == null) {
10110                    if (bp.sourcePackage == null
10111                            || bp.sourcePackage.equals(p.info.packageName)) {
10112                        BasePermission tree = findPermissionTreeLP(p.info.name);
10113                        if (tree == null
10114                                || tree.sourcePackage.equals(p.info.packageName)) {
10115                            bp.packageSetting = pkgSetting;
10116                            bp.perm = p;
10117                            bp.uid = pkg.applicationInfo.uid;
10118                            bp.sourcePackage = p.info.packageName;
10119                            p.info.flags |= PermissionInfo.FLAG_INSTALLED;
10120                            if (chatty) {
10121                                if (r == null) {
10122                                    r = new StringBuilder(256);
10123                                } else {
10124                                    r.append(' ');
10125                                }
10126                                r.append(p.info.name);
10127                            }
10128                        } else {
10129                            Slog.w(TAG, "Permission " + p.info.name + " from package "
10130                                    + p.info.packageName + " ignored: base tree "
10131                                    + tree.name + " is from package "
10132                                    + tree.sourcePackage);
10133                        }
10134                    } else {
10135                        Slog.w(TAG, "Permission " + p.info.name + " from package "
10136                                + p.info.packageName + " ignored: original from "
10137                                + bp.sourcePackage);
10138                    }
10139                } else if (chatty) {
10140                    if (r == null) {
10141                        r = new StringBuilder(256);
10142                    } else {
10143                        r.append(' ');
10144                    }
10145                    r.append("DUP:");
10146                    r.append(p.info.name);
10147                }
10148                if (bp.perm == p) {
10149                    bp.protectionLevel = p.info.protectionLevel;
10150                }
10151            }
10152
10153            if (r != null) {
10154                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Permissions: " + r);
10155            }
10156
10157            N = pkg.instrumentation.size();
10158            r = null;
10159            for (i=0; i<N; i++) {
10160                PackageParser.Instrumentation a = pkg.instrumentation.get(i);
10161                a.info.packageName = pkg.applicationInfo.packageName;
10162                a.info.sourceDir = pkg.applicationInfo.sourceDir;
10163                a.info.publicSourceDir = pkg.applicationInfo.publicSourceDir;
10164                a.info.splitNames = pkg.splitNames;
10165                a.info.splitSourceDirs = pkg.applicationInfo.splitSourceDirs;
10166                a.info.splitPublicSourceDirs = pkg.applicationInfo.splitPublicSourceDirs;
10167                a.info.splitDependencies = pkg.applicationInfo.splitDependencies;
10168                a.info.dataDir = pkg.applicationInfo.dataDir;
10169                a.info.deviceProtectedDataDir = pkg.applicationInfo.deviceProtectedDataDir;
10170                a.info.credentialProtectedDataDir = pkg.applicationInfo.credentialProtectedDataDir;
10171                a.info.nativeLibraryDir = pkg.applicationInfo.nativeLibraryDir;
10172                a.info.secondaryNativeLibraryDir = pkg.applicationInfo.secondaryNativeLibraryDir;
10173                mInstrumentation.put(a.getComponentName(), a);
10174                if (chatty) {
10175                    if (r == null) {
10176                        r = new StringBuilder(256);
10177                    } else {
10178                        r.append(' ');
10179                    }
10180                    r.append(a.info.name);
10181                }
10182            }
10183            if (r != null) {
10184                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Instrumentation: " + r);
10185            }
10186
10187            if (pkg.protectedBroadcasts != null) {
10188                N = pkg.protectedBroadcasts.size();
10189                for (i=0; i<N; i++) {
10190                    mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i));
10191                }
10192            }
10193
10194            // Create idmap files for pairs of (packages, overlay packages).
10195            // Note: "android", ie framework-res.apk, is handled by native layers.
10196            if (pkg.mOverlayTarget != null) {
10197                // This is an overlay package.
10198                if (pkg.mOverlayTarget != null && !pkg.mOverlayTarget.equals("android")) {
10199                    if (!mOverlays.containsKey(pkg.mOverlayTarget)) {
10200                        mOverlays.put(pkg.mOverlayTarget,
10201                                new ArrayMap<String, PackageParser.Package>());
10202                    }
10203                    ArrayMap<String, PackageParser.Package> map = mOverlays.get(pkg.mOverlayTarget);
10204                    map.put(pkg.packageName, pkg);
10205                    PackageParser.Package orig = mPackages.get(pkg.mOverlayTarget);
10206                    if (orig != null && !createIdmapForPackagePairLI(orig, pkg)) {
10207                        createIdmapFailed = true;
10208                    }
10209                }
10210            } else if (mOverlays.containsKey(pkg.packageName) &&
10211                    !pkg.packageName.equals("android")) {
10212                // This is a regular package, with one or more known overlay packages.
10213                createIdmapsForPackageLI(pkg);
10214            }
10215        }
10216
10217        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
10218
10219        if (createIdmapFailed) {
10220            throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
10221                    "scanPackageLI failed to createIdmap");
10222        }
10223    }
10224
10225    private static void maybeRenameForeignDexMarkers(PackageParser.Package existing,
10226            PackageParser.Package update, int[] userIds) {
10227        if (existing.applicationInfo == null || update.applicationInfo == null) {
10228            // This isn't due to an app installation.
10229            return;
10230        }
10231
10232        final File oldCodePath = new File(existing.applicationInfo.getCodePath());
10233        final File newCodePath = new File(update.applicationInfo.getCodePath());
10234
10235        // The codePath hasn't changed, so there's nothing for us to do.
10236        if (Objects.equals(oldCodePath, newCodePath)) {
10237            return;
10238        }
10239
10240        File canonicalNewCodePath;
10241        try {
10242            canonicalNewCodePath = new File(PackageManagerServiceUtils.realpath(newCodePath));
10243        } catch (IOException e) {
10244            Slog.w(TAG, "Failed to get canonical path.", e);
10245            return;
10246        }
10247
10248        // This is a bit of a hack. The oldCodePath doesn't exist at this point (because
10249        // we've already renamed / deleted it) so we cannot call realpath on it. Here we assume
10250        // that the last component of the path (i.e, the name) doesn't need canonicalization
10251        // (i.e, that it isn't ".", ".." or a symbolic link). This is a valid assumption for now
10252        // but may change in the future. Hopefully this function won't exist at that point.
10253        final File canonicalOldCodePath = new File(canonicalNewCodePath.getParentFile(),
10254                oldCodePath.getName());
10255
10256        // Calculate the prefixes of the markers. These are just the paths with "/" replaced
10257        // with "@".
10258        String oldMarkerPrefix = canonicalOldCodePath.getAbsolutePath().replace('/', '@');
10259        if (!oldMarkerPrefix.endsWith("@")) {
10260            oldMarkerPrefix += "@";
10261        }
10262        String newMarkerPrefix = canonicalNewCodePath.getAbsolutePath().replace('/', '@');
10263        if (!newMarkerPrefix.endsWith("@")) {
10264            newMarkerPrefix += "@";
10265        }
10266
10267        List<String> updatedPaths = update.getAllCodePathsExcludingResourceOnly();
10268        List<String> markerSuffixes = new ArrayList<String>(updatedPaths.size());
10269        for (String updatedPath : updatedPaths) {
10270            String updatedPathName = new File(updatedPath).getName();
10271            markerSuffixes.add(updatedPathName.replace('/', '@'));
10272        }
10273
10274        for (int userId : userIds) {
10275            File profileDir = Environment.getDataProfilesDeForeignDexDirectory(userId);
10276
10277            for (String markerSuffix : markerSuffixes) {
10278                File oldForeignUseMark = new File(profileDir, oldMarkerPrefix + markerSuffix);
10279                File newForeignUseMark = new File(profileDir, newMarkerPrefix + markerSuffix);
10280                if (oldForeignUseMark.exists()) {
10281                    try {
10282                        Os.rename(oldForeignUseMark.getAbsolutePath(),
10283                                newForeignUseMark.getAbsolutePath());
10284                    } catch (ErrnoException e) {
10285                        Slog.w(TAG, "Failed to rename foreign use marker", e);
10286                        oldForeignUseMark.delete();
10287                    }
10288                }
10289            }
10290        }
10291    }
10292
10293    /**
10294     * Derive the ABI of a non-system package located at {@code scanFile}. This information
10295     * is derived purely on the basis of the contents of {@code scanFile} and
10296     * {@code cpuAbiOverride}.
10297     *
10298     * If {@code extractLibs} is true, native libraries are extracted from the app if required.
10299     */
10300    private static void derivePackageAbi(PackageParser.Package pkg, File scanFile,
10301                                 String cpuAbiOverride, boolean extractLibs,
10302                                 File appLib32InstallDir)
10303            throws PackageManagerException {
10304        // Give ourselves some initial paths; we'll come back for another
10305        // pass once we've determined ABI below.
10306        setNativeLibraryPaths(pkg, appLib32InstallDir);
10307
10308        // We would never need to extract libs for forward-locked and external packages,
10309        // since the container service will do it for us. We shouldn't attempt to
10310        // extract libs from system app when it was not updated.
10311        if (pkg.isForwardLocked() || pkg.applicationInfo.isExternalAsec() ||
10312                (isSystemApp(pkg) && !pkg.isUpdatedSystemApp())) {
10313            extractLibs = false;
10314        }
10315
10316        final String nativeLibraryRootStr = pkg.applicationInfo.nativeLibraryRootDir;
10317        final boolean useIsaSpecificSubdirs = pkg.applicationInfo.nativeLibraryRootRequiresIsa;
10318
10319        NativeLibraryHelper.Handle handle = null;
10320        try {
10321            handle = NativeLibraryHelper.Handle.create(pkg);
10322            // TODO(multiArch): This can be null for apps that didn't go through the
10323            // usual installation process. We can calculate it again, like we
10324            // do during install time.
10325            //
10326            // TODO(multiArch): Why do we need to rescan ASEC apps again ? It seems totally
10327            // unnecessary.
10328            final File nativeLibraryRoot = new File(nativeLibraryRootStr);
10329
10330            // Null out the abis so that they can be recalculated.
10331            pkg.applicationInfo.primaryCpuAbi = null;
10332            pkg.applicationInfo.secondaryCpuAbi = null;
10333            if (isMultiArch(pkg.applicationInfo)) {
10334                // Warn if we've set an abiOverride for multi-lib packages..
10335                // By definition, we need to copy both 32 and 64 bit libraries for
10336                // such packages.
10337                if (pkg.cpuAbiOverride != null
10338                        && !NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(pkg.cpuAbiOverride)) {
10339                    Slog.w(TAG, "Ignoring abiOverride for multi arch application.");
10340                }
10341
10342                int abi32 = PackageManager.NO_NATIVE_LIBRARIES;
10343                int abi64 = PackageManager.NO_NATIVE_LIBRARIES;
10344                if (Build.SUPPORTED_32_BIT_ABIS.length > 0) {
10345                    if (extractLibs) {
10346                        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
10347                        abi32 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
10348                                nativeLibraryRoot, Build.SUPPORTED_32_BIT_ABIS,
10349                                useIsaSpecificSubdirs);
10350                    } else {
10351                        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
10352                        abi32 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_32_BIT_ABIS);
10353                    }
10354                    Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
10355                }
10356
10357                maybeThrowExceptionForMultiArchCopy(
10358                        "Error unpackaging 32 bit native libs for multiarch app.", abi32);
10359
10360                if (Build.SUPPORTED_64_BIT_ABIS.length > 0) {
10361                    if (extractLibs) {
10362                        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
10363                        abi64 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
10364                                nativeLibraryRoot, Build.SUPPORTED_64_BIT_ABIS,
10365                                useIsaSpecificSubdirs);
10366                    } else {
10367                        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
10368                        abi64 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_64_BIT_ABIS);
10369                    }
10370                    Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
10371                }
10372
10373                maybeThrowExceptionForMultiArchCopy(
10374                        "Error unpackaging 64 bit native libs for multiarch app.", abi64);
10375
10376                if (abi64 >= 0) {
10377                    pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[abi64];
10378                }
10379
10380                if (abi32 >= 0) {
10381                    final String abi = Build.SUPPORTED_32_BIT_ABIS[abi32];
10382                    if (abi64 >= 0) {
10383                        if (pkg.use32bitAbi) {
10384                            pkg.applicationInfo.secondaryCpuAbi = pkg.applicationInfo.primaryCpuAbi;
10385                            pkg.applicationInfo.primaryCpuAbi = abi;
10386                        } else {
10387                            pkg.applicationInfo.secondaryCpuAbi = abi;
10388                        }
10389                    } else {
10390                        pkg.applicationInfo.primaryCpuAbi = abi;
10391                    }
10392                }
10393
10394            } else {
10395                String[] abiList = (cpuAbiOverride != null) ?
10396                        new String[] { cpuAbiOverride } : Build.SUPPORTED_ABIS;
10397
10398                // Enable gross and lame hacks for apps that are built with old
10399                // SDK tools. We must scan their APKs for renderscript bitcode and
10400                // not launch them if it's present. Don't bother checking on devices
10401                // that don't have 64 bit support.
10402                boolean needsRenderScriptOverride = false;
10403                if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && cpuAbiOverride == null &&
10404                        NativeLibraryHelper.hasRenderscriptBitcode(handle)) {
10405                    abiList = Build.SUPPORTED_32_BIT_ABIS;
10406                    needsRenderScriptOverride = true;
10407                }
10408
10409                final int copyRet;
10410                if (extractLibs) {
10411                    Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
10412                    copyRet = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
10413                            nativeLibraryRoot, abiList, useIsaSpecificSubdirs);
10414                } else {
10415                    Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
10416                    copyRet = NativeLibraryHelper.findSupportedAbi(handle, abiList);
10417                }
10418                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
10419
10420                if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) {
10421                    throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
10422                            "Error unpackaging native libs for app, errorCode=" + copyRet);
10423                }
10424
10425                if (copyRet >= 0) {
10426                    pkg.applicationInfo.primaryCpuAbi = abiList[copyRet];
10427                } else if (copyRet == PackageManager.NO_NATIVE_LIBRARIES && cpuAbiOverride != null) {
10428                    pkg.applicationInfo.primaryCpuAbi = cpuAbiOverride;
10429                } else if (needsRenderScriptOverride) {
10430                    pkg.applicationInfo.primaryCpuAbi = abiList[0];
10431                }
10432            }
10433        } catch (IOException ioe) {
10434            Slog.e(TAG, "Unable to get canonical file " + ioe.toString());
10435        } finally {
10436            IoUtils.closeQuietly(handle);
10437        }
10438
10439        // Now that we've calculated the ABIs and determined if it's an internal app,
10440        // we will go ahead and populate the nativeLibraryPath.
10441        setNativeLibraryPaths(pkg, appLib32InstallDir);
10442    }
10443
10444    /**
10445     * Adjusts ABIs for a set of packages belonging to a shared user so that they all match.
10446     * i.e, so that all packages can be run inside a single process if required.
10447     *
10448     * Optionally, callers can pass in a parsed package via {@code newPackage} in which case
10449     * this function will either try and make the ABI for all packages in {@code packagesForUser}
10450     * match {@code scannedPackage} or will update the ABI of {@code scannedPackage} to match
10451     * the ABI selected for {@code packagesForUser}. This variant is used when installing or
10452     * updating a package that belongs to a shared user.
10453     *
10454     * NOTE: We currently only match for the primary CPU abi string. Matching the secondary
10455     * adds unnecessary complexity.
10456     */
10457    private void adjustCpuAbisForSharedUserLPw(Set<PackageSetting> packagesForUser,
10458            PackageParser.Package scannedPackage) {
10459        String requiredInstructionSet = null;
10460        if (scannedPackage != null && scannedPackage.applicationInfo.primaryCpuAbi != null) {
10461            requiredInstructionSet = VMRuntime.getInstructionSet(
10462                     scannedPackage.applicationInfo.primaryCpuAbi);
10463        }
10464
10465        PackageSetting requirer = null;
10466        for (PackageSetting ps : packagesForUser) {
10467            // If packagesForUser contains scannedPackage, we skip it. This will happen
10468            // when scannedPackage is an update of an existing package. Without this check,
10469            // we will never be able to change the ABI of any package belonging to a shared
10470            // user, even if it's compatible with other packages.
10471            if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
10472                if (ps.primaryCpuAbiString == null) {
10473                    continue;
10474                }
10475
10476                final String instructionSet = VMRuntime.getInstructionSet(ps.primaryCpuAbiString);
10477                if (requiredInstructionSet != null && !instructionSet.equals(requiredInstructionSet)) {
10478                    // We have a mismatch between instruction sets (say arm vs arm64) warn about
10479                    // this but there's not much we can do.
10480                    String errorMessage = "Instruction set mismatch, "
10481                            + ((requirer == null) ? "[caller]" : requirer)
10482                            + " requires " + requiredInstructionSet + " whereas " + ps
10483                            + " requires " + instructionSet;
10484                    Slog.w(TAG, errorMessage);
10485                }
10486
10487                if (requiredInstructionSet == null) {
10488                    requiredInstructionSet = instructionSet;
10489                    requirer = ps;
10490                }
10491            }
10492        }
10493
10494        if (requiredInstructionSet != null) {
10495            String adjustedAbi;
10496            if (requirer != null) {
10497                // requirer != null implies that either scannedPackage was null or that scannedPackage
10498                // did not require an ABI, in which case we have to adjust scannedPackage to match
10499                // the ABI of the set (which is the same as requirer's ABI)
10500                adjustedAbi = requirer.primaryCpuAbiString;
10501                if (scannedPackage != null) {
10502                    scannedPackage.applicationInfo.primaryCpuAbi = adjustedAbi;
10503                }
10504            } else {
10505                // requirer == null implies that we're updating all ABIs in the set to
10506                // match scannedPackage.
10507                adjustedAbi =  scannedPackage.applicationInfo.primaryCpuAbi;
10508            }
10509
10510            for (PackageSetting ps : packagesForUser) {
10511                if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
10512                    if (ps.primaryCpuAbiString != null) {
10513                        continue;
10514                    }
10515
10516                    ps.primaryCpuAbiString = adjustedAbi;
10517                    if (ps.pkg != null && ps.pkg.applicationInfo != null &&
10518                            !TextUtils.equals(adjustedAbi, ps.pkg.applicationInfo.primaryCpuAbi)) {
10519                        ps.pkg.applicationInfo.primaryCpuAbi = adjustedAbi;
10520                        Slog.i(TAG, "Adjusting ABI for " + ps.name + " to " + adjustedAbi
10521                                + " (requirer="
10522                                + (requirer == null ? "null" : requirer.pkg.packageName)
10523                                + ", scannedPackage="
10524                                + (scannedPackage != null ? scannedPackage.packageName : "null")
10525                                + ")");
10526                        try {
10527                            mInstaller.rmdex(ps.codePathString,
10528                                    getDexCodeInstructionSet(getPreferredInstructionSet()));
10529                        } catch (InstallerException ignored) {
10530                        }
10531                    }
10532                }
10533            }
10534        }
10535    }
10536
10537    private void setUpCustomResolverActivity(PackageParser.Package pkg) {
10538        synchronized (mPackages) {
10539            mResolverReplaced = true;
10540            // Set up information for custom user intent resolution activity.
10541            mResolveActivity.applicationInfo = pkg.applicationInfo;
10542            mResolveActivity.name = mCustomResolverComponentName.getClassName();
10543            mResolveActivity.packageName = pkg.applicationInfo.packageName;
10544            mResolveActivity.processName = pkg.applicationInfo.packageName;
10545            mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
10546            mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS |
10547                    ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
10548            mResolveActivity.theme = 0;
10549            mResolveActivity.exported = true;
10550            mResolveActivity.enabled = true;
10551            mResolveInfo.activityInfo = mResolveActivity;
10552            mResolveInfo.priority = 0;
10553            mResolveInfo.preferredOrder = 0;
10554            mResolveInfo.match = 0;
10555            mResolveComponentName = mCustomResolverComponentName;
10556            Slog.i(TAG, "Replacing default ResolverActivity with custom activity: " +
10557                    mResolveComponentName);
10558        }
10559    }
10560
10561    private void setUpEphemeralInstallerActivityLP(ComponentName installerComponent) {
10562        if (installerComponent == null) {
10563            if (DEBUG_EPHEMERAL) {
10564                Slog.d(TAG, "Clear ephemeral installer activity");
10565            }
10566            mEphemeralInstallerActivity.applicationInfo = null;
10567            return;
10568        }
10569
10570        if (DEBUG_EPHEMERAL) {
10571            Slog.d(TAG, "Set ephemeral installer activity: " + installerComponent);
10572        }
10573        final PackageParser.Package pkg = mPackages.get(installerComponent.getPackageName());
10574        // Set up information for ephemeral installer activity
10575        mEphemeralInstallerActivity.applicationInfo = pkg.applicationInfo;
10576        mEphemeralInstallerActivity.name = installerComponent.getClassName();
10577        mEphemeralInstallerActivity.packageName = pkg.applicationInfo.packageName;
10578        mEphemeralInstallerActivity.processName = pkg.applicationInfo.packageName;
10579        mEphemeralInstallerActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
10580        mEphemeralInstallerActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS
10581                | ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
10582        mEphemeralInstallerActivity.theme = 0;
10583        mEphemeralInstallerActivity.exported = true;
10584        mEphemeralInstallerActivity.enabled = true;
10585        mEphemeralInstallerInfo.activityInfo = mEphemeralInstallerActivity;
10586        mEphemeralInstallerInfo.priority = 0;
10587        mEphemeralInstallerInfo.preferredOrder = 1;
10588        mEphemeralInstallerInfo.isDefault = true;
10589        mEphemeralInstallerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
10590                | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
10591    }
10592
10593    private static String calculateBundledApkRoot(final String codePathString) {
10594        final File codePath = new File(codePathString);
10595        final File codeRoot;
10596        if (FileUtils.contains(Environment.getRootDirectory(), codePath)) {
10597            codeRoot = Environment.getRootDirectory();
10598        } else if (FileUtils.contains(Environment.getOemDirectory(), codePath)) {
10599            codeRoot = Environment.getOemDirectory();
10600        } else if (FileUtils.contains(Environment.getVendorDirectory(), codePath)) {
10601            codeRoot = Environment.getVendorDirectory();
10602        } else {
10603            // Unrecognized code path; take its top real segment as the apk root:
10604            // e.g. /something/app/blah.apk => /something
10605            try {
10606                File f = codePath.getCanonicalFile();
10607                File parent = f.getParentFile();    // non-null because codePath is a file
10608                File tmp;
10609                while ((tmp = parent.getParentFile()) != null) {
10610                    f = parent;
10611                    parent = tmp;
10612                }
10613                codeRoot = f;
10614                Slog.w(TAG, "Unrecognized code path "
10615                        + codePath + " - using " + codeRoot);
10616            } catch (IOException e) {
10617                // Can't canonicalize the code path -- shenanigans?
10618                Slog.w(TAG, "Can't canonicalize code path " + codePath);
10619                return Environment.getRootDirectory().getPath();
10620            }
10621        }
10622        return codeRoot.getPath();
10623    }
10624
10625    /**
10626     * Derive and set the location of native libraries for the given package,
10627     * which varies depending on where and how the package was installed.
10628     */
10629    private static void setNativeLibraryPaths(PackageParser.Package pkg, File appLib32InstallDir) {
10630        final ApplicationInfo info = pkg.applicationInfo;
10631        final String codePath = pkg.codePath;
10632        final File codeFile = new File(codePath);
10633        final boolean bundledApp = info.isSystemApp() && !info.isUpdatedSystemApp();
10634        final boolean asecApp = info.isForwardLocked() || info.isExternalAsec();
10635
10636        info.nativeLibraryRootDir = null;
10637        info.nativeLibraryRootRequiresIsa = false;
10638        info.nativeLibraryDir = null;
10639        info.secondaryNativeLibraryDir = null;
10640
10641        if (isApkFile(codeFile)) {
10642            // Monolithic install
10643            if (bundledApp) {
10644                // If "/system/lib64/apkname" exists, assume that is the per-package
10645                // native library directory to use; otherwise use "/system/lib/apkname".
10646                final String apkRoot = calculateBundledApkRoot(info.sourceDir);
10647                final boolean is64Bit = VMRuntime.is64BitInstructionSet(
10648                        getPrimaryInstructionSet(info));
10649
10650                // This is a bundled system app so choose the path based on the ABI.
10651                // if it's a 64 bit abi, use lib64 otherwise use lib32. Note that this
10652                // is just the default path.
10653                final String apkName = deriveCodePathName(codePath);
10654                final String libDir = is64Bit ? LIB64_DIR_NAME : LIB_DIR_NAME;
10655                info.nativeLibraryRootDir = Environment.buildPath(new File(apkRoot), libDir,
10656                        apkName).getAbsolutePath();
10657
10658                if (info.secondaryCpuAbi != null) {
10659                    final String secondaryLibDir = is64Bit ? LIB_DIR_NAME : LIB64_DIR_NAME;
10660                    info.secondaryNativeLibraryDir = Environment.buildPath(new File(apkRoot),
10661                            secondaryLibDir, apkName).getAbsolutePath();
10662                }
10663            } else if (asecApp) {
10664                info.nativeLibraryRootDir = new File(codeFile.getParentFile(), LIB_DIR_NAME)
10665                        .getAbsolutePath();
10666            } else {
10667                final String apkName = deriveCodePathName(codePath);
10668                info.nativeLibraryRootDir = new File(appLib32InstallDir, apkName)
10669                        .getAbsolutePath();
10670            }
10671
10672            info.nativeLibraryRootRequiresIsa = false;
10673            info.nativeLibraryDir = info.nativeLibraryRootDir;
10674        } else {
10675            // Cluster install
10676            info.nativeLibraryRootDir = new File(codeFile, LIB_DIR_NAME).getAbsolutePath();
10677            info.nativeLibraryRootRequiresIsa = true;
10678
10679            info.nativeLibraryDir = new File(info.nativeLibraryRootDir,
10680                    getPrimaryInstructionSet(info)).getAbsolutePath();
10681
10682            if (info.secondaryCpuAbi != null) {
10683                info.secondaryNativeLibraryDir = new File(info.nativeLibraryRootDir,
10684                        VMRuntime.getInstructionSet(info.secondaryCpuAbi)).getAbsolutePath();
10685            }
10686        }
10687    }
10688
10689    /**
10690     * Calculate the abis and roots for a bundled app. These can uniquely
10691     * be determined from the contents of the system partition, i.e whether
10692     * it contains 64 or 32 bit shared libraries etc. We do not validate any
10693     * of this information, and instead assume that the system was built
10694     * sensibly.
10695     */
10696    private static void setBundledAppAbisAndRoots(PackageParser.Package pkg,
10697                                           PackageSetting pkgSetting) {
10698        final String apkName = deriveCodePathName(pkg.applicationInfo.getCodePath());
10699
10700        // If "/system/lib64/apkname" exists, assume that is the per-package
10701        // native library directory to use; otherwise use "/system/lib/apkname".
10702        final String apkRoot = calculateBundledApkRoot(pkg.applicationInfo.sourceDir);
10703        setBundledAppAbi(pkg, apkRoot, apkName);
10704        // pkgSetting might be null during rescan following uninstall of updates
10705        // to a bundled app, so accommodate that possibility.  The settings in
10706        // that case will be established later from the parsed package.
10707        //
10708        // If the settings aren't null, sync them up with what we've just derived.
10709        // note that apkRoot isn't stored in the package settings.
10710        if (pkgSetting != null) {
10711            pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
10712            pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
10713        }
10714    }
10715
10716    /**
10717     * Deduces the ABI of a bundled app and sets the relevant fields on the
10718     * parsed pkg object.
10719     *
10720     * @param apkRoot the root of the installed apk, something like {@code /system} or {@code /oem}
10721     *        under which system libraries are installed.
10722     * @param apkName the name of the installed package.
10723     */
10724    private static void setBundledAppAbi(PackageParser.Package pkg, String apkRoot, String apkName) {
10725        final File codeFile = new File(pkg.codePath);
10726
10727        final boolean has64BitLibs;
10728        final boolean has32BitLibs;
10729        if (isApkFile(codeFile)) {
10730            // Monolithic install
10731            has64BitLibs = (new File(apkRoot, new File(LIB64_DIR_NAME, apkName).getPath())).exists();
10732            has32BitLibs = (new File(apkRoot, new File(LIB_DIR_NAME, apkName).getPath())).exists();
10733        } else {
10734            // Cluster install
10735            final File rootDir = new File(codeFile, LIB_DIR_NAME);
10736            if (!ArrayUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS)
10737                    && !TextUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS[0])) {
10738                final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_64_BIT_ABIS[0]);
10739                has64BitLibs = (new File(rootDir, isa)).exists();
10740            } else {
10741                has64BitLibs = false;
10742            }
10743            if (!ArrayUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS)
10744                    && !TextUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS[0])) {
10745                final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_32_BIT_ABIS[0]);
10746                has32BitLibs = (new File(rootDir, isa)).exists();
10747            } else {
10748                has32BitLibs = false;
10749            }
10750        }
10751
10752        if (has64BitLibs && !has32BitLibs) {
10753            // The package has 64 bit libs, but not 32 bit libs. Its primary
10754            // ABI should be 64 bit. We can safely assume here that the bundled
10755            // native libraries correspond to the most preferred ABI in the list.
10756
10757            pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
10758            pkg.applicationInfo.secondaryCpuAbi = null;
10759        } else if (has32BitLibs && !has64BitLibs) {
10760            // The package has 32 bit libs but not 64 bit libs. Its primary
10761            // ABI should be 32 bit.
10762
10763            pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
10764            pkg.applicationInfo.secondaryCpuAbi = null;
10765        } else if (has32BitLibs && has64BitLibs) {
10766            // The application has both 64 and 32 bit bundled libraries. We check
10767            // here that the app declares multiArch support, and warn if it doesn't.
10768            //
10769            // We will be lenient here and record both ABIs. The primary will be the
10770            // ABI that's higher on the list, i.e, a device that's configured to prefer
10771            // 64 bit apps will see a 64 bit primary ABI,
10772
10773            if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) == 0) {
10774                Slog.e(TAG, "Package " + pkg + " has multiple bundled libs, but is not multiarch.");
10775            }
10776
10777            if (VMRuntime.is64BitInstructionSet(getPreferredInstructionSet())) {
10778                pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
10779                pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
10780            } else {
10781                pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
10782                pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
10783            }
10784        } else {
10785            pkg.applicationInfo.primaryCpuAbi = null;
10786            pkg.applicationInfo.secondaryCpuAbi = null;
10787        }
10788    }
10789
10790    private void killApplication(String pkgName, int appId, String reason) {
10791        killApplication(pkgName, appId, UserHandle.USER_ALL, reason);
10792    }
10793
10794    private void killApplication(String pkgName, int appId, int userId, String reason) {
10795        // Request the ActivityManager to kill the process(only for existing packages)
10796        // so that we do not end up in a confused state while the user is still using the older
10797        // version of the application while the new one gets installed.
10798        final long token = Binder.clearCallingIdentity();
10799        try {
10800            IActivityManager am = ActivityManager.getService();
10801            if (am != null) {
10802                try {
10803                    am.killApplication(pkgName, appId, userId, reason);
10804                } catch (RemoteException e) {
10805                }
10806            }
10807        } finally {
10808            Binder.restoreCallingIdentity(token);
10809        }
10810    }
10811
10812    private void removePackageLI(PackageParser.Package pkg, boolean chatty) {
10813        // Remove the parent package setting
10814        PackageSetting ps = (PackageSetting) pkg.mExtras;
10815        if (ps != null) {
10816            removePackageLI(ps, chatty);
10817        }
10818        // Remove the child package setting
10819        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
10820        for (int i = 0; i < childCount; i++) {
10821            PackageParser.Package childPkg = pkg.childPackages.get(i);
10822            ps = (PackageSetting) childPkg.mExtras;
10823            if (ps != null) {
10824                removePackageLI(ps, chatty);
10825            }
10826        }
10827    }
10828
10829    void removePackageLI(PackageSetting ps, boolean chatty) {
10830        if (DEBUG_INSTALL) {
10831            if (chatty)
10832                Log.d(TAG, "Removing package " + ps.name);
10833        }
10834
10835        // writer
10836        synchronized (mPackages) {
10837            mPackages.remove(ps.name);
10838            final PackageParser.Package pkg = ps.pkg;
10839            if (pkg != null) {
10840                cleanPackageDataStructuresLILPw(pkg, chatty);
10841            }
10842        }
10843    }
10844
10845    void removeInstalledPackageLI(PackageParser.Package pkg, boolean chatty) {
10846        if (DEBUG_INSTALL) {
10847            if (chatty)
10848                Log.d(TAG, "Removing package " + pkg.applicationInfo.packageName);
10849        }
10850
10851        // writer
10852        synchronized (mPackages) {
10853            // Remove the parent package
10854            mPackages.remove(pkg.applicationInfo.packageName);
10855            cleanPackageDataStructuresLILPw(pkg, chatty);
10856
10857            // Remove the child packages
10858            final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
10859            for (int i = 0; i < childCount; i++) {
10860                PackageParser.Package childPkg = pkg.childPackages.get(i);
10861                mPackages.remove(childPkg.applicationInfo.packageName);
10862                cleanPackageDataStructuresLILPw(childPkg, chatty);
10863            }
10864        }
10865    }
10866
10867    void cleanPackageDataStructuresLILPw(PackageParser.Package pkg, boolean chatty) {
10868        int N = pkg.providers.size();
10869        StringBuilder r = null;
10870        int i;
10871        for (i=0; i<N; i++) {
10872            PackageParser.Provider p = pkg.providers.get(i);
10873            mProviders.removeProvider(p);
10874            if (p.info.authority == null) {
10875
10876                /* There was another ContentProvider with this authority when
10877                 * this app was installed so this authority is null,
10878                 * Ignore it as we don't have to unregister the provider.
10879                 */
10880                continue;
10881            }
10882            String names[] = p.info.authority.split(";");
10883            for (int j = 0; j < names.length; j++) {
10884                if (mProvidersByAuthority.get(names[j]) == p) {
10885                    mProvidersByAuthority.remove(names[j]);
10886                    if (DEBUG_REMOVE) {
10887                        if (chatty)
10888                            Log.d(TAG, "Unregistered content provider: " + names[j]
10889                                    + ", className = " + p.info.name + ", isSyncable = "
10890                                    + p.info.isSyncable);
10891                    }
10892                }
10893            }
10894            if (DEBUG_REMOVE && chatty) {
10895                if (r == null) {
10896                    r = new StringBuilder(256);
10897                } else {
10898                    r.append(' ');
10899                }
10900                r.append(p.info.name);
10901            }
10902        }
10903        if (r != null) {
10904            if (DEBUG_REMOVE) Log.d(TAG, "  Providers: " + r);
10905        }
10906
10907        N = pkg.services.size();
10908        r = null;
10909        for (i=0; i<N; i++) {
10910            PackageParser.Service s = pkg.services.get(i);
10911            mServices.removeService(s);
10912            if (chatty) {
10913                if (r == null) {
10914                    r = new StringBuilder(256);
10915                } else {
10916                    r.append(' ');
10917                }
10918                r.append(s.info.name);
10919            }
10920        }
10921        if (r != null) {
10922            if (DEBUG_REMOVE) Log.d(TAG, "  Services: " + r);
10923        }
10924
10925        N = pkg.receivers.size();
10926        r = null;
10927        for (i=0; i<N; i++) {
10928            PackageParser.Activity a = pkg.receivers.get(i);
10929            mReceivers.removeActivity(a, "receiver");
10930            if (DEBUG_REMOVE && chatty) {
10931                if (r == null) {
10932                    r = new StringBuilder(256);
10933                } else {
10934                    r.append(' ');
10935                }
10936                r.append(a.info.name);
10937            }
10938        }
10939        if (r != null) {
10940            if (DEBUG_REMOVE) Log.d(TAG, "  Receivers: " + r);
10941        }
10942
10943        N = pkg.activities.size();
10944        r = null;
10945        for (i=0; i<N; i++) {
10946            PackageParser.Activity a = pkg.activities.get(i);
10947            mActivities.removeActivity(a, "activity");
10948            if (DEBUG_REMOVE && chatty) {
10949                if (r == null) {
10950                    r = new StringBuilder(256);
10951                } else {
10952                    r.append(' ');
10953                }
10954                r.append(a.info.name);
10955            }
10956        }
10957        if (r != null) {
10958            if (DEBUG_REMOVE) Log.d(TAG, "  Activities: " + r);
10959        }
10960
10961        N = pkg.permissions.size();
10962        r = null;
10963        for (i=0; i<N; i++) {
10964            PackageParser.Permission p = pkg.permissions.get(i);
10965            BasePermission bp = mSettings.mPermissions.get(p.info.name);
10966            if (bp == null) {
10967                bp = mSettings.mPermissionTrees.get(p.info.name);
10968            }
10969            if (bp != null && bp.perm == p) {
10970                bp.perm = null;
10971                if (DEBUG_REMOVE && chatty) {
10972                    if (r == null) {
10973                        r = new StringBuilder(256);
10974                    } else {
10975                        r.append(' ');
10976                    }
10977                    r.append(p.info.name);
10978                }
10979            }
10980            if ((p.info.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
10981                ArraySet<String> appOpPkgs = mAppOpPermissionPackages.get(p.info.name);
10982                if (appOpPkgs != null) {
10983                    appOpPkgs.remove(pkg.packageName);
10984                }
10985            }
10986        }
10987        if (r != null) {
10988            if (DEBUG_REMOVE) Log.d(TAG, "  Permissions: " + r);
10989        }
10990
10991        N = pkg.requestedPermissions.size();
10992        r = null;
10993        for (i=0; i<N; i++) {
10994            String perm = pkg.requestedPermissions.get(i);
10995            BasePermission bp = mSettings.mPermissions.get(perm);
10996            if (bp != null && (bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
10997                ArraySet<String> appOpPkgs = mAppOpPermissionPackages.get(perm);
10998                if (appOpPkgs != null) {
10999                    appOpPkgs.remove(pkg.packageName);
11000                    if (appOpPkgs.isEmpty()) {
11001                        mAppOpPermissionPackages.remove(perm);
11002                    }
11003                }
11004            }
11005        }
11006        if (r != null) {
11007            if (DEBUG_REMOVE) Log.d(TAG, "  Permissions: " + r);
11008        }
11009
11010        N = pkg.instrumentation.size();
11011        r = null;
11012        for (i=0; i<N; i++) {
11013            PackageParser.Instrumentation a = pkg.instrumentation.get(i);
11014            mInstrumentation.remove(a.getComponentName());
11015            if (DEBUG_REMOVE && chatty) {
11016                if (r == null) {
11017                    r = new StringBuilder(256);
11018                } else {
11019                    r.append(' ');
11020                }
11021                r.append(a.info.name);
11022            }
11023        }
11024        if (r != null) {
11025            if (DEBUG_REMOVE) Log.d(TAG, "  Instrumentation: " + r);
11026        }
11027
11028        r = null;
11029        if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11030            // Only system apps can hold shared libraries.
11031            if (pkg.libraryNames != null) {
11032                for (i = 0; i < pkg.libraryNames.size(); i++) {
11033                    String name = pkg.libraryNames.get(i);
11034                    if (removeSharedLibraryLPw(name, 0)) {
11035                        if (DEBUG_REMOVE && chatty) {
11036                            if (r == null) {
11037                                r = new StringBuilder(256);
11038                            } else {
11039                                r.append(' ');
11040                            }
11041                            r.append(name);
11042                        }
11043                    }
11044                }
11045            }
11046        }
11047
11048        r = null;
11049
11050        // Any package can hold static shared libraries.
11051        if (pkg.staticSharedLibName != null) {
11052            if (removeSharedLibraryLPw(pkg.staticSharedLibName, pkg.staticSharedLibVersion)) {
11053                if (DEBUG_REMOVE && chatty) {
11054                    if (r == null) {
11055                        r = new StringBuilder(256);
11056                    } else {
11057                        r.append(' ');
11058                    }
11059                    r.append(pkg.staticSharedLibName);
11060                }
11061            }
11062        }
11063
11064        if (r != null) {
11065            if (DEBUG_REMOVE) Log.d(TAG, "  Libraries: " + r);
11066        }
11067    }
11068
11069    private static boolean hasPermission(PackageParser.Package pkgInfo, String perm) {
11070        for (int i=pkgInfo.permissions.size()-1; i>=0; i--) {
11071            if (pkgInfo.permissions.get(i).info.name.equals(perm)) {
11072                return true;
11073            }
11074        }
11075        return false;
11076    }
11077
11078    static final int UPDATE_PERMISSIONS_ALL = 1<<0;
11079    static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1<<1;
11080    static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1<<2;
11081
11082    private void updatePermissionsLPw(PackageParser.Package pkg, int flags) {
11083        // Update the parent permissions
11084        updatePermissionsLPw(pkg.packageName, pkg, flags);
11085        // Update the child permissions
11086        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
11087        for (int i = 0; i < childCount; i++) {
11088            PackageParser.Package childPkg = pkg.childPackages.get(i);
11089            updatePermissionsLPw(childPkg.packageName, childPkg, flags);
11090        }
11091    }
11092
11093    private void updatePermissionsLPw(String changingPkg, PackageParser.Package pkgInfo,
11094            int flags) {
11095        final String volumeUuid = (pkgInfo != null) ? getVolumeUuidForPackage(pkgInfo) : null;
11096        updatePermissionsLPw(changingPkg, pkgInfo, volumeUuid, flags);
11097    }
11098
11099    private void updatePermissionsLPw(String changingPkg,
11100            PackageParser.Package pkgInfo, String replaceVolumeUuid, int flags) {
11101        // Make sure there are no dangling permission trees.
11102        Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator();
11103        while (it.hasNext()) {
11104            final BasePermission bp = it.next();
11105            if (bp.packageSetting == null) {
11106                // We may not yet have parsed the package, so just see if
11107                // we still know about its settings.
11108                bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage);
11109            }
11110            if (bp.packageSetting == null) {
11111                Slog.w(TAG, "Removing dangling permission tree: " + bp.name
11112                        + " from package " + bp.sourcePackage);
11113                it.remove();
11114            } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) {
11115                if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
11116                    Slog.i(TAG, "Removing old permission tree: " + bp.name
11117                            + " from package " + bp.sourcePackage);
11118                    flags |= UPDATE_PERMISSIONS_ALL;
11119                    it.remove();
11120                }
11121            }
11122        }
11123
11124        // Make sure all dynamic permissions have been assigned to a package,
11125        // and make sure there are no dangling permissions.
11126        it = mSettings.mPermissions.values().iterator();
11127        while (it.hasNext()) {
11128            final BasePermission bp = it.next();
11129            if (bp.type == BasePermission.TYPE_DYNAMIC) {
11130                if (DEBUG_SETTINGS) Log.v(TAG, "Dynamic permission: name="
11131                        + bp.name + " pkg=" + bp.sourcePackage
11132                        + " info=" + bp.pendingInfo);
11133                if (bp.packageSetting == null && bp.pendingInfo != null) {
11134                    final BasePermission tree = findPermissionTreeLP(bp.name);
11135                    if (tree != null && tree.perm != null) {
11136                        bp.packageSetting = tree.packageSetting;
11137                        bp.perm = new PackageParser.Permission(tree.perm.owner,
11138                                new PermissionInfo(bp.pendingInfo));
11139                        bp.perm.info.packageName = tree.perm.info.packageName;
11140                        bp.perm.info.name = bp.name;
11141                        bp.uid = tree.uid;
11142                    }
11143                }
11144            }
11145            if (bp.packageSetting == null) {
11146                // We may not yet have parsed the package, so just see if
11147                // we still know about its settings.
11148                bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage);
11149            }
11150            if (bp.packageSetting == null) {
11151                Slog.w(TAG, "Removing dangling permission: " + bp.name
11152                        + " from package " + bp.sourcePackage);
11153                it.remove();
11154            } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) {
11155                if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
11156                    Slog.i(TAG, "Removing old permission: " + bp.name
11157                            + " from package " + bp.sourcePackage);
11158                    flags |= UPDATE_PERMISSIONS_ALL;
11159                    it.remove();
11160                }
11161            }
11162        }
11163
11164        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "grantPermissions");
11165        // Now update the permissions for all packages, in particular
11166        // replace the granted permissions of the system packages.
11167        if ((flags&UPDATE_PERMISSIONS_ALL) != 0) {
11168            for (PackageParser.Package pkg : mPackages.values()) {
11169                if (pkg != pkgInfo) {
11170                    // Only replace for packages on requested volume
11171                    final String volumeUuid = getVolumeUuidForPackage(pkg);
11172                    final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_ALL) != 0)
11173                            && Objects.equals(replaceVolumeUuid, volumeUuid);
11174                    grantPermissionsLPw(pkg, replace, changingPkg);
11175                }
11176            }
11177        }
11178
11179        if (pkgInfo != null) {
11180            // Only replace for packages on requested volume
11181            final String volumeUuid = getVolumeUuidForPackage(pkgInfo);
11182            final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_PKG) != 0)
11183                    && Objects.equals(replaceVolumeUuid, volumeUuid);
11184            grantPermissionsLPw(pkgInfo, replace, changingPkg);
11185        }
11186        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
11187    }
11188
11189    private void grantPermissionsLPw(PackageParser.Package pkg, boolean replace,
11190            String packageOfInterest) {
11191        // IMPORTANT: There are two types of permissions: install and runtime.
11192        // Install time permissions are granted when the app is installed to
11193        // all device users and users added in the future. Runtime permissions
11194        // are granted at runtime explicitly to specific users. Normal and signature
11195        // protected permissions are install time permissions. Dangerous permissions
11196        // are install permissions if the app's target SDK is Lollipop MR1 or older,
11197        // otherwise they are runtime permissions. This function does not manage
11198        // runtime permissions except for the case an app targeting Lollipop MR1
11199        // being upgraded to target a newer SDK, in which case dangerous permissions
11200        // are transformed from install time to runtime ones.
11201
11202        final PackageSetting ps = (PackageSetting) pkg.mExtras;
11203        if (ps == null) {
11204            return;
11205        }
11206
11207        PermissionsState permissionsState = ps.getPermissionsState();
11208        PermissionsState origPermissions = permissionsState;
11209
11210        final int[] currentUserIds = UserManagerService.getInstance().getUserIds();
11211
11212        boolean runtimePermissionsRevoked = false;
11213        int[] changedRuntimePermissionUserIds = EMPTY_INT_ARRAY;
11214
11215        boolean changedInstallPermission = false;
11216
11217        if (replace) {
11218            ps.installPermissionsFixed = false;
11219            if (!ps.isSharedUser()) {
11220                origPermissions = new PermissionsState(permissionsState);
11221                permissionsState.reset();
11222            } else {
11223                // We need to know only about runtime permission changes since the
11224                // calling code always writes the install permissions state but
11225                // the runtime ones are written only if changed. The only cases of
11226                // changed runtime permissions here are promotion of an install to
11227                // runtime and revocation of a runtime from a shared user.
11228                changedRuntimePermissionUserIds = revokeUnusedSharedUserPermissionsLPw(
11229                        ps.sharedUser, UserManagerService.getInstance().getUserIds());
11230                if (!ArrayUtils.isEmpty(changedRuntimePermissionUserIds)) {
11231                    runtimePermissionsRevoked = true;
11232                }
11233            }
11234        }
11235
11236        permissionsState.setGlobalGids(mGlobalGids);
11237
11238        final int N = pkg.requestedPermissions.size();
11239        for (int i=0; i<N; i++) {
11240            final String name = pkg.requestedPermissions.get(i);
11241            final BasePermission bp = mSettings.mPermissions.get(name);
11242
11243            if (DEBUG_INSTALL) {
11244                Log.i(TAG, "Package " + pkg.packageName + " checking " + name + ": " + bp);
11245            }
11246
11247            if (bp == null || bp.packageSetting == null) {
11248                if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) {
11249                    Slog.w(TAG, "Unknown permission " + name
11250                            + " in package " + pkg.packageName);
11251                }
11252                continue;
11253            }
11254
11255
11256            // Limit ephemeral apps to ephemeral allowed permissions.
11257            if (pkg.applicationInfo.isInstantApp() && !bp.isInstant()) {
11258                Log.i(TAG, "Denying non-ephemeral permission " + bp.name + " for package "
11259                        + pkg.packageName);
11260                continue;
11261            }
11262
11263            final String perm = bp.name;
11264            boolean allowedSig = false;
11265            int grant = GRANT_DENIED;
11266
11267            // Keep track of app op permissions.
11268            if ((bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
11269                ArraySet<String> pkgs = mAppOpPermissionPackages.get(bp.name);
11270                if (pkgs == null) {
11271                    pkgs = new ArraySet<>();
11272                    mAppOpPermissionPackages.put(bp.name, pkgs);
11273                }
11274                pkgs.add(pkg.packageName);
11275            }
11276
11277            final int level = bp.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE;
11278            final boolean appSupportsRuntimePermissions = pkg.applicationInfo.targetSdkVersion
11279                    >= Build.VERSION_CODES.M;
11280            switch (level) {
11281                case PermissionInfo.PROTECTION_NORMAL: {
11282                    // For all apps normal permissions are install time ones.
11283                    grant = GRANT_INSTALL;
11284                } break;
11285
11286                case PermissionInfo.PROTECTION_DANGEROUS: {
11287                    // If a permission review is required for legacy apps we represent
11288                    // their permissions as always granted runtime ones since we need
11289                    // to keep the review required permission flag per user while an
11290                    // install permission's state is shared across all users.
11291                    if (!appSupportsRuntimePermissions && !mPermissionReviewRequired) {
11292                        // For legacy apps dangerous permissions are install time ones.
11293                        grant = GRANT_INSTALL;
11294                    } else if (origPermissions.hasInstallPermission(bp.name)) {
11295                        // For legacy apps that became modern, install becomes runtime.
11296                        grant = GRANT_UPGRADE;
11297                    } else if (mPromoteSystemApps
11298                            && isSystemApp(ps)
11299                            && mExistingSystemPackages.contains(ps.name)) {
11300                        // For legacy system apps, install becomes runtime.
11301                        // We cannot check hasInstallPermission() for system apps since those
11302                        // permissions were granted implicitly and not persisted pre-M.
11303                        grant = GRANT_UPGRADE;
11304                    } else {
11305                        // For modern apps keep runtime permissions unchanged.
11306                        grant = GRANT_RUNTIME;
11307                    }
11308                } break;
11309
11310                case PermissionInfo.PROTECTION_SIGNATURE: {
11311                    // For all apps signature permissions are install time ones.
11312                    allowedSig = grantSignaturePermission(perm, pkg, bp, origPermissions);
11313                    if (allowedSig) {
11314                        grant = GRANT_INSTALL;
11315                    }
11316                } break;
11317            }
11318
11319            if (DEBUG_INSTALL) {
11320                Log.i(TAG, "Package " + pkg.packageName + " granting " + perm);
11321            }
11322
11323            if (grant != GRANT_DENIED) {
11324                if (!isSystemApp(ps) && ps.installPermissionsFixed) {
11325                    // If this is an existing, non-system package, then
11326                    // we can't add any new permissions to it.
11327                    if (!allowedSig && !origPermissions.hasInstallPermission(perm)) {
11328                        // Except...  if this is a permission that was added
11329                        // to the platform (note: need to only do this when
11330                        // updating the platform).
11331                        if (!isNewPlatformPermissionForPackage(perm, pkg)) {
11332                            grant = GRANT_DENIED;
11333                        }
11334                    }
11335                }
11336
11337                switch (grant) {
11338                    case GRANT_INSTALL: {
11339                        // Revoke this as runtime permission to handle the case of
11340                        // a runtime permission being downgraded to an install one.
11341                        // Also in permission review mode we keep dangerous permissions
11342                        // for legacy apps
11343                        for (int userId : UserManagerService.getInstance().getUserIds()) {
11344                            if (origPermissions.getRuntimePermissionState(
11345                                    bp.name, userId) != null) {
11346                                // Revoke the runtime permission and clear the flags.
11347                                origPermissions.revokeRuntimePermission(bp, userId);
11348                                origPermissions.updatePermissionFlags(bp, userId,
11349                                      PackageManager.MASK_PERMISSION_FLAGS, 0);
11350                                // If we revoked a permission permission, we have to write.
11351                                changedRuntimePermissionUserIds = ArrayUtils.appendInt(
11352                                        changedRuntimePermissionUserIds, userId);
11353                            }
11354                        }
11355                        // Grant an install permission.
11356                        if (permissionsState.grantInstallPermission(bp) !=
11357                                PermissionsState.PERMISSION_OPERATION_FAILURE) {
11358                            changedInstallPermission = true;
11359                        }
11360                    } break;
11361
11362                    case GRANT_RUNTIME: {
11363                        // Grant previously granted runtime permissions.
11364                        for (int userId : UserManagerService.getInstance().getUserIds()) {
11365                            PermissionState permissionState = origPermissions
11366                                    .getRuntimePermissionState(bp.name, userId);
11367                            int flags = permissionState != null
11368                                    ? permissionState.getFlags() : 0;
11369                            if (origPermissions.hasRuntimePermission(bp.name, userId)) {
11370                                // Don't propagate the permission in a permission review mode if
11371                                // the former was revoked, i.e. marked to not propagate on upgrade.
11372                                // Note that in a permission review mode install permissions are
11373                                // represented as constantly granted runtime ones since we need to
11374                                // keep a per user state associated with the permission. Also the
11375                                // revoke on upgrade flag is no longer applicable and is reset.
11376                                final boolean revokeOnUpgrade = (flags & PackageManager
11377                                        .FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0;
11378                                if (revokeOnUpgrade) {
11379                                    flags &= ~PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE;
11380                                    // Since we changed the flags, we have to write.
11381                                    changedRuntimePermissionUserIds = ArrayUtils.appendInt(
11382                                            changedRuntimePermissionUserIds, userId);
11383                                }
11384                                if (!mPermissionReviewRequired || !revokeOnUpgrade) {
11385                                    if (permissionsState.grantRuntimePermission(bp, userId) ==
11386                                            PermissionsState.PERMISSION_OPERATION_FAILURE) {
11387                                        // If we cannot put the permission as it was,
11388                                        // we have to write.
11389                                        changedRuntimePermissionUserIds = ArrayUtils.appendInt(
11390                                                changedRuntimePermissionUserIds, userId);
11391                                    }
11392                                }
11393
11394                                // If the app supports runtime permissions no need for a review.
11395                                if (mPermissionReviewRequired
11396                                        && appSupportsRuntimePermissions
11397                                        && (flags & PackageManager
11398                                                .FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
11399                                    flags &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
11400                                    // Since we changed the flags, we have to write.
11401                                    changedRuntimePermissionUserIds = ArrayUtils.appendInt(
11402                                            changedRuntimePermissionUserIds, userId);
11403                                }
11404                            } else if (mPermissionReviewRequired
11405                                    && !appSupportsRuntimePermissions) {
11406                                // For legacy apps that need a permission review, every new
11407                                // runtime permission is granted but it is pending a review.
11408                                // We also need to review only platform defined runtime
11409                                // permissions as these are the only ones the platform knows
11410                                // how to disable the API to simulate revocation as legacy
11411                                // apps don't expect to run with revoked permissions.
11412                                if (PLATFORM_PACKAGE_NAME.equals(bp.sourcePackage)) {
11413                                    if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) {
11414                                        flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
11415                                        // We changed the flags, hence have to write.
11416                                        changedRuntimePermissionUserIds = ArrayUtils.appendInt(
11417                                                changedRuntimePermissionUserIds, userId);
11418                                    }
11419                                }
11420                                if (permissionsState.grantRuntimePermission(bp, userId)
11421                                        != PermissionsState.PERMISSION_OPERATION_FAILURE) {
11422                                    // We changed the permission, hence have to write.
11423                                    changedRuntimePermissionUserIds = ArrayUtils.appendInt(
11424                                            changedRuntimePermissionUserIds, userId);
11425                                }
11426                            }
11427                            // Propagate the permission flags.
11428                            permissionsState.updatePermissionFlags(bp, userId, flags, flags);
11429                        }
11430                    } break;
11431
11432                    case GRANT_UPGRADE: {
11433                        // Grant runtime permissions for a previously held install permission.
11434                        PermissionState permissionState = origPermissions
11435                                .getInstallPermissionState(bp.name);
11436                        final int flags = permissionState != null ? permissionState.getFlags() : 0;
11437
11438                        if (origPermissions.revokeInstallPermission(bp)
11439                                != PermissionsState.PERMISSION_OPERATION_FAILURE) {
11440                            // We will be transferring the permission flags, so clear them.
11441                            origPermissions.updatePermissionFlags(bp, UserHandle.USER_ALL,
11442                                    PackageManager.MASK_PERMISSION_FLAGS, 0);
11443                            changedInstallPermission = true;
11444                        }
11445
11446                        // If the permission is not to be promoted to runtime we ignore it and
11447                        // also its other flags as they are not applicable to install permissions.
11448                        if ((flags & PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE) == 0) {
11449                            for (int userId : currentUserIds) {
11450                                if (permissionsState.grantRuntimePermission(bp, userId) !=
11451                                        PermissionsState.PERMISSION_OPERATION_FAILURE) {
11452                                    // Transfer the permission flags.
11453                                    permissionsState.updatePermissionFlags(bp, userId,
11454                                            flags, flags);
11455                                    // If we granted the permission, we have to write.
11456                                    changedRuntimePermissionUserIds = ArrayUtils.appendInt(
11457                                            changedRuntimePermissionUserIds, userId);
11458                                }
11459                            }
11460                        }
11461                    } break;
11462
11463                    default: {
11464                        if (packageOfInterest == null
11465                                || packageOfInterest.equals(pkg.packageName)) {
11466                            Slog.w(TAG, "Not granting permission " + perm
11467                                    + " to package " + pkg.packageName
11468                                    + " because it was previously installed without");
11469                        }
11470                    } break;
11471                }
11472            } else {
11473                if (permissionsState.revokeInstallPermission(bp) !=
11474                        PermissionsState.PERMISSION_OPERATION_FAILURE) {
11475                    // Also drop the permission flags.
11476                    permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
11477                            PackageManager.MASK_PERMISSION_FLAGS, 0);
11478                    changedInstallPermission = true;
11479                    Slog.i(TAG, "Un-granting permission " + perm
11480                            + " from package " + pkg.packageName
11481                            + " (protectionLevel=" + bp.protectionLevel
11482                            + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
11483                            + ")");
11484                } else if ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) == 0) {
11485                    // Don't print warning for app op permissions, since it is fine for them
11486                    // not to be granted, there is a UI for the user to decide.
11487                    if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) {
11488                        Slog.w(TAG, "Not granting permission " + perm
11489                                + " to package " + pkg.packageName
11490                                + " (protectionLevel=" + bp.protectionLevel
11491                                + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
11492                                + ")");
11493                    }
11494                }
11495            }
11496        }
11497
11498        if ((changedInstallPermission || replace) && !ps.installPermissionsFixed &&
11499                !isSystemApp(ps) || isUpdatedSystemApp(ps)){
11500            // This is the first that we have heard about this package, so the
11501            // permissions we have now selected are fixed until explicitly
11502            // changed.
11503            ps.installPermissionsFixed = true;
11504        }
11505
11506        // Persist the runtime permissions state for users with changes. If permissions
11507        // were revoked because no app in the shared user declares them we have to
11508        // write synchronously to avoid losing runtime permissions state.
11509        for (int userId : changedRuntimePermissionUserIds) {
11510            mSettings.writeRuntimePermissionsForUserLPr(userId, runtimePermissionsRevoked);
11511        }
11512    }
11513
11514    private boolean isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg) {
11515        boolean allowed = false;
11516        final int NP = PackageParser.NEW_PERMISSIONS.length;
11517        for (int ip=0; ip<NP; ip++) {
11518            final PackageParser.NewPermissionInfo npi
11519                    = PackageParser.NEW_PERMISSIONS[ip];
11520            if (npi.name.equals(perm)
11521                    && pkg.applicationInfo.targetSdkVersion < npi.sdkVersion) {
11522                allowed = true;
11523                Log.i(TAG, "Auto-granting " + perm + " to old pkg "
11524                        + pkg.packageName);
11525                break;
11526            }
11527        }
11528        return allowed;
11529    }
11530
11531    private boolean grantSignaturePermission(String perm, PackageParser.Package pkg,
11532            BasePermission bp, PermissionsState origPermissions) {
11533        boolean privilegedPermission = (bp.protectionLevel
11534                & PermissionInfo.PROTECTION_FLAG_PRIVILEGED) != 0;
11535        boolean privappPermissionsDisable =
11536                RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_DISABLE;
11537        boolean platformPermission = PLATFORM_PACKAGE_NAME.equals(bp.sourcePackage);
11538        boolean platformPackage = PLATFORM_PACKAGE_NAME.equals(pkg.packageName);
11539        if (!privappPermissionsDisable && privilegedPermission && pkg.isPrivilegedApp()
11540                && !platformPackage && platformPermission) {
11541            ArraySet<String> wlPermissions = SystemConfig.getInstance()
11542                    .getPrivAppPermissions(pkg.packageName);
11543            boolean whitelisted = wlPermissions != null && wlPermissions.contains(perm);
11544            if (!whitelisted) {
11545                Slog.w(TAG, "Privileged permission " + perm + " for package "
11546                        + pkg.packageName + " - not in privapp-permissions whitelist");
11547                if (RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_ENFORCE) {
11548                    return false;
11549                }
11550            }
11551        }
11552        boolean allowed = (compareSignatures(
11553                bp.packageSetting.signatures.mSignatures, pkg.mSignatures)
11554                        == PackageManager.SIGNATURE_MATCH)
11555                || (compareSignatures(mPlatformPackage.mSignatures, pkg.mSignatures)
11556                        == PackageManager.SIGNATURE_MATCH);
11557        if (!allowed && privilegedPermission) {
11558            if (isSystemApp(pkg)) {
11559                // For updated system applications, a system permission
11560                // is granted only if it had been defined by the original application.
11561                if (pkg.isUpdatedSystemApp()) {
11562                    final PackageSetting sysPs = mSettings
11563                            .getDisabledSystemPkgLPr(pkg.packageName);
11564                    if (sysPs != null && sysPs.getPermissionsState().hasInstallPermission(perm)) {
11565                        // If the original was granted this permission, we take
11566                        // that grant decision as read and propagate it to the
11567                        // update.
11568                        if (sysPs.isPrivileged()) {
11569                            allowed = true;
11570                        }
11571                    } else {
11572                        // The system apk may have been updated with an older
11573                        // version of the one on the data partition, but which
11574                        // granted a new system permission that it didn't have
11575                        // before.  In this case we do want to allow the app to
11576                        // now get the new permission if the ancestral apk is
11577                        // privileged to get it.
11578                        if (sysPs != null && sysPs.pkg != null && sysPs.isPrivileged()) {
11579                            for (int j = 0; j < sysPs.pkg.requestedPermissions.size(); j++) {
11580                                if (perm.equals(sysPs.pkg.requestedPermissions.get(j))) {
11581                                    allowed = true;
11582                                    break;
11583                                }
11584                            }
11585                        }
11586                        // Also if a privileged parent package on the system image or any of
11587                        // its children requested a privileged permission, the updated child
11588                        // packages can also get the permission.
11589                        if (pkg.parentPackage != null) {
11590                            final PackageSetting disabledSysParentPs = mSettings
11591                                    .getDisabledSystemPkgLPr(pkg.parentPackage.packageName);
11592                            if (disabledSysParentPs != null && disabledSysParentPs.pkg != null
11593                                    && disabledSysParentPs.isPrivileged()) {
11594                                if (isPackageRequestingPermission(disabledSysParentPs.pkg, perm)) {
11595                                    allowed = true;
11596                                } else if (disabledSysParentPs.pkg.childPackages != null) {
11597                                    final int count = disabledSysParentPs.pkg.childPackages.size();
11598                                    for (int i = 0; i < count; i++) {
11599                                        PackageParser.Package disabledSysChildPkg =
11600                                                disabledSysParentPs.pkg.childPackages.get(i);
11601                                        if (isPackageRequestingPermission(disabledSysChildPkg,
11602                                                perm)) {
11603                                            allowed = true;
11604                                            break;
11605                                        }
11606                                    }
11607                                }
11608                            }
11609                        }
11610                    }
11611                } else {
11612                    allowed = isPrivilegedApp(pkg);
11613                }
11614            }
11615        }
11616        if (!allowed) {
11617            if (!allowed && (bp.protectionLevel
11618                    & PermissionInfo.PROTECTION_FLAG_PRE23) != 0
11619                    && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
11620                // If this was a previously normal/dangerous permission that got moved
11621                // to a system permission as part of the runtime permission redesign, then
11622                // we still want to blindly grant it to old apps.
11623                allowed = true;
11624            }
11625            if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_INSTALLER) != 0
11626                    && pkg.packageName.equals(mRequiredInstallerPackage)) {
11627                // If this permission is to be granted to the system installer and
11628                // this app is an installer, then it gets the permission.
11629                allowed = true;
11630            }
11631            if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_VERIFIER) != 0
11632                    && pkg.packageName.equals(mRequiredVerifierPackage)) {
11633                // If this permission is to be granted to the system verifier and
11634                // this app is a verifier, then it gets the permission.
11635                allowed = true;
11636            }
11637            if (!allowed && (bp.protectionLevel
11638                    & PermissionInfo.PROTECTION_FLAG_PREINSTALLED) != 0
11639                    && isSystemApp(pkg)) {
11640                // Any pre-installed system app is allowed to get this permission.
11641                allowed = true;
11642            }
11643            if (!allowed && (bp.protectionLevel
11644                    & PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0) {
11645                // For development permissions, a development permission
11646                // is granted only if it was already granted.
11647                allowed = origPermissions.hasInstallPermission(perm);
11648            }
11649            if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_SETUP) != 0
11650                    && pkg.packageName.equals(mSetupWizardPackage)) {
11651                // If this permission is to be granted to the system setup wizard and
11652                // this app is a setup wizard, then it gets the permission.
11653                allowed = true;
11654            }
11655        }
11656        return allowed;
11657    }
11658
11659    private boolean isPackageRequestingPermission(PackageParser.Package pkg, String permission) {
11660        final int permCount = pkg.requestedPermissions.size();
11661        for (int j = 0; j < permCount; j++) {
11662            String requestedPermission = pkg.requestedPermissions.get(j);
11663            if (permission.equals(requestedPermission)) {
11664                return true;
11665            }
11666        }
11667        return false;
11668    }
11669
11670    final class ActivityIntentResolver
11671            extends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo> {
11672        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
11673                boolean defaultOnly, boolean visibleToEphemeral, boolean isEphemeral, int userId) {
11674            if (!sUserManager.exists(userId)) return null;
11675            mFlags = (defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0)
11676                    | (visibleToEphemeral ? PackageManager.MATCH_VISIBLE_TO_EPHEMERAL_ONLY : 0)
11677                    | (isEphemeral ? PackageManager.MATCH_EPHEMERAL : 0);
11678            return super.queryIntent(intent, resolvedType, defaultOnly, visibleToEphemeral,
11679                    isEphemeral, userId);
11680        }
11681
11682        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
11683                int userId) {
11684            if (!sUserManager.exists(userId)) return null;
11685            mFlags = flags;
11686            return super.queryIntent(intent, resolvedType,
11687                    (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
11688                    (flags & PackageManager.MATCH_VISIBLE_TO_EPHEMERAL_ONLY) != 0,
11689                    (flags & PackageManager.MATCH_EPHEMERAL) != 0, userId);
11690        }
11691
11692        public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
11693                int flags, ArrayList<PackageParser.Activity> packageActivities, int userId) {
11694            if (!sUserManager.exists(userId)) return null;
11695            if (packageActivities == null) {
11696                return null;
11697            }
11698            mFlags = flags;
11699            final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0;
11700            final boolean vislbleToEphemeral =
11701                    (flags & PackageManager.MATCH_VISIBLE_TO_EPHEMERAL_ONLY) != 0;
11702            final boolean isEphemeral = (flags & PackageManager.MATCH_EPHEMERAL) != 0;
11703            final int N = packageActivities.size();
11704            ArrayList<PackageParser.ActivityIntentInfo[]> listCut =
11705                new ArrayList<PackageParser.ActivityIntentInfo[]>(N);
11706
11707            ArrayList<PackageParser.ActivityIntentInfo> intentFilters;
11708            for (int i = 0; i < N; ++i) {
11709                intentFilters = packageActivities.get(i).intents;
11710                if (intentFilters != null && intentFilters.size() > 0) {
11711                    PackageParser.ActivityIntentInfo[] array =
11712                            new PackageParser.ActivityIntentInfo[intentFilters.size()];
11713                    intentFilters.toArray(array);
11714                    listCut.add(array);
11715                }
11716            }
11717            return super.queryIntentFromList(intent, resolvedType, defaultOnly,
11718                    vislbleToEphemeral, isEphemeral, listCut, userId);
11719        }
11720
11721        /**
11722         * Finds a privileged activity that matches the specified activity names.
11723         */
11724        private PackageParser.Activity findMatchingActivity(
11725                List<PackageParser.Activity> activityList, ActivityInfo activityInfo) {
11726            for (PackageParser.Activity sysActivity : activityList) {
11727                if (sysActivity.info.name.equals(activityInfo.name)) {
11728                    return sysActivity;
11729                }
11730                if (sysActivity.info.name.equals(activityInfo.targetActivity)) {
11731                    return sysActivity;
11732                }
11733                if (sysActivity.info.targetActivity != null) {
11734                    if (sysActivity.info.targetActivity.equals(activityInfo.name)) {
11735                        return sysActivity;
11736                    }
11737                    if (sysActivity.info.targetActivity.equals(activityInfo.targetActivity)) {
11738                        return sysActivity;
11739                    }
11740                }
11741            }
11742            return null;
11743        }
11744
11745        public class IterGenerator<E> {
11746            public Iterator<E> generate(ActivityIntentInfo info) {
11747                return null;
11748            }
11749        }
11750
11751        public class ActionIterGenerator extends IterGenerator<String> {
11752            @Override
11753            public Iterator<String> generate(ActivityIntentInfo info) {
11754                return info.actionsIterator();
11755            }
11756        }
11757
11758        public class CategoriesIterGenerator extends IterGenerator<String> {
11759            @Override
11760            public Iterator<String> generate(ActivityIntentInfo info) {
11761                return info.categoriesIterator();
11762            }
11763        }
11764
11765        public class SchemesIterGenerator extends IterGenerator<String> {
11766            @Override
11767            public Iterator<String> generate(ActivityIntentInfo info) {
11768                return info.schemesIterator();
11769            }
11770        }
11771
11772        public class AuthoritiesIterGenerator extends IterGenerator<IntentFilter.AuthorityEntry> {
11773            @Override
11774            public Iterator<IntentFilter.AuthorityEntry> generate(ActivityIntentInfo info) {
11775                return info.authoritiesIterator();
11776            }
11777        }
11778
11779        /**
11780         * <em>WARNING</em> for performance reasons, the passed in intentList WILL BE
11781         * MODIFIED. Do not pass in a list that should not be changed.
11782         */
11783        private <T> void getIntentListSubset(List<ActivityIntentInfo> intentList,
11784                IterGenerator<T> generator, Iterator<T> searchIterator) {
11785            // loop through the set of actions; every one must be found in the intent filter
11786            while (searchIterator.hasNext()) {
11787                // we must have at least one filter in the list to consider a match
11788                if (intentList.size() == 0) {
11789                    break;
11790                }
11791
11792                final T searchAction = searchIterator.next();
11793
11794                // loop through the set of intent filters
11795                final Iterator<ActivityIntentInfo> intentIter = intentList.iterator();
11796                while (intentIter.hasNext()) {
11797                    final ActivityIntentInfo intentInfo = intentIter.next();
11798                    boolean selectionFound = false;
11799
11800                    // loop through the intent filter's selection criteria; at least one
11801                    // of them must match the searched criteria
11802                    final Iterator<T> intentSelectionIter = generator.generate(intentInfo);
11803                    while (intentSelectionIter != null && intentSelectionIter.hasNext()) {
11804                        final T intentSelection = intentSelectionIter.next();
11805                        if (intentSelection != null && intentSelection.equals(searchAction)) {
11806                            selectionFound = true;
11807                            break;
11808                        }
11809                    }
11810
11811                    // the selection criteria wasn't found in this filter's set; this filter
11812                    // is not a potential match
11813                    if (!selectionFound) {
11814                        intentIter.remove();
11815                    }
11816                }
11817            }
11818        }
11819
11820        private boolean isProtectedAction(ActivityIntentInfo filter) {
11821            final Iterator<String> actionsIter = filter.actionsIterator();
11822            while (actionsIter != null && actionsIter.hasNext()) {
11823                final String filterAction = actionsIter.next();
11824                if (PROTECTED_ACTIONS.contains(filterAction)) {
11825                    return true;
11826                }
11827            }
11828            return false;
11829        }
11830
11831        /**
11832         * Adjusts the priority of the given intent filter according to policy.
11833         * <p>
11834         * <ul>
11835         * <li>The priority for non privileged applications is capped to '0'</li>
11836         * <li>The priority for protected actions on privileged applications is capped to '0'</li>
11837         * <li>The priority for unbundled updates to privileged applications is capped to the
11838         *      priority defined on the system partition</li>
11839         * </ul>
11840         * <p>
11841         * <em>NOTE:</em> There is one exception. For security reasons, the setup wizard is
11842         * allowed to obtain any priority on any action.
11843         */
11844        private void adjustPriority(
11845                List<PackageParser.Activity> systemActivities, ActivityIntentInfo intent) {
11846            // nothing to do; priority is fine as-is
11847            if (intent.getPriority() <= 0) {
11848                return;
11849            }
11850
11851            final ActivityInfo activityInfo = intent.activity.info;
11852            final ApplicationInfo applicationInfo = activityInfo.applicationInfo;
11853
11854            final boolean privilegedApp =
11855                    ((applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0);
11856            if (!privilegedApp) {
11857                // non-privileged applications can never define a priority >0
11858                Slog.w(TAG, "Non-privileged app; cap priority to 0;"
11859                        + " package: " + applicationInfo.packageName
11860                        + " activity: " + intent.activity.className
11861                        + " origPrio: " + intent.getPriority());
11862                intent.setPriority(0);
11863                return;
11864            }
11865
11866            if (systemActivities == null) {
11867                // the system package is not disabled; we're parsing the system partition
11868                if (isProtectedAction(intent)) {
11869                    if (mDeferProtectedFilters) {
11870                        // We can't deal with these just yet. No component should ever obtain a
11871                        // >0 priority for a protected actions, with ONE exception -- the setup
11872                        // wizard. The setup wizard, however, cannot be known until we're able to
11873                        // query it for the category CATEGORY_SETUP_WIZARD. Which we can't do
11874                        // until all intent filters have been processed. Chicken, meet egg.
11875                        // Let the filter temporarily have a high priority and rectify the
11876                        // priorities after all system packages have been scanned.
11877                        mProtectedFilters.add(intent);
11878                        if (DEBUG_FILTERS) {
11879                            Slog.i(TAG, "Protected action; save for later;"
11880                                    + " package: " + applicationInfo.packageName
11881                                    + " activity: " + intent.activity.className
11882                                    + " origPrio: " + intent.getPriority());
11883                        }
11884                        return;
11885                    } else {
11886                        if (DEBUG_FILTERS && mSetupWizardPackage == null) {
11887                            Slog.i(TAG, "No setup wizard;"
11888                                + " All protected intents capped to priority 0");
11889                        }
11890                        if (intent.activity.info.packageName.equals(mSetupWizardPackage)) {
11891                            if (DEBUG_FILTERS) {
11892                                Slog.i(TAG, "Found setup wizard;"
11893                                    + " allow priority " + intent.getPriority() + ";"
11894                                    + " package: " + intent.activity.info.packageName
11895                                    + " activity: " + intent.activity.className
11896                                    + " priority: " + intent.getPriority());
11897                            }
11898                            // setup wizard gets whatever it wants
11899                            return;
11900                        }
11901                        Slog.w(TAG, "Protected action; cap priority to 0;"
11902                                + " package: " + intent.activity.info.packageName
11903                                + " activity: " + intent.activity.className
11904                                + " origPrio: " + intent.getPriority());
11905                        intent.setPriority(0);
11906                        return;
11907                    }
11908                }
11909                // privileged apps on the system image get whatever priority they request
11910                return;
11911            }
11912
11913            // privileged app unbundled update ... try to find the same activity
11914            final PackageParser.Activity foundActivity =
11915                    findMatchingActivity(systemActivities, activityInfo);
11916            if (foundActivity == null) {
11917                // this is a new activity; it cannot obtain >0 priority
11918                if (DEBUG_FILTERS) {
11919                    Slog.i(TAG, "New activity; cap priority to 0;"
11920                            + " package: " + applicationInfo.packageName
11921                            + " activity: " + intent.activity.className
11922                            + " origPrio: " + intent.getPriority());
11923                }
11924                intent.setPriority(0);
11925                return;
11926            }
11927
11928            // found activity, now check for filter equivalence
11929
11930            // a shallow copy is enough; we modify the list, not its contents
11931            final List<ActivityIntentInfo> intentListCopy =
11932                    new ArrayList<>(foundActivity.intents);
11933            final List<ActivityIntentInfo> foundFilters = findFilters(intent);
11934
11935            // find matching action subsets
11936            final Iterator<String> actionsIterator = intent.actionsIterator();
11937            if (actionsIterator != null) {
11938                getIntentListSubset(
11939                        intentListCopy, new ActionIterGenerator(), actionsIterator);
11940                if (intentListCopy.size() == 0) {
11941                    // no more intents to match; we're not equivalent
11942                    if (DEBUG_FILTERS) {
11943                        Slog.i(TAG, "Mismatched action; cap priority to 0;"
11944                                + " package: " + applicationInfo.packageName
11945                                + " activity: " + intent.activity.className
11946                                + " origPrio: " + intent.getPriority());
11947                    }
11948                    intent.setPriority(0);
11949                    return;
11950                }
11951            }
11952
11953            // find matching category subsets
11954            final Iterator<String> categoriesIterator = intent.categoriesIterator();
11955            if (categoriesIterator != null) {
11956                getIntentListSubset(intentListCopy, new CategoriesIterGenerator(),
11957                        categoriesIterator);
11958                if (intentListCopy.size() == 0) {
11959                    // no more intents to match; we're not equivalent
11960                    if (DEBUG_FILTERS) {
11961                        Slog.i(TAG, "Mismatched category; cap priority to 0;"
11962                                + " package: " + applicationInfo.packageName
11963                                + " activity: " + intent.activity.className
11964                                + " origPrio: " + intent.getPriority());
11965                    }
11966                    intent.setPriority(0);
11967                    return;
11968                }
11969            }
11970
11971            // find matching schemes subsets
11972            final Iterator<String> schemesIterator = intent.schemesIterator();
11973            if (schemesIterator != null) {
11974                getIntentListSubset(intentListCopy, new SchemesIterGenerator(),
11975                        schemesIterator);
11976                if (intentListCopy.size() == 0) {
11977                    // no more intents to match; we're not equivalent
11978                    if (DEBUG_FILTERS) {
11979                        Slog.i(TAG, "Mismatched scheme; cap priority to 0;"
11980                                + " package: " + applicationInfo.packageName
11981                                + " activity: " + intent.activity.className
11982                                + " origPrio: " + intent.getPriority());
11983                    }
11984                    intent.setPriority(0);
11985                    return;
11986                }
11987            }
11988
11989            // find matching authorities subsets
11990            final Iterator<IntentFilter.AuthorityEntry>
11991                    authoritiesIterator = intent.authoritiesIterator();
11992            if (authoritiesIterator != null) {
11993                getIntentListSubset(intentListCopy,
11994                        new AuthoritiesIterGenerator(),
11995                        authoritiesIterator);
11996                if (intentListCopy.size() == 0) {
11997                    // no more intents to match; we're not equivalent
11998                    if (DEBUG_FILTERS) {
11999                        Slog.i(TAG, "Mismatched authority; cap priority to 0;"
12000                                + " package: " + applicationInfo.packageName
12001                                + " activity: " + intent.activity.className
12002                                + " origPrio: " + intent.getPriority());
12003                    }
12004                    intent.setPriority(0);
12005                    return;
12006                }
12007            }
12008
12009            // we found matching filter(s); app gets the max priority of all intents
12010            int cappedPriority = 0;
12011            for (int i = intentListCopy.size() - 1; i >= 0; --i) {
12012                cappedPriority = Math.max(cappedPriority, intentListCopy.get(i).getPriority());
12013            }
12014            if (intent.getPriority() > cappedPriority) {
12015                if (DEBUG_FILTERS) {
12016                    Slog.i(TAG, "Found matching filter(s);"
12017                            + " cap priority to " + cappedPriority + ";"
12018                            + " package: " + applicationInfo.packageName
12019                            + " activity: " + intent.activity.className
12020                            + " origPrio: " + intent.getPriority());
12021                }
12022                intent.setPriority(cappedPriority);
12023                return;
12024            }
12025            // all this for nothing; the requested priority was <= what was on the system
12026        }
12027
12028        public final void addActivity(PackageParser.Activity a, String type) {
12029            mActivities.put(a.getComponentName(), a);
12030            if (DEBUG_SHOW_INFO)
12031                Log.v(
12032                TAG, "  " + type + " " +
12033                (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel : a.info.name) + ":");
12034            if (DEBUG_SHOW_INFO)
12035                Log.v(TAG, "    Class=" + a.info.name);
12036            final int NI = a.intents.size();
12037            for (int j=0; j<NI; j++) {
12038                PackageParser.ActivityIntentInfo intent = a.intents.get(j);
12039                if ("activity".equals(type)) {
12040                    final PackageSetting ps =
12041                            mSettings.getDisabledSystemPkgLPr(intent.activity.info.packageName);
12042                    final List<PackageParser.Activity> systemActivities =
12043                            ps != null && ps.pkg != null ? ps.pkg.activities : null;
12044                    adjustPriority(systemActivities, intent);
12045                }
12046                if (DEBUG_SHOW_INFO) {
12047                    Log.v(TAG, "    IntentFilter:");
12048                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
12049                }
12050                if (!intent.debugCheck()) {
12051                    Log.w(TAG, "==> For Activity " + a.info.name);
12052                }
12053                addFilter(intent);
12054            }
12055        }
12056
12057        public final void removeActivity(PackageParser.Activity a, String type) {
12058            mActivities.remove(a.getComponentName());
12059            if (DEBUG_SHOW_INFO) {
12060                Log.v(TAG, "  " + type + " "
12061                        + (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel
12062                                : a.info.name) + ":");
12063                Log.v(TAG, "    Class=" + a.info.name);
12064            }
12065            final int NI = a.intents.size();
12066            for (int j=0; j<NI; j++) {
12067                PackageParser.ActivityIntentInfo intent = a.intents.get(j);
12068                if (DEBUG_SHOW_INFO) {
12069                    Log.v(TAG, "    IntentFilter:");
12070                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
12071                }
12072                removeFilter(intent);
12073            }
12074        }
12075
12076        @Override
12077        protected boolean allowFilterResult(
12078                PackageParser.ActivityIntentInfo filter, List<ResolveInfo> dest) {
12079            ActivityInfo filterAi = filter.activity.info;
12080            for (int i=dest.size()-1; i>=0; i--) {
12081                ActivityInfo destAi = dest.get(i).activityInfo;
12082                if (destAi.name == filterAi.name
12083                        && destAi.packageName == filterAi.packageName) {
12084                    return false;
12085                }
12086            }
12087            return true;
12088        }
12089
12090        @Override
12091        protected ActivityIntentInfo[] newArray(int size) {
12092            return new ActivityIntentInfo[size];
12093        }
12094
12095        @Override
12096        protected boolean isFilterStopped(PackageParser.ActivityIntentInfo filter, int userId) {
12097            if (!sUserManager.exists(userId)) return true;
12098            PackageParser.Package p = filter.activity.owner;
12099            if (p != null) {
12100                PackageSetting ps = (PackageSetting)p.mExtras;
12101                if (ps != null) {
12102                    // System apps are never considered stopped for purposes of
12103                    // filtering, because there may be no way for the user to
12104                    // actually re-launch them.
12105                    return (ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0
12106                            && ps.getStopped(userId);
12107                }
12108            }
12109            return false;
12110        }
12111
12112        @Override
12113        protected boolean isPackageForFilter(String packageName,
12114                PackageParser.ActivityIntentInfo info) {
12115            return packageName.equals(info.activity.owner.packageName);
12116        }
12117
12118        @Override
12119        protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info,
12120                int match, int userId) {
12121            if (!sUserManager.exists(userId)) return null;
12122            if (!mSettings.isEnabledAndMatchLPr(info.activity.info, mFlags, userId)) {
12123                return null;
12124            }
12125            final PackageParser.Activity activity = info.activity;
12126            PackageSetting ps = (PackageSetting) activity.owner.mExtras;
12127            if (ps == null) {
12128                return null;
12129            }
12130            ActivityInfo ai = PackageParser.generateActivityInfo(activity, mFlags,
12131                    ps.readUserState(userId), userId);
12132            if (ai == null) {
12133                return null;
12134            }
12135            final ResolveInfo res = new ResolveInfo();
12136            res.activityInfo = ai;
12137            if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
12138                res.filter = info;
12139            }
12140            if (info != null) {
12141                res.handleAllWebDataURI = info.handleAllWebDataURI();
12142            }
12143            res.priority = info.getPriority();
12144            res.preferredOrder = activity.owner.mPreferredOrder;
12145            //System.out.println("Result: " + res.activityInfo.className +
12146            //                   " = " + res.priority);
12147            res.match = match;
12148            res.isDefault = info.hasDefault;
12149            res.labelRes = info.labelRes;
12150            res.nonLocalizedLabel = info.nonLocalizedLabel;
12151            if (userNeedsBadging(userId)) {
12152                res.noResourceId = true;
12153            } else {
12154                res.icon = info.icon;
12155            }
12156            res.iconResourceId = info.icon;
12157            res.system = res.activityInfo.applicationInfo.isSystemApp();
12158            return res;
12159        }
12160
12161        @Override
12162        protected void sortResults(List<ResolveInfo> results) {
12163            Collections.sort(results, mResolvePrioritySorter);
12164        }
12165
12166        @Override
12167        protected void dumpFilter(PrintWriter out, String prefix,
12168                PackageParser.ActivityIntentInfo filter) {
12169            out.print(prefix); out.print(
12170                    Integer.toHexString(System.identityHashCode(filter.activity)));
12171                    out.print(' ');
12172                    filter.activity.printComponentShortName(out);
12173                    out.print(" filter ");
12174                    out.println(Integer.toHexString(System.identityHashCode(filter)));
12175        }
12176
12177        @Override
12178        protected Object filterToLabel(PackageParser.ActivityIntentInfo filter) {
12179            return filter.activity;
12180        }
12181
12182        protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
12183            PackageParser.Activity activity = (PackageParser.Activity)label;
12184            out.print(prefix); out.print(
12185                    Integer.toHexString(System.identityHashCode(activity)));
12186                    out.print(' ');
12187                    activity.printComponentShortName(out);
12188            if (count > 1) {
12189                out.print(" ("); out.print(count); out.print(" filters)");
12190            }
12191            out.println();
12192        }
12193
12194        // Keys are String (activity class name), values are Activity.
12195        private final ArrayMap<ComponentName, PackageParser.Activity> mActivities
12196                = new ArrayMap<ComponentName, PackageParser.Activity>();
12197        private int mFlags;
12198    }
12199
12200    private final class ServiceIntentResolver
12201            extends IntentResolver<PackageParser.ServiceIntentInfo, ResolveInfo> {
12202        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
12203                boolean defaultOnly, boolean visibleToEphemeral, boolean isEphemeral, int userId) {
12204            mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
12205            return super.queryIntent(intent, resolvedType, defaultOnly, visibleToEphemeral,
12206                    isEphemeral, userId);
12207        }
12208
12209        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
12210                int userId) {
12211            if (!sUserManager.exists(userId)) return null;
12212            mFlags = flags;
12213            return super.queryIntent(intent, resolvedType,
12214                    (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
12215                    (flags & PackageManager.MATCH_VISIBLE_TO_EPHEMERAL_ONLY) != 0,
12216                    (flags & PackageManager.MATCH_EPHEMERAL) != 0, userId);
12217        }
12218
12219        public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
12220                int flags, ArrayList<PackageParser.Service> packageServices, int userId) {
12221            if (!sUserManager.exists(userId)) return null;
12222            if (packageServices == null) {
12223                return null;
12224            }
12225            mFlags = flags;
12226            final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0;
12227            final boolean vislbleToEphemeral =
12228                    (flags&PackageManager.MATCH_VISIBLE_TO_EPHEMERAL_ONLY) != 0;
12229            final boolean isEphemeral = (flags&PackageManager.MATCH_EPHEMERAL) != 0;
12230            final int N = packageServices.size();
12231            ArrayList<PackageParser.ServiceIntentInfo[]> listCut =
12232                new ArrayList<PackageParser.ServiceIntentInfo[]>(N);
12233
12234            ArrayList<PackageParser.ServiceIntentInfo> intentFilters;
12235            for (int i = 0; i < N; ++i) {
12236                intentFilters = packageServices.get(i).intents;
12237                if (intentFilters != null && intentFilters.size() > 0) {
12238                    PackageParser.ServiceIntentInfo[] array =
12239                            new PackageParser.ServiceIntentInfo[intentFilters.size()];
12240                    intentFilters.toArray(array);
12241                    listCut.add(array);
12242                }
12243            }
12244            return super.queryIntentFromList(intent, resolvedType, defaultOnly,
12245                    vislbleToEphemeral, isEphemeral, listCut, userId);
12246        }
12247
12248        public final void addService(PackageParser.Service s) {
12249            mServices.put(s.getComponentName(), s);
12250            if (DEBUG_SHOW_INFO) {
12251                Log.v(TAG, "  "
12252                        + (s.info.nonLocalizedLabel != null
12253                        ? s.info.nonLocalizedLabel : s.info.name) + ":");
12254                Log.v(TAG, "    Class=" + s.info.name);
12255            }
12256            final int NI = s.intents.size();
12257            int j;
12258            for (j=0; j<NI; j++) {
12259                PackageParser.ServiceIntentInfo intent = s.intents.get(j);
12260                if (DEBUG_SHOW_INFO) {
12261                    Log.v(TAG, "    IntentFilter:");
12262                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
12263                }
12264                if (!intent.debugCheck()) {
12265                    Log.w(TAG, "==> For Service " + s.info.name);
12266                }
12267                addFilter(intent);
12268            }
12269        }
12270
12271        public final void removeService(PackageParser.Service s) {
12272            mServices.remove(s.getComponentName());
12273            if (DEBUG_SHOW_INFO) {
12274                Log.v(TAG, "  " + (s.info.nonLocalizedLabel != null
12275                        ? s.info.nonLocalizedLabel : s.info.name) + ":");
12276                Log.v(TAG, "    Class=" + s.info.name);
12277            }
12278            final int NI = s.intents.size();
12279            int j;
12280            for (j=0; j<NI; j++) {
12281                PackageParser.ServiceIntentInfo intent = s.intents.get(j);
12282                if (DEBUG_SHOW_INFO) {
12283                    Log.v(TAG, "    IntentFilter:");
12284                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
12285                }
12286                removeFilter(intent);
12287            }
12288        }
12289
12290        @Override
12291        protected boolean allowFilterResult(
12292                PackageParser.ServiceIntentInfo filter, List<ResolveInfo> dest) {
12293            ServiceInfo filterSi = filter.service.info;
12294            for (int i=dest.size()-1; i>=0; i--) {
12295                ServiceInfo destAi = dest.get(i).serviceInfo;
12296                if (destAi.name == filterSi.name
12297                        && destAi.packageName == filterSi.packageName) {
12298                    return false;
12299                }
12300            }
12301            return true;
12302        }
12303
12304        @Override
12305        protected PackageParser.ServiceIntentInfo[] newArray(int size) {
12306            return new PackageParser.ServiceIntentInfo[size];
12307        }
12308
12309        @Override
12310        protected boolean isFilterStopped(PackageParser.ServiceIntentInfo filter, int userId) {
12311            if (!sUserManager.exists(userId)) return true;
12312            PackageParser.Package p = filter.service.owner;
12313            if (p != null) {
12314                PackageSetting ps = (PackageSetting)p.mExtras;
12315                if (ps != null) {
12316                    // System apps are never considered stopped for purposes of
12317                    // filtering, because there may be no way for the user to
12318                    // actually re-launch them.
12319                    return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
12320                            && ps.getStopped(userId);
12321                }
12322            }
12323            return false;
12324        }
12325
12326        @Override
12327        protected boolean isPackageForFilter(String packageName,
12328                PackageParser.ServiceIntentInfo info) {
12329            return packageName.equals(info.service.owner.packageName);
12330        }
12331
12332        @Override
12333        protected ResolveInfo newResult(PackageParser.ServiceIntentInfo filter,
12334                int match, int userId) {
12335            if (!sUserManager.exists(userId)) return null;
12336            final PackageParser.ServiceIntentInfo info = (PackageParser.ServiceIntentInfo)filter;
12337            if (!mSettings.isEnabledAndMatchLPr(info.service.info, mFlags, userId)) {
12338                return null;
12339            }
12340            final PackageParser.Service service = info.service;
12341            PackageSetting ps = (PackageSetting) service.owner.mExtras;
12342            if (ps == null) {
12343                return null;
12344            }
12345            ServiceInfo si = PackageParser.generateServiceInfo(service, mFlags,
12346                    ps.readUserState(userId), userId);
12347            if (si == null) {
12348                return null;
12349            }
12350            final ResolveInfo res = new ResolveInfo();
12351            res.serviceInfo = si;
12352            if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
12353                res.filter = filter;
12354            }
12355            res.priority = info.getPriority();
12356            res.preferredOrder = service.owner.mPreferredOrder;
12357            res.match = match;
12358            res.isDefault = info.hasDefault;
12359            res.labelRes = info.labelRes;
12360            res.nonLocalizedLabel = info.nonLocalizedLabel;
12361            res.icon = info.icon;
12362            res.system = res.serviceInfo.applicationInfo.isSystemApp();
12363            return res;
12364        }
12365
12366        @Override
12367        protected void sortResults(List<ResolveInfo> results) {
12368            Collections.sort(results, mResolvePrioritySorter);
12369        }
12370
12371        @Override
12372        protected void dumpFilter(PrintWriter out, String prefix,
12373                PackageParser.ServiceIntentInfo filter) {
12374            out.print(prefix); out.print(
12375                    Integer.toHexString(System.identityHashCode(filter.service)));
12376                    out.print(' ');
12377                    filter.service.printComponentShortName(out);
12378                    out.print(" filter ");
12379                    out.println(Integer.toHexString(System.identityHashCode(filter)));
12380        }
12381
12382        @Override
12383        protected Object filterToLabel(PackageParser.ServiceIntentInfo filter) {
12384            return filter.service;
12385        }
12386
12387        protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
12388            PackageParser.Service service = (PackageParser.Service)label;
12389            out.print(prefix); out.print(
12390                    Integer.toHexString(System.identityHashCode(service)));
12391                    out.print(' ');
12392                    service.printComponentShortName(out);
12393            if (count > 1) {
12394                out.print(" ("); out.print(count); out.print(" filters)");
12395            }
12396            out.println();
12397        }
12398
12399//        List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) {
12400//            final Iterator<ResolveInfo> i = resolveInfoList.iterator();
12401//            final List<ResolveInfo> retList = Lists.newArrayList();
12402//            while (i.hasNext()) {
12403//                final ResolveInfo resolveInfo = (ResolveInfo) i;
12404//                if (isEnabledLP(resolveInfo.serviceInfo)) {
12405//                    retList.add(resolveInfo);
12406//                }
12407//            }
12408//            return retList;
12409//        }
12410
12411        // Keys are String (activity class name), values are Activity.
12412        private final ArrayMap<ComponentName, PackageParser.Service> mServices
12413                = new ArrayMap<ComponentName, PackageParser.Service>();
12414        private int mFlags;
12415    }
12416
12417    private final class ProviderIntentResolver
12418            extends IntentResolver<PackageParser.ProviderIntentInfo, ResolveInfo> {
12419        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
12420                boolean defaultOnly, boolean visibleToEphemeral, boolean isEphemeral, int userId) {
12421            mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
12422            return super.queryIntent(intent, resolvedType, defaultOnly, visibleToEphemeral,
12423                    isEphemeral, userId);
12424        }
12425
12426        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
12427                int userId) {
12428            if (!sUserManager.exists(userId))
12429                return null;
12430            mFlags = flags;
12431            return super.queryIntent(intent, resolvedType,
12432                    (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
12433                    (flags & PackageManager.MATCH_VISIBLE_TO_EPHEMERAL_ONLY) != 0,
12434                    (flags & PackageManager.MATCH_EPHEMERAL) != 0, userId);
12435        }
12436
12437        public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
12438                int flags, ArrayList<PackageParser.Provider> packageProviders, int userId) {
12439            if (!sUserManager.exists(userId))
12440                return null;
12441            if (packageProviders == null) {
12442                return null;
12443            }
12444            mFlags = flags;
12445            final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0;
12446            final boolean isEphemeral = (flags&PackageManager.MATCH_EPHEMERAL) != 0;
12447            final boolean vislbleToEphemeral =
12448                    (flags&PackageManager.MATCH_VISIBLE_TO_EPHEMERAL_ONLY) != 0;
12449            final int N = packageProviders.size();
12450            ArrayList<PackageParser.ProviderIntentInfo[]> listCut =
12451                    new ArrayList<PackageParser.ProviderIntentInfo[]>(N);
12452
12453            ArrayList<PackageParser.ProviderIntentInfo> intentFilters;
12454            for (int i = 0; i < N; ++i) {
12455                intentFilters = packageProviders.get(i).intents;
12456                if (intentFilters != null && intentFilters.size() > 0) {
12457                    PackageParser.ProviderIntentInfo[] array =
12458                            new PackageParser.ProviderIntentInfo[intentFilters.size()];
12459                    intentFilters.toArray(array);
12460                    listCut.add(array);
12461                }
12462            }
12463            return super.queryIntentFromList(intent, resolvedType, defaultOnly,
12464                    vislbleToEphemeral, isEphemeral, listCut, userId);
12465        }
12466
12467        public final void addProvider(PackageParser.Provider p) {
12468            if (mProviders.containsKey(p.getComponentName())) {
12469                Slog.w(TAG, "Provider " + p.getComponentName() + " already defined; ignoring");
12470                return;
12471            }
12472
12473            mProviders.put(p.getComponentName(), p);
12474            if (DEBUG_SHOW_INFO) {
12475                Log.v(TAG, "  "
12476                        + (p.info.nonLocalizedLabel != null
12477                                ? p.info.nonLocalizedLabel : p.info.name) + ":");
12478                Log.v(TAG, "    Class=" + p.info.name);
12479            }
12480            final int NI = p.intents.size();
12481            int j;
12482            for (j = 0; j < NI; j++) {
12483                PackageParser.ProviderIntentInfo intent = p.intents.get(j);
12484                if (DEBUG_SHOW_INFO) {
12485                    Log.v(TAG, "    IntentFilter:");
12486                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
12487                }
12488                if (!intent.debugCheck()) {
12489                    Log.w(TAG, "==> For Provider " + p.info.name);
12490                }
12491                addFilter(intent);
12492            }
12493        }
12494
12495        public final void removeProvider(PackageParser.Provider p) {
12496            mProviders.remove(p.getComponentName());
12497            if (DEBUG_SHOW_INFO) {
12498                Log.v(TAG, "  " + (p.info.nonLocalizedLabel != null
12499                        ? p.info.nonLocalizedLabel : p.info.name) + ":");
12500                Log.v(TAG, "    Class=" + p.info.name);
12501            }
12502            final int NI = p.intents.size();
12503            int j;
12504            for (j = 0; j < NI; j++) {
12505                PackageParser.ProviderIntentInfo intent = p.intents.get(j);
12506                if (DEBUG_SHOW_INFO) {
12507                    Log.v(TAG, "    IntentFilter:");
12508                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
12509                }
12510                removeFilter(intent);
12511            }
12512        }
12513
12514        @Override
12515        protected boolean allowFilterResult(
12516                PackageParser.ProviderIntentInfo filter, List<ResolveInfo> dest) {
12517            ProviderInfo filterPi = filter.provider.info;
12518            for (int i = dest.size() - 1; i >= 0; i--) {
12519                ProviderInfo destPi = dest.get(i).providerInfo;
12520                if (destPi.name == filterPi.name
12521                        && destPi.packageName == filterPi.packageName) {
12522                    return false;
12523                }
12524            }
12525            return true;
12526        }
12527
12528        @Override
12529        protected PackageParser.ProviderIntentInfo[] newArray(int size) {
12530            return new PackageParser.ProviderIntentInfo[size];
12531        }
12532
12533        @Override
12534        protected boolean isFilterStopped(PackageParser.ProviderIntentInfo filter, int userId) {
12535            if (!sUserManager.exists(userId))
12536                return true;
12537            PackageParser.Package p = filter.provider.owner;
12538            if (p != null) {
12539                PackageSetting ps = (PackageSetting) p.mExtras;
12540                if (ps != null) {
12541                    // System apps are never considered stopped for purposes of
12542                    // filtering, because there may be no way for the user to
12543                    // actually re-launch them.
12544                    return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
12545                            && ps.getStopped(userId);
12546                }
12547            }
12548            return false;
12549        }
12550
12551        @Override
12552        protected boolean isPackageForFilter(String packageName,
12553                PackageParser.ProviderIntentInfo info) {
12554            return packageName.equals(info.provider.owner.packageName);
12555        }
12556
12557        @Override
12558        protected ResolveInfo newResult(PackageParser.ProviderIntentInfo filter,
12559                int match, int userId) {
12560            if (!sUserManager.exists(userId))
12561                return null;
12562            final PackageParser.ProviderIntentInfo info = filter;
12563            if (!mSettings.isEnabledAndMatchLPr(info.provider.info, mFlags, userId)) {
12564                return null;
12565            }
12566            final PackageParser.Provider provider = info.provider;
12567            PackageSetting ps = (PackageSetting) provider.owner.mExtras;
12568            if (ps == null) {
12569                return null;
12570            }
12571            ProviderInfo pi = PackageParser.generateProviderInfo(provider, mFlags,
12572                    ps.readUserState(userId), userId);
12573            if (pi == null) {
12574                return null;
12575            }
12576            final ResolveInfo res = new ResolveInfo();
12577            res.providerInfo = pi;
12578            if ((mFlags & PackageManager.GET_RESOLVED_FILTER) != 0) {
12579                res.filter = filter;
12580            }
12581            res.priority = info.getPriority();
12582            res.preferredOrder = provider.owner.mPreferredOrder;
12583            res.match = match;
12584            res.isDefault = info.hasDefault;
12585            res.labelRes = info.labelRes;
12586            res.nonLocalizedLabel = info.nonLocalizedLabel;
12587            res.icon = info.icon;
12588            res.system = res.providerInfo.applicationInfo.isSystemApp();
12589            return res;
12590        }
12591
12592        @Override
12593        protected void sortResults(List<ResolveInfo> results) {
12594            Collections.sort(results, mResolvePrioritySorter);
12595        }
12596
12597        @Override
12598        protected void dumpFilter(PrintWriter out, String prefix,
12599                PackageParser.ProviderIntentInfo filter) {
12600            out.print(prefix);
12601            out.print(
12602                    Integer.toHexString(System.identityHashCode(filter.provider)));
12603            out.print(' ');
12604            filter.provider.printComponentShortName(out);
12605            out.print(" filter ");
12606            out.println(Integer.toHexString(System.identityHashCode(filter)));
12607        }
12608
12609        @Override
12610        protected Object filterToLabel(PackageParser.ProviderIntentInfo filter) {
12611            return filter.provider;
12612        }
12613
12614        protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
12615            PackageParser.Provider provider = (PackageParser.Provider)label;
12616            out.print(prefix); out.print(
12617                    Integer.toHexString(System.identityHashCode(provider)));
12618                    out.print(' ');
12619                    provider.printComponentShortName(out);
12620            if (count > 1) {
12621                out.print(" ("); out.print(count); out.print(" filters)");
12622            }
12623            out.println();
12624        }
12625
12626        private final ArrayMap<ComponentName, PackageParser.Provider> mProviders
12627                = new ArrayMap<ComponentName, PackageParser.Provider>();
12628        private int mFlags;
12629    }
12630
12631    static final class EphemeralIntentResolver
12632            extends IntentResolver<EphemeralResponse, EphemeralResponse> {
12633        /**
12634         * The result that has the highest defined order. Ordering applies on a
12635         * per-package basis. Mapping is from package name to Pair of order and
12636         * EphemeralResolveInfo.
12637         * <p>
12638         * NOTE: This is implemented as a field variable for convenience and efficiency.
12639         * By having a field variable, we're able to track filter ordering as soon as
12640         * a non-zero order is defined. Otherwise, multiple loops across the result set
12641         * would be needed to apply ordering. If the intent resolver becomes re-entrant,
12642         * this needs to be contained entirely within {@link #filterResults()}.
12643         */
12644        final ArrayMap<String, Pair<Integer, EphemeralResolveInfo>> mOrderResult = new ArrayMap<>();
12645
12646        @Override
12647        protected EphemeralResponse[] newArray(int size) {
12648            return new EphemeralResponse[size];
12649        }
12650
12651        @Override
12652        protected boolean isPackageForFilter(String packageName, EphemeralResponse responseObj) {
12653            return true;
12654        }
12655
12656        @Override
12657        protected EphemeralResponse newResult(EphemeralResponse responseObj, int match,
12658                int userId) {
12659            if (!sUserManager.exists(userId)) {
12660                return null;
12661            }
12662            final String packageName = responseObj.resolveInfo.getPackageName();
12663            final Integer order = responseObj.getOrder();
12664            final Pair<Integer, EphemeralResolveInfo> lastOrderResult =
12665                    mOrderResult.get(packageName);
12666            // ordering is enabled and this item's order isn't high enough
12667            if (lastOrderResult != null && lastOrderResult.first >= order) {
12668                return null;
12669            }
12670            final EphemeralResolveInfo res = responseObj.resolveInfo;
12671            if (order > 0) {
12672                // non-zero order, enable ordering
12673                mOrderResult.put(packageName, new Pair<>(order, res));
12674            }
12675            return responseObj;
12676        }
12677
12678        @Override
12679        protected void filterResults(List<EphemeralResponse> results) {
12680            // only do work if ordering is enabled [most of the time it won't be]
12681            if (mOrderResult.size() == 0) {
12682                return;
12683            }
12684            int resultSize = results.size();
12685            for (int i = 0; i < resultSize; i++) {
12686                final EphemeralResolveInfo info = results.get(i).resolveInfo;
12687                final String packageName = info.getPackageName();
12688                final Pair<Integer, EphemeralResolveInfo> savedInfo = mOrderResult.get(packageName);
12689                if (savedInfo == null) {
12690                    // package doesn't having ordering
12691                    continue;
12692                }
12693                if (savedInfo.second == info) {
12694                    // circled back to the highest ordered item; remove from order list
12695                    mOrderResult.remove(savedInfo);
12696                    if (mOrderResult.size() == 0) {
12697                        // no more ordered items
12698                        break;
12699                    }
12700                    continue;
12701                }
12702                // item has a worse order, remove it from the result list
12703                results.remove(i);
12704                resultSize--;
12705                i--;
12706            }
12707        }
12708    }
12709
12710    private static final Comparator<ResolveInfo> mResolvePrioritySorter =
12711            new Comparator<ResolveInfo>() {
12712        public int compare(ResolveInfo r1, ResolveInfo r2) {
12713            int v1 = r1.priority;
12714            int v2 = r2.priority;
12715            //System.out.println("Comparing: q1=" + q1 + " q2=" + q2);
12716            if (v1 != v2) {
12717                return (v1 > v2) ? -1 : 1;
12718            }
12719            v1 = r1.preferredOrder;
12720            v2 = r2.preferredOrder;
12721            if (v1 != v2) {
12722                return (v1 > v2) ? -1 : 1;
12723            }
12724            if (r1.isDefault != r2.isDefault) {
12725                return r1.isDefault ? -1 : 1;
12726            }
12727            v1 = r1.match;
12728            v2 = r2.match;
12729            //System.out.println("Comparing: m1=" + m1 + " m2=" + m2);
12730            if (v1 != v2) {
12731                return (v1 > v2) ? -1 : 1;
12732            }
12733            if (r1.system != r2.system) {
12734                return r1.system ? -1 : 1;
12735            }
12736            if (r1.activityInfo != null) {
12737                return r1.activityInfo.packageName.compareTo(r2.activityInfo.packageName);
12738            }
12739            if (r1.serviceInfo != null) {
12740                return r1.serviceInfo.packageName.compareTo(r2.serviceInfo.packageName);
12741            }
12742            if (r1.providerInfo != null) {
12743                return r1.providerInfo.packageName.compareTo(r2.providerInfo.packageName);
12744            }
12745            return 0;
12746        }
12747    };
12748
12749    private static final Comparator<ProviderInfo> mProviderInitOrderSorter =
12750            new Comparator<ProviderInfo>() {
12751        public int compare(ProviderInfo p1, ProviderInfo p2) {
12752            final int v1 = p1.initOrder;
12753            final int v2 = p2.initOrder;
12754            return (v1 > v2) ? -1 : ((v1 < v2) ? 1 : 0);
12755        }
12756    };
12757
12758    final void sendPackageBroadcast(final String action, final String pkg, final Bundle extras,
12759            final int flags, final String targetPkg, final IIntentReceiver finishedReceiver,
12760            final int[] userIds) {
12761        mHandler.post(new Runnable() {
12762            @Override
12763            public void run() {
12764                try {
12765                    final IActivityManager am = ActivityManager.getService();
12766                    if (am == null) return;
12767                    final int[] resolvedUserIds;
12768                    if (userIds == null) {
12769                        resolvedUserIds = am.getRunningUserIds();
12770                    } else {
12771                        resolvedUserIds = userIds;
12772                    }
12773                    for (int id : resolvedUserIds) {
12774                        final Intent intent = new Intent(action,
12775                                pkg != null ? Uri.fromParts(PACKAGE_SCHEME, pkg, null) : null);
12776                        if (extras != null) {
12777                            intent.putExtras(extras);
12778                        }
12779                        if (targetPkg != null) {
12780                            intent.setPackage(targetPkg);
12781                        }
12782                        // Modify the UID when posting to other users
12783                        int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
12784                        if (uid > 0 && UserHandle.getUserId(uid) != id) {
12785                            uid = UserHandle.getUid(id, UserHandle.getAppId(uid));
12786                            intent.putExtra(Intent.EXTRA_UID, uid);
12787                        }
12788                        intent.putExtra(Intent.EXTRA_USER_HANDLE, id);
12789                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT | flags);
12790                        if (DEBUG_BROADCASTS) {
12791                            RuntimeException here = new RuntimeException("here");
12792                            here.fillInStackTrace();
12793                            Slog.d(TAG, "Sending to user " + id + ": "
12794                                    + intent.toShortString(false, true, false, false)
12795                                    + " " + intent.getExtras(), here);
12796                        }
12797                        am.broadcastIntent(null, intent, null, finishedReceiver,
12798                                0, null, null, null, android.app.AppOpsManager.OP_NONE,
12799                                null, finishedReceiver != null, false, id);
12800                    }
12801                } catch (RemoteException ex) {
12802                }
12803            }
12804        });
12805    }
12806
12807    /**
12808     * Check if the external storage media is available. This is true if there
12809     * is a mounted external storage medium or if the external storage is
12810     * emulated.
12811     */
12812    private boolean isExternalMediaAvailable() {
12813        return mMediaMounted || Environment.isExternalStorageEmulated();
12814    }
12815
12816    @Override
12817    public PackageCleanItem nextPackageToClean(PackageCleanItem lastPackage) {
12818        // writer
12819        synchronized (mPackages) {
12820            if (!isExternalMediaAvailable()) {
12821                // If the external storage is no longer mounted at this point,
12822                // the caller may not have been able to delete all of this
12823                // packages files and can not delete any more.  Bail.
12824                return null;
12825            }
12826            final ArrayList<PackageCleanItem> pkgs = mSettings.mPackagesToBeCleaned;
12827            if (lastPackage != null) {
12828                pkgs.remove(lastPackage);
12829            }
12830            if (pkgs.size() > 0) {
12831                return pkgs.get(0);
12832            }
12833        }
12834        return null;
12835    }
12836
12837    void schedulePackageCleaning(String packageName, int userId, boolean andCode) {
12838        final Message msg = mHandler.obtainMessage(START_CLEANING_PACKAGE,
12839                userId, andCode ? 1 : 0, packageName);
12840        if (mSystemReady) {
12841            msg.sendToTarget();
12842        } else {
12843            if (mPostSystemReadyMessages == null) {
12844                mPostSystemReadyMessages = new ArrayList<>();
12845            }
12846            mPostSystemReadyMessages.add(msg);
12847        }
12848    }
12849
12850    void startCleaningPackages() {
12851        // reader
12852        if (!isExternalMediaAvailable()) {
12853            return;
12854        }
12855        synchronized (mPackages) {
12856            if (mSettings.mPackagesToBeCleaned.isEmpty()) {
12857                return;
12858            }
12859        }
12860        Intent intent = new Intent(PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE);
12861        intent.setComponent(DEFAULT_CONTAINER_COMPONENT);
12862        IActivityManager am = ActivityManager.getService();
12863        if (am != null) {
12864            try {
12865                am.startService(null, intent, null, -1, null, mContext.getOpPackageName(),
12866                        UserHandle.USER_SYSTEM);
12867            } catch (RemoteException e) {
12868            }
12869        }
12870    }
12871
12872    @Override
12873    public void installPackageAsUser(String originPath, IPackageInstallObserver2 observer,
12874            int installFlags, String installerPackageName, int userId) {
12875        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null);
12876
12877        final int callingUid = Binder.getCallingUid();
12878        enforceCrossUserPermission(callingUid, userId,
12879                true /* requireFullPermission */, true /* checkShell */, "installPackageAsUser");
12880
12881        if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
12882            try {
12883                if (observer != null) {
12884                    observer.onPackageInstalled("", INSTALL_FAILED_USER_RESTRICTED, null, null);
12885                }
12886            } catch (RemoteException re) {
12887            }
12888            return;
12889        }
12890
12891        if ((callingUid == Process.SHELL_UID) || (callingUid == Process.ROOT_UID)) {
12892            installFlags |= PackageManager.INSTALL_FROM_ADB;
12893
12894        } else {
12895            // Caller holds INSTALL_PACKAGES permission, so we're less strict
12896            // about installerPackageName.
12897
12898            installFlags &= ~PackageManager.INSTALL_FROM_ADB;
12899            installFlags &= ~PackageManager.INSTALL_ALL_USERS;
12900        }
12901
12902        UserHandle user;
12903        if ((installFlags & PackageManager.INSTALL_ALL_USERS) != 0) {
12904            user = UserHandle.ALL;
12905        } else {
12906            user = new UserHandle(userId);
12907        }
12908
12909        // Only system components can circumvent runtime permissions when installing.
12910        if ((installFlags & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0
12911                && mContext.checkCallingOrSelfPermission(Manifest.permission
12912                .INSTALL_GRANT_RUNTIME_PERMISSIONS) == PackageManager.PERMISSION_DENIED) {
12913            throw new SecurityException("You need the "
12914                    + "android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS permission "
12915                    + "to use the PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS flag");
12916        }
12917
12918        final File originFile = new File(originPath);
12919        final OriginInfo origin = OriginInfo.fromUntrustedFile(originFile);
12920
12921        final Message msg = mHandler.obtainMessage(INIT_COPY);
12922        final VerificationInfo verificationInfo = new VerificationInfo(
12923                null /*originatingUri*/, null /*referrer*/, -1 /*originatingUid*/, callingUid);
12924        final InstallParams params = new InstallParams(origin, null /*moveInfo*/, observer,
12925                installFlags, installerPackageName, null /*volumeUuid*/, verificationInfo, user,
12926                null /*packageAbiOverride*/, null /*grantedPermissions*/,
12927                null /*certificates*/, PackageManager.INSTALL_REASON_UNKNOWN);
12928        params.setTraceMethod("installAsUser").setTraceCookie(System.identityHashCode(params));
12929        msg.obj = params;
12930
12931        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installAsUser",
12932                System.identityHashCode(msg.obj));
12933        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
12934                System.identityHashCode(msg.obj));
12935
12936        mHandler.sendMessage(msg);
12937    }
12938
12939
12940    /**
12941     * Ensure that the install reason matches what we know about the package installer (e.g. whether
12942     * it is acting on behalf on an enterprise or the user).
12943     *
12944     * Note that the ordering of the conditionals in this method is important. The checks we perform
12945     * are as follows, in this order:
12946     *
12947     * 1) If the install is being performed by a system app, we can trust the app to have set the
12948     *    install reason correctly. Thus, we pass through the install reason unchanged, no matter
12949     *    what it is.
12950     * 2) If the install is being performed by a device or profile owner app, the install reason
12951     *    should be enterprise policy. However, we cannot be sure that the device or profile owner
12952     *    set the install reason correctly. If the app targets an older SDK version where install
12953     *    reasons did not exist yet, or if the app author simply forgot, the install reason may be
12954     *    unset or wrong. Thus, we force the install reason to be enterprise policy.
12955     * 3) In all other cases, the install is being performed by a regular app that is neither part
12956     *    of the system nor a device or profile owner. We have no reason to believe that this app is
12957     *    acting on behalf of the enterprise admin. Thus, we check whether the install reason was
12958     *    set to enterprise policy and if so, change it to unknown instead.
12959     */
12960    private int fixUpInstallReason(String installerPackageName, int installerUid,
12961            int installReason) {
12962        if (checkUidPermission(android.Manifest.permission.INSTALL_PACKAGES, installerUid)
12963                == PERMISSION_GRANTED) {
12964            // If the install is being performed by a system app, we trust that app to have set the
12965            // install reason correctly.
12966            return installReason;
12967        }
12968
12969        final IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
12970            ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
12971        if (dpm != null) {
12972            ComponentName owner = null;
12973            try {
12974                owner = dpm.getDeviceOwnerComponent(true /* callingUserOnly */);
12975                if (owner == null) {
12976                    owner = dpm.getProfileOwner(UserHandle.getUserId(installerUid));
12977                }
12978            } catch (RemoteException e) {
12979            }
12980            if (owner != null && owner.getPackageName().equals(installerPackageName)) {
12981                // If the install is being performed by a device or profile owner, the install
12982                // reason should be enterprise policy.
12983                return PackageManager.INSTALL_REASON_POLICY;
12984            }
12985        }
12986
12987        if (installReason == PackageManager.INSTALL_REASON_POLICY) {
12988            // If the install is being performed by a regular app (i.e. neither system app nor
12989            // device or profile owner), we have no reason to believe that the app is acting on
12990            // behalf of an enterprise. If the app set the install reason to enterprise policy,
12991            // change it to unknown instead.
12992            return PackageManager.INSTALL_REASON_UNKNOWN;
12993        }
12994
12995        // If the install is being performed by a regular app and the install reason was set to any
12996        // value but enterprise policy, leave the install reason unchanged.
12997        return installReason;
12998    }
12999
13000    void installStage(String packageName, File stagedDir, String stagedCid,
13001            IPackageInstallObserver2 observer, PackageInstaller.SessionParams sessionParams,
13002            String installerPackageName, int installerUid, UserHandle user,
13003            Certificate[][] certificates) {
13004        if (DEBUG_EPHEMERAL) {
13005            if ((sessionParams.installFlags & PackageManager.INSTALL_EPHEMERAL) != 0) {
13006                Slog.d(TAG, "Ephemeral install of " + packageName);
13007            }
13008        }
13009        final VerificationInfo verificationInfo = new VerificationInfo(
13010                sessionParams.originatingUri, sessionParams.referrerUri,
13011                sessionParams.originatingUid, installerUid);
13012
13013        final OriginInfo origin;
13014        if (stagedDir != null) {
13015            origin = OriginInfo.fromStagedFile(stagedDir);
13016        } else {
13017            origin = OriginInfo.fromStagedContainer(stagedCid);
13018        }
13019
13020        final Message msg = mHandler.obtainMessage(INIT_COPY);
13021        final int installReason = fixUpInstallReason(installerPackageName, installerUid,
13022                sessionParams.installReason);
13023        final InstallParams params = new InstallParams(origin, null, observer,
13024                sessionParams.installFlags, installerPackageName, sessionParams.volumeUuid,
13025                verificationInfo, user, sessionParams.abiOverride,
13026                sessionParams.grantedRuntimePermissions, certificates, installReason);
13027        params.setTraceMethod("installStage").setTraceCookie(System.identityHashCode(params));
13028        msg.obj = params;
13029
13030        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installStage",
13031                System.identityHashCode(msg.obj));
13032        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
13033                System.identityHashCode(msg.obj));
13034
13035        mHandler.sendMessage(msg);
13036    }
13037
13038    private void sendPackageAddedForUser(String packageName, PackageSetting pkgSetting,
13039            int userId) {
13040        final boolean isSystem = isSystemApp(pkgSetting) || isUpdatedSystemApp(pkgSetting);
13041        sendPackageAddedForNewUsers(packageName, isSystem, pkgSetting.appId, userId);
13042    }
13043
13044    private void sendPackageAddedForNewUsers(String packageName, boolean isSystem,
13045            int appId, int... userIds) {
13046        if (ArrayUtils.isEmpty(userIds)) {
13047            return;
13048        }
13049        Bundle extras = new Bundle(1);
13050        // Set to UID of the first user, EXTRA_UID is automatically updated in sendPackageBroadcast
13051        extras.putInt(Intent.EXTRA_UID, UserHandle.getUid(userIds[0], appId));
13052
13053        sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
13054                packageName, extras, 0, null, null, userIds);
13055        if (isSystem) {
13056            mHandler.post(() -> {
13057                        for (int userId : userIds) {
13058                            sendBootCompletedBroadcastToSystemApp(packageName, userId);
13059                        }
13060                    }
13061            );
13062        }
13063    }
13064
13065    /**
13066     * The just-installed/enabled app is bundled on the system, so presumed to be able to run
13067     * automatically without needing an explicit launch.
13068     * Send it a LOCKED_BOOT_COMPLETED/BOOT_COMPLETED if it would ordinarily have gotten ones.
13069     */
13070    private void sendBootCompletedBroadcastToSystemApp(String packageName, int userId) {
13071        // If user is not running, the app didn't miss any broadcast
13072        if (!mUserManagerInternal.isUserRunning(userId)) {
13073            return;
13074        }
13075        final IActivityManager am = ActivityManager.getService();
13076        try {
13077            // Deliver LOCKED_BOOT_COMPLETED first
13078            Intent lockedBcIntent = new Intent(Intent.ACTION_LOCKED_BOOT_COMPLETED)
13079                    .setPackage(packageName);
13080            final String[] requiredPermissions = {Manifest.permission.RECEIVE_BOOT_COMPLETED};
13081            am.broadcastIntent(null, lockedBcIntent, null, null, 0, null, null, requiredPermissions,
13082                    android.app.AppOpsManager.OP_NONE, null, false, false, userId);
13083
13084            // Deliver BOOT_COMPLETED only if user is unlocked
13085            if (mUserManagerInternal.isUserUnlockingOrUnlocked(userId)) {
13086                Intent bcIntent = new Intent(Intent.ACTION_BOOT_COMPLETED).setPackage(packageName);
13087                am.broadcastIntent(null, bcIntent, null, null, 0, null, null, requiredPermissions,
13088                        android.app.AppOpsManager.OP_NONE, null, false, false, userId);
13089            }
13090        } catch (RemoteException e) {
13091            throw e.rethrowFromSystemServer();
13092        }
13093    }
13094
13095    @Override
13096    public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden,
13097            int userId) {
13098        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
13099        PackageSetting pkgSetting;
13100        final int uid = Binder.getCallingUid();
13101        enforceCrossUserPermission(uid, userId,
13102                true /* requireFullPermission */, true /* checkShell */,
13103                "setApplicationHiddenSetting for user " + userId);
13104
13105        if (hidden && isPackageDeviceAdmin(packageName, userId)) {
13106            Slog.w(TAG, "Not hiding package " + packageName + ": has active device admin");
13107            return false;
13108        }
13109
13110        long callingId = Binder.clearCallingIdentity();
13111        try {
13112            boolean sendAdded = false;
13113            boolean sendRemoved = false;
13114            // writer
13115            synchronized (mPackages) {
13116                pkgSetting = mSettings.mPackages.get(packageName);
13117                if (pkgSetting == null) {
13118                    return false;
13119                }
13120                // Do not allow "android" is being disabled
13121                if ("android".equals(packageName)) {
13122                    Slog.w(TAG, "Cannot hide package: android");
13123                    return false;
13124                }
13125                // Cannot hide static shared libs as they are considered
13126                // a part of the using app (emulating static linking). Also
13127                // static libs are installed always on internal storage.
13128                PackageParser.Package pkg = mPackages.get(packageName);
13129                if (pkg != null && pkg.staticSharedLibName != null) {
13130                    Slog.w(TAG, "Cannot hide package: " + packageName
13131                            + " providing static shared library: "
13132                            + pkg.staticSharedLibName);
13133                    return false;
13134                }
13135                // Only allow protected packages to hide themselves.
13136                if (hidden && !UserHandle.isSameApp(uid, pkgSetting.appId)
13137                        && mProtectedPackages.isPackageStateProtected(userId, packageName)) {
13138                    Slog.w(TAG, "Not hiding protected package: " + packageName);
13139                    return false;
13140                }
13141
13142                if (pkgSetting.getHidden(userId) != hidden) {
13143                    pkgSetting.setHidden(hidden, userId);
13144                    mSettings.writePackageRestrictionsLPr(userId);
13145                    if (hidden) {
13146                        sendRemoved = true;
13147                    } else {
13148                        sendAdded = true;
13149                    }
13150                }
13151            }
13152            if (sendAdded) {
13153                sendPackageAddedForUser(packageName, pkgSetting, userId);
13154                return true;
13155            }
13156            if (sendRemoved) {
13157                killApplication(packageName, UserHandle.getUid(userId, pkgSetting.appId),
13158                        "hiding pkg");
13159                sendApplicationHiddenForUser(packageName, pkgSetting, userId);
13160                return true;
13161            }
13162        } finally {
13163            Binder.restoreCallingIdentity(callingId);
13164        }
13165        return false;
13166    }
13167
13168    private void sendApplicationHiddenForUser(String packageName, PackageSetting pkgSetting,
13169            int userId) {
13170        final PackageRemovedInfo info = new PackageRemovedInfo();
13171        info.removedPackage = packageName;
13172        info.removedUsers = new int[] {userId};
13173        info.uid = UserHandle.getUid(userId, pkgSetting.appId);
13174        info.sendPackageRemovedBroadcasts(true /*killApp*/);
13175    }
13176
13177    private void sendPackagesSuspendedForUser(String[] pkgList, int userId, boolean suspended) {
13178        if (pkgList.length > 0) {
13179            Bundle extras = new Bundle(1);
13180            extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
13181
13182            sendPackageBroadcast(
13183                    suspended ? Intent.ACTION_PACKAGES_SUSPENDED
13184                            : Intent.ACTION_PACKAGES_UNSUSPENDED,
13185                    null, extras, Intent.FLAG_RECEIVER_REGISTERED_ONLY, null, null,
13186                    new int[] {userId});
13187        }
13188    }
13189
13190    /**
13191     * Returns true if application is not found or there was an error. Otherwise it returns
13192     * the hidden state of the package for the given user.
13193     */
13194    @Override
13195    public boolean getApplicationHiddenSettingAsUser(String packageName, int userId) {
13196        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
13197        enforceCrossUserPermission(Binder.getCallingUid(), userId,
13198                true /* requireFullPermission */, false /* checkShell */,
13199                "getApplicationHidden for user " + userId);
13200        PackageSetting pkgSetting;
13201        long callingId = Binder.clearCallingIdentity();
13202        try {
13203            // writer
13204            synchronized (mPackages) {
13205                pkgSetting = mSettings.mPackages.get(packageName);
13206                if (pkgSetting == null) {
13207                    return true;
13208                }
13209                return pkgSetting.getHidden(userId);
13210            }
13211        } finally {
13212            Binder.restoreCallingIdentity(callingId);
13213        }
13214    }
13215
13216    /**
13217     * @hide
13218     */
13219    @Override
13220    public int installExistingPackageAsUser(String packageName, int userId, int installReason) {
13221        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES,
13222                null);
13223        PackageSetting pkgSetting;
13224        final int uid = Binder.getCallingUid();
13225        enforceCrossUserPermission(uid, userId,
13226                true /* requireFullPermission */, true /* checkShell */,
13227                "installExistingPackage for user " + userId);
13228        if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
13229            return PackageManager.INSTALL_FAILED_USER_RESTRICTED;
13230        }
13231
13232        long callingId = Binder.clearCallingIdentity();
13233        try {
13234            boolean installed = false;
13235
13236            // writer
13237            synchronized (mPackages) {
13238                pkgSetting = mSettings.mPackages.get(packageName);
13239                if (pkgSetting == null) {
13240                    return PackageManager.INSTALL_FAILED_INVALID_URI;
13241                }
13242                if (!pkgSetting.getInstalled(userId)) {
13243                    pkgSetting.setInstalled(true, userId);
13244                    pkgSetting.setHidden(false, userId);
13245                    pkgSetting.setInstallReason(installReason, userId);
13246                    mSettings.writePackageRestrictionsLPr(userId);
13247                    installed = true;
13248                }
13249            }
13250
13251            if (installed) {
13252                if (pkgSetting.pkg != null) {
13253                    synchronized (mInstallLock) {
13254                        // We don't need to freeze for a brand new install
13255                        prepareAppDataAfterInstallLIF(pkgSetting.pkg);
13256                    }
13257                }
13258                sendPackageAddedForUser(packageName, pkgSetting, userId);
13259            }
13260        } finally {
13261            Binder.restoreCallingIdentity(callingId);
13262        }
13263
13264        return PackageManager.INSTALL_SUCCEEDED;
13265    }
13266
13267    boolean isUserRestricted(int userId, String restrictionKey) {
13268        Bundle restrictions = sUserManager.getUserRestrictions(userId);
13269        if (restrictions.getBoolean(restrictionKey, false)) {
13270            Log.w(TAG, "User is restricted: " + restrictionKey);
13271            return true;
13272        }
13273        return false;
13274    }
13275
13276    @Override
13277    public String[] setPackagesSuspendedAsUser(String[] packageNames, boolean suspended,
13278            int userId) {
13279        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
13280        enforceCrossUserPermission(Binder.getCallingUid(), userId,
13281                true /* requireFullPermission */, true /* checkShell */,
13282                "setPackagesSuspended for user " + userId);
13283
13284        if (ArrayUtils.isEmpty(packageNames)) {
13285            return packageNames;
13286        }
13287
13288        // List of package names for whom the suspended state has changed.
13289        List<String> changedPackages = new ArrayList<>(packageNames.length);
13290        // List of package names for whom the suspended state is not set as requested in this
13291        // method.
13292        List<String> unactionedPackages = new ArrayList<>(packageNames.length);
13293        long callingId = Binder.clearCallingIdentity();
13294        try {
13295            for (int i = 0; i < packageNames.length; i++) {
13296                String packageName = packageNames[i];
13297                boolean changed = false;
13298                final int appId;
13299                synchronized (mPackages) {
13300                    final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
13301                    if (pkgSetting == null) {
13302                        Slog.w(TAG, "Could not find package setting for package \"" + packageName
13303                                + "\". Skipping suspending/un-suspending.");
13304                        unactionedPackages.add(packageName);
13305                        continue;
13306                    }
13307                    appId = pkgSetting.appId;
13308                    if (pkgSetting.getSuspended(userId) != suspended) {
13309                        if (!canSuspendPackageForUserLocked(packageName, userId)) {
13310                            unactionedPackages.add(packageName);
13311                            continue;
13312                        }
13313                        pkgSetting.setSuspended(suspended, userId);
13314                        mSettings.writePackageRestrictionsLPr(userId);
13315                        changed = true;
13316                        changedPackages.add(packageName);
13317                    }
13318                }
13319
13320                if (changed && suspended) {
13321                    killApplication(packageName, UserHandle.getUid(userId, appId),
13322                            "suspending package");
13323                }
13324            }
13325        } finally {
13326            Binder.restoreCallingIdentity(callingId);
13327        }
13328
13329        if (!changedPackages.isEmpty()) {
13330            sendPackagesSuspendedForUser(changedPackages.toArray(
13331                    new String[changedPackages.size()]), userId, suspended);
13332        }
13333
13334        return unactionedPackages.toArray(new String[unactionedPackages.size()]);
13335    }
13336
13337    @Override
13338    public boolean isPackageSuspendedForUser(String packageName, int userId) {
13339        enforceCrossUserPermission(Binder.getCallingUid(), userId,
13340                true /* requireFullPermission */, false /* checkShell */,
13341                "isPackageSuspendedForUser for user " + userId);
13342        synchronized (mPackages) {
13343            final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
13344            if (pkgSetting == null) {
13345                throw new IllegalArgumentException("Unknown target package: " + packageName);
13346            }
13347            return pkgSetting.getSuspended(userId);
13348        }
13349    }
13350
13351    private boolean canSuspendPackageForUserLocked(String packageName, int userId) {
13352        if (isPackageDeviceAdmin(packageName, userId)) {
13353            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
13354                    + "\": has an active device admin");
13355            return false;
13356        }
13357
13358        String activeLauncherPackageName = getActiveLauncherPackageName(userId);
13359        if (packageName.equals(activeLauncherPackageName)) {
13360            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
13361                    + "\": contains the active launcher");
13362            return false;
13363        }
13364
13365        if (packageName.equals(mRequiredInstallerPackage)) {
13366            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
13367                    + "\": required for package installation");
13368            return false;
13369        }
13370
13371        if (packageName.equals(mRequiredUninstallerPackage)) {
13372            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
13373                    + "\": required for package uninstallation");
13374            return false;
13375        }
13376
13377        if (packageName.equals(mRequiredVerifierPackage)) {
13378            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
13379                    + "\": required for package verification");
13380            return false;
13381        }
13382
13383        if (packageName.equals(getDefaultDialerPackageName(userId))) {
13384            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
13385                    + "\": is the default dialer");
13386            return false;
13387        }
13388
13389        if (mProtectedPackages.isPackageStateProtected(userId, packageName)) {
13390            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
13391                    + "\": protected package");
13392            return false;
13393        }
13394
13395        // Cannot suspend static shared libs as they are considered
13396        // a part of the using app (emulating static linking). Also
13397        // static libs are installed always on internal storage.
13398        PackageParser.Package pkg = mPackages.get(packageName);
13399        if (pkg != null && pkg.applicationInfo.isStaticSharedLibrary()) {
13400            Slog.w(TAG, "Cannot suspend package: " + packageName
13401                    + " providing static shared library: "
13402                    + pkg.staticSharedLibName);
13403            return false;
13404        }
13405
13406        return true;
13407    }
13408
13409    private String getActiveLauncherPackageName(int userId) {
13410        Intent intent = new Intent(Intent.ACTION_MAIN);
13411        intent.addCategory(Intent.CATEGORY_HOME);
13412        ResolveInfo resolveInfo = resolveIntent(
13413                intent,
13414                intent.resolveTypeIfNeeded(mContext.getContentResolver()),
13415                PackageManager.MATCH_DEFAULT_ONLY,
13416                userId);
13417
13418        return resolveInfo == null ? null : resolveInfo.activityInfo.packageName;
13419    }
13420
13421    private String getDefaultDialerPackageName(int userId) {
13422        synchronized (mPackages) {
13423            return mSettings.getDefaultDialerPackageNameLPw(userId);
13424        }
13425    }
13426
13427    @Override
13428    public void verifyPendingInstall(int id, int verificationCode) throws RemoteException {
13429        mContext.enforceCallingOrSelfPermission(
13430                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
13431                "Only package verification agents can verify applications");
13432
13433        final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
13434        final PackageVerificationResponse response = new PackageVerificationResponse(
13435                verificationCode, Binder.getCallingUid());
13436        msg.arg1 = id;
13437        msg.obj = response;
13438        mHandler.sendMessage(msg);
13439    }
13440
13441    @Override
13442    public void extendVerificationTimeout(int id, int verificationCodeAtTimeout,
13443            long millisecondsToDelay) {
13444        mContext.enforceCallingOrSelfPermission(
13445                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
13446                "Only package verification agents can extend verification timeouts");
13447
13448        final PackageVerificationState state = mPendingVerification.get(id);
13449        final PackageVerificationResponse response = new PackageVerificationResponse(
13450                verificationCodeAtTimeout, Binder.getCallingUid());
13451
13452        if (millisecondsToDelay > PackageManager.MAXIMUM_VERIFICATION_TIMEOUT) {
13453            millisecondsToDelay = PackageManager.MAXIMUM_VERIFICATION_TIMEOUT;
13454        }
13455        if (millisecondsToDelay < 0) {
13456            millisecondsToDelay = 0;
13457        }
13458        if ((verificationCodeAtTimeout != PackageManager.VERIFICATION_ALLOW)
13459                && (verificationCodeAtTimeout != PackageManager.VERIFICATION_REJECT)) {
13460            verificationCodeAtTimeout = PackageManager.VERIFICATION_REJECT;
13461        }
13462
13463        if ((state != null) && !state.timeoutExtended()) {
13464            state.extendTimeout();
13465
13466            final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
13467            msg.arg1 = id;
13468            msg.obj = response;
13469            mHandler.sendMessageDelayed(msg, millisecondsToDelay);
13470        }
13471    }
13472
13473    private void broadcastPackageVerified(int verificationId, Uri packageUri,
13474            int verificationCode, UserHandle user) {
13475        final Intent intent = new Intent(Intent.ACTION_PACKAGE_VERIFIED);
13476        intent.setDataAndType(packageUri, PACKAGE_MIME_TYPE);
13477        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
13478        intent.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
13479        intent.putExtra(PackageManager.EXTRA_VERIFICATION_RESULT, verificationCode);
13480
13481        mContext.sendBroadcastAsUser(intent, user,
13482                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT);
13483    }
13484
13485    private ComponentName matchComponentForVerifier(String packageName,
13486            List<ResolveInfo> receivers) {
13487        ActivityInfo targetReceiver = null;
13488
13489        final int NR = receivers.size();
13490        for (int i = 0; i < NR; i++) {
13491            final ResolveInfo info = receivers.get(i);
13492            if (info.activityInfo == null) {
13493                continue;
13494            }
13495
13496            if (packageName.equals(info.activityInfo.packageName)) {
13497                targetReceiver = info.activityInfo;
13498                break;
13499            }
13500        }
13501
13502        if (targetReceiver == null) {
13503            return null;
13504        }
13505
13506        return new ComponentName(targetReceiver.packageName, targetReceiver.name);
13507    }
13508
13509    private List<ComponentName> matchVerifiers(PackageInfoLite pkgInfo,
13510            List<ResolveInfo> receivers, final PackageVerificationState verificationState) {
13511        if (pkgInfo.verifiers.length == 0) {
13512            return null;
13513        }
13514
13515        final int N = pkgInfo.verifiers.length;
13516        final List<ComponentName> sufficientVerifiers = new ArrayList<ComponentName>(N + 1);
13517        for (int i = 0; i < N; i++) {
13518            final VerifierInfo verifierInfo = pkgInfo.verifiers[i];
13519
13520            final ComponentName comp = matchComponentForVerifier(verifierInfo.packageName,
13521                    receivers);
13522            if (comp == null) {
13523                continue;
13524            }
13525
13526            final int verifierUid = getUidForVerifier(verifierInfo);
13527            if (verifierUid == -1) {
13528                continue;
13529            }
13530
13531            if (DEBUG_VERIFY) {
13532                Slog.d(TAG, "Added sufficient verifier " + verifierInfo.packageName
13533                        + " with the correct signature");
13534            }
13535            sufficientVerifiers.add(comp);
13536            verificationState.addSufficientVerifier(verifierUid);
13537        }
13538
13539        return sufficientVerifiers;
13540    }
13541
13542    private int getUidForVerifier(VerifierInfo verifierInfo) {
13543        synchronized (mPackages) {
13544            final PackageParser.Package pkg = mPackages.get(verifierInfo.packageName);
13545            if (pkg == null) {
13546                return -1;
13547            } else if (pkg.mSignatures.length != 1) {
13548                Slog.i(TAG, "Verifier package " + verifierInfo.packageName
13549                        + " has more than one signature; ignoring");
13550                return -1;
13551            }
13552
13553            /*
13554             * If the public key of the package's signature does not match
13555             * our expected public key, then this is a different package and
13556             * we should skip.
13557             */
13558
13559            final byte[] expectedPublicKey;
13560            try {
13561                final Signature verifierSig = pkg.mSignatures[0];
13562                final PublicKey publicKey = verifierSig.getPublicKey();
13563                expectedPublicKey = publicKey.getEncoded();
13564            } catch (CertificateException e) {
13565                return -1;
13566            }
13567
13568            final byte[] actualPublicKey = verifierInfo.publicKey.getEncoded();
13569
13570            if (!Arrays.equals(actualPublicKey, expectedPublicKey)) {
13571                Slog.i(TAG, "Verifier package " + verifierInfo.packageName
13572                        + " does not have the expected public key; ignoring");
13573                return -1;
13574            }
13575
13576            return pkg.applicationInfo.uid;
13577        }
13578    }
13579
13580    @Override
13581    public void finishPackageInstall(int token, boolean didLaunch) {
13582        enforceSystemOrRoot("Only the system is allowed to finish installs");
13583
13584        if (DEBUG_INSTALL) {
13585            Slog.v(TAG, "BM finishing package install for " + token);
13586        }
13587        Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "restore", token);
13588
13589        final Message msg = mHandler.obtainMessage(POST_INSTALL, token, didLaunch ? 1 : 0);
13590        mHandler.sendMessage(msg);
13591    }
13592
13593    /**
13594     * Get the verification agent timeout.
13595     *
13596     * @return verification timeout in milliseconds
13597     */
13598    private long getVerificationTimeout() {
13599        return android.provider.Settings.Global.getLong(mContext.getContentResolver(),
13600                android.provider.Settings.Global.PACKAGE_VERIFIER_TIMEOUT,
13601                DEFAULT_VERIFICATION_TIMEOUT);
13602    }
13603
13604    /**
13605     * Get the default verification agent response code.
13606     *
13607     * @return default verification response code
13608     */
13609    private int getDefaultVerificationResponse() {
13610        return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
13611                android.provider.Settings.Global.PACKAGE_VERIFIER_DEFAULT_RESPONSE,
13612                DEFAULT_VERIFICATION_RESPONSE);
13613    }
13614
13615    /**
13616     * Check whether or not package verification has been enabled.
13617     *
13618     * @return true if verification should be performed
13619     */
13620    private boolean isVerificationEnabled(int userId, int installFlags) {
13621        if (!DEFAULT_VERIFY_ENABLE) {
13622            return false;
13623        }
13624        // Ephemeral apps don't get the full verification treatment
13625        if ((installFlags & PackageManager.INSTALL_EPHEMERAL) != 0) {
13626            if (DEBUG_EPHEMERAL) {
13627                Slog.d(TAG, "INSTALL_EPHEMERAL so skipping verification");
13628            }
13629            return false;
13630        }
13631
13632        boolean ensureVerifyAppsEnabled = isUserRestricted(userId, UserManager.ENSURE_VERIFY_APPS);
13633
13634        // Check if installing from ADB
13635        if ((installFlags & PackageManager.INSTALL_FROM_ADB) != 0) {
13636            // Do not run verification in a test harness environment
13637            if (ActivityManager.isRunningInTestHarness()) {
13638                return false;
13639            }
13640            if (ensureVerifyAppsEnabled) {
13641                return true;
13642            }
13643            // Check if the developer does not want package verification for ADB installs
13644            if (android.provider.Settings.Global.getInt(mContext.getContentResolver(),
13645                    android.provider.Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, 1) == 0) {
13646                return false;
13647            }
13648        }
13649
13650        if (ensureVerifyAppsEnabled) {
13651            return true;
13652        }
13653
13654        return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
13655                android.provider.Settings.Global.PACKAGE_VERIFIER_ENABLE, 1) == 1;
13656    }
13657
13658    @Override
13659    public void verifyIntentFilter(int id, int verificationCode, List<String> failedDomains)
13660            throws RemoteException {
13661        mContext.enforceCallingOrSelfPermission(
13662                Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT,
13663                "Only intentfilter verification agents can verify applications");
13664
13665        final Message msg = mHandler.obtainMessage(INTENT_FILTER_VERIFIED);
13666        final IntentFilterVerificationResponse response = new IntentFilterVerificationResponse(
13667                Binder.getCallingUid(), verificationCode, failedDomains);
13668        msg.arg1 = id;
13669        msg.obj = response;
13670        mHandler.sendMessage(msg);
13671    }
13672
13673    @Override
13674    public int getIntentVerificationStatus(String packageName, int userId) {
13675        synchronized (mPackages) {
13676            return mSettings.getIntentFilterVerificationStatusLPr(packageName, userId);
13677        }
13678    }
13679
13680    @Override
13681    public boolean updateIntentVerificationStatus(String packageName, int status, int userId) {
13682        mContext.enforceCallingOrSelfPermission(
13683                android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
13684
13685        boolean result = false;
13686        synchronized (mPackages) {
13687            result = mSettings.updateIntentFilterVerificationStatusLPw(packageName, status, userId);
13688        }
13689        if (result) {
13690            scheduleWritePackageRestrictionsLocked(userId);
13691        }
13692        return result;
13693    }
13694
13695    @Override
13696    public @NonNull ParceledListSlice<IntentFilterVerificationInfo> getIntentFilterVerifications(
13697            String packageName) {
13698        synchronized (mPackages) {
13699            return new ParceledListSlice<>(mSettings.getIntentFilterVerificationsLPr(packageName));
13700        }
13701    }
13702
13703    @Override
13704    public @NonNull ParceledListSlice<IntentFilter> getAllIntentFilters(String packageName) {
13705        if (TextUtils.isEmpty(packageName)) {
13706            return ParceledListSlice.emptyList();
13707        }
13708        synchronized (mPackages) {
13709            PackageParser.Package pkg = mPackages.get(packageName);
13710            if (pkg == null || pkg.activities == null) {
13711                return ParceledListSlice.emptyList();
13712            }
13713            final int count = pkg.activities.size();
13714            ArrayList<IntentFilter> result = new ArrayList<>();
13715            for (int n=0; n<count; n++) {
13716                PackageParser.Activity activity = pkg.activities.get(n);
13717                if (activity.intents != null && activity.intents.size() > 0) {
13718                    result.addAll(activity.intents);
13719                }
13720            }
13721            return new ParceledListSlice<>(result);
13722        }
13723    }
13724
13725    @Override
13726    public boolean setDefaultBrowserPackageName(String packageName, int userId) {
13727        mContext.enforceCallingOrSelfPermission(
13728                android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
13729
13730        synchronized (mPackages) {
13731            boolean result = mSettings.setDefaultBrowserPackageNameLPw(packageName, userId);
13732            if (packageName != null) {
13733                result |= updateIntentVerificationStatus(packageName,
13734                        PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS,
13735                        userId);
13736                mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultBrowserLPr(
13737                        packageName, userId);
13738            }
13739            return result;
13740        }
13741    }
13742
13743    @Override
13744    public String getDefaultBrowserPackageName(int userId) {
13745        synchronized (mPackages) {
13746            return mSettings.getDefaultBrowserPackageNameLPw(userId);
13747        }
13748    }
13749
13750    /**
13751     * Get the "allow unknown sources" setting.
13752     *
13753     * @return the current "allow unknown sources" setting
13754     */
13755    private int getUnknownSourcesSettings() {
13756        return android.provider.Settings.Secure.getInt(mContext.getContentResolver(),
13757                android.provider.Settings.Secure.INSTALL_NON_MARKET_APPS,
13758                -1);
13759    }
13760
13761    @Override
13762    public void setInstallerPackageName(String targetPackage, String installerPackageName) {
13763        final int uid = Binder.getCallingUid();
13764        // writer
13765        synchronized (mPackages) {
13766            PackageSetting targetPackageSetting = mSettings.mPackages.get(targetPackage);
13767            if (targetPackageSetting == null) {
13768                throw new IllegalArgumentException("Unknown target package: " + targetPackage);
13769            }
13770
13771            PackageSetting installerPackageSetting;
13772            if (installerPackageName != null) {
13773                installerPackageSetting = mSettings.mPackages.get(installerPackageName);
13774                if (installerPackageSetting == null) {
13775                    throw new IllegalArgumentException("Unknown installer package: "
13776                            + installerPackageName);
13777                }
13778            } else {
13779                installerPackageSetting = null;
13780            }
13781
13782            Signature[] callerSignature;
13783            Object obj = mSettings.getUserIdLPr(uid);
13784            if (obj != null) {
13785                if (obj instanceof SharedUserSetting) {
13786                    callerSignature = ((SharedUserSetting)obj).signatures.mSignatures;
13787                } else if (obj instanceof PackageSetting) {
13788                    callerSignature = ((PackageSetting)obj).signatures.mSignatures;
13789                } else {
13790                    throw new SecurityException("Bad object " + obj + " for uid " + uid);
13791                }
13792            } else {
13793                throw new SecurityException("Unknown calling UID: " + uid);
13794            }
13795
13796            // Verify: can't set installerPackageName to a package that is
13797            // not signed with the same cert as the caller.
13798            if (installerPackageSetting != null) {
13799                if (compareSignatures(callerSignature,
13800                        installerPackageSetting.signatures.mSignatures)
13801                        != PackageManager.SIGNATURE_MATCH) {
13802                    throw new SecurityException(
13803                            "Caller does not have same cert as new installer package "
13804                            + installerPackageName);
13805                }
13806            }
13807
13808            // Verify: if target already has an installer package, it must
13809            // be signed with the same cert as the caller.
13810            if (targetPackageSetting.installerPackageName != null) {
13811                PackageSetting setting = mSettings.mPackages.get(
13812                        targetPackageSetting.installerPackageName);
13813                // If the currently set package isn't valid, then it's always
13814                // okay to change it.
13815                if (setting != null) {
13816                    if (compareSignatures(callerSignature,
13817                            setting.signatures.mSignatures)
13818                            != PackageManager.SIGNATURE_MATCH) {
13819                        throw new SecurityException(
13820                                "Caller does not have same cert as old installer package "
13821                                + targetPackageSetting.installerPackageName);
13822                    }
13823                }
13824            }
13825
13826            // Okay!
13827            targetPackageSetting.installerPackageName = installerPackageName;
13828            if (installerPackageName != null) {
13829                mSettings.mInstallerPackages.add(installerPackageName);
13830            }
13831            scheduleWriteSettingsLocked();
13832        }
13833    }
13834
13835    @Override
13836    public void setApplicationCategoryHint(String packageName, int categoryHint,
13837            String callerPackageName) {
13838        mContext.getSystemService(AppOpsManager.class).checkPackage(Binder.getCallingUid(),
13839                callerPackageName);
13840        synchronized (mPackages) {
13841            PackageSetting ps = mSettings.mPackages.get(packageName);
13842            if (ps == null) {
13843                throw new IllegalArgumentException("Unknown target package " + packageName);
13844            }
13845
13846            if (!Objects.equals(callerPackageName, ps.installerPackageName)) {
13847                throw new IllegalArgumentException("Calling package " + callerPackageName
13848                        + " is not installer for " + packageName);
13849            }
13850
13851            if (ps.categoryHint != categoryHint) {
13852                ps.categoryHint = categoryHint;
13853                scheduleWriteSettingsLocked();
13854            }
13855        }
13856    }
13857
13858    private void processPendingInstall(final InstallArgs args, final int currentStatus) {
13859        // Queue up an async operation since the package installation may take a little while.
13860        mHandler.post(new Runnable() {
13861            public void run() {
13862                mHandler.removeCallbacks(this);
13863                 // Result object to be returned
13864                PackageInstalledInfo res = new PackageInstalledInfo();
13865                res.setReturnCode(currentStatus);
13866                res.uid = -1;
13867                res.pkg = null;
13868                res.removedInfo = null;
13869                if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
13870                    args.doPreInstall(res.returnCode);
13871                    synchronized (mInstallLock) {
13872                        installPackageTracedLI(args, res);
13873                    }
13874                    args.doPostInstall(res.returnCode, res.uid);
13875                }
13876
13877                // A restore should be performed at this point if (a) the install
13878                // succeeded, (b) the operation is not an update, and (c) the new
13879                // package has not opted out of backup participation.
13880                final boolean update = res.removedInfo != null
13881                        && res.removedInfo.removedPackage != null;
13882                final int flags = (res.pkg == null) ? 0 : res.pkg.applicationInfo.flags;
13883                boolean doRestore = !update
13884                        && ((flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0);
13885
13886                // Set up the post-install work request bookkeeping.  This will be used
13887                // and cleaned up by the post-install event handling regardless of whether
13888                // there's a restore pass performed.  Token values are >= 1.
13889                int token;
13890                if (mNextInstallToken < 0) mNextInstallToken = 1;
13891                token = mNextInstallToken++;
13892
13893                PostInstallData data = new PostInstallData(args, res);
13894                mRunningInstalls.put(token, data);
13895                if (DEBUG_INSTALL) Log.v(TAG, "+ starting restore round-trip " + token);
13896
13897                if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && doRestore) {
13898                    // Pass responsibility to the Backup Manager.  It will perform a
13899                    // restore if appropriate, then pass responsibility back to the
13900                    // Package Manager to run the post-install observer callbacks
13901                    // and broadcasts.
13902                    IBackupManager bm = IBackupManager.Stub.asInterface(
13903                            ServiceManager.getService(Context.BACKUP_SERVICE));
13904                    if (bm != null) {
13905                        if (DEBUG_INSTALL) Log.v(TAG, "token " + token
13906                                + " to BM for possible restore");
13907                        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "restore", token);
13908                        try {
13909                            // TODO: http://b/22388012
13910                            if (bm.isBackupServiceActive(UserHandle.USER_SYSTEM)) {
13911                                bm.restoreAtInstall(res.pkg.applicationInfo.packageName, token);
13912                            } else {
13913                                doRestore = false;
13914                            }
13915                        } catch (RemoteException e) {
13916                            // can't happen; the backup manager is local
13917                        } catch (Exception e) {
13918                            Slog.e(TAG, "Exception trying to enqueue restore", e);
13919                            doRestore = false;
13920                        }
13921                    } else {
13922                        Slog.e(TAG, "Backup Manager not found!");
13923                        doRestore = false;
13924                    }
13925                }
13926
13927                if (!doRestore) {
13928                    // No restore possible, or the Backup Manager was mysteriously not
13929                    // available -- just fire the post-install work request directly.
13930                    if (DEBUG_INSTALL) Log.v(TAG, "No restore - queue post-install for " + token);
13931
13932                    Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "postInstall", token);
13933
13934                    Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0);
13935                    mHandler.sendMessage(msg);
13936                }
13937            }
13938        });
13939    }
13940
13941    /**
13942     * Callback from PackageSettings whenever an app is first transitioned out of the
13943     * 'stopped' state.  Normally we just issue the broadcast, but we can't do that if
13944     * the app was "launched" for a restoreAtInstall operation.  Therefore we check
13945     * here whether the app is the target of an ongoing install, and only send the
13946     * broadcast immediately if it is not in that state.  If it *is* undergoing a restore,
13947     * the first-launch broadcast will be sent implicitly on that basis in POST_INSTALL
13948     * handling.
13949     */
13950    void notifyFirstLaunch(final String pkgName, final String installerPackage, final int userId) {
13951        // Serialize this with the rest of the install-process message chain.  In the
13952        // restore-at-install case, this Runnable will necessarily run before the
13953        // POST_INSTALL message is processed, so the contents of mRunningInstalls
13954        // are coherent.  In the non-restore case, the app has already completed install
13955        // and been launched through some other means, so it is not in a problematic
13956        // state for observers to see the FIRST_LAUNCH signal.
13957        mHandler.post(new Runnable() {
13958            @Override
13959            public void run() {
13960                for (int i = 0; i < mRunningInstalls.size(); i++) {
13961                    final PostInstallData data = mRunningInstalls.valueAt(i);
13962                    if (data.res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
13963                        continue;
13964                    }
13965                    if (pkgName.equals(data.res.pkg.applicationInfo.packageName)) {
13966                        // right package; but is it for the right user?
13967                        for (int uIndex = 0; uIndex < data.res.newUsers.length; uIndex++) {
13968                            if (userId == data.res.newUsers[uIndex]) {
13969                                if (DEBUG_BACKUP) {
13970                                    Slog.i(TAG, "Package " + pkgName
13971                                            + " being restored so deferring FIRST_LAUNCH");
13972                                }
13973                                return;
13974                            }
13975                        }
13976                    }
13977                }
13978                // didn't find it, so not being restored
13979                if (DEBUG_BACKUP) {
13980                    Slog.i(TAG, "Package " + pkgName + " sending normal FIRST_LAUNCH");
13981                }
13982                sendFirstLaunchBroadcast(pkgName, installerPackage, new int[] {userId});
13983            }
13984        });
13985    }
13986
13987    private void sendFirstLaunchBroadcast(String pkgName, String installerPkg, int[] userIds) {
13988        sendPackageBroadcast(Intent.ACTION_PACKAGE_FIRST_LAUNCH, pkgName, null, 0,
13989                installerPkg, null, userIds);
13990    }
13991
13992    private abstract class HandlerParams {
13993        private static final int MAX_RETRIES = 4;
13994
13995        /**
13996         * Number of times startCopy() has been attempted and had a non-fatal
13997         * error.
13998         */
13999        private int mRetries = 0;
14000
14001        /** User handle for the user requesting the information or installation. */
14002        private final UserHandle mUser;
14003        String traceMethod;
14004        int traceCookie;
14005
14006        HandlerParams(UserHandle user) {
14007            mUser = user;
14008        }
14009
14010        UserHandle getUser() {
14011            return mUser;
14012        }
14013
14014        HandlerParams setTraceMethod(String traceMethod) {
14015            this.traceMethod = traceMethod;
14016            return this;
14017        }
14018
14019        HandlerParams setTraceCookie(int traceCookie) {
14020            this.traceCookie = traceCookie;
14021            return this;
14022        }
14023
14024        final boolean startCopy() {
14025            boolean res;
14026            try {
14027                if (DEBUG_INSTALL) Slog.i(TAG, "startCopy " + mUser + ": " + this);
14028
14029                if (++mRetries > MAX_RETRIES) {
14030                    Slog.w(TAG, "Failed to invoke remote methods on default container service. Giving up");
14031                    mHandler.sendEmptyMessage(MCS_GIVE_UP);
14032                    handleServiceError();
14033                    return false;
14034                } else {
14035                    handleStartCopy();
14036                    res = true;
14037                }
14038            } catch (RemoteException e) {
14039                if (DEBUG_INSTALL) Slog.i(TAG, "Posting install MCS_RECONNECT");
14040                mHandler.sendEmptyMessage(MCS_RECONNECT);
14041                res = false;
14042            }
14043            handleReturnCode();
14044            return res;
14045        }
14046
14047        final void serviceError() {
14048            if (DEBUG_INSTALL) Slog.i(TAG, "serviceError");
14049            handleServiceError();
14050            handleReturnCode();
14051        }
14052
14053        abstract void handleStartCopy() throws RemoteException;
14054        abstract void handleServiceError();
14055        abstract void handleReturnCode();
14056    }
14057
14058    class MeasureParams extends HandlerParams {
14059        private final PackageStats mStats;
14060        private boolean mSuccess;
14061
14062        private final IPackageStatsObserver mObserver;
14063
14064        public MeasureParams(PackageStats stats, IPackageStatsObserver observer) {
14065            super(new UserHandle(stats.userHandle));
14066            mObserver = observer;
14067            mStats = stats;
14068        }
14069
14070        @Override
14071        public String toString() {
14072            return "MeasureParams{"
14073                + Integer.toHexString(System.identityHashCode(this))
14074                + " " + mStats.packageName + "}";
14075        }
14076
14077        @Override
14078        void handleStartCopy() throws RemoteException {
14079            synchronized (mInstallLock) {
14080                mSuccess = getPackageSizeInfoLI(mStats.packageName, mStats.userHandle, mStats);
14081            }
14082
14083            if (mSuccess) {
14084                boolean mounted = false;
14085                try {
14086                    final String status = Environment.getExternalStorageState();
14087                    mounted = (Environment.MEDIA_MOUNTED.equals(status)
14088                            || Environment.MEDIA_MOUNTED_READ_ONLY.equals(status));
14089                } catch (Exception e) {
14090                }
14091
14092                if (mounted) {
14093                    final UserEnvironment userEnv = new UserEnvironment(mStats.userHandle);
14094
14095                    mStats.externalCacheSize = calculateDirectorySize(mContainerService,
14096                            userEnv.buildExternalStorageAppCacheDirs(mStats.packageName));
14097
14098                    mStats.externalDataSize = calculateDirectorySize(mContainerService,
14099                            userEnv.buildExternalStorageAppDataDirs(mStats.packageName));
14100
14101                    // Always subtract cache size, since it's a subdirectory
14102                    mStats.externalDataSize -= mStats.externalCacheSize;
14103
14104                    mStats.externalMediaSize = calculateDirectorySize(mContainerService,
14105                            userEnv.buildExternalStorageAppMediaDirs(mStats.packageName));
14106
14107                    mStats.externalObbSize = calculateDirectorySize(mContainerService,
14108                            userEnv.buildExternalStorageAppObbDirs(mStats.packageName));
14109                }
14110            }
14111        }
14112
14113        @Override
14114        void handleReturnCode() {
14115            if (mObserver != null) {
14116                try {
14117                    mObserver.onGetStatsCompleted(mStats, mSuccess);
14118                } catch (RemoteException e) {
14119                    Slog.i(TAG, "Observer no longer exists.");
14120                }
14121            }
14122        }
14123
14124        @Override
14125        void handleServiceError() {
14126            Slog.e(TAG, "Could not measure application " + mStats.packageName
14127                            + " external storage");
14128        }
14129    }
14130
14131    private static long calculateDirectorySize(IMediaContainerService mcs, File[] paths)
14132            throws RemoteException {
14133        long result = 0;
14134        for (File path : paths) {
14135            result += mcs.calculateDirectorySize(path.getAbsolutePath());
14136        }
14137        return result;
14138    }
14139
14140    private static void clearDirectory(IMediaContainerService mcs, File[] paths) {
14141        for (File path : paths) {
14142            try {
14143                mcs.clearDirectory(path.getAbsolutePath());
14144            } catch (RemoteException e) {
14145            }
14146        }
14147    }
14148
14149    static class OriginInfo {
14150        /**
14151         * Location where install is coming from, before it has been
14152         * copied/renamed into place. This could be a single monolithic APK
14153         * file, or a cluster directory. This location may be untrusted.
14154         */
14155        final File file;
14156        final String cid;
14157
14158        /**
14159         * Flag indicating that {@link #file} or {@link #cid} has already been
14160         * staged, meaning downstream users don't need to defensively copy the
14161         * contents.
14162         */
14163        final boolean staged;
14164
14165        /**
14166         * Flag indicating that {@link #file} or {@link #cid} is an already
14167         * installed app that is being moved.
14168         */
14169        final boolean existing;
14170
14171        final String resolvedPath;
14172        final File resolvedFile;
14173
14174        static OriginInfo fromNothing() {
14175            return new OriginInfo(null, null, false, false);
14176        }
14177
14178        static OriginInfo fromUntrustedFile(File file) {
14179            return new OriginInfo(file, null, false, false);
14180        }
14181
14182        static OriginInfo fromExistingFile(File file) {
14183            return new OriginInfo(file, null, false, true);
14184        }
14185
14186        static OriginInfo fromStagedFile(File file) {
14187            return new OriginInfo(file, null, true, false);
14188        }
14189
14190        static OriginInfo fromStagedContainer(String cid) {
14191            return new OriginInfo(null, cid, true, false);
14192        }
14193
14194        private OriginInfo(File file, String cid, boolean staged, boolean existing) {
14195            this.file = file;
14196            this.cid = cid;
14197            this.staged = staged;
14198            this.existing = existing;
14199
14200            if (cid != null) {
14201                resolvedPath = PackageHelper.getSdDir(cid);
14202                resolvedFile = new File(resolvedPath);
14203            } else if (file != null) {
14204                resolvedPath = file.getAbsolutePath();
14205                resolvedFile = file;
14206            } else {
14207                resolvedPath = null;
14208                resolvedFile = null;
14209            }
14210        }
14211    }
14212
14213    static class MoveInfo {
14214        final int moveId;
14215        final String fromUuid;
14216        final String toUuid;
14217        final String packageName;
14218        final String dataAppName;
14219        final int appId;
14220        final String seinfo;
14221        final int targetSdkVersion;
14222
14223        public MoveInfo(int moveId, String fromUuid, String toUuid, String packageName,
14224                String dataAppName, int appId, String seinfo, int targetSdkVersion) {
14225            this.moveId = moveId;
14226            this.fromUuid = fromUuid;
14227            this.toUuid = toUuid;
14228            this.packageName = packageName;
14229            this.dataAppName = dataAppName;
14230            this.appId = appId;
14231            this.seinfo = seinfo;
14232            this.targetSdkVersion = targetSdkVersion;
14233        }
14234    }
14235
14236    static class VerificationInfo {
14237        /** A constant used to indicate that a uid value is not present. */
14238        public static final int NO_UID = -1;
14239
14240        /** URI referencing where the package was downloaded from. */
14241        final Uri originatingUri;
14242
14243        /** HTTP referrer URI associated with the originatingURI. */
14244        final Uri referrer;
14245
14246        /** UID of the application that the install request originated from. */
14247        final int originatingUid;
14248
14249        /** UID of application requesting the install */
14250        final int installerUid;
14251
14252        VerificationInfo(Uri originatingUri, Uri referrer, int originatingUid, int installerUid) {
14253            this.originatingUri = originatingUri;
14254            this.referrer = referrer;
14255            this.originatingUid = originatingUid;
14256            this.installerUid = installerUid;
14257        }
14258    }
14259
14260    class InstallParams extends HandlerParams {
14261        final OriginInfo origin;
14262        final MoveInfo move;
14263        final IPackageInstallObserver2 observer;
14264        int installFlags;
14265        final String installerPackageName;
14266        final String volumeUuid;
14267        private InstallArgs mArgs;
14268        private int mRet;
14269        final String packageAbiOverride;
14270        final String[] grantedRuntimePermissions;
14271        final VerificationInfo verificationInfo;
14272        final Certificate[][] certificates;
14273        final int installReason;
14274
14275        InstallParams(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
14276                int installFlags, String installerPackageName, String volumeUuid,
14277                VerificationInfo verificationInfo, UserHandle user, String packageAbiOverride,
14278                String[] grantedPermissions, Certificate[][] certificates, int installReason) {
14279            super(user);
14280            this.origin = origin;
14281            this.move = move;
14282            this.observer = observer;
14283            this.installFlags = installFlags;
14284            this.installerPackageName = installerPackageName;
14285            this.volumeUuid = volumeUuid;
14286            this.verificationInfo = verificationInfo;
14287            this.packageAbiOverride = packageAbiOverride;
14288            this.grantedRuntimePermissions = grantedPermissions;
14289            this.certificates = certificates;
14290            this.installReason = installReason;
14291        }
14292
14293        @Override
14294        public String toString() {
14295            return "InstallParams{" + Integer.toHexString(System.identityHashCode(this))
14296                    + " file=" + origin.file + " cid=" + origin.cid + "}";
14297        }
14298
14299        private int installLocationPolicy(PackageInfoLite pkgLite) {
14300            String packageName = pkgLite.packageName;
14301            int installLocation = pkgLite.installLocation;
14302            boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
14303            // reader
14304            synchronized (mPackages) {
14305                // Currently installed package which the new package is attempting to replace or
14306                // null if no such package is installed.
14307                PackageParser.Package installedPkg = mPackages.get(packageName);
14308                // Package which currently owns the data which the new package will own if installed.
14309                // If an app is unstalled while keeping data (e.g., adb uninstall -k), installedPkg
14310                // will be null whereas dataOwnerPkg will contain information about the package
14311                // which was uninstalled while keeping its data.
14312                PackageParser.Package dataOwnerPkg = installedPkg;
14313                if (dataOwnerPkg  == null) {
14314                    PackageSetting ps = mSettings.mPackages.get(packageName);
14315                    if (ps != null) {
14316                        dataOwnerPkg = ps.pkg;
14317                    }
14318                }
14319
14320                if (dataOwnerPkg != null) {
14321                    // If installed, the package will get access to data left on the device by its
14322                    // predecessor. As a security measure, this is permited only if this is not a
14323                    // version downgrade or if the predecessor package is marked as debuggable and
14324                    // a downgrade is explicitly requested.
14325                    //
14326                    // On debuggable platform builds, downgrades are permitted even for
14327                    // non-debuggable packages to make testing easier. Debuggable platform builds do
14328                    // not offer security guarantees and thus it's OK to disable some security
14329                    // mechanisms to make debugging/testing easier on those builds. However, even on
14330                    // debuggable builds downgrades of packages are permitted only if requested via
14331                    // installFlags. This is because we aim to keep the behavior of debuggable
14332                    // platform builds as close as possible to the behavior of non-debuggable
14333                    // platform builds.
14334                    final boolean downgradeRequested =
14335                            (installFlags & PackageManager.INSTALL_ALLOW_DOWNGRADE) != 0;
14336                    final boolean packageDebuggable =
14337                                (dataOwnerPkg.applicationInfo.flags
14338                                        & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
14339                    final boolean downgradePermitted =
14340                            (downgradeRequested) && ((Build.IS_DEBUGGABLE) || (packageDebuggable));
14341                    if (!downgradePermitted) {
14342                        try {
14343                            checkDowngrade(dataOwnerPkg, pkgLite);
14344                        } catch (PackageManagerException e) {
14345                            Slog.w(TAG, "Downgrade detected: " + e.getMessage());
14346                            return PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE;
14347                        }
14348                    }
14349                }
14350
14351                if (installedPkg != null) {
14352                    if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
14353                        // Check for updated system application.
14354                        if ((installedPkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
14355                            if (onSd) {
14356                                Slog.w(TAG, "Cannot install update to system app on sdcard");
14357                                return PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION;
14358                            }
14359                            return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
14360                        } else {
14361                            if (onSd) {
14362                                // Install flag overrides everything.
14363                                return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
14364                            }
14365                            // If current upgrade specifies particular preference
14366                            if (installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) {
14367                                // Application explicitly specified internal.
14368                                return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
14369                            } else if (installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) {
14370                                // App explictly prefers external. Let policy decide
14371                            } else {
14372                                // Prefer previous location
14373                                if (isExternal(installedPkg)) {
14374                                    return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
14375                                }
14376                                return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
14377                            }
14378                        }
14379                    } else {
14380                        // Invalid install. Return error code
14381                        return PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS;
14382                    }
14383                }
14384            }
14385            // All the special cases have been taken care of.
14386            // Return result based on recommended install location.
14387            if (onSd) {
14388                return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
14389            }
14390            return pkgLite.recommendedInstallLocation;
14391        }
14392
14393        /*
14394         * Invoke remote method to get package information and install
14395         * location values. Override install location based on default
14396         * policy if needed and then create install arguments based
14397         * on the install location.
14398         */
14399        public void handleStartCopy() throws RemoteException {
14400            int ret = PackageManager.INSTALL_SUCCEEDED;
14401
14402            // If we're already staged, we've firmly committed to an install location
14403            if (origin.staged) {
14404                if (origin.file != null) {
14405                    installFlags |= PackageManager.INSTALL_INTERNAL;
14406                    installFlags &= ~PackageManager.INSTALL_EXTERNAL;
14407                } else if (origin.cid != null) {
14408                    installFlags |= PackageManager.INSTALL_EXTERNAL;
14409                    installFlags &= ~PackageManager.INSTALL_INTERNAL;
14410                } else {
14411                    throw new IllegalStateException("Invalid stage location");
14412                }
14413            }
14414
14415            final boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
14416            final boolean onInt = (installFlags & PackageManager.INSTALL_INTERNAL) != 0;
14417            final boolean ephemeral = (installFlags & PackageManager.INSTALL_EPHEMERAL) != 0;
14418            PackageInfoLite pkgLite = null;
14419
14420            if (onInt && onSd) {
14421                // Check if both bits are set.
14422                Slog.w(TAG, "Conflicting flags specified for installing on both internal and external");
14423                ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
14424            } else if (onSd && ephemeral) {
14425                Slog.w(TAG,  "Conflicting flags specified for installing ephemeral on external");
14426                ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
14427            } else {
14428                pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, installFlags,
14429                        packageAbiOverride);
14430
14431                if (DEBUG_EPHEMERAL && ephemeral) {
14432                    Slog.v(TAG, "pkgLite for install: " + pkgLite);
14433                }
14434
14435                /*
14436                 * If we have too little free space, try to free cache
14437                 * before giving up.
14438                 */
14439                if (!origin.staged && pkgLite.recommendedInstallLocation
14440                        == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
14441                    // TODO: focus freeing disk space on the target device
14442                    final StorageManager storage = StorageManager.from(mContext);
14443                    final long lowThreshold = storage.getStorageLowBytes(
14444                            Environment.getDataDirectory());
14445
14446                    final long sizeBytes = mContainerService.calculateInstalledSize(
14447                            origin.resolvedPath, isForwardLocked(), packageAbiOverride);
14448
14449                    try {
14450                        mInstaller.freeCache(null, sizeBytes + lowThreshold, 0);
14451                        pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath,
14452                                installFlags, packageAbiOverride);
14453                    } catch (InstallerException e) {
14454                        Slog.w(TAG, "Failed to free cache", e);
14455                    }
14456
14457                    /*
14458                     * The cache free must have deleted the file we
14459                     * downloaded to install.
14460                     *
14461                     * TODO: fix the "freeCache" call to not delete
14462                     *       the file we care about.
14463                     */
14464                    if (pkgLite.recommendedInstallLocation
14465                            == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
14466                        pkgLite.recommendedInstallLocation
14467                            = PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE;
14468                    }
14469                }
14470            }
14471
14472            if (ret == PackageManager.INSTALL_SUCCEEDED) {
14473                int loc = pkgLite.recommendedInstallLocation;
14474                if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION) {
14475                    ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
14476                } else if (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS) {
14477                    ret = PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
14478                } else if (loc == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
14479                    ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
14480                } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_APK) {
14481                    ret = PackageManager.INSTALL_FAILED_INVALID_APK;
14482                } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
14483                    ret = PackageManager.INSTALL_FAILED_INVALID_URI;
14484                } else if (loc == PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE) {
14485                    ret = PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE;
14486                } else {
14487                    // Override with defaults if needed.
14488                    loc = installLocationPolicy(pkgLite);
14489                    if (loc == PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE) {
14490                        ret = PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
14491                    } else if (!onSd && !onInt) {
14492                        // Override install location with flags
14493                        if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) {
14494                            // Set the flag to install on external media.
14495                            installFlags |= PackageManager.INSTALL_EXTERNAL;
14496                            installFlags &= ~PackageManager.INSTALL_INTERNAL;
14497                        } else if (loc == PackageHelper.RECOMMEND_INSTALL_EPHEMERAL) {
14498                            if (DEBUG_EPHEMERAL) {
14499                                Slog.v(TAG, "...setting INSTALL_EPHEMERAL install flag");
14500                            }
14501                            installFlags |= PackageManager.INSTALL_EPHEMERAL;
14502                            installFlags &= ~(PackageManager.INSTALL_EXTERNAL
14503                                    |PackageManager.INSTALL_INTERNAL);
14504                        } else {
14505                            // Make sure the flag for installing on external
14506                            // media is unset
14507                            installFlags |= PackageManager.INSTALL_INTERNAL;
14508                            installFlags &= ~PackageManager.INSTALL_EXTERNAL;
14509                        }
14510                    }
14511                }
14512            }
14513
14514            final InstallArgs args = createInstallArgs(this);
14515            mArgs = args;
14516
14517            if (ret == PackageManager.INSTALL_SUCCEEDED) {
14518                // TODO: http://b/22976637
14519                // Apps installed for "all" users use the device owner to verify the app
14520                UserHandle verifierUser = getUser();
14521                if (verifierUser == UserHandle.ALL) {
14522                    verifierUser = UserHandle.SYSTEM;
14523                }
14524
14525                /*
14526                 * Determine if we have any installed package verifiers. If we
14527                 * do, then we'll defer to them to verify the packages.
14528                 */
14529                final int requiredUid = mRequiredVerifierPackage == null ? -1
14530                        : getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
14531                                verifierUser.getIdentifier());
14532                if (!origin.existing && requiredUid != -1
14533                        && isVerificationEnabled(verifierUser.getIdentifier(), installFlags)) {
14534                    final Intent verification = new Intent(
14535                            Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
14536                    verification.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14537                    verification.setDataAndType(Uri.fromFile(new File(origin.resolvedPath)),
14538                            PACKAGE_MIME_TYPE);
14539                    verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
14540
14541                    // Query all live verifiers based on current user state
14542                    final List<ResolveInfo> receivers = queryIntentReceiversInternal(verification,
14543                            PACKAGE_MIME_TYPE, 0, verifierUser.getIdentifier());
14544
14545                    if (DEBUG_VERIFY) {
14546                        Slog.d(TAG, "Found " + receivers.size() + " verifiers for intent "
14547                                + verification.toString() + " with " + pkgLite.verifiers.length
14548                                + " optional verifiers");
14549                    }
14550
14551                    final int verificationId = mPendingVerificationToken++;
14552
14553                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
14554
14555                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_PACKAGE,
14556                            installerPackageName);
14557
14558                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALL_FLAGS,
14559                            installFlags);
14560
14561                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_PACKAGE_NAME,
14562                            pkgLite.packageName);
14563
14564                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_VERSION_CODE,
14565                            pkgLite.versionCode);
14566
14567                    if (verificationInfo != null) {
14568                        if (verificationInfo.originatingUri != null) {
14569                            verification.putExtra(Intent.EXTRA_ORIGINATING_URI,
14570                                    verificationInfo.originatingUri);
14571                        }
14572                        if (verificationInfo.referrer != null) {
14573                            verification.putExtra(Intent.EXTRA_REFERRER,
14574                                    verificationInfo.referrer);
14575                        }
14576                        if (verificationInfo.originatingUid >= 0) {
14577                            verification.putExtra(Intent.EXTRA_ORIGINATING_UID,
14578                                    verificationInfo.originatingUid);
14579                        }
14580                        if (verificationInfo.installerUid >= 0) {
14581                            verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_UID,
14582                                    verificationInfo.installerUid);
14583                        }
14584                    }
14585
14586                    final PackageVerificationState verificationState = new PackageVerificationState(
14587                            requiredUid, args);
14588
14589                    mPendingVerification.append(verificationId, verificationState);
14590
14591                    final List<ComponentName> sufficientVerifiers = matchVerifiers(pkgLite,
14592                            receivers, verificationState);
14593
14594                    /*
14595                     * If any sufficient verifiers were listed in the package
14596                     * manifest, attempt to ask them.
14597                     */
14598                    if (sufficientVerifiers != null) {
14599                        final int N = sufficientVerifiers.size();
14600                        if (N == 0) {
14601                            Slog.i(TAG, "Additional verifiers required, but none installed.");
14602                            ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
14603                        } else {
14604                            for (int i = 0; i < N; i++) {
14605                                final ComponentName verifierComponent = sufficientVerifiers.get(i);
14606
14607                                final Intent sufficientIntent = new Intent(verification);
14608                                sufficientIntent.setComponent(verifierComponent);
14609                                mContext.sendBroadcastAsUser(sufficientIntent, verifierUser);
14610                            }
14611                        }
14612                    }
14613
14614                    final ComponentName requiredVerifierComponent = matchComponentForVerifier(
14615                            mRequiredVerifierPackage, receivers);
14616                    if (ret == PackageManager.INSTALL_SUCCEEDED
14617                            && mRequiredVerifierPackage != null) {
14618                        Trace.asyncTraceBegin(
14619                                TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
14620                        /*
14621                         * Send the intent to the required verification agent,
14622                         * but only start the verification timeout after the
14623                         * target BroadcastReceivers have run.
14624                         */
14625                        verification.setComponent(requiredVerifierComponent);
14626                        mContext.sendOrderedBroadcastAsUser(verification, verifierUser,
14627                                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
14628                                new BroadcastReceiver() {
14629                                    @Override
14630                                    public void onReceive(Context context, Intent intent) {
14631                                        final Message msg = mHandler
14632                                                .obtainMessage(CHECK_PENDING_VERIFICATION);
14633                                        msg.arg1 = verificationId;
14634                                        mHandler.sendMessageDelayed(msg, getVerificationTimeout());
14635                                    }
14636                                }, null, 0, null, null);
14637
14638                        /*
14639                         * We don't want the copy to proceed until verification
14640                         * succeeds, so null out this field.
14641                         */
14642                        mArgs = null;
14643                    }
14644                } else {
14645                    /*
14646                     * No package verification is enabled, so immediately start
14647                     * the remote call to initiate copy using temporary file.
14648                     */
14649                    ret = args.copyApk(mContainerService, true);
14650                }
14651            }
14652
14653            mRet = ret;
14654        }
14655
14656        @Override
14657        void handleReturnCode() {
14658            // If mArgs is null, then MCS couldn't be reached. When it
14659            // reconnects, it will try again to install. At that point, this
14660            // will succeed.
14661            if (mArgs != null) {
14662                processPendingInstall(mArgs, mRet);
14663            }
14664        }
14665
14666        @Override
14667        void handleServiceError() {
14668            mArgs = createInstallArgs(this);
14669            mRet = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
14670        }
14671
14672        public boolean isForwardLocked() {
14673            return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
14674        }
14675    }
14676
14677    /**
14678     * Used during creation of InstallArgs
14679     *
14680     * @param installFlags package installation flags
14681     * @return true if should be installed on external storage
14682     */
14683    private static boolean installOnExternalAsec(int installFlags) {
14684        if ((installFlags & PackageManager.INSTALL_INTERNAL) != 0) {
14685            return false;
14686        }
14687        if ((installFlags & PackageManager.INSTALL_EXTERNAL) != 0) {
14688            return true;
14689        }
14690        return false;
14691    }
14692
14693    /**
14694     * Used during creation of InstallArgs
14695     *
14696     * @param installFlags package installation flags
14697     * @return true if should be installed as forward locked
14698     */
14699    private static boolean installForwardLocked(int installFlags) {
14700        return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
14701    }
14702
14703    private InstallArgs createInstallArgs(InstallParams params) {
14704        if (params.move != null) {
14705            return new MoveInstallArgs(params);
14706        } else if (installOnExternalAsec(params.installFlags) || params.isForwardLocked()) {
14707            return new AsecInstallArgs(params);
14708        } else {
14709            return new FileInstallArgs(params);
14710        }
14711    }
14712
14713    /**
14714     * Create args that describe an existing installed package. Typically used
14715     * when cleaning up old installs, or used as a move source.
14716     */
14717    private InstallArgs createInstallArgsForExisting(int installFlags, String codePath,
14718            String resourcePath, String[] instructionSets) {
14719        final boolean isInAsec;
14720        if (installOnExternalAsec(installFlags)) {
14721            /* Apps on SD card are always in ASEC containers. */
14722            isInAsec = true;
14723        } else if (installForwardLocked(installFlags)
14724                && !codePath.startsWith(mDrmAppPrivateInstallDir.getAbsolutePath())) {
14725            /*
14726             * Forward-locked apps are only in ASEC containers if they're the
14727             * new style
14728             */
14729            isInAsec = true;
14730        } else {
14731            isInAsec = false;
14732        }
14733
14734        if (isInAsec) {
14735            return new AsecInstallArgs(codePath, instructionSets,
14736                    installOnExternalAsec(installFlags), installForwardLocked(installFlags));
14737        } else {
14738            return new FileInstallArgs(codePath, resourcePath, instructionSets);
14739        }
14740    }
14741
14742    static abstract class InstallArgs {
14743        /** @see InstallParams#origin */
14744        final OriginInfo origin;
14745        /** @see InstallParams#move */
14746        final MoveInfo move;
14747
14748        final IPackageInstallObserver2 observer;
14749        // Always refers to PackageManager flags only
14750        final int installFlags;
14751        final String installerPackageName;
14752        final String volumeUuid;
14753        final UserHandle user;
14754        final String abiOverride;
14755        final String[] installGrantPermissions;
14756        /** If non-null, drop an async trace when the install completes */
14757        final String traceMethod;
14758        final int traceCookie;
14759        final Certificate[][] certificates;
14760        final int installReason;
14761
14762        // The list of instruction sets supported by this app. This is currently
14763        // only used during the rmdex() phase to clean up resources. We can get rid of this
14764        // if we move dex files under the common app path.
14765        /* nullable */ String[] instructionSets;
14766
14767        InstallArgs(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
14768                int installFlags, String installerPackageName, String volumeUuid,
14769                UserHandle user, String[] instructionSets,
14770                String abiOverride, String[] installGrantPermissions,
14771                String traceMethod, int traceCookie, Certificate[][] certificates,
14772                int installReason) {
14773            this.origin = origin;
14774            this.move = move;
14775            this.installFlags = installFlags;
14776            this.observer = observer;
14777            this.installerPackageName = installerPackageName;
14778            this.volumeUuid = volumeUuid;
14779            this.user = user;
14780            this.instructionSets = instructionSets;
14781            this.abiOverride = abiOverride;
14782            this.installGrantPermissions = installGrantPermissions;
14783            this.traceMethod = traceMethod;
14784            this.traceCookie = traceCookie;
14785            this.certificates = certificates;
14786            this.installReason = installReason;
14787        }
14788
14789        abstract int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException;
14790        abstract int doPreInstall(int status);
14791
14792        /**
14793         * Rename package into final resting place. All paths on the given
14794         * scanned package should be updated to reflect the rename.
14795         */
14796        abstract boolean doRename(int status, PackageParser.Package pkg, String oldCodePath);
14797        abstract int doPostInstall(int status, int uid);
14798
14799        /** @see PackageSettingBase#codePathString */
14800        abstract String getCodePath();
14801        /** @see PackageSettingBase#resourcePathString */
14802        abstract String getResourcePath();
14803
14804        // Need installer lock especially for dex file removal.
14805        abstract void cleanUpResourcesLI();
14806        abstract boolean doPostDeleteLI(boolean delete);
14807
14808        /**
14809         * Called before the source arguments are copied. This is used mostly
14810         * for MoveParams when it needs to read the source file to put it in the
14811         * destination.
14812         */
14813        int doPreCopy() {
14814            return PackageManager.INSTALL_SUCCEEDED;
14815        }
14816
14817        /**
14818         * Called after the source arguments are copied. This is used mostly for
14819         * MoveParams when it needs to read the source file to put it in the
14820         * destination.
14821         */
14822        int doPostCopy(int uid) {
14823            return PackageManager.INSTALL_SUCCEEDED;
14824        }
14825
14826        protected boolean isFwdLocked() {
14827            return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
14828        }
14829
14830        protected boolean isExternalAsec() {
14831            return (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
14832        }
14833
14834        protected boolean isEphemeral() {
14835            return (installFlags & PackageManager.INSTALL_EPHEMERAL) != 0;
14836        }
14837
14838        UserHandle getUser() {
14839            return user;
14840        }
14841    }
14842
14843    private void removeDexFiles(List<String> allCodePaths, String[] instructionSets) {
14844        if (!allCodePaths.isEmpty()) {
14845            if (instructionSets == null) {
14846                throw new IllegalStateException("instructionSet == null");
14847            }
14848            String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
14849            for (String codePath : allCodePaths) {
14850                for (String dexCodeInstructionSet : dexCodeInstructionSets) {
14851                    try {
14852                        mInstaller.rmdex(codePath, dexCodeInstructionSet);
14853                    } catch (InstallerException ignored) {
14854                    }
14855                }
14856            }
14857        }
14858    }
14859
14860    /**
14861     * Logic to handle installation of non-ASEC applications, including copying
14862     * and renaming logic.
14863     */
14864    class FileInstallArgs extends InstallArgs {
14865        private File codeFile;
14866        private File resourceFile;
14867
14868        // Example topology:
14869        // /data/app/com.example/base.apk
14870        // /data/app/com.example/split_foo.apk
14871        // /data/app/com.example/lib/arm/libfoo.so
14872        // /data/app/com.example/lib/arm64/libfoo.so
14873        // /data/app/com.example/dalvik/arm/base.apk@classes.dex
14874
14875        /** New install */
14876        FileInstallArgs(InstallParams params) {
14877            super(params.origin, params.move, params.observer, params.installFlags,
14878                    params.installerPackageName, params.volumeUuid,
14879                    params.getUser(), null /*instructionSets*/, params.packageAbiOverride,
14880                    params.grantedRuntimePermissions,
14881                    params.traceMethod, params.traceCookie, params.certificates,
14882                    params.installReason);
14883            if (isFwdLocked()) {
14884                throw new IllegalArgumentException("Forward locking only supported in ASEC");
14885            }
14886        }
14887
14888        /** Existing install */
14889        FileInstallArgs(String codePath, String resourcePath, String[] instructionSets) {
14890            super(OriginInfo.fromNothing(), null, null, 0, null, null, null, instructionSets,
14891                    null, null, null, 0, null /*certificates*/,
14892                    PackageManager.INSTALL_REASON_UNKNOWN);
14893            this.codeFile = (codePath != null) ? new File(codePath) : null;
14894            this.resourceFile = (resourcePath != null) ? new File(resourcePath) : null;
14895        }
14896
14897        int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
14898            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyApk");
14899            try {
14900                return doCopyApk(imcs, temp);
14901            } finally {
14902                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
14903            }
14904        }
14905
14906        private int doCopyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
14907            if (origin.staged) {
14908                if (DEBUG_INSTALL) Slog.d(TAG, origin.file + " already staged; skipping copy");
14909                codeFile = origin.file;
14910                resourceFile = origin.file;
14911                return PackageManager.INSTALL_SUCCEEDED;
14912            }
14913
14914            try {
14915                final boolean isEphemeral = (installFlags & PackageManager.INSTALL_EPHEMERAL) != 0;
14916                final File tempDir =
14917                        mInstallerService.allocateStageDirLegacy(volumeUuid, isEphemeral);
14918                codeFile = tempDir;
14919                resourceFile = tempDir;
14920            } catch (IOException e) {
14921                Slog.w(TAG, "Failed to create copy file: " + e);
14922                return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
14923            }
14924
14925            final IParcelFileDescriptorFactory target = new IParcelFileDescriptorFactory.Stub() {
14926                @Override
14927                public ParcelFileDescriptor open(String name, int mode) throws RemoteException {
14928                    if (!FileUtils.isValidExtFilename(name)) {
14929                        throw new IllegalArgumentException("Invalid filename: " + name);
14930                    }
14931                    try {
14932                        final File file = new File(codeFile, name);
14933                        final FileDescriptor fd = Os.open(file.getAbsolutePath(),
14934                                O_RDWR | O_CREAT, 0644);
14935                        Os.chmod(file.getAbsolutePath(), 0644);
14936                        return new ParcelFileDescriptor(fd);
14937                    } catch (ErrnoException e) {
14938                        throw new RemoteException("Failed to open: " + e.getMessage());
14939                    }
14940                }
14941            };
14942
14943            int ret = PackageManager.INSTALL_SUCCEEDED;
14944            ret = imcs.copyPackage(origin.file.getAbsolutePath(), target);
14945            if (ret != PackageManager.INSTALL_SUCCEEDED) {
14946                Slog.e(TAG, "Failed to copy package");
14947                return ret;
14948            }
14949
14950            final File libraryRoot = new File(codeFile, LIB_DIR_NAME);
14951            NativeLibraryHelper.Handle handle = null;
14952            try {
14953                handle = NativeLibraryHelper.Handle.create(codeFile);
14954                ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot,
14955                        abiOverride);
14956            } catch (IOException e) {
14957                Slog.e(TAG, "Copying native libraries failed", e);
14958                ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
14959            } finally {
14960                IoUtils.closeQuietly(handle);
14961            }
14962
14963            return ret;
14964        }
14965
14966        int doPreInstall(int status) {
14967            if (status != PackageManager.INSTALL_SUCCEEDED) {
14968                cleanUp();
14969            }
14970            return status;
14971        }
14972
14973        boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
14974            if (status != PackageManager.INSTALL_SUCCEEDED) {
14975                cleanUp();
14976                return false;
14977            }
14978
14979            final File targetDir = codeFile.getParentFile();
14980            final File beforeCodeFile = codeFile;
14981            final File afterCodeFile = getNextCodePath(targetDir, pkg.packageName);
14982
14983            if (DEBUG_INSTALL) Slog.d(TAG, "Renaming " + beforeCodeFile + " to " + afterCodeFile);
14984            try {
14985                Os.rename(beforeCodeFile.getAbsolutePath(), afterCodeFile.getAbsolutePath());
14986            } catch (ErrnoException e) {
14987                Slog.w(TAG, "Failed to rename", e);
14988                return false;
14989            }
14990
14991            if (!SELinux.restoreconRecursive(afterCodeFile)) {
14992                Slog.w(TAG, "Failed to restorecon");
14993                return false;
14994            }
14995
14996            // Reflect the rename internally
14997            codeFile = afterCodeFile;
14998            resourceFile = afterCodeFile;
14999
15000            // Reflect the rename in scanned details
15001            pkg.setCodePath(afterCodeFile.getAbsolutePath());
15002            pkg.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile,
15003                    afterCodeFile, pkg.baseCodePath));
15004            pkg.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile,
15005                    afterCodeFile, pkg.splitCodePaths));
15006
15007            // Reflect the rename in app info
15008            pkg.setApplicationVolumeUuid(pkg.volumeUuid);
15009            pkg.setApplicationInfoCodePath(pkg.codePath);
15010            pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
15011            pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
15012            pkg.setApplicationInfoResourcePath(pkg.codePath);
15013            pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
15014            pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
15015
15016            return true;
15017        }
15018
15019        int doPostInstall(int status, int uid) {
15020            if (status != PackageManager.INSTALL_SUCCEEDED) {
15021                cleanUp();
15022            }
15023            return status;
15024        }
15025
15026        @Override
15027        String getCodePath() {
15028            return (codeFile != null) ? codeFile.getAbsolutePath() : null;
15029        }
15030
15031        @Override
15032        String getResourcePath() {
15033            return (resourceFile != null) ? resourceFile.getAbsolutePath() : null;
15034        }
15035
15036        private boolean cleanUp() {
15037            if (codeFile == null || !codeFile.exists()) {
15038                return false;
15039            }
15040
15041            removeCodePathLI(codeFile);
15042
15043            if (resourceFile != null && !FileUtils.contains(codeFile, resourceFile)) {
15044                resourceFile.delete();
15045            }
15046
15047            return true;
15048        }
15049
15050        void cleanUpResourcesLI() {
15051            // Try enumerating all code paths before deleting
15052            List<String> allCodePaths = Collections.EMPTY_LIST;
15053            if (codeFile != null && codeFile.exists()) {
15054                try {
15055                    final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0);
15056                    allCodePaths = pkg.getAllCodePaths();
15057                } catch (PackageParserException e) {
15058                    // Ignored; we tried our best
15059                }
15060            }
15061
15062            cleanUp();
15063            removeDexFiles(allCodePaths, instructionSets);
15064        }
15065
15066        boolean doPostDeleteLI(boolean delete) {
15067            // XXX err, shouldn't we respect the delete flag?
15068            cleanUpResourcesLI();
15069            return true;
15070        }
15071    }
15072
15073    private boolean isAsecExternal(String cid) {
15074        final String asecPath = PackageHelper.getSdFilesystem(cid);
15075        return !asecPath.startsWith(mAsecInternalPath);
15076    }
15077
15078    private static void maybeThrowExceptionForMultiArchCopy(String message, int copyRet) throws
15079            PackageManagerException {
15080        if (copyRet < 0) {
15081            if (copyRet != PackageManager.NO_NATIVE_LIBRARIES &&
15082                    copyRet != PackageManager.INSTALL_FAILED_NO_MATCHING_ABIS) {
15083                throw new PackageManagerException(copyRet, message);
15084            }
15085        }
15086    }
15087
15088    /**
15089     * Extract the StorageManagerService "container ID" from the full code path of an
15090     * .apk.
15091     */
15092    static String cidFromCodePath(String fullCodePath) {
15093        int eidx = fullCodePath.lastIndexOf("/");
15094        String subStr1 = fullCodePath.substring(0, eidx);
15095        int sidx = subStr1.lastIndexOf("/");
15096        return subStr1.substring(sidx+1, eidx);
15097    }
15098
15099    /**
15100     * Logic to handle installation of ASEC applications, including copying and
15101     * renaming logic.
15102     */
15103    class AsecInstallArgs extends InstallArgs {
15104        static final String RES_FILE_NAME = "pkg.apk";
15105        static final String PUBLIC_RES_FILE_NAME = "res.zip";
15106
15107        String cid;
15108        String packagePath;
15109        String resourcePath;
15110
15111        /** New install */
15112        AsecInstallArgs(InstallParams params) {
15113            super(params.origin, params.move, params.observer, params.installFlags,
15114                    params.installerPackageName, params.volumeUuid,
15115                    params.getUser(), null /* instruction sets */, params.packageAbiOverride,
15116                    params.grantedRuntimePermissions,
15117                    params.traceMethod, params.traceCookie, params.certificates,
15118                    params.installReason);
15119        }
15120
15121        /** Existing install */
15122        AsecInstallArgs(String fullCodePath, String[] instructionSets,
15123                        boolean isExternal, boolean isForwardLocked) {
15124            super(OriginInfo.fromNothing(), null, null, (isExternal ? INSTALL_EXTERNAL : 0)
15125                    | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null,
15126                    instructionSets, null, null, null, 0, null /*certificates*/,
15127                    PackageManager.INSTALL_REASON_UNKNOWN);
15128            // Hackily pretend we're still looking at a full code path
15129            if (!fullCodePath.endsWith(RES_FILE_NAME)) {
15130                fullCodePath = new File(fullCodePath, RES_FILE_NAME).getAbsolutePath();
15131            }
15132
15133            // Extract cid from fullCodePath
15134            int eidx = fullCodePath.lastIndexOf("/");
15135            String subStr1 = fullCodePath.substring(0, eidx);
15136            int sidx = subStr1.lastIndexOf("/");
15137            cid = subStr1.substring(sidx+1, eidx);
15138            setMountPath(subStr1);
15139        }
15140
15141        AsecInstallArgs(String cid, String[] instructionSets, boolean isForwardLocked) {
15142            super(OriginInfo.fromNothing(), null, null, (isAsecExternal(cid) ? INSTALL_EXTERNAL : 0)
15143                    | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null,
15144                    instructionSets, null, null, null, 0, null /*certificates*/,
15145                    PackageManager.INSTALL_REASON_UNKNOWN);
15146            this.cid = cid;
15147            setMountPath(PackageHelper.getSdDir(cid));
15148        }
15149
15150        void createCopyFile() {
15151            cid = mInstallerService.allocateExternalStageCidLegacy();
15152        }
15153
15154        int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
15155            if (origin.staged && origin.cid != null) {
15156                if (DEBUG_INSTALL) Slog.d(TAG, origin.cid + " already staged; skipping copy");
15157                cid = origin.cid;
15158                setMountPath(PackageHelper.getSdDir(cid));
15159                return PackageManager.INSTALL_SUCCEEDED;
15160            }
15161
15162            if (temp) {
15163                createCopyFile();
15164            } else {
15165                /*
15166                 * Pre-emptively destroy the container since it's destroyed if
15167                 * copying fails due to it existing anyway.
15168                 */
15169                PackageHelper.destroySdDir(cid);
15170            }
15171
15172            final String newMountPath = imcs.copyPackageToContainer(
15173                    origin.file.getAbsolutePath(), cid, getEncryptKey(), isExternalAsec(),
15174                    isFwdLocked(), deriveAbiOverride(abiOverride, null /* settings */));
15175
15176            if (newMountPath != null) {
15177                setMountPath(newMountPath);
15178                return PackageManager.INSTALL_SUCCEEDED;
15179            } else {
15180                return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
15181            }
15182        }
15183
15184        @Override
15185        String getCodePath() {
15186            return packagePath;
15187        }
15188
15189        @Override
15190        String getResourcePath() {
15191            return resourcePath;
15192        }
15193
15194        int doPreInstall(int status) {
15195            if (status != PackageManager.INSTALL_SUCCEEDED) {
15196                // Destroy container
15197                PackageHelper.destroySdDir(cid);
15198            } else {
15199                boolean mounted = PackageHelper.isContainerMounted(cid);
15200                if (!mounted) {
15201                    String newMountPath = PackageHelper.mountSdDir(cid, getEncryptKey(),
15202                            Process.SYSTEM_UID);
15203                    if (newMountPath != null) {
15204                        setMountPath(newMountPath);
15205                    } else {
15206                        return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
15207                    }
15208                }
15209            }
15210            return status;
15211        }
15212
15213        boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
15214            String newCacheId = getNextCodePath(oldCodePath, pkg.packageName, "/" + RES_FILE_NAME);
15215            String newMountPath = null;
15216            if (PackageHelper.isContainerMounted(cid)) {
15217                // Unmount the container
15218                if (!PackageHelper.unMountSdDir(cid)) {
15219                    Slog.i(TAG, "Failed to unmount " + cid + " before renaming");
15220                    return false;
15221                }
15222            }
15223            if (!PackageHelper.renameSdDir(cid, newCacheId)) {
15224                Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId +
15225                        " which might be stale. Will try to clean up.");
15226                // Clean up the stale container and proceed to recreate.
15227                if (!PackageHelper.destroySdDir(newCacheId)) {
15228                    Slog.e(TAG, "Very strange. Cannot clean up stale container " + newCacheId);
15229                    return false;
15230                }
15231                // Successfully cleaned up stale container. Try to rename again.
15232                if (!PackageHelper.renameSdDir(cid, newCacheId)) {
15233                    Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId
15234                            + " inspite of cleaning it up.");
15235                    return false;
15236                }
15237            }
15238            if (!PackageHelper.isContainerMounted(newCacheId)) {
15239                Slog.w(TAG, "Mounting container " + newCacheId);
15240                newMountPath = PackageHelper.mountSdDir(newCacheId,
15241                        getEncryptKey(), Process.SYSTEM_UID);
15242            } else {
15243                newMountPath = PackageHelper.getSdDir(newCacheId);
15244            }
15245            if (newMountPath == null) {
15246                Slog.w(TAG, "Failed to get cache path for  " + newCacheId);
15247                return false;
15248            }
15249            Log.i(TAG, "Succesfully renamed " + cid +
15250                    " to " + newCacheId +
15251                    " at new path: " + newMountPath);
15252            cid = newCacheId;
15253
15254            final File beforeCodeFile = new File(packagePath);
15255            setMountPath(newMountPath);
15256            final File afterCodeFile = new File(packagePath);
15257
15258            // Reflect the rename in scanned details
15259            pkg.setCodePath(afterCodeFile.getAbsolutePath());
15260            pkg.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile,
15261                    afterCodeFile, pkg.baseCodePath));
15262            pkg.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile,
15263                    afterCodeFile, pkg.splitCodePaths));
15264
15265            // Reflect the rename in app info
15266            pkg.setApplicationVolumeUuid(pkg.volumeUuid);
15267            pkg.setApplicationInfoCodePath(pkg.codePath);
15268            pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
15269            pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
15270            pkg.setApplicationInfoResourcePath(pkg.codePath);
15271            pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
15272            pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
15273
15274            return true;
15275        }
15276
15277        private void setMountPath(String mountPath) {
15278            final File mountFile = new File(mountPath);
15279
15280            final File monolithicFile = new File(mountFile, RES_FILE_NAME);
15281            if (monolithicFile.exists()) {
15282                packagePath = monolithicFile.getAbsolutePath();
15283                if (isFwdLocked()) {
15284                    resourcePath = new File(mountFile, PUBLIC_RES_FILE_NAME).getAbsolutePath();
15285                } else {
15286                    resourcePath = packagePath;
15287                }
15288            } else {
15289                packagePath = mountFile.getAbsolutePath();
15290                resourcePath = packagePath;
15291            }
15292        }
15293
15294        int doPostInstall(int status, int uid) {
15295            if (status != PackageManager.INSTALL_SUCCEEDED) {
15296                cleanUp();
15297            } else {
15298                final int groupOwner;
15299                final String protectedFile;
15300                if (isFwdLocked()) {
15301                    groupOwner = UserHandle.getSharedAppGid(uid);
15302                    protectedFile = RES_FILE_NAME;
15303                } else {
15304                    groupOwner = -1;
15305                    protectedFile = null;
15306                }
15307
15308                if (uid < Process.FIRST_APPLICATION_UID
15309                        || !PackageHelper.fixSdPermissions(cid, groupOwner, protectedFile)) {
15310                    Slog.e(TAG, "Failed to finalize " + cid);
15311                    PackageHelper.destroySdDir(cid);
15312                    return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
15313                }
15314
15315                boolean mounted = PackageHelper.isContainerMounted(cid);
15316                if (!mounted) {
15317                    PackageHelper.mountSdDir(cid, getEncryptKey(), Process.myUid());
15318                }
15319            }
15320            return status;
15321        }
15322
15323        private void cleanUp() {
15324            if (DEBUG_SD_INSTALL) Slog.i(TAG, "cleanUp");
15325
15326            // Destroy secure container
15327            PackageHelper.destroySdDir(cid);
15328        }
15329
15330        private List<String> getAllCodePaths() {
15331            final File codeFile = new File(getCodePath());
15332            if (codeFile != null && codeFile.exists()) {
15333                try {
15334                    final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0);
15335                    return pkg.getAllCodePaths();
15336                } catch (PackageParserException e) {
15337                    // Ignored; we tried our best
15338                }
15339            }
15340            return Collections.EMPTY_LIST;
15341        }
15342
15343        void cleanUpResourcesLI() {
15344            // Enumerate all code paths before deleting
15345            cleanUpResourcesLI(getAllCodePaths());
15346        }
15347
15348        private void cleanUpResourcesLI(List<String> allCodePaths) {
15349            cleanUp();
15350            removeDexFiles(allCodePaths, instructionSets);
15351        }
15352
15353        String getPackageName() {
15354            return getAsecPackageName(cid);
15355        }
15356
15357        boolean doPostDeleteLI(boolean delete) {
15358            if (DEBUG_SD_INSTALL) Slog.i(TAG, "doPostDeleteLI() del=" + delete);
15359            final List<String> allCodePaths = getAllCodePaths();
15360            boolean mounted = PackageHelper.isContainerMounted(cid);
15361            if (mounted) {
15362                // Unmount first
15363                if (PackageHelper.unMountSdDir(cid)) {
15364                    mounted = false;
15365                }
15366            }
15367            if (!mounted && delete) {
15368                cleanUpResourcesLI(allCodePaths);
15369            }
15370            return !mounted;
15371        }
15372
15373        @Override
15374        int doPreCopy() {
15375            if (isFwdLocked()) {
15376                if (!PackageHelper.fixSdPermissions(cid, getPackageUid(DEFAULT_CONTAINER_PACKAGE,
15377                        MATCH_SYSTEM_ONLY, UserHandle.USER_SYSTEM), RES_FILE_NAME)) {
15378                    return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
15379                }
15380            }
15381
15382            return PackageManager.INSTALL_SUCCEEDED;
15383        }
15384
15385        @Override
15386        int doPostCopy(int uid) {
15387            if (isFwdLocked()) {
15388                if (uid < Process.FIRST_APPLICATION_UID
15389                        || !PackageHelper.fixSdPermissions(cid, UserHandle.getSharedAppGid(uid),
15390                                RES_FILE_NAME)) {
15391                    Slog.e(TAG, "Failed to finalize " + cid);
15392                    PackageHelper.destroySdDir(cid);
15393                    return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
15394                }
15395            }
15396
15397            return PackageManager.INSTALL_SUCCEEDED;
15398        }
15399    }
15400
15401    /**
15402     * Logic to handle movement of existing installed applications.
15403     */
15404    class MoveInstallArgs extends InstallArgs {
15405        private File codeFile;
15406        private File resourceFile;
15407
15408        /** New install */
15409        MoveInstallArgs(InstallParams params) {
15410            super(params.origin, params.move, params.observer, params.installFlags,
15411                    params.installerPackageName, params.volumeUuid,
15412                    params.getUser(), null /* instruction sets */, params.packageAbiOverride,
15413                    params.grantedRuntimePermissions,
15414                    params.traceMethod, params.traceCookie, params.certificates,
15415                    params.installReason);
15416        }
15417
15418        int copyApk(IMediaContainerService imcs, boolean temp) {
15419            if (DEBUG_INSTALL) Slog.d(TAG, "Moving " + move.packageName + " from "
15420                    + move.fromUuid + " to " + move.toUuid);
15421            synchronized (mInstaller) {
15422                try {
15423                    mInstaller.moveCompleteApp(move.fromUuid, move.toUuid, move.packageName,
15424                            move.dataAppName, move.appId, move.seinfo, move.targetSdkVersion);
15425                } catch (InstallerException e) {
15426                    Slog.w(TAG, "Failed to move app", e);
15427                    return PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
15428                }
15429            }
15430
15431            codeFile = new File(Environment.getDataAppDirectory(move.toUuid), move.dataAppName);
15432            resourceFile = codeFile;
15433            if (DEBUG_INSTALL) Slog.d(TAG, "codeFile after move is " + codeFile);
15434
15435            return PackageManager.INSTALL_SUCCEEDED;
15436        }
15437
15438        int doPreInstall(int status) {
15439            if (status != PackageManager.INSTALL_SUCCEEDED) {
15440                cleanUp(move.toUuid);
15441            }
15442            return status;
15443        }
15444
15445        boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
15446            if (status != PackageManager.INSTALL_SUCCEEDED) {
15447                cleanUp(move.toUuid);
15448                return false;
15449            }
15450
15451            // Reflect the move in app info
15452            pkg.setApplicationVolumeUuid(pkg.volumeUuid);
15453            pkg.setApplicationInfoCodePath(pkg.codePath);
15454            pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
15455            pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
15456            pkg.setApplicationInfoResourcePath(pkg.codePath);
15457            pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
15458            pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
15459
15460            return true;
15461        }
15462
15463        int doPostInstall(int status, int uid) {
15464            if (status == PackageManager.INSTALL_SUCCEEDED) {
15465                cleanUp(move.fromUuid);
15466            } else {
15467                cleanUp(move.toUuid);
15468            }
15469            return status;
15470        }
15471
15472        @Override
15473        String getCodePath() {
15474            return (codeFile != null) ? codeFile.getAbsolutePath() : null;
15475        }
15476
15477        @Override
15478        String getResourcePath() {
15479            return (resourceFile != null) ? resourceFile.getAbsolutePath() : null;
15480        }
15481
15482        private boolean cleanUp(String volumeUuid) {
15483            final File codeFile = new File(Environment.getDataAppDirectory(volumeUuid),
15484                    move.dataAppName);
15485            Slog.d(TAG, "Cleaning up " + move.packageName + " on " + volumeUuid);
15486            final int[] userIds = sUserManager.getUserIds();
15487            synchronized (mInstallLock) {
15488                // Clean up both app data and code
15489                // All package moves are frozen until finished
15490                for (int userId : userIds) {
15491                    try {
15492                        mInstaller.destroyAppData(volumeUuid, move.packageName, userId,
15493                                StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE, 0);
15494                    } catch (InstallerException e) {
15495                        Slog.w(TAG, String.valueOf(e));
15496                    }
15497                }
15498                removeCodePathLI(codeFile);
15499            }
15500            return true;
15501        }
15502
15503        void cleanUpResourcesLI() {
15504            throw new UnsupportedOperationException();
15505        }
15506
15507        boolean doPostDeleteLI(boolean delete) {
15508            throw new UnsupportedOperationException();
15509        }
15510    }
15511
15512    static String getAsecPackageName(String packageCid) {
15513        int idx = packageCid.lastIndexOf("-");
15514        if (idx == -1) {
15515            return packageCid;
15516        }
15517        return packageCid.substring(0, idx);
15518    }
15519
15520    // Utility method used to create code paths based on package name and available index.
15521    private static String getNextCodePath(String oldCodePath, String prefix, String suffix) {
15522        String idxStr = "";
15523        int idx = 1;
15524        // Fall back to default value of idx=1 if prefix is not
15525        // part of oldCodePath
15526        if (oldCodePath != null) {
15527            String subStr = oldCodePath;
15528            // Drop the suffix right away
15529            if (suffix != null && subStr.endsWith(suffix)) {
15530                subStr = subStr.substring(0, subStr.length() - suffix.length());
15531            }
15532            // If oldCodePath already contains prefix find out the
15533            // ending index to either increment or decrement.
15534            int sidx = subStr.lastIndexOf(prefix);
15535            if (sidx != -1) {
15536                subStr = subStr.substring(sidx + prefix.length());
15537                if (subStr != null) {
15538                    if (subStr.startsWith(INSTALL_PACKAGE_SUFFIX)) {
15539                        subStr = subStr.substring(INSTALL_PACKAGE_SUFFIX.length());
15540                    }
15541                    try {
15542                        idx = Integer.parseInt(subStr);
15543                        if (idx <= 1) {
15544                            idx++;
15545                        } else {
15546                            idx--;
15547                        }
15548                    } catch(NumberFormatException e) {
15549                    }
15550                }
15551            }
15552        }
15553        idxStr = INSTALL_PACKAGE_SUFFIX + Integer.toString(idx);
15554        return prefix + idxStr;
15555    }
15556
15557    private File getNextCodePath(File targetDir, String packageName) {
15558        File result;
15559        SecureRandom random = new SecureRandom();
15560        byte[] bytes = new byte[16];
15561        do {
15562            random.nextBytes(bytes);
15563            String suffix = Base64.encodeToString(bytes, Base64.URL_SAFE | Base64.NO_WRAP);
15564            result = new File(targetDir, packageName + "-" + suffix);
15565        } while (result.exists());
15566        return result;
15567    }
15568
15569    // Utility method that returns the relative package path with respect
15570    // to the installation directory. Like say for /data/data/com.test-1.apk
15571    // string com.test-1 is returned.
15572    static String deriveCodePathName(String codePath) {
15573        if (codePath == null) {
15574            return null;
15575        }
15576        final File codeFile = new File(codePath);
15577        final String name = codeFile.getName();
15578        if (codeFile.isDirectory()) {
15579            return name;
15580        } else if (name.endsWith(".apk") || name.endsWith(".tmp")) {
15581            final int lastDot = name.lastIndexOf('.');
15582            return name.substring(0, lastDot);
15583        } else {
15584            Slog.w(TAG, "Odd, " + codePath + " doesn't look like an APK");
15585            return null;
15586        }
15587    }
15588
15589    static class PackageInstalledInfo {
15590        String name;
15591        int uid;
15592        // The set of users that originally had this package installed.
15593        int[] origUsers;
15594        // The set of users that now have this package installed.
15595        int[] newUsers;
15596        PackageParser.Package pkg;
15597        int returnCode;
15598        String returnMsg;
15599        PackageRemovedInfo removedInfo;
15600        ArrayMap<String, PackageInstalledInfo> addedChildPackages;
15601
15602        public void setError(int code, String msg) {
15603            setReturnCode(code);
15604            setReturnMessage(msg);
15605            Slog.w(TAG, msg);
15606        }
15607
15608        public void setError(String msg, PackageParserException e) {
15609            setReturnCode(e.error);
15610            setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e));
15611            Slog.w(TAG, msg, e);
15612        }
15613
15614        public void setError(String msg, PackageManagerException e) {
15615            returnCode = e.error;
15616            setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e));
15617            Slog.w(TAG, msg, e);
15618        }
15619
15620        public void setReturnCode(int returnCode) {
15621            this.returnCode = returnCode;
15622            final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
15623            for (int i = 0; i < childCount; i++) {
15624                addedChildPackages.valueAt(i).returnCode = returnCode;
15625            }
15626        }
15627
15628        private void setReturnMessage(String returnMsg) {
15629            this.returnMsg = returnMsg;
15630            final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
15631            for (int i = 0; i < childCount; i++) {
15632                addedChildPackages.valueAt(i).returnMsg = returnMsg;
15633            }
15634        }
15635
15636        // In some error cases we want to convey more info back to the observer
15637        String origPackage;
15638        String origPermission;
15639    }
15640
15641    /*
15642     * Install a non-existing package.
15643     */
15644    private void installNewPackageLIF(PackageParser.Package pkg, final int policyFlags,
15645            int scanFlags, UserHandle user, String installerPackageName, String volumeUuid,
15646            PackageInstalledInfo res, int installReason) {
15647        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installNewPackage");
15648
15649        // Remember this for later, in case we need to rollback this install
15650        String pkgName = pkg.packageName;
15651
15652        if (DEBUG_INSTALL) Slog.d(TAG, "installNewPackageLI: " + pkg);
15653
15654        synchronized(mPackages) {
15655            final String renamedPackage = mSettings.getRenamedPackageLPr(pkgName);
15656            if (renamedPackage != null) {
15657                // A package with the same name is already installed, though
15658                // it has been renamed to an older name.  The package we
15659                // are trying to install should be installed as an update to
15660                // the existing one, but that has not been requested, so bail.
15661                res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName
15662                        + " without first uninstalling package running as "
15663                        + renamedPackage);
15664                return;
15665            }
15666            if (mPackages.containsKey(pkgName)) {
15667                // Don't allow installation over an existing package with the same name.
15668                res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName
15669                        + " without first uninstalling.");
15670                return;
15671            }
15672        }
15673
15674        try {
15675            PackageParser.Package newPackage = scanPackageTracedLI(pkg, policyFlags, scanFlags,
15676                    System.currentTimeMillis(), user);
15677
15678            updateSettingsLI(newPackage, installerPackageName, null, res, user, installReason);
15679
15680            if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
15681                prepareAppDataAfterInstallLIF(newPackage);
15682
15683            } else {
15684                // Remove package from internal structures, but keep around any
15685                // data that might have already existed
15686                deletePackageLIF(pkgName, UserHandle.ALL, false, null,
15687                        PackageManager.DELETE_KEEP_DATA, res.removedInfo, true, null);
15688            }
15689        } catch (PackageManagerException e) {
15690            res.setError("Package couldn't be installed in " + pkg.codePath, e);
15691        }
15692
15693        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
15694    }
15695
15696    private boolean shouldCheckUpgradeKeySetLP(PackageSetting oldPs, int scanFlags) {
15697        // Can't rotate keys during boot or if sharedUser.
15698        if (oldPs == null || (scanFlags&SCAN_INITIAL) != 0 || oldPs.sharedUser != null
15699                || !oldPs.keySetData.isUsingUpgradeKeySets()) {
15700            return false;
15701        }
15702        // app is using upgradeKeySets; make sure all are valid
15703        KeySetManagerService ksms = mSettings.mKeySetManagerService;
15704        long[] upgradeKeySets = oldPs.keySetData.getUpgradeKeySets();
15705        for (int i = 0; i < upgradeKeySets.length; i++) {
15706            if (!ksms.isIdValidKeySetId(upgradeKeySets[i])) {
15707                Slog.wtf(TAG, "Package "
15708                         + (oldPs.name != null ? oldPs.name : "<null>")
15709                         + " contains upgrade-key-set reference to unknown key-set: "
15710                         + upgradeKeySets[i]
15711                         + " reverting to signatures check.");
15712                return false;
15713            }
15714        }
15715        return true;
15716    }
15717
15718    private boolean checkUpgradeKeySetLP(PackageSetting oldPS, PackageParser.Package newPkg) {
15719        // Upgrade keysets are being used.  Determine if new package has a superset of the
15720        // required keys.
15721        long[] upgradeKeySets = oldPS.keySetData.getUpgradeKeySets();
15722        KeySetManagerService ksms = mSettings.mKeySetManagerService;
15723        for (int i = 0; i < upgradeKeySets.length; i++) {
15724            Set<PublicKey> upgradeSet = ksms.getPublicKeysFromKeySetLPr(upgradeKeySets[i]);
15725            if (upgradeSet != null && newPkg.mSigningKeys.containsAll(upgradeSet)) {
15726                return true;
15727            }
15728        }
15729        return false;
15730    }
15731
15732    private static void updateDigest(MessageDigest digest, File file) throws IOException {
15733        try (DigestInputStream digestStream =
15734                new DigestInputStream(new FileInputStream(file), digest)) {
15735            while (digestStream.read() != -1) {} // nothing to do; just plow through the file
15736        }
15737    }
15738
15739    private void replacePackageLIF(PackageParser.Package pkg, final int policyFlags, int scanFlags,
15740            UserHandle user, String installerPackageName, PackageInstalledInfo res,
15741            int installReason) {
15742        final boolean isEphemeral = (policyFlags & PackageParser.PARSE_IS_EPHEMERAL) != 0;
15743
15744        final PackageParser.Package oldPackage;
15745        final String pkgName = pkg.packageName;
15746        final int[] allUsers;
15747        final int[] installedUsers;
15748
15749        synchronized(mPackages) {
15750            oldPackage = mPackages.get(pkgName);
15751            if (DEBUG_INSTALL) Slog.d(TAG, "replacePackageLI: new=" + pkg + ", old=" + oldPackage);
15752
15753            // don't allow upgrade to target a release SDK from a pre-release SDK
15754            final boolean oldTargetsPreRelease = oldPackage.applicationInfo.targetSdkVersion
15755                    == android.os.Build.VERSION_CODES.CUR_DEVELOPMENT;
15756            final boolean newTargetsPreRelease = pkg.applicationInfo.targetSdkVersion
15757                    == android.os.Build.VERSION_CODES.CUR_DEVELOPMENT;
15758            if (oldTargetsPreRelease
15759                    && !newTargetsPreRelease
15760                    && ((policyFlags & PackageParser.PARSE_FORCE_SDK) == 0)) {
15761                Slog.w(TAG, "Can't install package targeting released sdk");
15762                res.setReturnCode(PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE);
15763                return;
15764            }
15765
15766            // don't allow an upgrade from full to ephemeral
15767            final boolean oldIsEphemeral = oldPackage.applicationInfo.isInstantApp();
15768            if (isEphemeral && !oldIsEphemeral) {
15769                // can't downgrade from full to ephemeral
15770                Slog.w(TAG, "Can't replace app with ephemeral: " + pkgName);
15771                res.setReturnCode(PackageManager.INSTALL_FAILED_EPHEMERAL_INVALID);
15772                return;
15773            }
15774
15775            // verify signatures are valid
15776            final PackageSetting ps = mSettings.mPackages.get(pkgName);
15777            if (shouldCheckUpgradeKeySetLP(ps, scanFlags)) {
15778                if (!checkUpgradeKeySetLP(ps, pkg)) {
15779                    res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
15780                            "New package not signed by keys specified by upgrade-keysets: "
15781                                    + pkgName);
15782                    return;
15783                }
15784            } else {
15785                // default to original signature matching
15786                if (compareSignatures(oldPackage.mSignatures, pkg.mSignatures)
15787                        != PackageManager.SIGNATURE_MATCH) {
15788                    res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
15789                            "New package has a different signature: " + pkgName);
15790                    return;
15791                }
15792            }
15793
15794            // don't allow a system upgrade unless the upgrade hash matches
15795            if (oldPackage.restrictUpdateHash != null && oldPackage.isSystemApp()) {
15796                byte[] digestBytes = null;
15797                try {
15798                    final MessageDigest digest = MessageDigest.getInstance("SHA-512");
15799                    updateDigest(digest, new File(pkg.baseCodePath));
15800                    if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) {
15801                        for (String path : pkg.splitCodePaths) {
15802                            updateDigest(digest, new File(path));
15803                        }
15804                    }
15805                    digestBytes = digest.digest();
15806                } catch (NoSuchAlgorithmException | IOException e) {
15807                    res.setError(INSTALL_FAILED_INVALID_APK,
15808                            "Could not compute hash: " + pkgName);
15809                    return;
15810                }
15811                if (!Arrays.equals(oldPackage.restrictUpdateHash, digestBytes)) {
15812                    res.setError(INSTALL_FAILED_INVALID_APK,
15813                            "New package fails restrict-update check: " + pkgName);
15814                    return;
15815                }
15816                // retain upgrade restriction
15817                pkg.restrictUpdateHash = oldPackage.restrictUpdateHash;
15818            }
15819
15820            // Check for shared user id changes
15821            String invalidPackageName =
15822                    getParentOrChildPackageChangedSharedUser(oldPackage, pkg);
15823            if (invalidPackageName != null) {
15824                res.setError(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
15825                        "Package " + invalidPackageName + " tried to change user "
15826                                + oldPackage.mSharedUserId);
15827                return;
15828            }
15829
15830            // In case of rollback, remember per-user/profile install state
15831            allUsers = sUserManager.getUserIds();
15832            installedUsers = ps.queryInstalledUsers(allUsers, true);
15833        }
15834
15835        // Update what is removed
15836        res.removedInfo = new PackageRemovedInfo();
15837        res.removedInfo.uid = oldPackage.applicationInfo.uid;
15838        res.removedInfo.removedPackage = oldPackage.packageName;
15839        res.removedInfo.isStaticSharedLib = pkg.staticSharedLibName != null;
15840        res.removedInfo.isUpdate = true;
15841        res.removedInfo.origUsers = installedUsers;
15842        final PackageSetting ps = mSettings.getPackageLPr(pkgName);
15843        res.removedInfo.installReasons = new SparseArray<>(installedUsers.length);
15844        for (int i = 0; i < installedUsers.length; i++) {
15845            final int userId = installedUsers[i];
15846            res.removedInfo.installReasons.put(userId, ps.getInstallReason(userId));
15847        }
15848
15849        final int childCount = (oldPackage.childPackages != null)
15850                ? oldPackage.childPackages.size() : 0;
15851        for (int i = 0; i < childCount; i++) {
15852            boolean childPackageUpdated = false;
15853            PackageParser.Package childPkg = oldPackage.childPackages.get(i);
15854            final PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName);
15855            if (res.addedChildPackages != null) {
15856                PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName);
15857                if (childRes != null) {
15858                    childRes.removedInfo.uid = childPkg.applicationInfo.uid;
15859                    childRes.removedInfo.removedPackage = childPkg.packageName;
15860                    childRes.removedInfo.isUpdate = true;
15861                    childRes.removedInfo.installReasons = res.removedInfo.installReasons;
15862                    childPackageUpdated = true;
15863                }
15864            }
15865            if (!childPackageUpdated) {
15866                PackageRemovedInfo childRemovedRes = new PackageRemovedInfo();
15867                childRemovedRes.removedPackage = childPkg.packageName;
15868                childRemovedRes.isUpdate = false;
15869                childRemovedRes.dataRemoved = true;
15870                synchronized (mPackages) {
15871                    if (childPs != null) {
15872                        childRemovedRes.origUsers = childPs.queryInstalledUsers(allUsers, true);
15873                    }
15874                }
15875                if (res.removedInfo.removedChildPackages == null) {
15876                    res.removedInfo.removedChildPackages = new ArrayMap<>();
15877                }
15878                res.removedInfo.removedChildPackages.put(childPkg.packageName, childRemovedRes);
15879            }
15880        }
15881
15882        boolean sysPkg = (isSystemApp(oldPackage));
15883        if (sysPkg) {
15884            // Set the system/privileged flags as needed
15885            final boolean privileged =
15886                    (oldPackage.applicationInfo.privateFlags
15887                            & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0;
15888            final int systemPolicyFlags = policyFlags
15889                    | PackageParser.PARSE_IS_SYSTEM
15890                    | (privileged ? PackageParser.PARSE_IS_PRIVILEGED : 0);
15891
15892            replaceSystemPackageLIF(oldPackage, pkg, systemPolicyFlags, scanFlags,
15893                    user, allUsers, installerPackageName, res, installReason);
15894        } else {
15895            replaceNonSystemPackageLIF(oldPackage, pkg, policyFlags, scanFlags,
15896                    user, allUsers, installerPackageName, res, installReason);
15897        }
15898    }
15899
15900    public List<String> getPreviousCodePaths(String packageName) {
15901        final PackageSetting ps = mSettings.mPackages.get(packageName);
15902        final List<String> result = new ArrayList<String>();
15903        if (ps != null && ps.oldCodePaths != null) {
15904            result.addAll(ps.oldCodePaths);
15905        }
15906        return result;
15907    }
15908
15909    private void replaceNonSystemPackageLIF(PackageParser.Package deletedPackage,
15910            PackageParser.Package pkg, final int policyFlags, int scanFlags, UserHandle user,
15911            int[] allUsers, String installerPackageName, PackageInstalledInfo res,
15912            int installReason) {
15913        if (DEBUG_INSTALL) Slog.d(TAG, "replaceNonSystemPackageLI: new=" + pkg + ", old="
15914                + deletedPackage);
15915
15916        String pkgName = deletedPackage.packageName;
15917        boolean deletedPkg = true;
15918        boolean addedPkg = false;
15919        boolean updatedSettings = false;
15920        final boolean killApp = (scanFlags & SCAN_DONT_KILL_APP) == 0;
15921        final int deleteFlags = PackageManager.DELETE_KEEP_DATA
15922                | (killApp ? 0 : PackageManager.DELETE_DONT_KILL_APP);
15923
15924        final long origUpdateTime = (pkg.mExtras != null)
15925                ? ((PackageSetting)pkg.mExtras).lastUpdateTime : 0;
15926
15927        // First delete the existing package while retaining the data directory
15928        if (!deletePackageLIF(pkgName, null, true, allUsers, deleteFlags,
15929                res.removedInfo, true, pkg)) {
15930            // If the existing package wasn't successfully deleted
15931            res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE, "replaceNonSystemPackageLI");
15932            deletedPkg = false;
15933        } else {
15934            // Successfully deleted the old package; proceed with replace.
15935
15936            // If deleted package lived in a container, give users a chance to
15937            // relinquish resources before killing.
15938            if (deletedPackage.isForwardLocked() || isExternal(deletedPackage)) {
15939                if (DEBUG_INSTALL) {
15940                    Slog.i(TAG, "upgrading pkg " + deletedPackage + " is ASEC-hosted -> UNAVAILABLE");
15941                }
15942                final int[] uidArray = new int[] { deletedPackage.applicationInfo.uid };
15943                final ArrayList<String> pkgList = new ArrayList<String>(1);
15944                pkgList.add(deletedPackage.applicationInfo.packageName);
15945                sendResourcesChangedBroadcast(false, true, pkgList, uidArray, null);
15946            }
15947
15948            clearAppDataLIF(pkg, UserHandle.USER_ALL, StorageManager.FLAG_STORAGE_DE
15949                    | StorageManager.FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
15950            clearAppProfilesLIF(deletedPackage, UserHandle.USER_ALL);
15951
15952            try {
15953                final PackageParser.Package newPackage = scanPackageTracedLI(pkg, policyFlags,
15954                        scanFlags | SCAN_UPDATE_TIME, System.currentTimeMillis(), user);
15955                updateSettingsLI(newPackage, installerPackageName, allUsers, res, user,
15956                        installReason);
15957
15958                // Update the in-memory copy of the previous code paths.
15959                PackageSetting ps = mSettings.mPackages.get(pkgName);
15960                if (!killApp) {
15961                    if (ps.oldCodePaths == null) {
15962                        ps.oldCodePaths = new ArraySet<>();
15963                    }
15964                    Collections.addAll(ps.oldCodePaths, deletedPackage.baseCodePath);
15965                    if (deletedPackage.splitCodePaths != null) {
15966                        Collections.addAll(ps.oldCodePaths, deletedPackage.splitCodePaths);
15967                    }
15968                } else {
15969                    ps.oldCodePaths = null;
15970                }
15971                if (ps.childPackageNames != null) {
15972                    for (int i = ps.childPackageNames.size() - 1; i >= 0; --i) {
15973                        final String childPkgName = ps.childPackageNames.get(i);
15974                        final PackageSetting childPs = mSettings.mPackages.get(childPkgName);
15975                        childPs.oldCodePaths = ps.oldCodePaths;
15976                    }
15977                }
15978                prepareAppDataAfterInstallLIF(newPackage);
15979                addedPkg = true;
15980            } catch (PackageManagerException e) {
15981                res.setError("Package couldn't be installed in " + pkg.codePath, e);
15982            }
15983        }
15984
15985        if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
15986            if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, rolling pack: " + pkgName);
15987
15988            // Revert all internal state mutations and added folders for the failed install
15989            if (addedPkg) {
15990                deletePackageLIF(pkgName, null, true, allUsers, deleteFlags,
15991                        res.removedInfo, true, null);
15992            }
15993
15994            // Restore the old package
15995            if (deletedPkg) {
15996                if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, reinstalling: " + deletedPackage);
15997                File restoreFile = new File(deletedPackage.codePath);
15998                // Parse old package
15999                boolean oldExternal = isExternal(deletedPackage);
16000                int oldParseFlags  = mDefParseFlags | PackageParser.PARSE_CHATTY |
16001                        (deletedPackage.isForwardLocked() ? PackageParser.PARSE_FORWARD_LOCK : 0) |
16002                        (oldExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0);
16003                int oldScanFlags = SCAN_UPDATE_SIGNATURE | SCAN_UPDATE_TIME;
16004                try {
16005                    scanPackageTracedLI(restoreFile, oldParseFlags, oldScanFlags, origUpdateTime,
16006                            null);
16007                } catch (PackageManagerException e) {
16008                    Slog.e(TAG, "Failed to restore package : " + pkgName + " after failed upgrade: "
16009                            + e.getMessage());
16010                    return;
16011                }
16012
16013                synchronized (mPackages) {
16014                    // Ensure the installer package name up to date
16015                    setInstallerPackageNameLPw(deletedPackage, installerPackageName);
16016
16017                    // Update permissions for restored package
16018                    updatePermissionsLPw(deletedPackage, UPDATE_PERMISSIONS_ALL);
16019
16020                    mSettings.writeLPr();
16021                }
16022
16023                Slog.i(TAG, "Successfully restored package : " + pkgName + " after failed upgrade");
16024            }
16025        } else {
16026            synchronized (mPackages) {
16027                PackageSetting ps = mSettings.getPackageLPr(pkg.packageName);
16028                if (ps != null) {
16029                    res.removedInfo.removedForAllUsers = mPackages.get(ps.name) == null;
16030                    if (res.removedInfo.removedChildPackages != null) {
16031                        final int childCount = res.removedInfo.removedChildPackages.size();
16032                        // Iterate in reverse as we may modify the collection
16033                        for (int i = childCount - 1; i >= 0; i--) {
16034                            String childPackageName = res.removedInfo.removedChildPackages.keyAt(i);
16035                            if (res.addedChildPackages.containsKey(childPackageName)) {
16036                                res.removedInfo.removedChildPackages.removeAt(i);
16037                            } else {
16038                                PackageRemovedInfo childInfo = res.removedInfo
16039                                        .removedChildPackages.valueAt(i);
16040                                childInfo.removedForAllUsers = mPackages.get(
16041                                        childInfo.removedPackage) == null;
16042                            }
16043                        }
16044                    }
16045                }
16046            }
16047        }
16048    }
16049
16050    private void replaceSystemPackageLIF(PackageParser.Package deletedPackage,
16051            PackageParser.Package pkg, final int policyFlags, int scanFlags, UserHandle user,
16052            int[] allUsers, String installerPackageName, PackageInstalledInfo res,
16053            int installReason) {
16054        if (DEBUG_INSTALL) Slog.d(TAG, "replaceSystemPackageLI: new=" + pkg
16055                + ", old=" + deletedPackage);
16056
16057        final boolean disabledSystem;
16058
16059        // Remove existing system package
16060        removePackageLI(deletedPackage, true);
16061
16062        synchronized (mPackages) {
16063            disabledSystem = disableSystemPackageLPw(deletedPackage, pkg);
16064        }
16065        if (!disabledSystem) {
16066            // We didn't need to disable the .apk as a current system package,
16067            // which means we are replacing another update that is already
16068            // installed.  We need to make sure to delete the older one's .apk.
16069            res.removedInfo.args = createInstallArgsForExisting(0,
16070                    deletedPackage.applicationInfo.getCodePath(),
16071                    deletedPackage.applicationInfo.getResourcePath(),
16072                    getAppDexInstructionSets(deletedPackage.applicationInfo));
16073        } else {
16074            res.removedInfo.args = null;
16075        }
16076
16077        // Successfully disabled the old package. Now proceed with re-installation
16078        clearAppDataLIF(pkg, UserHandle.USER_ALL, StorageManager.FLAG_STORAGE_DE
16079                | StorageManager.FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
16080        clearAppProfilesLIF(deletedPackage, UserHandle.USER_ALL);
16081
16082        res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
16083        pkg.setApplicationInfoFlags(ApplicationInfo.FLAG_UPDATED_SYSTEM_APP,
16084                ApplicationInfo.FLAG_UPDATED_SYSTEM_APP);
16085
16086        PackageParser.Package newPackage = null;
16087        try {
16088            // Add the package to the internal data structures
16089            newPackage = scanPackageTracedLI(pkg, policyFlags, scanFlags, 0, user);
16090
16091            // Set the update and install times
16092            PackageSetting deletedPkgSetting = (PackageSetting) deletedPackage.mExtras;
16093            setInstallAndUpdateTime(newPackage, deletedPkgSetting.firstInstallTime,
16094                    System.currentTimeMillis());
16095
16096            // Update the package dynamic state if succeeded
16097            if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
16098                // Now that the install succeeded make sure we remove data
16099                // directories for any child package the update removed.
16100                final int deletedChildCount = (deletedPackage.childPackages != null)
16101                        ? deletedPackage.childPackages.size() : 0;
16102                final int newChildCount = (newPackage.childPackages != null)
16103                        ? newPackage.childPackages.size() : 0;
16104                for (int i = 0; i < deletedChildCount; i++) {
16105                    PackageParser.Package deletedChildPkg = deletedPackage.childPackages.get(i);
16106                    boolean childPackageDeleted = true;
16107                    for (int j = 0; j < newChildCount; j++) {
16108                        PackageParser.Package newChildPkg = newPackage.childPackages.get(j);
16109                        if (deletedChildPkg.packageName.equals(newChildPkg.packageName)) {
16110                            childPackageDeleted = false;
16111                            break;
16112                        }
16113                    }
16114                    if (childPackageDeleted) {
16115                        PackageSetting ps = mSettings.getDisabledSystemPkgLPr(
16116                                deletedChildPkg.packageName);
16117                        if (ps != null && res.removedInfo.removedChildPackages != null) {
16118                            PackageRemovedInfo removedChildRes = res.removedInfo
16119                                    .removedChildPackages.get(deletedChildPkg.packageName);
16120                            removePackageDataLIF(ps, allUsers, removedChildRes, 0, false);
16121                            removedChildRes.removedForAllUsers = mPackages.get(ps.name) == null;
16122                        }
16123                    }
16124                }
16125
16126                updateSettingsLI(newPackage, installerPackageName, allUsers, res, user,
16127                        installReason);
16128                prepareAppDataAfterInstallLIF(newPackage);
16129            }
16130        } catch (PackageManagerException e) {
16131            res.setReturnCode(INSTALL_FAILED_INTERNAL_ERROR);
16132            res.setError("Package couldn't be installed in " + pkg.codePath, e);
16133        }
16134
16135        if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
16136            // Re installation failed. Restore old information
16137            // Remove new pkg information
16138            if (newPackage != null) {
16139                removeInstalledPackageLI(newPackage, true);
16140            }
16141            // Add back the old system package
16142            try {
16143                scanPackageTracedLI(deletedPackage, policyFlags, SCAN_UPDATE_SIGNATURE, 0, user);
16144            } catch (PackageManagerException e) {
16145                Slog.e(TAG, "Failed to restore original package: " + e.getMessage());
16146            }
16147
16148            synchronized (mPackages) {
16149                if (disabledSystem) {
16150                    enableSystemPackageLPw(deletedPackage);
16151                }
16152
16153                // Ensure the installer package name up to date
16154                setInstallerPackageNameLPw(deletedPackage, installerPackageName);
16155
16156                // Update permissions for restored package
16157                updatePermissionsLPw(deletedPackage, UPDATE_PERMISSIONS_ALL);
16158
16159                mSettings.writeLPr();
16160            }
16161
16162            Slog.i(TAG, "Successfully restored package : " + deletedPackage.packageName
16163                    + " after failed upgrade");
16164        }
16165    }
16166
16167    /**
16168     * Checks whether the parent or any of the child packages have a change shared
16169     * user. For a package to be a valid update the shred users of the parent and
16170     * the children should match. We may later support changing child shared users.
16171     * @param oldPkg The updated package.
16172     * @param newPkg The update package.
16173     * @return The shared user that change between the versions.
16174     */
16175    private String getParentOrChildPackageChangedSharedUser(PackageParser.Package oldPkg,
16176            PackageParser.Package newPkg) {
16177        // Check parent shared user
16178        if (!Objects.equals(oldPkg.mSharedUserId, newPkg.mSharedUserId)) {
16179            return newPkg.packageName;
16180        }
16181        // Check child shared users
16182        final int oldChildCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0;
16183        final int newChildCount = (newPkg.childPackages != null) ? newPkg.childPackages.size() : 0;
16184        for (int i = 0; i < newChildCount; i++) {
16185            PackageParser.Package newChildPkg = newPkg.childPackages.get(i);
16186            // If this child was present, did it have the same shared user?
16187            for (int j = 0; j < oldChildCount; j++) {
16188                PackageParser.Package oldChildPkg = oldPkg.childPackages.get(j);
16189                if (newChildPkg.packageName.equals(oldChildPkg.packageName)
16190                        && !Objects.equals(newChildPkg.mSharedUserId, oldChildPkg.mSharedUserId)) {
16191                    return newChildPkg.packageName;
16192                }
16193            }
16194        }
16195        return null;
16196    }
16197
16198    private void removeNativeBinariesLI(PackageSetting ps) {
16199        // Remove the lib path for the parent package
16200        if (ps != null) {
16201            NativeLibraryHelper.removeNativeBinariesLI(ps.legacyNativeLibraryPathString);
16202            // Remove the lib path for the child packages
16203            final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0;
16204            for (int i = 0; i < childCount; i++) {
16205                PackageSetting childPs = null;
16206                synchronized (mPackages) {
16207                    childPs = mSettings.getPackageLPr(ps.childPackageNames.get(i));
16208                }
16209                if (childPs != null) {
16210                    NativeLibraryHelper.removeNativeBinariesLI(childPs
16211                            .legacyNativeLibraryPathString);
16212                }
16213            }
16214        }
16215    }
16216
16217    private void enableSystemPackageLPw(PackageParser.Package pkg) {
16218        // Enable the parent package
16219        mSettings.enableSystemPackageLPw(pkg.packageName);
16220        // Enable the child packages
16221        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
16222        for (int i = 0; i < childCount; i++) {
16223            PackageParser.Package childPkg = pkg.childPackages.get(i);
16224            mSettings.enableSystemPackageLPw(childPkg.packageName);
16225        }
16226    }
16227
16228    private boolean disableSystemPackageLPw(PackageParser.Package oldPkg,
16229            PackageParser.Package newPkg) {
16230        // Disable the parent package (parent always replaced)
16231        boolean disabled = mSettings.disableSystemPackageLPw(oldPkg.packageName, true);
16232        // Disable the child packages
16233        final int childCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0;
16234        for (int i = 0; i < childCount; i++) {
16235            PackageParser.Package childPkg = oldPkg.childPackages.get(i);
16236            final boolean replace = newPkg.hasChildPackage(childPkg.packageName);
16237            disabled |= mSettings.disableSystemPackageLPw(childPkg.packageName, replace);
16238        }
16239        return disabled;
16240    }
16241
16242    private void setInstallerPackageNameLPw(PackageParser.Package pkg,
16243            String installerPackageName) {
16244        // Enable the parent package
16245        mSettings.setInstallerPackageName(pkg.packageName, installerPackageName);
16246        // Enable the child packages
16247        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
16248        for (int i = 0; i < childCount; i++) {
16249            PackageParser.Package childPkg = pkg.childPackages.get(i);
16250            mSettings.setInstallerPackageName(childPkg.packageName, installerPackageName);
16251        }
16252    }
16253
16254    private int[] revokeUnusedSharedUserPermissionsLPw(SharedUserSetting su, int[] allUserIds) {
16255        // Collect all used permissions in the UID
16256        ArraySet<String> usedPermissions = new ArraySet<>();
16257        final int packageCount = su.packages.size();
16258        for (int i = 0; i < packageCount; i++) {
16259            PackageSetting ps = su.packages.valueAt(i);
16260            if (ps.pkg == null) {
16261                continue;
16262            }
16263            final int requestedPermCount = ps.pkg.requestedPermissions.size();
16264            for (int j = 0; j < requestedPermCount; j++) {
16265                String permission = ps.pkg.requestedPermissions.get(j);
16266                BasePermission bp = mSettings.mPermissions.get(permission);
16267                if (bp != null) {
16268                    usedPermissions.add(permission);
16269                }
16270            }
16271        }
16272
16273        PermissionsState permissionsState = su.getPermissionsState();
16274        // Prune install permissions
16275        List<PermissionState> installPermStates = permissionsState.getInstallPermissionStates();
16276        final int installPermCount = installPermStates.size();
16277        for (int i = installPermCount - 1; i >= 0;  i--) {
16278            PermissionState permissionState = installPermStates.get(i);
16279            if (!usedPermissions.contains(permissionState.getName())) {
16280                BasePermission bp = mSettings.mPermissions.get(permissionState.getName());
16281                if (bp != null) {
16282                    permissionsState.revokeInstallPermission(bp);
16283                    permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
16284                            PackageManager.MASK_PERMISSION_FLAGS, 0);
16285                }
16286            }
16287        }
16288
16289        int[] runtimePermissionChangedUserIds = EmptyArray.INT;
16290
16291        // Prune runtime permissions
16292        for (int userId : allUserIds) {
16293            List<PermissionState> runtimePermStates = permissionsState
16294                    .getRuntimePermissionStates(userId);
16295            final int runtimePermCount = runtimePermStates.size();
16296            for (int i = runtimePermCount - 1; i >= 0; i--) {
16297                PermissionState permissionState = runtimePermStates.get(i);
16298                if (!usedPermissions.contains(permissionState.getName())) {
16299                    BasePermission bp = mSettings.mPermissions.get(permissionState.getName());
16300                    if (bp != null) {
16301                        permissionsState.revokeRuntimePermission(bp, userId);
16302                        permissionsState.updatePermissionFlags(bp, userId,
16303                                PackageManager.MASK_PERMISSION_FLAGS, 0);
16304                        runtimePermissionChangedUserIds = ArrayUtils.appendInt(
16305                                runtimePermissionChangedUserIds, userId);
16306                    }
16307                }
16308            }
16309        }
16310
16311        return runtimePermissionChangedUserIds;
16312    }
16313
16314    private void updateSettingsLI(PackageParser.Package newPackage, String installerPackageName,
16315            int[] allUsers, PackageInstalledInfo res, UserHandle user, int installReason) {
16316        // Update the parent package setting
16317        updateSettingsInternalLI(newPackage, installerPackageName, allUsers, res.origUsers,
16318                res, user, installReason);
16319        // Update the child packages setting
16320        final int childCount = (newPackage.childPackages != null)
16321                ? newPackage.childPackages.size() : 0;
16322        for (int i = 0; i < childCount; i++) {
16323            PackageParser.Package childPackage = newPackage.childPackages.get(i);
16324            PackageInstalledInfo childRes = res.addedChildPackages.get(childPackage.packageName);
16325            updateSettingsInternalLI(childPackage, installerPackageName, allUsers,
16326                    childRes.origUsers, childRes, user, installReason);
16327        }
16328    }
16329
16330    private void updateSettingsInternalLI(PackageParser.Package newPackage,
16331            String installerPackageName, int[] allUsers, int[] installedForUsers,
16332            PackageInstalledInfo res, UserHandle user, int installReason) {
16333        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");
16334
16335        String pkgName = newPackage.packageName;
16336        synchronized (mPackages) {
16337            //write settings. the installStatus will be incomplete at this stage.
16338            //note that the new package setting would have already been
16339            //added to mPackages. It hasn't been persisted yet.
16340            mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_INCOMPLETE);
16341            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings");
16342            mSettings.writeLPr();
16343            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16344        }
16345
16346        if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + newPackage.codePath);
16347        synchronized (mPackages) {
16348            updatePermissionsLPw(newPackage.packageName, newPackage,
16349                    UPDATE_PERMISSIONS_REPLACE_PKG | (newPackage.permissions.size() > 0
16350                            ? UPDATE_PERMISSIONS_ALL : 0));
16351            // For system-bundled packages, we assume that installing an upgraded version
16352            // of the package implies that the user actually wants to run that new code,
16353            // so we enable the package.
16354            PackageSetting ps = mSettings.mPackages.get(pkgName);
16355            final int userId = user.getIdentifier();
16356            if (ps != null) {
16357                if (isSystemApp(newPackage)) {
16358                    if (DEBUG_INSTALL) {
16359                        Slog.d(TAG, "Implicitly enabling system package on upgrade: " + pkgName);
16360                    }
16361                    // Enable system package for requested users
16362                    if (res.origUsers != null) {
16363                        for (int origUserId : res.origUsers) {
16364                            if (userId == UserHandle.USER_ALL || userId == origUserId) {
16365                                ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT,
16366                                        origUserId, installerPackageName);
16367                            }
16368                        }
16369                    }
16370                    // Also convey the prior install/uninstall state
16371                    if (allUsers != null && installedForUsers != null) {
16372                        for (int currentUserId : allUsers) {
16373                            final boolean installed = ArrayUtils.contains(
16374                                    installedForUsers, currentUserId);
16375                            if (DEBUG_INSTALL) {
16376                                Slog.d(TAG, "    user " + currentUserId + " => " + installed);
16377                            }
16378                            ps.setInstalled(installed, currentUserId);
16379                        }
16380                        // these install state changes will be persisted in the
16381                        // upcoming call to mSettings.writeLPr().
16382                    }
16383                }
16384                // It's implied that when a user requests installation, they want the app to be
16385                // installed and enabled.
16386                if (userId != UserHandle.USER_ALL) {
16387                    ps.setInstalled(true, userId);
16388                    ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, userId, installerPackageName);
16389                }
16390
16391                // When replacing an existing package, preserve the original install reason for all
16392                // users that had the package installed before.
16393                final Set<Integer> previousUserIds = new ArraySet<>();
16394                if (res.removedInfo != null && res.removedInfo.installReasons != null) {
16395                    final int installReasonCount = res.removedInfo.installReasons.size();
16396                    for (int i = 0; i < installReasonCount; i++) {
16397                        final int previousUserId = res.removedInfo.installReasons.keyAt(i);
16398                        final int previousInstallReason = res.removedInfo.installReasons.valueAt(i);
16399                        ps.setInstallReason(previousInstallReason, previousUserId);
16400                        previousUserIds.add(previousUserId);
16401                    }
16402                }
16403
16404                // Set install reason for users that are having the package newly installed.
16405                if (userId == UserHandle.USER_ALL) {
16406                    for (int currentUserId : sUserManager.getUserIds()) {
16407                        if (!previousUserIds.contains(currentUserId)) {
16408                            ps.setInstallReason(installReason, currentUserId);
16409                        }
16410                    }
16411                } else if (!previousUserIds.contains(userId)) {
16412                    ps.setInstallReason(installReason, userId);
16413                }
16414            }
16415            res.name = pkgName;
16416            res.uid = newPackage.applicationInfo.uid;
16417            res.pkg = newPackage;
16418            mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_COMPLETE);
16419            mSettings.setInstallerPackageName(pkgName, installerPackageName);
16420            res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
16421            //to update install status
16422            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings");
16423            mSettings.writeLPr();
16424            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16425        }
16426
16427        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16428    }
16429
16430    private void installPackageTracedLI(InstallArgs args, PackageInstalledInfo res) {
16431        try {
16432            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installPackage");
16433            installPackageLI(args, res);
16434        } finally {
16435            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16436        }
16437    }
16438
16439    private void installPackageLI(InstallArgs args, PackageInstalledInfo res) {
16440        final int installFlags = args.installFlags;
16441        final String installerPackageName = args.installerPackageName;
16442        final String volumeUuid = args.volumeUuid;
16443        final File tmpPackageFile = new File(args.getCodePath());
16444        final boolean forwardLocked = ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0);
16445        final boolean onExternal = (((installFlags & PackageManager.INSTALL_EXTERNAL) != 0)
16446                || (args.volumeUuid != null));
16447        final boolean ephemeral = ((installFlags & PackageManager.INSTALL_EPHEMERAL) != 0);
16448        final boolean forceSdk = ((installFlags & PackageManager.INSTALL_FORCE_SDK) != 0);
16449        boolean replace = false;
16450        int scanFlags = SCAN_NEW_INSTALL | SCAN_UPDATE_SIGNATURE;
16451        if (args.move != null) {
16452            // moving a complete application; perform an initial scan on the new install location
16453            scanFlags |= SCAN_INITIAL;
16454        }
16455        if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) {
16456            scanFlags |= SCAN_DONT_KILL_APP;
16457        }
16458
16459        // Result object to be returned
16460        res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
16461
16462        if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile);
16463
16464        // Sanity check
16465        if (ephemeral && (forwardLocked || onExternal)) {
16466            Slog.i(TAG, "Incompatible ephemeral install; fwdLocked=" + forwardLocked
16467                    + " external=" + onExternal);
16468            res.setReturnCode(PackageManager.INSTALL_FAILED_EPHEMERAL_INVALID);
16469            return;
16470        }
16471
16472        // Retrieve PackageSettings and parse package
16473        final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY
16474                | PackageParser.PARSE_ENFORCE_CODE
16475                | (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0)
16476                | (onExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0)
16477                | (ephemeral ? PackageParser.PARSE_IS_EPHEMERAL : 0)
16478                | (forceSdk ? PackageParser.PARSE_FORCE_SDK : 0);
16479        PackageParser pp = new PackageParser();
16480        pp.setSeparateProcesses(mSeparateProcesses);
16481        pp.setDisplayMetrics(mMetrics);
16482
16483        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
16484        final PackageParser.Package pkg;
16485        try {
16486            pkg = pp.parsePackage(tmpPackageFile, parseFlags);
16487        } catch (PackageParserException e) {
16488            res.setError("Failed parse during installPackageLI", e);
16489            return;
16490        } finally {
16491            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16492        }
16493
16494//        // Ephemeral apps must have target SDK >= O.
16495//        // TODO: Update conditional and error message when O gets locked down
16496//        if (ephemeral && pkg.applicationInfo.targetSdkVersion <= Build.VERSION_CODES.N_MR1) {
16497//            res.setError(PackageManager.INSTALL_FAILED_EPHEMERAL_INVALID,
16498//                    "Ephemeral apps must have target SDK version of at least O");
16499//            return;
16500//        }
16501
16502        if (pkg.applicationInfo.isStaticSharedLibrary()) {
16503            // Static shared libraries have synthetic package names
16504            renameStaticSharedLibraryPackage(pkg);
16505
16506            // No static shared libs on external storage
16507            if (onExternal) {
16508                Slog.i(TAG, "Static shared libs can only be installed on internal storage.");
16509                res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
16510                        "Packages declaring static-shared libs cannot be updated");
16511                return;
16512            }
16513        }
16514
16515        // If we are installing a clustered package add results for the children
16516        if (pkg.childPackages != null) {
16517            synchronized (mPackages) {
16518                final int childCount = pkg.childPackages.size();
16519                for (int i = 0; i < childCount; i++) {
16520                    PackageParser.Package childPkg = pkg.childPackages.get(i);
16521                    PackageInstalledInfo childRes = new PackageInstalledInfo();
16522                    childRes.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
16523                    childRes.pkg = childPkg;
16524                    childRes.name = childPkg.packageName;
16525                    PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName);
16526                    if (childPs != null) {
16527                        childRes.origUsers = childPs.queryInstalledUsers(
16528                                sUserManager.getUserIds(), true);
16529                    }
16530                    if ((mPackages.containsKey(childPkg.packageName))) {
16531                        childRes.removedInfo = new PackageRemovedInfo();
16532                        childRes.removedInfo.removedPackage = childPkg.packageName;
16533                    }
16534                    if (res.addedChildPackages == null) {
16535                        res.addedChildPackages = new ArrayMap<>();
16536                    }
16537                    res.addedChildPackages.put(childPkg.packageName, childRes);
16538                }
16539            }
16540        }
16541
16542        // If package doesn't declare API override, mark that we have an install
16543        // time CPU ABI override.
16544        if (TextUtils.isEmpty(pkg.cpuAbiOverride)) {
16545            pkg.cpuAbiOverride = args.abiOverride;
16546        }
16547
16548        String pkgName = res.name = pkg.packageName;
16549        if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_TEST_ONLY) != 0) {
16550            if ((installFlags & PackageManager.INSTALL_ALLOW_TEST) == 0) {
16551                res.setError(INSTALL_FAILED_TEST_ONLY, "installPackageLI");
16552                return;
16553            }
16554        }
16555
16556        try {
16557            // either use what we've been given or parse directly from the APK
16558            if (args.certificates != null) {
16559                try {
16560                    PackageParser.populateCertificates(pkg, args.certificates);
16561                } catch (PackageParserException e) {
16562                    // there was something wrong with the certificates we were given;
16563                    // try to pull them from the APK
16564                    PackageParser.collectCertificates(pkg, parseFlags);
16565                }
16566            } else {
16567                PackageParser.collectCertificates(pkg, parseFlags);
16568            }
16569        } catch (PackageParserException e) {
16570            res.setError("Failed collect during installPackageLI", e);
16571            return;
16572        }
16573
16574        // Get rid of all references to package scan path via parser.
16575        pp = null;
16576        String oldCodePath = null;
16577        boolean systemApp = false;
16578        synchronized (mPackages) {
16579            // Check if installing already existing package
16580            if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
16581                String oldName = mSettings.getRenamedPackageLPr(pkgName);
16582                if (pkg.mOriginalPackages != null
16583                        && pkg.mOriginalPackages.contains(oldName)
16584                        && mPackages.containsKey(oldName)) {
16585                    // This package is derived from an original package,
16586                    // and this device has been updating from that original
16587                    // name.  We must continue using the original name, so
16588                    // rename the new package here.
16589                    pkg.setPackageName(oldName);
16590                    pkgName = pkg.packageName;
16591                    replace = true;
16592                    if (DEBUG_INSTALL) Slog.d(TAG, "Replacing existing renamed package: oldName="
16593                            + oldName + " pkgName=" + pkgName);
16594                } else if (mPackages.containsKey(pkgName)) {
16595                    // This package, under its official name, already exists
16596                    // on the device; we should replace it.
16597                    replace = true;
16598                    if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing pacakge: " + pkgName);
16599                }
16600
16601                // Child packages are installed through the parent package
16602                if (pkg.parentPackage != null) {
16603                    res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME,
16604                            "Package " + pkg.packageName + " is child of package "
16605                                    + pkg.parentPackage.parentPackage + ". Child packages "
16606                                    + "can be updated only through the parent package.");
16607                    return;
16608                }
16609
16610                if (replace) {
16611                    // Prevent apps opting out from runtime permissions
16612                    PackageParser.Package oldPackage = mPackages.get(pkgName);
16613                    final int oldTargetSdk = oldPackage.applicationInfo.targetSdkVersion;
16614                    final int newTargetSdk = pkg.applicationInfo.targetSdkVersion;
16615                    if (oldTargetSdk > Build.VERSION_CODES.LOLLIPOP_MR1
16616                            && newTargetSdk <= Build.VERSION_CODES.LOLLIPOP_MR1) {
16617                        res.setError(PackageManager.INSTALL_FAILED_PERMISSION_MODEL_DOWNGRADE,
16618                                "Package " + pkg.packageName + " new target SDK " + newTargetSdk
16619                                        + " doesn't support runtime permissions but the old"
16620                                        + " target SDK " + oldTargetSdk + " does.");
16621                        return;
16622                    }
16623
16624                    // Prevent installing of child packages
16625                    if (oldPackage.parentPackage != null) {
16626                        res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME,
16627                                "Package " + pkg.packageName + " is child of package "
16628                                        + oldPackage.parentPackage + ". Child packages "
16629                                        + "can be updated only through the parent package.");
16630                        return;
16631                    }
16632                }
16633            }
16634
16635            PackageSetting ps = mSettings.mPackages.get(pkgName);
16636            if (ps != null) {
16637                if (DEBUG_INSTALL) Slog.d(TAG, "Existing package: " + ps);
16638
16639                // Static shared libs have same package with different versions where
16640                // we internally use a synthetic package name to allow multiple versions
16641                // of the same package, therefore we need to compare signatures against
16642                // the package setting for the latest library version.
16643                PackageSetting signatureCheckPs = ps;
16644                if (pkg.applicationInfo.isStaticSharedLibrary()) {
16645                    SharedLibraryEntry libraryEntry = getLatestSharedLibraVersionLPr(pkg);
16646                    if (libraryEntry != null) {
16647                        signatureCheckPs = mSettings.getPackageLPr(libraryEntry.apk);
16648                    }
16649                }
16650
16651                // Quick sanity check that we're signed correctly if updating;
16652                // we'll check this again later when scanning, but we want to
16653                // bail early here before tripping over redefined permissions.
16654                if (shouldCheckUpgradeKeySetLP(signatureCheckPs, scanFlags)) {
16655                    if (!checkUpgradeKeySetLP(signatureCheckPs, pkg)) {
16656                        res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
16657                                + pkg.packageName + " upgrade keys do not match the "
16658                                + "previously installed version");
16659                        return;
16660                    }
16661                } else {
16662                    try {
16663                        verifySignaturesLP(signatureCheckPs, pkg);
16664                    } catch (PackageManagerException e) {
16665                        res.setError(e.error, e.getMessage());
16666                        return;
16667                    }
16668                }
16669
16670                oldCodePath = mSettings.mPackages.get(pkgName).codePathString;
16671                if (ps.pkg != null && ps.pkg.applicationInfo != null) {
16672                    systemApp = (ps.pkg.applicationInfo.flags &
16673                            ApplicationInfo.FLAG_SYSTEM) != 0;
16674                }
16675                res.origUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
16676            }
16677
16678            // Check whether the newly-scanned package wants to define an already-defined perm
16679            int N = pkg.permissions.size();
16680            for (int i = N-1; i >= 0; i--) {
16681                PackageParser.Permission perm = pkg.permissions.get(i);
16682                BasePermission bp = mSettings.mPermissions.get(perm.info.name);
16683                if (bp != null) {
16684                    // If the defining package is signed with our cert, it's okay.  This
16685                    // also includes the "updating the same package" case, of course.
16686                    // "updating same package" could also involve key-rotation.
16687                    final boolean sigsOk;
16688                    if (bp.sourcePackage.equals(pkg.packageName)
16689                            && (bp.packageSetting instanceof PackageSetting)
16690                            && (shouldCheckUpgradeKeySetLP((PackageSetting) bp.packageSetting,
16691                                    scanFlags))) {
16692                        sigsOk = checkUpgradeKeySetLP((PackageSetting) bp.packageSetting, pkg);
16693                    } else {
16694                        sigsOk = compareSignatures(bp.packageSetting.signatures.mSignatures,
16695                                pkg.mSignatures) == PackageManager.SIGNATURE_MATCH;
16696                    }
16697                    if (!sigsOk) {
16698                        // If the owning package is the system itself, we log but allow
16699                        // install to proceed; we fail the install on all other permission
16700                        // redefinitions.
16701                        if (!bp.sourcePackage.equals("android")) {
16702                            res.setError(INSTALL_FAILED_DUPLICATE_PERMISSION, "Package "
16703                                    + pkg.packageName + " attempting to redeclare permission "
16704                                    + perm.info.name + " already owned by " + bp.sourcePackage);
16705                            res.origPermission = perm.info.name;
16706                            res.origPackage = bp.sourcePackage;
16707                            return;
16708                        } else {
16709                            Slog.w(TAG, "Package " + pkg.packageName
16710                                    + " attempting to redeclare system permission "
16711                                    + perm.info.name + "; ignoring new declaration");
16712                            pkg.permissions.remove(i);
16713                        }
16714                    } else if (!PLATFORM_PACKAGE_NAME.equals(pkg.packageName)) {
16715                        // Prevent apps to change protection level to dangerous from any other
16716                        // type as this would allow a privilege escalation where an app adds a
16717                        // normal/signature permission in other app's group and later redefines
16718                        // it as dangerous leading to the group auto-grant.
16719                        if ((perm.info.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
16720                                == PermissionInfo.PROTECTION_DANGEROUS) {
16721                            if (bp != null && !bp.isRuntime()) {
16722                                Slog.w(TAG, "Package " + pkg.packageName + " trying to change a "
16723                                        + "non-runtime permission " + perm.info.name
16724                                        + " to runtime; keeping old protection level");
16725                                perm.info.protectionLevel = bp.protectionLevel;
16726                            }
16727                        }
16728                    }
16729                }
16730            }
16731        }
16732
16733        if (systemApp) {
16734            if (onExternal) {
16735                // Abort update; system app can't be replaced with app on sdcard
16736                res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
16737                        "Cannot install updates to system apps on sdcard");
16738                return;
16739            } else if (ephemeral) {
16740                // Abort update; system app can't be replaced with an ephemeral app
16741                res.setError(INSTALL_FAILED_EPHEMERAL_INVALID,
16742                        "Cannot update a system app with an ephemeral app");
16743                return;
16744            }
16745        }
16746
16747        if (args.move != null) {
16748            // We did an in-place move, so dex is ready to roll
16749            scanFlags |= SCAN_NO_DEX;
16750            scanFlags |= SCAN_MOVE;
16751
16752            synchronized (mPackages) {
16753                final PackageSetting ps = mSettings.mPackages.get(pkgName);
16754                if (ps == null) {
16755                    res.setError(INSTALL_FAILED_INTERNAL_ERROR,
16756                            "Missing settings for moved package " + pkgName);
16757                }
16758
16759                // We moved the entire application as-is, so bring over the
16760                // previously derived ABI information.
16761                pkg.applicationInfo.primaryCpuAbi = ps.primaryCpuAbiString;
16762                pkg.applicationInfo.secondaryCpuAbi = ps.secondaryCpuAbiString;
16763            }
16764
16765        } else if (!forwardLocked && !pkg.applicationInfo.isExternalAsec()) {
16766            // Enable SCAN_NO_DEX flag to skip dexopt at a later stage
16767            scanFlags |= SCAN_NO_DEX;
16768
16769            try {
16770                String abiOverride = (TextUtils.isEmpty(pkg.cpuAbiOverride) ?
16771                    args.abiOverride : pkg.cpuAbiOverride);
16772                derivePackageAbi(pkg, new File(pkg.codePath), abiOverride,
16773                        true /*extractLibs*/, mAppLib32InstallDir);
16774            } catch (PackageManagerException pme) {
16775                Slog.e(TAG, "Error deriving application ABI", pme);
16776                res.setError(INSTALL_FAILED_INTERNAL_ERROR, "Error deriving application ABI");
16777                return;
16778            }
16779
16780            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
16781            // Do not run PackageDexOptimizer through the local performDexOpt
16782            // method because `pkg` may not be in `mPackages` yet.
16783            //
16784            // Also, don't fail application installs if the dexopt step fails.
16785            mPackageDexOptimizer.performDexOpt(pkg, pkg.usesLibraryFiles,
16786                    null /* instructionSets */, false /* checkProfiles */,
16787                    getCompilerFilterForReason(REASON_INSTALL),
16788                    getOrCreateCompilerPackageStats(pkg));
16789            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16790
16791            // Notify BackgroundDexOptJobService that the package has been changed.
16792            // If this is an update of a package which used to fail to compile,
16793            // BDOS will remove it from its blacklist.
16794            // TODO: Layering violation
16795            BackgroundDexOptJobService.notifyPackageChanged(pkg.packageName);
16796        }
16797
16798        if (!args.doRename(res.returnCode, pkg, oldCodePath)) {
16799            res.setError(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename");
16800            return;
16801        }
16802
16803        startIntentFilterVerifications(args.user.getIdentifier(), replace, pkg);
16804
16805        try (PackageFreezer freezer = freezePackageForInstall(pkgName, installFlags,
16806                "installPackageLI")) {
16807            if (replace) {
16808                if (pkg.applicationInfo.isStaticSharedLibrary()) {
16809                    // Static libs have a synthetic package name containing the version
16810                    // and cannot be updated as an update would get a new package name,
16811                    // unless this is the exact same version code which is useful for
16812                    // development.
16813                    PackageParser.Package existingPkg = mPackages.get(pkg.packageName);
16814                    if (existingPkg != null && existingPkg.mVersionCode != pkg.mVersionCode) {
16815                        res.setError(INSTALL_FAILED_DUPLICATE_PACKAGE, "Packages declaring "
16816                                + "static-shared libs cannot be updated");
16817                        return;
16818                    }
16819                }
16820                replacePackageLIF(pkg, parseFlags, scanFlags | SCAN_REPLACING, args.user,
16821                        installerPackageName, res, args.installReason);
16822            } else {
16823                installNewPackageLIF(pkg, parseFlags, scanFlags | SCAN_DELETE_DATA_ON_FAILURES,
16824                        args.user, installerPackageName, volumeUuid, res, args.installReason);
16825            }
16826        }
16827        synchronized (mPackages) {
16828            final PackageSetting ps = mSettings.mPackages.get(pkgName);
16829            if (ps != null) {
16830                res.newUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
16831            }
16832
16833            final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
16834            for (int i = 0; i < childCount; i++) {
16835                PackageParser.Package childPkg = pkg.childPackages.get(i);
16836                PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName);
16837                PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName);
16838                if (childPs != null) {
16839                    childRes.newUsers = childPs.queryInstalledUsers(
16840                            sUserManager.getUserIds(), true);
16841                }
16842            }
16843        }
16844    }
16845
16846    private void startIntentFilterVerifications(int userId, boolean replacing,
16847            PackageParser.Package pkg) {
16848        if (mIntentFilterVerifierComponent == null) {
16849            Slog.w(TAG, "No IntentFilter verification will not be done as "
16850                    + "there is no IntentFilterVerifier available!");
16851            return;
16852        }
16853
16854        final int verifierUid = getPackageUid(
16855                mIntentFilterVerifierComponent.getPackageName(),
16856                MATCH_DEBUG_TRIAGED_MISSING,
16857                (userId == UserHandle.USER_ALL) ? UserHandle.USER_SYSTEM : userId);
16858
16859        Message msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS);
16860        msg.obj = new IFVerificationParams(pkg, replacing, userId, verifierUid);
16861        mHandler.sendMessage(msg);
16862
16863        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
16864        for (int i = 0; i < childCount; i++) {
16865            PackageParser.Package childPkg = pkg.childPackages.get(i);
16866            msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS);
16867            msg.obj = new IFVerificationParams(childPkg, replacing, userId, verifierUid);
16868            mHandler.sendMessage(msg);
16869        }
16870    }
16871
16872    private void verifyIntentFiltersIfNeeded(int userId, int verifierUid, boolean replacing,
16873            PackageParser.Package pkg) {
16874        int size = pkg.activities.size();
16875        if (size == 0) {
16876            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
16877                    "No activity, so no need to verify any IntentFilter!");
16878            return;
16879        }
16880
16881        final boolean hasDomainURLs = hasDomainURLs(pkg);
16882        if (!hasDomainURLs) {
16883            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
16884                    "No domain URLs, so no need to verify any IntentFilter!");
16885            return;
16886        }
16887
16888        if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Checking for userId:" + userId
16889                + " if any IntentFilter from the " + size
16890                + " Activities needs verification ...");
16891
16892        int count = 0;
16893        final String packageName = pkg.packageName;
16894
16895        synchronized (mPackages) {
16896            // If this is a new install and we see that we've already run verification for this
16897            // package, we have nothing to do: it means the state was restored from backup.
16898            if (!replacing) {
16899                IntentFilterVerificationInfo ivi =
16900                        mSettings.getIntentFilterVerificationLPr(packageName);
16901                if (ivi != null) {
16902                    if (DEBUG_DOMAIN_VERIFICATION) {
16903                        Slog.i(TAG, "Package " + packageName+ " already verified: status="
16904                                + ivi.getStatusString());
16905                    }
16906                    return;
16907                }
16908            }
16909
16910            // If any filters need to be verified, then all need to be.
16911            boolean needToVerify = false;
16912            for (PackageParser.Activity a : pkg.activities) {
16913                for (ActivityIntentInfo filter : a.intents) {
16914                    if (filter.needsVerification() && needsNetworkVerificationLPr(filter)) {
16915                        if (DEBUG_DOMAIN_VERIFICATION) {
16916                            Slog.d(TAG, "Intent filter needs verification, so processing all filters");
16917                        }
16918                        needToVerify = true;
16919                        break;
16920                    }
16921                }
16922            }
16923
16924            if (needToVerify) {
16925                final int verificationId = mIntentFilterVerificationToken++;
16926                for (PackageParser.Activity a : pkg.activities) {
16927                    for (ActivityIntentInfo filter : a.intents) {
16928                        if (filter.handlesWebUris(true) && needsNetworkVerificationLPr(filter)) {
16929                            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
16930                                    "Verification needed for IntentFilter:" + filter.toString());
16931                            mIntentFilterVerifier.addOneIntentFilterVerification(
16932                                    verifierUid, userId, verificationId, filter, packageName);
16933                            count++;
16934                        }
16935                    }
16936                }
16937            }
16938        }
16939
16940        if (count > 0) {
16941            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Starting " + count
16942                    + " IntentFilter verification" + (count > 1 ? "s" : "")
16943                    +  " for userId:" + userId);
16944            mIntentFilterVerifier.startVerifications(userId);
16945        } else {
16946            if (DEBUG_DOMAIN_VERIFICATION) {
16947                Slog.d(TAG, "No filters or not all autoVerify for " + packageName);
16948            }
16949        }
16950    }
16951
16952    private boolean needsNetworkVerificationLPr(ActivityIntentInfo filter) {
16953        final ComponentName cn  = filter.activity.getComponentName();
16954        final String packageName = cn.getPackageName();
16955
16956        IntentFilterVerificationInfo ivi = mSettings.getIntentFilterVerificationLPr(
16957                packageName);
16958        if (ivi == null) {
16959            return true;
16960        }
16961        int status = ivi.getStatus();
16962        switch (status) {
16963            case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED:
16964            case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK:
16965                return true;
16966
16967            default:
16968                // Nothing to do
16969                return false;
16970        }
16971    }
16972
16973    private static boolean isMultiArch(ApplicationInfo info) {
16974        return (info.flags & ApplicationInfo.FLAG_MULTIARCH) != 0;
16975    }
16976
16977    private static boolean isExternal(PackageParser.Package pkg) {
16978        return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
16979    }
16980
16981    private static boolean isExternal(PackageSetting ps) {
16982        return (ps.pkgFlags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
16983    }
16984
16985    private static boolean isEphemeral(PackageParser.Package pkg) {
16986        return pkg.applicationInfo.isInstantApp();
16987    }
16988
16989    private static boolean isEphemeral(PackageSetting ps) {
16990        return ps.pkg != null && isEphemeral(ps.pkg);
16991    }
16992
16993    private static boolean isSystemApp(PackageParser.Package pkg) {
16994        return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
16995    }
16996
16997    private static boolean isPrivilegedApp(PackageParser.Package pkg) {
16998        return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0;
16999    }
17000
17001    private static boolean hasDomainURLs(PackageParser.Package pkg) {
17002        return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) != 0;
17003    }
17004
17005    private static boolean isSystemApp(PackageSetting ps) {
17006        return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0;
17007    }
17008
17009    private static boolean isUpdatedSystemApp(PackageSetting ps) {
17010        return (ps.pkgFlags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
17011    }
17012
17013    private int packageFlagsToInstallFlags(PackageSetting ps) {
17014        int installFlags = 0;
17015        if (isEphemeral(ps)) {
17016            installFlags |= PackageManager.INSTALL_EPHEMERAL;
17017        }
17018        if (isExternal(ps) && TextUtils.isEmpty(ps.volumeUuid)) {
17019            // This existing package was an external ASEC install when we have
17020            // the external flag without a UUID
17021            installFlags |= PackageManager.INSTALL_EXTERNAL;
17022        }
17023        if (ps.isForwardLocked()) {
17024            installFlags |= PackageManager.INSTALL_FORWARD_LOCK;
17025        }
17026        return installFlags;
17027    }
17028
17029    private String getVolumeUuidForPackage(PackageParser.Package pkg) {
17030        if (isExternal(pkg)) {
17031            if (TextUtils.isEmpty(pkg.volumeUuid)) {
17032                return StorageManager.UUID_PRIMARY_PHYSICAL;
17033            } else {
17034                return pkg.volumeUuid;
17035            }
17036        } else {
17037            return StorageManager.UUID_PRIVATE_INTERNAL;
17038        }
17039    }
17040
17041    private VersionInfo getSettingsVersionForPackage(PackageParser.Package pkg) {
17042        if (isExternal(pkg)) {
17043            if (TextUtils.isEmpty(pkg.volumeUuid)) {
17044                return mSettings.getExternalVersion();
17045            } else {
17046                return mSettings.findOrCreateVersion(pkg.volumeUuid);
17047            }
17048        } else {
17049            return mSettings.getInternalVersion();
17050        }
17051    }
17052
17053    private void deleteTempPackageFiles() {
17054        final FilenameFilter filter = new FilenameFilter() {
17055            public boolean accept(File dir, String name) {
17056                return name.startsWith("vmdl") && name.endsWith(".tmp");
17057            }
17058        };
17059        for (File file : mDrmAppPrivateInstallDir.listFiles(filter)) {
17060            file.delete();
17061        }
17062    }
17063
17064    @Override
17065    public void deletePackageAsUser(String packageName, int versionCode,
17066            IPackageDeleteObserver observer, int userId, int flags) {
17067        deletePackageVersioned(new VersionedPackage(packageName, versionCode),
17068                new LegacyPackageDeleteObserver(observer).getBinder(), userId, flags);
17069    }
17070
17071    @Override
17072    public void deletePackageVersioned(VersionedPackage versionedPackage,
17073            final IPackageDeleteObserver2 observer, final int userId, final int deleteFlags) {
17074        mContext.enforceCallingOrSelfPermission(
17075                android.Manifest.permission.DELETE_PACKAGES, null);
17076        Preconditions.checkNotNull(versionedPackage);
17077        Preconditions.checkNotNull(observer);
17078        Preconditions.checkArgumentInRange(versionedPackage.getVersionCode(),
17079                PackageManager.VERSION_CODE_HIGHEST,
17080                Integer.MAX_VALUE, "versionCode must be >= -1");
17081
17082        final String packageName = versionedPackage.getPackageName();
17083        // TODO: We will change version code to long, so in the new API it is long
17084        final int versionCode = (int) versionedPackage.getVersionCode();
17085        final String internalPackageName;
17086        synchronized (mPackages) {
17087            // Normalize package name to handle renamed packages and static libs
17088            internalPackageName = resolveInternalPackageNameLPr(versionedPackage.getPackageName(),
17089                    // TODO: We will change version code to long, so in the new API it is long
17090                    (int) versionedPackage.getVersionCode());
17091        }
17092
17093        final int uid = Binder.getCallingUid();
17094        if (!isOrphaned(internalPackageName)
17095                && !isCallerAllowedToSilentlyUninstall(uid, internalPackageName)) {
17096            try {
17097                final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE);
17098                intent.setData(Uri.fromParts(PACKAGE_SCHEME, packageName, null));
17099                intent.putExtra(PackageInstaller.EXTRA_CALLBACK, observer.asBinder());
17100                observer.onUserActionRequired(intent);
17101            } catch (RemoteException re) {
17102            }
17103            return;
17104        }
17105        final boolean deleteAllUsers = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0;
17106        final int[] users = deleteAllUsers ? sUserManager.getUserIds() : new int[]{ userId };
17107        if (UserHandle.getUserId(uid) != userId || (deleteAllUsers && users.length > 1)) {
17108            mContext.enforceCallingOrSelfPermission(
17109                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
17110                    "deletePackage for user " + userId);
17111        }
17112
17113        if (isUserRestricted(userId, UserManager.DISALLOW_UNINSTALL_APPS)) {
17114            try {
17115                observer.onPackageDeleted(packageName,
17116                        PackageManager.DELETE_FAILED_USER_RESTRICTED, null);
17117            } catch (RemoteException re) {
17118            }
17119            return;
17120        }
17121
17122        if (!deleteAllUsers && getBlockUninstallForUser(internalPackageName, userId)) {
17123            try {
17124                observer.onPackageDeleted(packageName,
17125                        PackageManager.DELETE_FAILED_OWNER_BLOCKED, null);
17126            } catch (RemoteException re) {
17127            }
17128            return;
17129        }
17130
17131        if (DEBUG_REMOVE) {
17132            Slog.d(TAG, "deletePackageAsUser: pkg=" + internalPackageName + " user=" + userId
17133                    + " deleteAllUsers: " + deleteAllUsers + " version="
17134                    + (versionCode == PackageManager.VERSION_CODE_HIGHEST
17135                    ? "VERSION_CODE_HIGHEST" : versionCode));
17136        }
17137        // Queue up an async operation since the package deletion may take a little while.
17138        mHandler.post(new Runnable() {
17139            public void run() {
17140                mHandler.removeCallbacks(this);
17141                int returnCode;
17142                if (!deleteAllUsers) {
17143                    returnCode = deletePackageX(internalPackageName, versionCode,
17144                            userId, deleteFlags);
17145                } else {
17146                    int[] blockUninstallUserIds = getBlockUninstallForUsers(
17147                            internalPackageName, users);
17148                    // If nobody is blocking uninstall, proceed with delete for all users
17149                    if (ArrayUtils.isEmpty(blockUninstallUserIds)) {
17150                        returnCode = deletePackageX(internalPackageName, versionCode,
17151                                userId, deleteFlags);
17152                    } else {
17153                        // Otherwise uninstall individually for users with blockUninstalls=false
17154                        final int userFlags = deleteFlags & ~PackageManager.DELETE_ALL_USERS;
17155                        for (int userId : users) {
17156                            if (!ArrayUtils.contains(blockUninstallUserIds, userId)) {
17157                                returnCode = deletePackageX(internalPackageName, versionCode,
17158                                        userId, userFlags);
17159                                if (returnCode != PackageManager.DELETE_SUCCEEDED) {
17160                                    Slog.w(TAG, "Package delete failed for user " + userId
17161                                            + ", returnCode " + returnCode);
17162                                }
17163                            }
17164                        }
17165                        // The app has only been marked uninstalled for certain users.
17166                        // We still need to report that delete was blocked
17167                        returnCode = PackageManager.DELETE_FAILED_OWNER_BLOCKED;
17168                    }
17169                }
17170                try {
17171                    observer.onPackageDeleted(packageName, returnCode, null);
17172                } catch (RemoteException e) {
17173                    Log.i(TAG, "Observer no longer exists.");
17174                } //end catch
17175            } //end run
17176        });
17177    }
17178
17179    private String resolveExternalPackageNameLPr(PackageParser.Package pkg) {
17180        if (pkg.staticSharedLibName != null) {
17181            return pkg.manifestPackageName;
17182        }
17183        return pkg.packageName;
17184    }
17185
17186    private String resolveInternalPackageNameLPr(String packageName, int versionCode) {
17187        // Handle renamed packages
17188        String normalizedPackageName = mSettings.getRenamedPackageLPr(packageName);
17189        packageName = normalizedPackageName != null ? normalizedPackageName : packageName;
17190
17191        // Is this a static library?
17192        SparseArray<SharedLibraryEntry> versionedLib =
17193                mStaticLibsByDeclaringPackage.get(packageName);
17194        if (versionedLib == null || versionedLib.size() <= 0) {
17195            return packageName;
17196        }
17197
17198        // Figure out which lib versions the caller can see
17199        SparseIntArray versionsCallerCanSee = null;
17200        final int callingAppId = UserHandle.getAppId(Binder.getCallingUid());
17201        if (callingAppId != Process.SYSTEM_UID && callingAppId != Process.SHELL_UID
17202                && callingAppId != Process.ROOT_UID) {
17203            versionsCallerCanSee = new SparseIntArray();
17204            String libName = versionedLib.valueAt(0).info.getName();
17205            String[] uidPackages = getPackagesForUid(Binder.getCallingUid());
17206            if (uidPackages != null) {
17207                for (String uidPackage : uidPackages) {
17208                    PackageSetting ps = mSettings.getPackageLPr(uidPackage);
17209                    final int libIdx = ArrayUtils.indexOf(ps.usesStaticLibraries, libName);
17210                    if (libIdx >= 0) {
17211                        final int libVersion = ps.usesStaticLibrariesVersions[libIdx];
17212                        versionsCallerCanSee.append(libVersion, libVersion);
17213                    }
17214                }
17215            }
17216        }
17217
17218        // Caller can see nothing - done
17219        if (versionsCallerCanSee != null && versionsCallerCanSee.size() <= 0) {
17220            return packageName;
17221        }
17222
17223        // Find the version the caller can see and the app version code
17224        SharedLibraryEntry highestVersion = null;
17225        final int versionCount = versionedLib.size();
17226        for (int i = 0; i < versionCount; i++) {
17227            SharedLibraryEntry libEntry = versionedLib.valueAt(i);
17228            if (versionsCallerCanSee != null && versionsCallerCanSee.indexOfKey(
17229                    libEntry.info.getVersion()) < 0) {
17230                continue;
17231            }
17232            // TODO: We will change version code to long, so in the new API it is long
17233            final int libVersionCode = (int) libEntry.info.getDeclaringPackage().getVersionCode();
17234            if (versionCode != PackageManager.VERSION_CODE_HIGHEST) {
17235                if (libVersionCode == versionCode) {
17236                    return libEntry.apk;
17237                }
17238            } else if (highestVersion == null) {
17239                highestVersion = libEntry;
17240            } else if (libVersionCode  > highestVersion.info
17241                    .getDeclaringPackage().getVersionCode()) {
17242                highestVersion = libEntry;
17243            }
17244        }
17245
17246        if (highestVersion != null) {
17247            return highestVersion.apk;
17248        }
17249
17250        return packageName;
17251    }
17252
17253    private boolean isCallerAllowedToSilentlyUninstall(int callingUid, String pkgName) {
17254        if (callingUid == Process.SHELL_UID || callingUid == Process.ROOT_UID
17255              || callingUid == Process.SYSTEM_UID) {
17256            return true;
17257        }
17258        final int callingUserId = UserHandle.getUserId(callingUid);
17259        // If the caller installed the pkgName, then allow it to silently uninstall.
17260        if (callingUid == getPackageUid(getInstallerPackageName(pkgName), 0, callingUserId)) {
17261            return true;
17262        }
17263
17264        // Allow package verifier to silently uninstall.
17265        if (mRequiredVerifierPackage != null &&
17266                callingUid == getPackageUid(mRequiredVerifierPackage, 0, callingUserId)) {
17267            return true;
17268        }
17269
17270        // Allow package uninstaller to silently uninstall.
17271        if (mRequiredUninstallerPackage != null &&
17272                callingUid == getPackageUid(mRequiredUninstallerPackage, 0, callingUserId)) {
17273            return true;
17274        }
17275
17276        // Allow storage manager to silently uninstall.
17277        if (mStorageManagerPackage != null &&
17278                callingUid == getPackageUid(mStorageManagerPackage, 0, callingUserId)) {
17279            return true;
17280        }
17281        return false;
17282    }
17283
17284    private int[] getBlockUninstallForUsers(String packageName, int[] userIds) {
17285        int[] result = EMPTY_INT_ARRAY;
17286        for (int userId : userIds) {
17287            if (getBlockUninstallForUser(packageName, userId)) {
17288                result = ArrayUtils.appendInt(result, userId);
17289            }
17290        }
17291        return result;
17292    }
17293
17294    @Override
17295    public boolean isPackageDeviceAdminOnAnyUser(String packageName) {
17296        return isPackageDeviceAdmin(packageName, UserHandle.USER_ALL);
17297    }
17298
17299    private boolean isPackageDeviceAdmin(String packageName, int userId) {
17300        IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
17301                ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
17302        try {
17303            if (dpm != null) {
17304                final ComponentName deviceOwnerComponentName = dpm.getDeviceOwnerComponent(
17305                        /* callingUserOnly =*/ false);
17306                final String deviceOwnerPackageName = deviceOwnerComponentName == null ? null
17307                        : deviceOwnerComponentName.getPackageName();
17308                // Does the package contains the device owner?
17309                // TODO Do we have to do it even if userId != UserHandle.USER_ALL?  Otherwise,
17310                // this check is probably not needed, since DO should be registered as a device
17311                // admin on some user too. (Original bug for this: b/17657954)
17312                if (packageName.equals(deviceOwnerPackageName)) {
17313                    return true;
17314                }
17315                // Does it contain a device admin for any user?
17316                int[] users;
17317                if (userId == UserHandle.USER_ALL) {
17318                    users = sUserManager.getUserIds();
17319                } else {
17320                    users = new int[]{userId};
17321                }
17322                for (int i = 0; i < users.length; ++i) {
17323                    if (dpm.packageHasActiveAdmins(packageName, users[i])) {
17324                        return true;
17325                    }
17326                }
17327            }
17328        } catch (RemoteException e) {
17329        }
17330        return false;
17331    }
17332
17333    private boolean shouldKeepUninstalledPackageLPr(String packageName) {
17334        return mKeepUninstalledPackages != null && mKeepUninstalledPackages.contains(packageName);
17335    }
17336
17337    /**
17338     *  This method is an internal method that could be get invoked either
17339     *  to delete an installed package or to clean up a failed installation.
17340     *  After deleting an installed package, a broadcast is sent to notify any
17341     *  listeners that the package has been removed. For cleaning up a failed
17342     *  installation, the broadcast is not necessary since the package's
17343     *  installation wouldn't have sent the initial broadcast either
17344     *  The key steps in deleting a package are
17345     *  deleting the package information in internal structures like mPackages,
17346     *  deleting the packages base directories through installd
17347     *  updating mSettings to reflect current status
17348     *  persisting settings for later use
17349     *  sending a broadcast if necessary
17350     */
17351    private int deletePackageX(String packageName, int versionCode, int userId, int deleteFlags) {
17352        final PackageRemovedInfo info = new PackageRemovedInfo();
17353        final boolean res;
17354
17355        final int removeUser = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0
17356                ? UserHandle.USER_ALL : userId;
17357
17358        if (isPackageDeviceAdmin(packageName, removeUser)) {
17359            Slog.w(TAG, "Not removing package " + packageName + ": has active device admin");
17360            return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER;
17361        }
17362
17363        PackageSetting uninstalledPs = null;
17364
17365        // for the uninstall-updates case and restricted profiles, remember the per-
17366        // user handle installed state
17367        int[] allUsers;
17368        synchronized (mPackages) {
17369            uninstalledPs = mSettings.mPackages.get(packageName);
17370            if (uninstalledPs == null) {
17371                Slog.w(TAG, "Not removing non-existent package " + packageName);
17372                return PackageManager.DELETE_FAILED_INTERNAL_ERROR;
17373            }
17374
17375            if (versionCode != PackageManager.VERSION_CODE_HIGHEST
17376                    && uninstalledPs.versionCode != versionCode) {
17377                Slog.w(TAG, "Not removing package " + packageName + " with versionCode "
17378                        + uninstalledPs.versionCode + " != " + versionCode);
17379                return PackageManager.DELETE_FAILED_INTERNAL_ERROR;
17380            }
17381
17382            // Static shared libs can be declared by any package, so let us not
17383            // allow removing a package if it provides a lib others depend on.
17384            PackageParser.Package pkg = mPackages.get(packageName);
17385            if (pkg != null && pkg.staticSharedLibName != null) {
17386                SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(pkg.staticSharedLibName,
17387                        pkg.staticSharedLibVersion);
17388                if (libEntry != null) {
17389                    List<VersionedPackage> libClientPackages = getPackagesUsingSharedLibraryLPr(
17390                            libEntry.info, 0, userId);
17391                    if (!ArrayUtils.isEmpty(libClientPackages)) {
17392                        Slog.w(TAG, "Not removing package " + pkg.manifestPackageName
17393                                + " hosting lib " + libEntry.info.getName() + " version "
17394                                + libEntry.info.getVersion()  + " used by " + libClientPackages);
17395                        return PackageManager.DELETE_FAILED_USED_SHARED_LIBRARY;
17396                    }
17397                }
17398            }
17399
17400            allUsers = sUserManager.getUserIds();
17401            info.origUsers = uninstalledPs.queryInstalledUsers(allUsers, true);
17402        }
17403
17404        final int freezeUser;
17405        if (isUpdatedSystemApp(uninstalledPs)
17406                && ((deleteFlags & PackageManager.DELETE_SYSTEM_APP) == 0)) {
17407            // We're downgrading a system app, which will apply to all users, so
17408            // freeze them all during the downgrade
17409            freezeUser = UserHandle.USER_ALL;
17410        } else {
17411            freezeUser = removeUser;
17412        }
17413
17414        synchronized (mInstallLock) {
17415            if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageX: pkg=" + packageName + " user=" + userId);
17416            try (PackageFreezer freezer = freezePackageForDelete(packageName, freezeUser,
17417                    deleteFlags, "deletePackageX")) {
17418                res = deletePackageLIF(packageName, UserHandle.of(removeUser), true, allUsers,
17419                        deleteFlags | REMOVE_CHATTY, info, true, null);
17420            }
17421            synchronized (mPackages) {
17422                if (res) {
17423                    mInstantAppRegistry.onPackageUninstalledLPw(uninstalledPs.pkg,
17424                            info.removedUsers);
17425                }
17426            }
17427        }
17428
17429        if (res) {
17430            final boolean killApp = (deleteFlags & PackageManager.DELETE_DONT_KILL_APP) == 0;
17431            info.sendPackageRemovedBroadcasts(killApp);
17432            info.sendSystemPackageUpdatedBroadcasts();
17433            info.sendSystemPackageAppearedBroadcasts();
17434        }
17435        // Force a gc here.
17436        Runtime.getRuntime().gc();
17437        // Delete the resources here after sending the broadcast to let
17438        // other processes clean up before deleting resources.
17439        if (info.args != null) {
17440            synchronized (mInstallLock) {
17441                info.args.doPostDeleteLI(true);
17442            }
17443        }
17444
17445        return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR;
17446    }
17447
17448    class PackageRemovedInfo {
17449        String removedPackage;
17450        int uid = -1;
17451        int removedAppId = -1;
17452        int[] origUsers;
17453        int[] removedUsers = null;
17454        SparseArray<Integer> installReasons;
17455        boolean isRemovedPackageSystemUpdate = false;
17456        boolean isUpdate;
17457        boolean dataRemoved;
17458        boolean removedForAllUsers;
17459        boolean isStaticSharedLib;
17460        // Clean up resources deleted packages.
17461        InstallArgs args = null;
17462        ArrayMap<String, PackageRemovedInfo> removedChildPackages;
17463        ArrayMap<String, PackageInstalledInfo> appearedChildPackages;
17464
17465        void sendPackageRemovedBroadcasts(boolean killApp) {
17466            sendPackageRemovedBroadcastInternal(killApp);
17467            final int childCount = removedChildPackages != null ? removedChildPackages.size() : 0;
17468            for (int i = 0; i < childCount; i++) {
17469                PackageRemovedInfo childInfo = removedChildPackages.valueAt(i);
17470                childInfo.sendPackageRemovedBroadcastInternal(killApp);
17471            }
17472        }
17473
17474        void sendSystemPackageUpdatedBroadcasts() {
17475            if (isRemovedPackageSystemUpdate) {
17476                sendSystemPackageUpdatedBroadcastsInternal();
17477                final int childCount = (removedChildPackages != null)
17478                        ? removedChildPackages.size() : 0;
17479                for (int i = 0; i < childCount; i++) {
17480                    PackageRemovedInfo childInfo = removedChildPackages.valueAt(i);
17481                    if (childInfo.isRemovedPackageSystemUpdate) {
17482                        childInfo.sendSystemPackageUpdatedBroadcastsInternal();
17483                    }
17484                }
17485            }
17486        }
17487
17488        void sendSystemPackageAppearedBroadcasts() {
17489            final int packageCount = (appearedChildPackages != null)
17490                    ? appearedChildPackages.size() : 0;
17491            for (int i = 0; i < packageCount; i++) {
17492                PackageInstalledInfo installedInfo = appearedChildPackages.valueAt(i);
17493                sendPackageAddedForNewUsers(installedInfo.name, true,
17494                        UserHandle.getAppId(installedInfo.uid), installedInfo.newUsers);
17495            }
17496        }
17497
17498        private void sendSystemPackageUpdatedBroadcastsInternal() {
17499            Bundle extras = new Bundle(2);
17500            extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid);
17501            extras.putBoolean(Intent.EXTRA_REPLACING, true);
17502            sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, removedPackage,
17503                    extras, 0, null, null, null);
17504            sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, removedPackage,
17505                    extras, 0, null, null, null);
17506            sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, null,
17507                    null, 0, removedPackage, null, null);
17508        }
17509
17510        private void sendPackageRemovedBroadcastInternal(boolean killApp) {
17511            // Don't send static shared library removal broadcasts as these
17512            // libs are visible only the the apps that depend on them an one
17513            // cannot remove the library if it has a dependency.
17514            if (isStaticSharedLib) {
17515                return;
17516            }
17517            Bundle extras = new Bundle(2);
17518            extras.putInt(Intent.EXTRA_UID, removedAppId >= 0  ? removedAppId : uid);
17519            extras.putBoolean(Intent.EXTRA_DATA_REMOVED, dataRemoved);
17520            extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, !killApp);
17521            if (isUpdate || isRemovedPackageSystemUpdate) {
17522                extras.putBoolean(Intent.EXTRA_REPLACING, true);
17523            }
17524            extras.putBoolean(Intent.EXTRA_REMOVED_FOR_ALL_USERS, removedForAllUsers);
17525            if (removedPackage != null) {
17526                sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED, removedPackage,
17527                        extras, 0, null, null, removedUsers);
17528                if (dataRemoved && !isRemovedPackageSystemUpdate) {
17529                    sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED,
17530                            removedPackage, extras, Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND,
17531                            null, null, removedUsers);
17532                }
17533            }
17534            if (removedAppId >= 0) {
17535                sendPackageBroadcast(Intent.ACTION_UID_REMOVED, null, extras, 0, null, null,
17536                        removedUsers);
17537            }
17538        }
17539    }
17540
17541    /*
17542     * This method deletes the package from internal data structures. If the DONT_DELETE_DATA
17543     * flag is not set, the data directory is removed as well.
17544     * make sure this flag is set for partially installed apps. If not its meaningless to
17545     * delete a partially installed application.
17546     */
17547    private void removePackageDataLIF(PackageSetting ps, int[] allUserHandles,
17548            PackageRemovedInfo outInfo, int flags, boolean writeSettings) {
17549        String packageName = ps.name;
17550        if (DEBUG_REMOVE) Slog.d(TAG, "removePackageDataLI: " + ps);
17551        // Retrieve object to delete permissions for shared user later on
17552        final PackageParser.Package deletedPkg;
17553        final PackageSetting deletedPs;
17554        // reader
17555        synchronized (mPackages) {
17556            deletedPkg = mPackages.get(packageName);
17557            deletedPs = mSettings.mPackages.get(packageName);
17558            if (outInfo != null) {
17559                outInfo.removedPackage = packageName;
17560                outInfo.isStaticSharedLib = deletedPkg != null
17561                        && deletedPkg.staticSharedLibName != null;
17562                outInfo.removedUsers = deletedPs != null
17563                        ? deletedPs.queryInstalledUsers(sUserManager.getUserIds(), true)
17564                        : null;
17565            }
17566        }
17567
17568        removePackageLI(ps, (flags & REMOVE_CHATTY) != 0);
17569
17570        if ((flags & PackageManager.DELETE_KEEP_DATA) == 0) {
17571            final PackageParser.Package resolvedPkg;
17572            if (deletedPkg != null) {
17573                resolvedPkg = deletedPkg;
17574            } else {
17575                // We don't have a parsed package when it lives on an ejected
17576                // adopted storage device, so fake something together
17577                resolvedPkg = new PackageParser.Package(ps.name);
17578                resolvedPkg.setVolumeUuid(ps.volumeUuid);
17579            }
17580            destroyAppDataLIF(resolvedPkg, UserHandle.USER_ALL,
17581                    StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
17582            destroyAppProfilesLIF(resolvedPkg, UserHandle.USER_ALL);
17583            if (outInfo != null) {
17584                outInfo.dataRemoved = true;
17585            }
17586            schedulePackageCleaning(packageName, UserHandle.USER_ALL, true);
17587        }
17588
17589        int removedAppId = -1;
17590
17591        // writer
17592        synchronized (mPackages) {
17593            if (deletedPs != null) {
17594                if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) {
17595                    clearIntentFilterVerificationsLPw(deletedPs.name, UserHandle.USER_ALL);
17596                    clearDefaultBrowserIfNeeded(packageName);
17597                    mSettings.mKeySetManagerService.removeAppKeySetDataLPw(packageName);
17598                    removedAppId = mSettings.removePackageLPw(packageName);
17599                    if (outInfo != null) {
17600                        outInfo.removedAppId = removedAppId;
17601                    }
17602                    updatePermissionsLPw(deletedPs.name, null, 0);
17603                    if (deletedPs.sharedUser != null) {
17604                        // Remove permissions associated with package. Since runtime
17605                        // permissions are per user we have to kill the removed package
17606                        // or packages running under the shared user of the removed
17607                        // package if revoking the permissions requested only by the removed
17608                        // package is successful and this causes a change in gids.
17609                        for (int userId : UserManagerService.getInstance().getUserIds()) {
17610                            final int userIdToKill = mSettings.updateSharedUserPermsLPw(deletedPs,
17611                                    userId);
17612                            if (userIdToKill == UserHandle.USER_ALL
17613                                    || userIdToKill >= UserHandle.USER_SYSTEM) {
17614                                // If gids changed for this user, kill all affected packages.
17615                                mHandler.post(new Runnable() {
17616                                    @Override
17617                                    public void run() {
17618                                        // This has to happen with no lock held.
17619                                        killApplication(deletedPs.name, deletedPs.appId,
17620                                                KILL_APP_REASON_GIDS_CHANGED);
17621                                    }
17622                                });
17623                                break;
17624                            }
17625                        }
17626                    }
17627                    clearPackagePreferredActivitiesLPw(deletedPs.name, UserHandle.USER_ALL);
17628                }
17629                // make sure to preserve per-user disabled state if this removal was just
17630                // a downgrade of a system app to the factory package
17631                if (allUserHandles != null && outInfo != null && outInfo.origUsers != null) {
17632                    if (DEBUG_REMOVE) {
17633                        Slog.d(TAG, "Propagating install state across downgrade");
17634                    }
17635                    for (int userId : allUserHandles) {
17636                        final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId);
17637                        if (DEBUG_REMOVE) {
17638                            Slog.d(TAG, "    user " + userId + " => " + installed);
17639                        }
17640                        ps.setInstalled(installed, userId);
17641                    }
17642                }
17643            }
17644            // can downgrade to reader
17645            if (writeSettings) {
17646                // Save settings now
17647                mSettings.writeLPr();
17648            }
17649        }
17650        if (removedAppId != -1) {
17651            // A user ID was deleted here. Go through all users and remove it
17652            // from KeyStore.
17653            removeKeystoreDataIfNeeded(UserHandle.USER_ALL, removedAppId);
17654        }
17655    }
17656
17657    static boolean locationIsPrivileged(File path) {
17658        try {
17659            final String privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app")
17660                    .getCanonicalPath();
17661            return path.getCanonicalPath().startsWith(privilegedAppDir);
17662        } catch (IOException e) {
17663            Slog.e(TAG, "Unable to access code path " + path);
17664        }
17665        return false;
17666    }
17667
17668    /*
17669     * Tries to delete system package.
17670     */
17671    private boolean deleteSystemPackageLIF(PackageParser.Package deletedPkg,
17672            PackageSetting deletedPs, int[] allUserHandles, int flags, PackageRemovedInfo outInfo,
17673            boolean writeSettings) {
17674        if (deletedPs.parentPackageName != null) {
17675            Slog.w(TAG, "Attempt to delete child system package " + deletedPkg.packageName);
17676            return false;
17677        }
17678
17679        final boolean applyUserRestrictions
17680                = (allUserHandles != null) && (outInfo.origUsers != null);
17681        final PackageSetting disabledPs;
17682        // Confirm if the system package has been updated
17683        // An updated system app can be deleted. This will also have to restore
17684        // the system pkg from system partition
17685        // reader
17686        synchronized (mPackages) {
17687            disabledPs = mSettings.getDisabledSystemPkgLPr(deletedPs.name);
17688        }
17689
17690        if (DEBUG_REMOVE) Slog.d(TAG, "deleteSystemPackageLI: newPs=" + deletedPkg.packageName
17691                + " disabledPs=" + disabledPs);
17692
17693        if (disabledPs == null) {
17694            Slog.w(TAG, "Attempt to delete unknown system package "+ deletedPkg.packageName);
17695            return false;
17696        } else if (DEBUG_REMOVE) {
17697            Slog.d(TAG, "Deleting system pkg from data partition");
17698        }
17699
17700        if (DEBUG_REMOVE) {
17701            if (applyUserRestrictions) {
17702                Slog.d(TAG, "Remembering install states:");
17703                for (int userId : allUserHandles) {
17704                    final boolean finstalled = ArrayUtils.contains(outInfo.origUsers, userId);
17705                    Slog.d(TAG, "   u=" + userId + " inst=" + finstalled);
17706                }
17707            }
17708        }
17709
17710        // Delete the updated package
17711        outInfo.isRemovedPackageSystemUpdate = true;
17712        if (outInfo.removedChildPackages != null) {
17713            final int childCount = (deletedPs.childPackageNames != null)
17714                    ? deletedPs.childPackageNames.size() : 0;
17715            for (int i = 0; i < childCount; i++) {
17716                String childPackageName = deletedPs.childPackageNames.get(i);
17717                if (disabledPs.childPackageNames != null && disabledPs.childPackageNames
17718                        .contains(childPackageName)) {
17719                    PackageRemovedInfo childInfo = outInfo.removedChildPackages.get(
17720                            childPackageName);
17721                    if (childInfo != null) {
17722                        childInfo.isRemovedPackageSystemUpdate = true;
17723                    }
17724                }
17725            }
17726        }
17727
17728        if (disabledPs.versionCode < deletedPs.versionCode) {
17729            // Delete data for downgrades
17730            flags &= ~PackageManager.DELETE_KEEP_DATA;
17731        } else {
17732            // Preserve data by setting flag
17733            flags |= PackageManager.DELETE_KEEP_DATA;
17734        }
17735
17736        boolean ret = deleteInstalledPackageLIF(deletedPs, true, flags, allUserHandles,
17737                outInfo, writeSettings, disabledPs.pkg);
17738        if (!ret) {
17739            return false;
17740        }
17741
17742        // writer
17743        synchronized (mPackages) {
17744            // Reinstate the old system package
17745            enableSystemPackageLPw(disabledPs.pkg);
17746            // Remove any native libraries from the upgraded package.
17747            removeNativeBinariesLI(deletedPs);
17748        }
17749
17750        // Install the system package
17751        if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs);
17752        int parseFlags = mDefParseFlags
17753                | PackageParser.PARSE_MUST_BE_APK
17754                | PackageParser.PARSE_IS_SYSTEM
17755                | PackageParser.PARSE_IS_SYSTEM_DIR;
17756        if (locationIsPrivileged(disabledPs.codePath)) {
17757            parseFlags |= PackageParser.PARSE_IS_PRIVILEGED;
17758        }
17759
17760        final PackageParser.Package newPkg;
17761        try {
17762            newPkg = scanPackageTracedLI(disabledPs.codePath, parseFlags, 0 /* scanFlags */,
17763                0 /* currentTime */, null);
17764        } catch (PackageManagerException e) {
17765            Slog.w(TAG, "Failed to restore system package:" + deletedPkg.packageName + ": "
17766                    + e.getMessage());
17767            return false;
17768        }
17769
17770        try {
17771            // update shared libraries for the newly re-installed system package
17772            updateSharedLibrariesLPr(newPkg, null);
17773        } catch (PackageManagerException e) {
17774            Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
17775        }
17776
17777        prepareAppDataAfterInstallLIF(newPkg);
17778
17779        // writer
17780        synchronized (mPackages) {
17781            PackageSetting ps = mSettings.mPackages.get(newPkg.packageName);
17782
17783            // Propagate the permissions state as we do not want to drop on the floor
17784            // runtime permissions. The update permissions method below will take
17785            // care of removing obsolete permissions and grant install permissions.
17786            ps.getPermissionsState().copyFrom(deletedPs.getPermissionsState());
17787            updatePermissionsLPw(newPkg.packageName, newPkg,
17788                    UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG);
17789
17790            if (applyUserRestrictions) {
17791                if (DEBUG_REMOVE) {
17792                    Slog.d(TAG, "Propagating install state across reinstall");
17793                }
17794                for (int userId : allUserHandles) {
17795                    final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId);
17796                    if (DEBUG_REMOVE) {
17797                        Slog.d(TAG, "    user " + userId + " => " + installed);
17798                    }
17799                    ps.setInstalled(installed, userId);
17800
17801                    mSettings.writeRuntimePermissionsForUserLPr(userId, false);
17802                }
17803                // Regardless of writeSettings we need to ensure that this restriction
17804                // state propagation is persisted
17805                mSettings.writeAllUsersPackageRestrictionsLPr();
17806            }
17807            // can downgrade to reader here
17808            if (writeSettings) {
17809                mSettings.writeLPr();
17810            }
17811        }
17812        return true;
17813    }
17814
17815    private boolean deleteInstalledPackageLIF(PackageSetting ps,
17816            boolean deleteCodeAndResources, int flags, int[] allUserHandles,
17817            PackageRemovedInfo outInfo, boolean writeSettings,
17818            PackageParser.Package replacingPackage) {
17819        synchronized (mPackages) {
17820            if (outInfo != null) {
17821                outInfo.uid = ps.appId;
17822            }
17823
17824            if (outInfo != null && outInfo.removedChildPackages != null) {
17825                final int childCount = (ps.childPackageNames != null)
17826                        ? ps.childPackageNames.size() : 0;
17827                for (int i = 0; i < childCount; i++) {
17828                    String childPackageName = ps.childPackageNames.get(i);
17829                    PackageSetting childPs = mSettings.mPackages.get(childPackageName);
17830                    if (childPs == null) {
17831                        return false;
17832                    }
17833                    PackageRemovedInfo childInfo = outInfo.removedChildPackages.get(
17834                            childPackageName);
17835                    if (childInfo != null) {
17836                        childInfo.uid = childPs.appId;
17837                    }
17838                }
17839            }
17840        }
17841
17842        // Delete package data from internal structures and also remove data if flag is set
17843        removePackageDataLIF(ps, allUserHandles, outInfo, flags, writeSettings);
17844
17845        // Delete the child packages data
17846        final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0;
17847        for (int i = 0; i < childCount; i++) {
17848            PackageSetting childPs;
17849            synchronized (mPackages) {
17850                childPs = mSettings.getPackageLPr(ps.childPackageNames.get(i));
17851            }
17852            if (childPs != null) {
17853                PackageRemovedInfo childOutInfo = (outInfo != null
17854                        && outInfo.removedChildPackages != null)
17855                        ? outInfo.removedChildPackages.get(childPs.name) : null;
17856                final int deleteFlags = (flags & DELETE_KEEP_DATA) != 0
17857                        && (replacingPackage != null
17858                        && !replacingPackage.hasChildPackage(childPs.name))
17859                        ? flags & ~DELETE_KEEP_DATA : flags;
17860                removePackageDataLIF(childPs, allUserHandles, childOutInfo,
17861                        deleteFlags, writeSettings);
17862            }
17863        }
17864
17865        // Delete application code and resources only for parent packages
17866        if (ps.parentPackageName == null) {
17867            if (deleteCodeAndResources && (outInfo != null)) {
17868                outInfo.args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
17869                        ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
17870                if (DEBUG_SD_INSTALL) Slog.i(TAG, "args=" + outInfo.args);
17871            }
17872        }
17873
17874        return true;
17875    }
17876
17877    @Override
17878    public boolean setBlockUninstallForUser(String packageName, boolean blockUninstall,
17879            int userId) {
17880        mContext.enforceCallingOrSelfPermission(
17881                android.Manifest.permission.DELETE_PACKAGES, null);
17882        synchronized (mPackages) {
17883            PackageSetting ps = mSettings.mPackages.get(packageName);
17884            if (ps == null) {
17885                Log.i(TAG, "Package doesn't exist in set block uninstall " + packageName);
17886                return false;
17887            }
17888            // Cannot block uninstall of static shared libs as they are
17889            // considered a part of the using app (emulating static linking).
17890            // Also static libs are installed always on internal storage.
17891            PackageParser.Package pkg = mPackages.get(packageName);
17892            if (pkg != null && pkg.staticSharedLibName != null) {
17893                Slog.w(TAG, "Cannot block uninstall of package: " + packageName
17894                        + " providing static shared library: " + pkg.staticSharedLibName);
17895                return false;
17896            }
17897            if (!ps.getInstalled(userId)) {
17898                // Can't block uninstall for an app that is not installed or enabled.
17899                Log.i(TAG, "Package not installed in set block uninstall " + packageName);
17900                return false;
17901            }
17902            ps.setBlockUninstall(blockUninstall, userId);
17903            mSettings.writePackageRestrictionsLPr(userId);
17904        }
17905        return true;
17906    }
17907
17908    @Override
17909    public boolean getBlockUninstallForUser(String packageName, int userId) {
17910        synchronized (mPackages) {
17911            PackageSetting ps = mSettings.mPackages.get(packageName);
17912            if (ps == null) {
17913                Log.i(TAG, "Package doesn't exist in get block uninstall " + packageName);
17914                return false;
17915            }
17916            return ps.getBlockUninstall(userId);
17917        }
17918    }
17919
17920    @Override
17921    public boolean setRequiredForSystemUser(String packageName, boolean systemUserApp) {
17922        int callingUid = Binder.getCallingUid();
17923        if (callingUid != Process.SYSTEM_UID && callingUid != Process.ROOT_UID) {
17924            throw new SecurityException(
17925                    "setRequiredForSystemUser can only be run by the system or root");
17926        }
17927        synchronized (mPackages) {
17928            PackageSetting ps = mSettings.mPackages.get(packageName);
17929            if (ps == null) {
17930                Log.w(TAG, "Package doesn't exist: " + packageName);
17931                return false;
17932            }
17933            if (systemUserApp) {
17934                ps.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER;
17935            } else {
17936                ps.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER;
17937            }
17938            mSettings.writeLPr();
17939        }
17940        return true;
17941    }
17942
17943    /*
17944     * This method handles package deletion in general
17945     */
17946    private boolean deletePackageLIF(String packageName, UserHandle user,
17947            boolean deleteCodeAndResources, int[] allUserHandles, int flags,
17948            PackageRemovedInfo outInfo, boolean writeSettings,
17949            PackageParser.Package replacingPackage) {
17950        if (packageName == null) {
17951            Slog.w(TAG, "Attempt to delete null packageName.");
17952            return false;
17953        }
17954
17955        if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: " + packageName + " user " + user);
17956
17957        PackageSetting ps;
17958        synchronized (mPackages) {
17959            ps = mSettings.mPackages.get(packageName);
17960            if (ps == null) {
17961                Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
17962                return false;
17963            }
17964
17965            if (ps.parentPackageName != null && (!isSystemApp(ps)
17966                    || (flags & PackageManager.DELETE_SYSTEM_APP) != 0)) {
17967                if (DEBUG_REMOVE) {
17968                    Slog.d(TAG, "Uninstalled child package:" + packageName + " for user:"
17969                            + ((user == null) ? UserHandle.USER_ALL : user));
17970                }
17971                final int removedUserId = (user != null) ? user.getIdentifier()
17972                        : UserHandle.USER_ALL;
17973                if (!clearPackageStateForUserLIF(ps, removedUserId, outInfo)) {
17974                    return false;
17975                }
17976                markPackageUninstalledForUserLPw(ps, user);
17977                scheduleWritePackageRestrictionsLocked(user);
17978                return true;
17979            }
17980        }
17981
17982        if (((!isSystemApp(ps) || (flags&PackageManager.DELETE_SYSTEM_APP) != 0) && user != null
17983                && user.getIdentifier() != UserHandle.USER_ALL)) {
17984            // The caller is asking that the package only be deleted for a single
17985            // user.  To do this, we just mark its uninstalled state and delete
17986            // its data. If this is a system app, we only allow this to happen if
17987            // they have set the special DELETE_SYSTEM_APP which requests different
17988            // semantics than normal for uninstalling system apps.
17989            markPackageUninstalledForUserLPw(ps, user);
17990
17991            if (!isSystemApp(ps)) {
17992                // Do not uninstall the APK if an app should be cached
17993                boolean keepUninstalledPackage = shouldKeepUninstalledPackageLPr(packageName);
17994                if (ps.isAnyInstalled(sUserManager.getUserIds()) || keepUninstalledPackage) {
17995                    // Other user still have this package installed, so all
17996                    // we need to do is clear this user's data and save that
17997                    // it is uninstalled.
17998                    if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users");
17999                    if (!clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo)) {
18000                        return false;
18001                    }
18002                    scheduleWritePackageRestrictionsLocked(user);
18003                    return true;
18004                } else {
18005                    // We need to set it back to 'installed' so the uninstall
18006                    // broadcasts will be sent correctly.
18007                    if (DEBUG_REMOVE) Slog.d(TAG, "Not installed by other users, full delete");
18008                    ps.setInstalled(true, user.getIdentifier());
18009                }
18010            } else {
18011                // This is a system app, so we assume that the
18012                // other users still have this package installed, so all
18013                // we need to do is clear this user's data and save that
18014                // it is uninstalled.
18015                if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app");
18016                if (!clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo)) {
18017                    return false;
18018                }
18019                scheduleWritePackageRestrictionsLocked(user);
18020                return true;
18021            }
18022        }
18023
18024        // If we are deleting a composite package for all users, keep track
18025        // of result for each child.
18026        if (ps.childPackageNames != null && outInfo != null) {
18027            synchronized (mPackages) {
18028                final int childCount = ps.childPackageNames.size();
18029                outInfo.removedChildPackages = new ArrayMap<>(childCount);
18030                for (int i = 0; i < childCount; i++) {
18031                    String childPackageName = ps.childPackageNames.get(i);
18032                    PackageRemovedInfo childInfo = new PackageRemovedInfo();
18033                    childInfo.removedPackage = childPackageName;
18034                    outInfo.removedChildPackages.put(childPackageName, childInfo);
18035                    PackageSetting childPs = mSettings.getPackageLPr(childPackageName);
18036                    if (childPs != null) {
18037                        childInfo.origUsers = childPs.queryInstalledUsers(allUserHandles, true);
18038                    }
18039                }
18040            }
18041        }
18042
18043        boolean ret = false;
18044        if (isSystemApp(ps)) {
18045            if (DEBUG_REMOVE) Slog.d(TAG, "Removing system package: " + ps.name);
18046            // When an updated system application is deleted we delete the existing resources
18047            // as well and fall back to existing code in system partition
18048            ret = deleteSystemPackageLIF(ps.pkg, ps, allUserHandles, flags, outInfo, writeSettings);
18049        } else {
18050            if (DEBUG_REMOVE) Slog.d(TAG, "Removing non-system package: " + ps.name);
18051            ret = deleteInstalledPackageLIF(ps, deleteCodeAndResources, flags, allUserHandles,
18052                    outInfo, writeSettings, replacingPackage);
18053        }
18054
18055        // Take a note whether we deleted the package for all users
18056        if (outInfo != null) {
18057            outInfo.removedForAllUsers = mPackages.get(ps.name) == null;
18058            if (outInfo.removedChildPackages != null) {
18059                synchronized (mPackages) {
18060                    final int childCount = outInfo.removedChildPackages.size();
18061                    for (int i = 0; i < childCount; i++) {
18062                        PackageRemovedInfo childInfo = outInfo.removedChildPackages.valueAt(i);
18063                        if (childInfo != null) {
18064                            childInfo.removedForAllUsers = mPackages.get(
18065                                    childInfo.removedPackage) == null;
18066                        }
18067                    }
18068                }
18069            }
18070            // If we uninstalled an update to a system app there may be some
18071            // child packages that appeared as they are declared in the system
18072            // app but were not declared in the update.
18073            if (isSystemApp(ps)) {
18074                synchronized (mPackages) {
18075                    PackageSetting updatedPs = mSettings.getPackageLPr(ps.name);
18076                    final int childCount = (updatedPs.childPackageNames != null)
18077                            ? updatedPs.childPackageNames.size() : 0;
18078                    for (int i = 0; i < childCount; i++) {
18079                        String childPackageName = updatedPs.childPackageNames.get(i);
18080                        if (outInfo.removedChildPackages == null
18081                                || outInfo.removedChildPackages.indexOfKey(childPackageName) < 0) {
18082                            PackageSetting childPs = mSettings.getPackageLPr(childPackageName);
18083                            if (childPs == null) {
18084                                continue;
18085                            }
18086                            PackageInstalledInfo installRes = new PackageInstalledInfo();
18087                            installRes.name = childPackageName;
18088                            installRes.newUsers = childPs.queryInstalledUsers(allUserHandles, true);
18089                            installRes.pkg = mPackages.get(childPackageName);
18090                            installRes.uid = childPs.pkg.applicationInfo.uid;
18091                            if (outInfo.appearedChildPackages == null) {
18092                                outInfo.appearedChildPackages = new ArrayMap<>();
18093                            }
18094                            outInfo.appearedChildPackages.put(childPackageName, installRes);
18095                        }
18096                    }
18097                }
18098            }
18099        }
18100
18101        return ret;
18102    }
18103
18104    private void markPackageUninstalledForUserLPw(PackageSetting ps, UserHandle user) {
18105        final int[] userIds = (user == null || user.getIdentifier() == UserHandle.USER_ALL)
18106                ? sUserManager.getUserIds() : new int[] {user.getIdentifier()};
18107        for (int nextUserId : userIds) {
18108            if (DEBUG_REMOVE) {
18109                Slog.d(TAG, "Marking package:" + ps.name + " uninstalled for user:" + nextUserId);
18110            }
18111            ps.setUserState(nextUserId, 0, COMPONENT_ENABLED_STATE_DEFAULT,
18112                    false /*installed*/, true /*stopped*/, true /*notLaunched*/,
18113                    false /*hidden*/, false /*suspended*/, null, null, null,
18114                    false /*blockUninstall*/,
18115                    ps.readUserState(nextUserId).domainVerificationStatus, 0,
18116                    PackageManager.INSTALL_REASON_UNKNOWN);
18117        }
18118    }
18119
18120    private boolean clearPackageStateForUserLIF(PackageSetting ps, int userId,
18121            PackageRemovedInfo outInfo) {
18122        final PackageParser.Package pkg;
18123        synchronized (mPackages) {
18124            pkg = mPackages.get(ps.name);
18125        }
18126
18127        final int[] userIds = (userId == UserHandle.USER_ALL) ? sUserManager.getUserIds()
18128                : new int[] {userId};
18129        for (int nextUserId : userIds) {
18130            if (DEBUG_REMOVE) {
18131                Slog.d(TAG, "Updating package:" + ps.name + " install state for user:"
18132                        + nextUserId);
18133            }
18134
18135            destroyAppDataLIF(pkg, userId,
18136                    StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
18137            destroyAppProfilesLIF(pkg, userId);
18138            removeKeystoreDataIfNeeded(nextUserId, ps.appId);
18139            schedulePackageCleaning(ps.name, nextUserId, false);
18140            synchronized (mPackages) {
18141                if (clearPackagePreferredActivitiesLPw(ps.name, nextUserId)) {
18142                    scheduleWritePackageRestrictionsLocked(nextUserId);
18143                }
18144                resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, nextUserId);
18145            }
18146        }
18147
18148        if (outInfo != null) {
18149            outInfo.removedPackage = ps.name;
18150            outInfo.isStaticSharedLib = pkg != null && pkg.staticSharedLibName != null;
18151            outInfo.removedAppId = ps.appId;
18152            outInfo.removedUsers = userIds;
18153        }
18154
18155        return true;
18156    }
18157
18158    private final class ClearStorageConnection implements ServiceConnection {
18159        IMediaContainerService mContainerService;
18160
18161        @Override
18162        public void onServiceConnected(ComponentName name, IBinder service) {
18163            synchronized (this) {
18164                mContainerService = IMediaContainerService.Stub
18165                        .asInterface(Binder.allowBlocking(service));
18166                notifyAll();
18167            }
18168        }
18169
18170        @Override
18171        public void onServiceDisconnected(ComponentName name) {
18172        }
18173    }
18174
18175    private void clearExternalStorageDataSync(String packageName, int userId, boolean allData) {
18176        if (DEFAULT_CONTAINER_PACKAGE.equals(packageName)) return;
18177
18178        final boolean mounted;
18179        if (Environment.isExternalStorageEmulated()) {
18180            mounted = true;
18181        } else {
18182            final String status = Environment.getExternalStorageState();
18183
18184            mounted = status.equals(Environment.MEDIA_MOUNTED)
18185                    || status.equals(Environment.MEDIA_MOUNTED_READ_ONLY);
18186        }
18187
18188        if (!mounted) {
18189            return;
18190        }
18191
18192        final Intent containerIntent = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
18193        int[] users;
18194        if (userId == UserHandle.USER_ALL) {
18195            users = sUserManager.getUserIds();
18196        } else {
18197            users = new int[] { userId };
18198        }
18199        final ClearStorageConnection conn = new ClearStorageConnection();
18200        if (mContext.bindServiceAsUser(
18201                containerIntent, conn, Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) {
18202            try {
18203                for (int curUser : users) {
18204                    long timeout = SystemClock.uptimeMillis() + 5000;
18205                    synchronized (conn) {
18206                        long now;
18207                        while (conn.mContainerService == null &&
18208                                (now = SystemClock.uptimeMillis()) < timeout) {
18209                            try {
18210                                conn.wait(timeout - now);
18211                            } catch (InterruptedException e) {
18212                            }
18213                        }
18214                    }
18215                    if (conn.mContainerService == null) {
18216                        return;
18217                    }
18218
18219                    final UserEnvironment userEnv = new UserEnvironment(curUser);
18220                    clearDirectory(conn.mContainerService,
18221                            userEnv.buildExternalStorageAppCacheDirs(packageName));
18222                    if (allData) {
18223                        clearDirectory(conn.mContainerService,
18224                                userEnv.buildExternalStorageAppDataDirs(packageName));
18225                        clearDirectory(conn.mContainerService,
18226                                userEnv.buildExternalStorageAppMediaDirs(packageName));
18227                    }
18228                }
18229            } finally {
18230                mContext.unbindService(conn);
18231            }
18232        }
18233    }
18234
18235    @Override
18236    public void clearApplicationProfileData(String packageName) {
18237        enforceSystemOrRoot("Only the system can clear all profile data");
18238
18239        final PackageParser.Package pkg;
18240        synchronized (mPackages) {
18241            pkg = mPackages.get(packageName);
18242        }
18243
18244        try (PackageFreezer freezer = freezePackage(packageName, "clearApplicationProfileData")) {
18245            synchronized (mInstallLock) {
18246                clearAppProfilesLIF(pkg, UserHandle.USER_ALL);
18247                destroyAppReferenceProfileLeafLIF(pkg, UserHandle.USER_ALL,
18248                        true /* removeBaseMarker */);
18249            }
18250        }
18251    }
18252
18253    @Override
18254    public void clearApplicationUserData(final String packageName,
18255            final IPackageDataObserver observer, final int userId) {
18256        mContext.enforceCallingOrSelfPermission(
18257                android.Manifest.permission.CLEAR_APP_USER_DATA, null);
18258
18259        enforceCrossUserPermission(Binder.getCallingUid(), userId,
18260                true /* requireFullPermission */, false /* checkShell */, "clear application data");
18261
18262        if (mProtectedPackages.isPackageDataProtected(userId, packageName)) {
18263            throw new SecurityException("Cannot clear data for a protected package: "
18264                    + packageName);
18265        }
18266        // Queue up an async operation since the package deletion may take a little while.
18267        mHandler.post(new Runnable() {
18268            public void run() {
18269                mHandler.removeCallbacks(this);
18270                final boolean succeeded;
18271                try (PackageFreezer freezer = freezePackage(packageName,
18272                        "clearApplicationUserData")) {
18273                    synchronized (mInstallLock) {
18274                        succeeded = clearApplicationUserDataLIF(packageName, userId);
18275                    }
18276                    clearExternalStorageDataSync(packageName, userId, true);
18277                    synchronized (mPackages) {
18278                        mInstantAppRegistry.deleteInstantApplicationMetadataLPw(
18279                                packageName, userId);
18280                    }
18281                }
18282                if (succeeded) {
18283                    // invoke DeviceStorageMonitor's update method to clear any notifications
18284                    DeviceStorageMonitorInternal dsm = LocalServices
18285                            .getService(DeviceStorageMonitorInternal.class);
18286                    if (dsm != null) {
18287                        dsm.checkMemory();
18288                    }
18289                }
18290                if(observer != null) {
18291                    try {
18292                        observer.onRemoveCompleted(packageName, succeeded);
18293                    } catch (RemoteException e) {
18294                        Log.i(TAG, "Observer no longer exists.");
18295                    }
18296                } //end if observer
18297            } //end run
18298        });
18299    }
18300
18301    private boolean clearApplicationUserDataLIF(String packageName, int userId) {
18302        if (packageName == null) {
18303            Slog.w(TAG, "Attempt to delete null packageName.");
18304            return false;
18305        }
18306
18307        // Try finding details about the requested package
18308        PackageParser.Package pkg;
18309        synchronized (mPackages) {
18310            pkg = mPackages.get(packageName);
18311            if (pkg == null) {
18312                final PackageSetting ps = mSettings.mPackages.get(packageName);
18313                if (ps != null) {
18314                    pkg = ps.pkg;
18315                }
18316            }
18317
18318            if (pkg == null) {
18319                Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
18320                return false;
18321            }
18322
18323            PackageSetting ps = (PackageSetting) pkg.mExtras;
18324            resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
18325        }
18326
18327        clearAppDataLIF(pkg, userId,
18328                StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
18329
18330        final int appId = UserHandle.getAppId(pkg.applicationInfo.uid);
18331        removeKeystoreDataIfNeeded(userId, appId);
18332
18333        UserManagerInternal umInternal = getUserManagerInternal();
18334        final int flags;
18335        if (umInternal.isUserUnlockingOrUnlocked(userId)) {
18336            flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
18337        } else if (umInternal.isUserRunning(userId)) {
18338            flags = StorageManager.FLAG_STORAGE_DE;
18339        } else {
18340            flags = 0;
18341        }
18342        prepareAppDataContentsLIF(pkg, userId, flags);
18343
18344        return true;
18345    }
18346
18347    /**
18348     * Reverts user permission state changes (permissions and flags) in
18349     * all packages for a given user.
18350     *
18351     * @param userId The device user for which to do a reset.
18352     */
18353    private void resetUserChangesToRuntimePermissionsAndFlagsLPw(int userId) {
18354        final int packageCount = mPackages.size();
18355        for (int i = 0; i < packageCount; i++) {
18356            PackageParser.Package pkg = mPackages.valueAt(i);
18357            PackageSetting ps = (PackageSetting) pkg.mExtras;
18358            resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
18359        }
18360    }
18361
18362    private void resetNetworkPolicies(int userId) {
18363        LocalServices.getService(NetworkPolicyManagerInternal.class).resetUserState(userId);
18364    }
18365
18366    /**
18367     * Reverts user permission state changes (permissions and flags).
18368     *
18369     * @param ps The package for which to reset.
18370     * @param userId The device user for which to do a reset.
18371     */
18372    private void resetUserChangesToRuntimePermissionsAndFlagsLPw(
18373            final PackageSetting ps, final int userId) {
18374        if (ps.pkg == null) {
18375            return;
18376        }
18377
18378        // These are flags that can change base on user actions.
18379        final int userSettableMask = FLAG_PERMISSION_USER_SET
18380                | FLAG_PERMISSION_USER_FIXED
18381                | FLAG_PERMISSION_REVOKE_ON_UPGRADE
18382                | FLAG_PERMISSION_REVIEW_REQUIRED;
18383
18384        final int policyOrSystemFlags = FLAG_PERMISSION_SYSTEM_FIXED
18385                | FLAG_PERMISSION_POLICY_FIXED;
18386
18387        boolean writeInstallPermissions = false;
18388        boolean writeRuntimePermissions = false;
18389
18390        final int permissionCount = ps.pkg.requestedPermissions.size();
18391        for (int i = 0; i < permissionCount; i++) {
18392            String permission = ps.pkg.requestedPermissions.get(i);
18393
18394            BasePermission bp = mSettings.mPermissions.get(permission);
18395            if (bp == null) {
18396                continue;
18397            }
18398
18399            // If shared user we just reset the state to which only this app contributed.
18400            if (ps.sharedUser != null) {
18401                boolean used = false;
18402                final int packageCount = ps.sharedUser.packages.size();
18403                for (int j = 0; j < packageCount; j++) {
18404                    PackageSetting pkg = ps.sharedUser.packages.valueAt(j);
18405                    if (pkg.pkg != null && !pkg.pkg.packageName.equals(ps.pkg.packageName)
18406                            && pkg.pkg.requestedPermissions.contains(permission)) {
18407                        used = true;
18408                        break;
18409                    }
18410                }
18411                if (used) {
18412                    continue;
18413                }
18414            }
18415
18416            PermissionsState permissionsState = ps.getPermissionsState();
18417
18418            final int oldFlags = permissionsState.getPermissionFlags(bp.name, userId);
18419
18420            // Always clear the user settable flags.
18421            final boolean hasInstallState = permissionsState.getInstallPermissionState(
18422                    bp.name) != null;
18423            // If permission review is enabled and this is a legacy app, mark the
18424            // permission as requiring a review as this is the initial state.
18425            int flags = 0;
18426            if (mPermissionReviewRequired
18427                    && ps.pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
18428                flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
18429            }
18430            if (permissionsState.updatePermissionFlags(bp, userId, userSettableMask, flags)) {
18431                if (hasInstallState) {
18432                    writeInstallPermissions = true;
18433                } else {
18434                    writeRuntimePermissions = true;
18435                }
18436            }
18437
18438            // Below is only runtime permission handling.
18439            if (!bp.isRuntime()) {
18440                continue;
18441            }
18442
18443            // Never clobber system or policy.
18444            if ((oldFlags & policyOrSystemFlags) != 0) {
18445                continue;
18446            }
18447
18448            // If this permission was granted by default, make sure it is.
18449            if ((oldFlags & FLAG_PERMISSION_GRANTED_BY_DEFAULT) != 0) {
18450                if (permissionsState.grantRuntimePermission(bp, userId)
18451                        != PERMISSION_OPERATION_FAILURE) {
18452                    writeRuntimePermissions = true;
18453                }
18454            // If permission review is enabled the permissions for a legacy apps
18455            // are represented as constantly granted runtime ones, so don't revoke.
18456            } else if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) {
18457                // Otherwise, reset the permission.
18458                final int revokeResult = permissionsState.revokeRuntimePermission(bp, userId);
18459                switch (revokeResult) {
18460                    case PERMISSION_OPERATION_SUCCESS:
18461                    case PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
18462                        writeRuntimePermissions = true;
18463                        final int appId = ps.appId;
18464                        mHandler.post(new Runnable() {
18465                            @Override
18466                            public void run() {
18467                                killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED);
18468                            }
18469                        });
18470                    } break;
18471                }
18472            }
18473        }
18474
18475        // Synchronously write as we are taking permissions away.
18476        if (writeRuntimePermissions) {
18477            mSettings.writeRuntimePermissionsForUserLPr(userId, true);
18478        }
18479
18480        // Synchronously write as we are taking permissions away.
18481        if (writeInstallPermissions) {
18482            mSettings.writeLPr();
18483        }
18484    }
18485
18486    /**
18487     * Remove entries from the keystore daemon. Will only remove it if the
18488     * {@code appId} is valid.
18489     */
18490    private static void removeKeystoreDataIfNeeded(int userId, int appId) {
18491        if (appId < 0) {
18492            return;
18493        }
18494
18495        final KeyStore keyStore = KeyStore.getInstance();
18496        if (keyStore != null) {
18497            if (userId == UserHandle.USER_ALL) {
18498                for (final int individual : sUserManager.getUserIds()) {
18499                    keyStore.clearUid(UserHandle.getUid(individual, appId));
18500                }
18501            } else {
18502                keyStore.clearUid(UserHandle.getUid(userId, appId));
18503            }
18504        } else {
18505            Slog.w(TAG, "Could not contact keystore to clear entries for app id " + appId);
18506        }
18507    }
18508
18509    @Override
18510    public void deleteApplicationCacheFiles(final String packageName,
18511            final IPackageDataObserver observer) {
18512        final int userId = UserHandle.getCallingUserId();
18513        deleteApplicationCacheFilesAsUser(packageName, userId, observer);
18514    }
18515
18516    @Override
18517    public void deleteApplicationCacheFilesAsUser(final String packageName, final int userId,
18518            final IPackageDataObserver observer) {
18519        mContext.enforceCallingOrSelfPermission(
18520                android.Manifest.permission.DELETE_CACHE_FILES, null);
18521        enforceCrossUserPermission(Binder.getCallingUid(), userId,
18522                /* requireFullPermission= */ true, /* checkShell= */ false,
18523                "delete application cache files");
18524
18525        final PackageParser.Package pkg;
18526        synchronized (mPackages) {
18527            pkg = mPackages.get(packageName);
18528        }
18529
18530        // Queue up an async operation since the package deletion may take a little while.
18531        mHandler.post(new Runnable() {
18532            public void run() {
18533                synchronized (mInstallLock) {
18534                    final int flags = StorageManager.FLAG_STORAGE_DE
18535                            | StorageManager.FLAG_STORAGE_CE;
18536                    // We're only clearing cache files, so we don't care if the
18537                    // app is unfrozen and still able to run
18538                    clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CACHE_ONLY);
18539                    clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
18540                }
18541                clearExternalStorageDataSync(packageName, userId, false);
18542                if (observer != null) {
18543                    try {
18544                        observer.onRemoveCompleted(packageName, true);
18545                    } catch (RemoteException e) {
18546                        Log.i(TAG, "Observer no longer exists.");
18547                    }
18548                }
18549            }
18550        });
18551    }
18552
18553    @Override
18554    public void getPackageSizeInfo(final String packageName, int userHandle,
18555            final IPackageStatsObserver observer) {
18556        mContext.enforceCallingOrSelfPermission(
18557                android.Manifest.permission.GET_PACKAGE_SIZE, null);
18558        if (packageName == null) {
18559            throw new IllegalArgumentException("Attempt to get size of null packageName");
18560        }
18561
18562        PackageStats stats = new PackageStats(packageName, userHandle);
18563
18564        /*
18565         * Queue up an async operation since the package measurement may take a
18566         * little while.
18567         */
18568        Message msg = mHandler.obtainMessage(INIT_COPY);
18569        msg.obj = new MeasureParams(stats, observer);
18570        mHandler.sendMessage(msg);
18571    }
18572
18573    private boolean getPackageSizeInfoLI(String packageName, int userId, PackageStats stats) {
18574        final PackageSetting ps;
18575        synchronized (mPackages) {
18576            ps = mSettings.mPackages.get(packageName);
18577            if (ps == null) {
18578                Slog.w(TAG, "Failed to find settings for " + packageName);
18579                return false;
18580            }
18581        }
18582
18583        final String[] packageNames = { packageName };
18584        final long[] ceDataInodes = { ps.getCeDataInode(userId) };
18585        final String[] codePaths = { ps.codePathString };
18586
18587        try {
18588            mInstaller.getAppSize(ps.volumeUuid, packageNames, userId, 0,
18589                    ps.appId, ceDataInodes, codePaths, stats);
18590
18591            // For now, ignore code size of packages on system partition
18592            if (isSystemApp(ps) && !isUpdatedSystemApp(ps)) {
18593                stats.codeSize = 0;
18594            }
18595
18596            // External clients expect these to be tracked separately
18597            stats.dataSize -= stats.cacheSize;
18598
18599        } catch (InstallerException e) {
18600            Slog.w(TAG, String.valueOf(e));
18601            return false;
18602        }
18603
18604        return true;
18605    }
18606
18607    private int getUidTargetSdkVersionLockedLPr(int uid) {
18608        Object obj = mSettings.getUserIdLPr(uid);
18609        if (obj instanceof SharedUserSetting) {
18610            final SharedUserSetting sus = (SharedUserSetting) obj;
18611            int vers = Build.VERSION_CODES.CUR_DEVELOPMENT;
18612            final Iterator<PackageSetting> it = sus.packages.iterator();
18613            while (it.hasNext()) {
18614                final PackageSetting ps = it.next();
18615                if (ps.pkg != null) {
18616                    int v = ps.pkg.applicationInfo.targetSdkVersion;
18617                    if (v < vers) vers = v;
18618                }
18619            }
18620            return vers;
18621        } else if (obj instanceof PackageSetting) {
18622            final PackageSetting ps = (PackageSetting) obj;
18623            if (ps.pkg != null) {
18624                return ps.pkg.applicationInfo.targetSdkVersion;
18625            }
18626        }
18627        return Build.VERSION_CODES.CUR_DEVELOPMENT;
18628    }
18629
18630    @Override
18631    public void addPreferredActivity(IntentFilter filter, int match,
18632            ComponentName[] set, ComponentName activity, int userId) {
18633        addPreferredActivityInternal(filter, match, set, activity, true, userId,
18634                "Adding preferred");
18635    }
18636
18637    private void addPreferredActivityInternal(IntentFilter filter, int match,
18638            ComponentName[] set, ComponentName activity, boolean always, int userId,
18639            String opname) {
18640        // writer
18641        int callingUid = Binder.getCallingUid();
18642        enforceCrossUserPermission(callingUid, userId,
18643                true /* requireFullPermission */, false /* checkShell */, "add preferred activity");
18644        if (filter.countActions() == 0) {
18645            Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
18646            return;
18647        }
18648        synchronized (mPackages) {
18649            if (mContext.checkCallingOrSelfPermission(
18650                    android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
18651                    != PackageManager.PERMISSION_GRANTED) {
18652                if (getUidTargetSdkVersionLockedLPr(callingUid)
18653                        < Build.VERSION_CODES.FROYO) {
18654                    Slog.w(TAG, "Ignoring addPreferredActivity() from uid "
18655                            + callingUid);
18656                    return;
18657                }
18658                mContext.enforceCallingOrSelfPermission(
18659                        android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
18660            }
18661
18662            PreferredIntentResolver pir = mSettings.editPreferredActivitiesLPw(userId);
18663            Slog.i(TAG, opname + " activity " + activity.flattenToShortString() + " for user "
18664                    + userId + ":");
18665            filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
18666            pir.addFilter(new PreferredActivity(filter, match, set, activity, always));
18667            scheduleWritePackageRestrictionsLocked(userId);
18668            postPreferredActivityChangedBroadcast(userId);
18669        }
18670    }
18671
18672    private void postPreferredActivityChangedBroadcast(int userId) {
18673        mHandler.post(() -> {
18674            final IActivityManager am = ActivityManager.getService();
18675            if (am == null) {
18676                return;
18677            }
18678
18679            final Intent intent = new Intent(Intent.ACTION_PREFERRED_ACTIVITY_CHANGED);
18680            intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18681            try {
18682                am.broadcastIntent(null, intent, null, null,
18683                        0, null, null, null, android.app.AppOpsManager.OP_NONE,
18684                        null, false, false, userId);
18685            } catch (RemoteException e) {
18686            }
18687        });
18688    }
18689
18690    @Override
18691    public void replacePreferredActivity(IntentFilter filter, int match,
18692            ComponentName[] set, ComponentName activity, int userId) {
18693        if (filter.countActions() != 1) {
18694            throw new IllegalArgumentException(
18695                    "replacePreferredActivity expects filter to have only 1 action.");
18696        }
18697        if (filter.countDataAuthorities() != 0
18698                || filter.countDataPaths() != 0
18699                || filter.countDataSchemes() > 1
18700                || filter.countDataTypes() != 0) {
18701            throw new IllegalArgumentException(
18702                    "replacePreferredActivity expects filter to have no data authorities, " +
18703                    "paths, or types; and at most one scheme.");
18704        }
18705
18706        final int callingUid = Binder.getCallingUid();
18707        enforceCrossUserPermission(callingUid, userId,
18708                true /* requireFullPermission */, false /* checkShell */,
18709                "replace preferred activity");
18710        synchronized (mPackages) {
18711            if (mContext.checkCallingOrSelfPermission(
18712                    android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
18713                    != PackageManager.PERMISSION_GRANTED) {
18714                if (getUidTargetSdkVersionLockedLPr(callingUid)
18715                        < Build.VERSION_CODES.FROYO) {
18716                    Slog.w(TAG, "Ignoring replacePreferredActivity() from uid "
18717                            + Binder.getCallingUid());
18718                    return;
18719                }
18720                mContext.enforceCallingOrSelfPermission(
18721                        android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
18722            }
18723
18724            PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
18725            if (pir != null) {
18726                // Get all of the existing entries that exactly match this filter.
18727                ArrayList<PreferredActivity> existing = pir.findFilters(filter);
18728                if (existing != null && existing.size() == 1) {
18729                    PreferredActivity cur = existing.get(0);
18730                    if (DEBUG_PREFERRED) {
18731                        Slog.i(TAG, "Checking replace of preferred:");
18732                        filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
18733                        if (!cur.mPref.mAlways) {
18734                            Slog.i(TAG, "  -- CUR; not mAlways!");
18735                        } else {
18736                            Slog.i(TAG, "  -- CUR: mMatch=" + cur.mPref.mMatch);
18737                            Slog.i(TAG, "  -- CUR: mSet="
18738                                    + Arrays.toString(cur.mPref.mSetComponents));
18739                            Slog.i(TAG, "  -- CUR: mComponent=" + cur.mPref.mShortComponent);
18740                            Slog.i(TAG, "  -- NEW: mMatch="
18741                                    + (match&IntentFilter.MATCH_CATEGORY_MASK));
18742                            Slog.i(TAG, "  -- CUR: mSet=" + Arrays.toString(set));
18743                            Slog.i(TAG, "  -- CUR: mComponent=" + activity.flattenToShortString());
18744                        }
18745                    }
18746                    if (cur.mPref.mAlways && cur.mPref.mComponent.equals(activity)
18747                            && cur.mPref.mMatch == (match&IntentFilter.MATCH_CATEGORY_MASK)
18748                            && cur.mPref.sameSet(set)) {
18749                        // Setting the preferred activity to what it happens to be already
18750                        if (DEBUG_PREFERRED) {
18751                            Slog.i(TAG, "Replacing with same preferred activity "
18752                                    + cur.mPref.mShortComponent + " for user "
18753                                    + userId + ":");
18754                            filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
18755                        }
18756                        return;
18757                    }
18758                }
18759
18760                if (existing != null) {
18761                    if (DEBUG_PREFERRED) {
18762                        Slog.i(TAG, existing.size() + " existing preferred matches for:");
18763                        filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
18764                    }
18765                    for (int i = 0; i < existing.size(); i++) {
18766                        PreferredActivity pa = existing.get(i);
18767                        if (DEBUG_PREFERRED) {
18768                            Slog.i(TAG, "Removing existing preferred activity "
18769                                    + pa.mPref.mComponent + ":");
18770                            pa.dump(new LogPrinter(Log.INFO, TAG), "  ");
18771                        }
18772                        pir.removeFilter(pa);
18773                    }
18774                }
18775            }
18776            addPreferredActivityInternal(filter, match, set, activity, true, userId,
18777                    "Replacing preferred");
18778        }
18779    }
18780
18781    @Override
18782    public void clearPackagePreferredActivities(String packageName) {
18783        final int uid = Binder.getCallingUid();
18784        // writer
18785        synchronized (mPackages) {
18786            PackageParser.Package pkg = mPackages.get(packageName);
18787            if (pkg == null || pkg.applicationInfo.uid != uid) {
18788                if (mContext.checkCallingOrSelfPermission(
18789                        android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
18790                        != PackageManager.PERMISSION_GRANTED) {
18791                    if (getUidTargetSdkVersionLockedLPr(Binder.getCallingUid())
18792                            < Build.VERSION_CODES.FROYO) {
18793                        Slog.w(TAG, "Ignoring clearPackagePreferredActivities() from uid "
18794                                + Binder.getCallingUid());
18795                        return;
18796                    }
18797                    mContext.enforceCallingOrSelfPermission(
18798                            android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
18799                }
18800            }
18801
18802            int user = UserHandle.getCallingUserId();
18803            if (clearPackagePreferredActivitiesLPw(packageName, user)) {
18804                scheduleWritePackageRestrictionsLocked(user);
18805            }
18806        }
18807    }
18808
18809    /** This method takes a specific user id as well as UserHandle.USER_ALL. */
18810    boolean clearPackagePreferredActivitiesLPw(String packageName, int userId) {
18811        ArrayList<PreferredActivity> removed = null;
18812        boolean changed = false;
18813        for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
18814            final int thisUserId = mSettings.mPreferredActivities.keyAt(i);
18815            PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
18816            if (userId != UserHandle.USER_ALL && userId != thisUserId) {
18817                continue;
18818            }
18819            Iterator<PreferredActivity> it = pir.filterIterator();
18820            while (it.hasNext()) {
18821                PreferredActivity pa = it.next();
18822                // Mark entry for removal only if it matches the package name
18823                // and the entry is of type "always".
18824                if (packageName == null ||
18825                        (pa.mPref.mComponent.getPackageName().equals(packageName)
18826                                && pa.mPref.mAlways)) {
18827                    if (removed == null) {
18828                        removed = new ArrayList<PreferredActivity>();
18829                    }
18830                    removed.add(pa);
18831                }
18832            }
18833            if (removed != null) {
18834                for (int j=0; j<removed.size(); j++) {
18835                    PreferredActivity pa = removed.get(j);
18836                    pir.removeFilter(pa);
18837                }
18838                changed = true;
18839            }
18840        }
18841        if (changed) {
18842            postPreferredActivityChangedBroadcast(userId);
18843        }
18844        return changed;
18845    }
18846
18847    /** This method takes a specific user id as well as UserHandle.USER_ALL. */
18848    private void clearIntentFilterVerificationsLPw(int userId) {
18849        final int packageCount = mPackages.size();
18850        for (int i = 0; i < packageCount; i++) {
18851            PackageParser.Package pkg = mPackages.valueAt(i);
18852            clearIntentFilterVerificationsLPw(pkg.packageName, userId);
18853        }
18854    }
18855
18856    /** This method takes a specific user id as well as UserHandle.USER_ALL. */
18857    void clearIntentFilterVerificationsLPw(String packageName, int userId) {
18858        if (userId == UserHandle.USER_ALL) {
18859            if (mSettings.removeIntentFilterVerificationLPw(packageName,
18860                    sUserManager.getUserIds())) {
18861                for (int oneUserId : sUserManager.getUserIds()) {
18862                    scheduleWritePackageRestrictionsLocked(oneUserId);
18863                }
18864            }
18865        } else {
18866            if (mSettings.removeIntentFilterVerificationLPw(packageName, userId)) {
18867                scheduleWritePackageRestrictionsLocked(userId);
18868            }
18869        }
18870    }
18871
18872    void clearDefaultBrowserIfNeeded(String packageName) {
18873        for (int oneUserId : sUserManager.getUserIds()) {
18874            String defaultBrowserPackageName = getDefaultBrowserPackageName(oneUserId);
18875            if (TextUtils.isEmpty(defaultBrowserPackageName)) continue;
18876            if (packageName.equals(defaultBrowserPackageName)) {
18877                setDefaultBrowserPackageName(null, oneUserId);
18878            }
18879        }
18880    }
18881
18882    @Override
18883    public void resetApplicationPreferences(int userId) {
18884        mContext.enforceCallingOrSelfPermission(
18885                android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
18886        final long identity = Binder.clearCallingIdentity();
18887        // writer
18888        try {
18889            synchronized (mPackages) {
18890                clearPackagePreferredActivitiesLPw(null, userId);
18891                mSettings.applyDefaultPreferredAppsLPw(this, userId);
18892                // TODO: We have to reset the default SMS and Phone. This requires
18893                // significant refactoring to keep all default apps in the package
18894                // manager (cleaner but more work) or have the services provide
18895                // callbacks to the package manager to request a default app reset.
18896                applyFactoryDefaultBrowserLPw(userId);
18897                clearIntentFilterVerificationsLPw(userId);
18898                primeDomainVerificationsLPw(userId);
18899                resetUserChangesToRuntimePermissionsAndFlagsLPw(userId);
18900                scheduleWritePackageRestrictionsLocked(userId);
18901            }
18902            resetNetworkPolicies(userId);
18903        } finally {
18904            Binder.restoreCallingIdentity(identity);
18905        }
18906    }
18907
18908    @Override
18909    public int getPreferredActivities(List<IntentFilter> outFilters,
18910            List<ComponentName> outActivities, String packageName) {
18911
18912        int num = 0;
18913        final int userId = UserHandle.getCallingUserId();
18914        // reader
18915        synchronized (mPackages) {
18916            PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
18917            if (pir != null) {
18918                final Iterator<PreferredActivity> it = pir.filterIterator();
18919                while (it.hasNext()) {
18920                    final PreferredActivity pa = it.next();
18921                    if (packageName == null
18922                            || (pa.mPref.mComponent.getPackageName().equals(packageName)
18923                                    && pa.mPref.mAlways)) {
18924                        if (outFilters != null) {
18925                            outFilters.add(new IntentFilter(pa));
18926                        }
18927                        if (outActivities != null) {
18928                            outActivities.add(pa.mPref.mComponent);
18929                        }
18930                    }
18931                }
18932            }
18933        }
18934
18935        return num;
18936    }
18937
18938    @Override
18939    public void addPersistentPreferredActivity(IntentFilter filter, ComponentName activity,
18940            int userId) {
18941        int callingUid = Binder.getCallingUid();
18942        if (callingUid != Process.SYSTEM_UID) {
18943            throw new SecurityException(
18944                    "addPersistentPreferredActivity can only be run by the system");
18945        }
18946        if (filter.countActions() == 0) {
18947            Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
18948            return;
18949        }
18950        synchronized (mPackages) {
18951            Slog.i(TAG, "Adding persistent preferred activity " + activity + " for user " + userId +
18952                    ":");
18953            filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
18954            mSettings.editPersistentPreferredActivitiesLPw(userId).addFilter(
18955                    new PersistentPreferredActivity(filter, activity));
18956            scheduleWritePackageRestrictionsLocked(userId);
18957            postPreferredActivityChangedBroadcast(userId);
18958        }
18959    }
18960
18961    @Override
18962    public void clearPackagePersistentPreferredActivities(String packageName, int userId) {
18963        int callingUid = Binder.getCallingUid();
18964        if (callingUid != Process.SYSTEM_UID) {
18965            throw new SecurityException(
18966                    "clearPackagePersistentPreferredActivities can only be run by the system");
18967        }
18968        ArrayList<PersistentPreferredActivity> removed = null;
18969        boolean changed = false;
18970        synchronized (mPackages) {
18971            for (int i=0; i<mSettings.mPersistentPreferredActivities.size(); i++) {
18972                final int thisUserId = mSettings.mPersistentPreferredActivities.keyAt(i);
18973                PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
18974                        .valueAt(i);
18975                if (userId != thisUserId) {
18976                    continue;
18977                }
18978                Iterator<PersistentPreferredActivity> it = ppir.filterIterator();
18979                while (it.hasNext()) {
18980                    PersistentPreferredActivity ppa = it.next();
18981                    // Mark entry for removal only if it matches the package name.
18982                    if (ppa.mComponent.getPackageName().equals(packageName)) {
18983                        if (removed == null) {
18984                            removed = new ArrayList<PersistentPreferredActivity>();
18985                        }
18986                        removed.add(ppa);
18987                    }
18988                }
18989                if (removed != null) {
18990                    for (int j=0; j<removed.size(); j++) {
18991                        PersistentPreferredActivity ppa = removed.get(j);
18992                        ppir.removeFilter(ppa);
18993                    }
18994                    changed = true;
18995                }
18996            }
18997
18998            if (changed) {
18999                scheduleWritePackageRestrictionsLocked(userId);
19000                postPreferredActivityChangedBroadcast(userId);
19001            }
19002        }
19003    }
19004
19005    /**
19006     * Common machinery for picking apart a restored XML blob and passing
19007     * it to a caller-supplied functor to be applied to the running system.
19008     */
19009    private void restoreFromXml(XmlPullParser parser, int userId,
19010            String expectedStartTag, BlobXmlRestorer functor)
19011            throws IOException, XmlPullParserException {
19012        int type;
19013        while ((type = parser.next()) != XmlPullParser.START_TAG
19014                && type != XmlPullParser.END_DOCUMENT) {
19015        }
19016        if (type != XmlPullParser.START_TAG) {
19017            // oops didn't find a start tag?!
19018            if (DEBUG_BACKUP) {
19019                Slog.e(TAG, "Didn't find start tag during restore");
19020            }
19021            return;
19022        }
19023Slog.v(TAG, ":: restoreFromXml() : got to tag " + parser.getName());
19024        // this is supposed to be TAG_PREFERRED_BACKUP
19025        if (!expectedStartTag.equals(parser.getName())) {
19026            if (DEBUG_BACKUP) {
19027                Slog.e(TAG, "Found unexpected tag " + parser.getName());
19028            }
19029            return;
19030        }
19031
19032        // skip interfering stuff, then we're aligned with the backing implementation
19033        while ((type = parser.next()) == XmlPullParser.TEXT) { }
19034Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName());
19035        functor.apply(parser, userId);
19036    }
19037
19038    private interface BlobXmlRestorer {
19039        public void apply(XmlPullParser parser, int userId) throws IOException, XmlPullParserException;
19040    }
19041
19042    /**
19043     * Non-Binder method, support for the backup/restore mechanism: write the
19044     * full set of preferred activities in its canonical XML format.  Returns the
19045     * XML output as a byte array, or null if there is none.
19046     */
19047    @Override
19048    public byte[] getPreferredActivityBackup(int userId) {
19049        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19050            throw new SecurityException("Only the system may call getPreferredActivityBackup()");
19051        }
19052
19053        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
19054        try {
19055            final XmlSerializer serializer = new FastXmlSerializer();
19056            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
19057            serializer.startDocument(null, true);
19058            serializer.startTag(null, TAG_PREFERRED_BACKUP);
19059
19060            synchronized (mPackages) {
19061                mSettings.writePreferredActivitiesLPr(serializer, userId, true);
19062            }
19063
19064            serializer.endTag(null, TAG_PREFERRED_BACKUP);
19065            serializer.endDocument();
19066            serializer.flush();
19067        } catch (Exception e) {
19068            if (DEBUG_BACKUP) {
19069                Slog.e(TAG, "Unable to write preferred activities for backup", e);
19070            }
19071            return null;
19072        }
19073
19074        return dataStream.toByteArray();
19075    }
19076
19077    @Override
19078    public void restorePreferredActivities(byte[] backup, int userId) {
19079        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19080            throw new SecurityException("Only the system may call restorePreferredActivities()");
19081        }
19082
19083        try {
19084            final XmlPullParser parser = Xml.newPullParser();
19085            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
19086            restoreFromXml(parser, userId, TAG_PREFERRED_BACKUP,
19087                    new BlobXmlRestorer() {
19088                        @Override
19089                        public void apply(XmlPullParser parser, int userId)
19090                                throws XmlPullParserException, IOException {
19091                            synchronized (mPackages) {
19092                                mSettings.readPreferredActivitiesLPw(parser, userId);
19093                            }
19094                        }
19095                    } );
19096        } catch (Exception e) {
19097            if (DEBUG_BACKUP) {
19098                Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
19099            }
19100        }
19101    }
19102
19103    /**
19104     * Non-Binder method, support for the backup/restore mechanism: write the
19105     * default browser (etc) settings in its canonical XML format.  Returns the default
19106     * browser XML representation as a byte array, or null if there is none.
19107     */
19108    @Override
19109    public byte[] getDefaultAppsBackup(int userId) {
19110        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19111            throw new SecurityException("Only the system may call getDefaultAppsBackup()");
19112        }
19113
19114        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
19115        try {
19116            final XmlSerializer serializer = new FastXmlSerializer();
19117            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
19118            serializer.startDocument(null, true);
19119            serializer.startTag(null, TAG_DEFAULT_APPS);
19120
19121            synchronized (mPackages) {
19122                mSettings.writeDefaultAppsLPr(serializer, userId);
19123            }
19124
19125            serializer.endTag(null, TAG_DEFAULT_APPS);
19126            serializer.endDocument();
19127            serializer.flush();
19128        } catch (Exception e) {
19129            if (DEBUG_BACKUP) {
19130                Slog.e(TAG, "Unable to write default apps for backup", e);
19131            }
19132            return null;
19133        }
19134
19135        return dataStream.toByteArray();
19136    }
19137
19138    @Override
19139    public void restoreDefaultApps(byte[] backup, int userId) {
19140        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19141            throw new SecurityException("Only the system may call restoreDefaultApps()");
19142        }
19143
19144        try {
19145            final XmlPullParser parser = Xml.newPullParser();
19146            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
19147            restoreFromXml(parser, userId, TAG_DEFAULT_APPS,
19148                    new BlobXmlRestorer() {
19149                        @Override
19150                        public void apply(XmlPullParser parser, int userId)
19151                                throws XmlPullParserException, IOException {
19152                            synchronized (mPackages) {
19153                                mSettings.readDefaultAppsLPw(parser, userId);
19154                            }
19155                        }
19156                    } );
19157        } catch (Exception e) {
19158            if (DEBUG_BACKUP) {
19159                Slog.e(TAG, "Exception restoring default apps: " + e.getMessage());
19160            }
19161        }
19162    }
19163
19164    @Override
19165    public byte[] getIntentFilterVerificationBackup(int userId) {
19166        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19167            throw new SecurityException("Only the system may call getIntentFilterVerificationBackup()");
19168        }
19169
19170        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
19171        try {
19172            final XmlSerializer serializer = new FastXmlSerializer();
19173            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
19174            serializer.startDocument(null, true);
19175            serializer.startTag(null, TAG_INTENT_FILTER_VERIFICATION);
19176
19177            synchronized (mPackages) {
19178                mSettings.writeAllDomainVerificationsLPr(serializer, userId);
19179            }
19180
19181            serializer.endTag(null, TAG_INTENT_FILTER_VERIFICATION);
19182            serializer.endDocument();
19183            serializer.flush();
19184        } catch (Exception e) {
19185            if (DEBUG_BACKUP) {
19186                Slog.e(TAG, "Unable to write default apps for backup", e);
19187            }
19188            return null;
19189        }
19190
19191        return dataStream.toByteArray();
19192    }
19193
19194    @Override
19195    public void restoreIntentFilterVerification(byte[] backup, int userId) {
19196        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19197            throw new SecurityException("Only the system may call restorePreferredActivities()");
19198        }
19199
19200        try {
19201            final XmlPullParser parser = Xml.newPullParser();
19202            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
19203            restoreFromXml(parser, userId, TAG_INTENT_FILTER_VERIFICATION,
19204                    new BlobXmlRestorer() {
19205                        @Override
19206                        public void apply(XmlPullParser parser, int userId)
19207                                throws XmlPullParserException, IOException {
19208                            synchronized (mPackages) {
19209                                mSettings.readAllDomainVerificationsLPr(parser, userId);
19210                                mSettings.writeLPr();
19211                            }
19212                        }
19213                    } );
19214        } catch (Exception e) {
19215            if (DEBUG_BACKUP) {
19216                Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
19217            }
19218        }
19219    }
19220
19221    @Override
19222    public byte[] getPermissionGrantBackup(int userId) {
19223        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19224            throw new SecurityException("Only the system may call getPermissionGrantBackup()");
19225        }
19226
19227        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
19228        try {
19229            final XmlSerializer serializer = new FastXmlSerializer();
19230            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
19231            serializer.startDocument(null, true);
19232            serializer.startTag(null, TAG_PERMISSION_BACKUP);
19233
19234            synchronized (mPackages) {
19235                serializeRuntimePermissionGrantsLPr(serializer, userId);
19236            }
19237
19238            serializer.endTag(null, TAG_PERMISSION_BACKUP);
19239            serializer.endDocument();
19240            serializer.flush();
19241        } catch (Exception e) {
19242            if (DEBUG_BACKUP) {
19243                Slog.e(TAG, "Unable to write default apps for backup", e);
19244            }
19245            return null;
19246        }
19247
19248        return dataStream.toByteArray();
19249    }
19250
19251    @Override
19252    public void restorePermissionGrants(byte[] backup, int userId) {
19253        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19254            throw new SecurityException("Only the system may call restorePermissionGrants()");
19255        }
19256
19257        try {
19258            final XmlPullParser parser = Xml.newPullParser();
19259            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
19260            restoreFromXml(parser, userId, TAG_PERMISSION_BACKUP,
19261                    new BlobXmlRestorer() {
19262                        @Override
19263                        public void apply(XmlPullParser parser, int userId)
19264                                throws XmlPullParserException, IOException {
19265                            synchronized (mPackages) {
19266                                processRestoredPermissionGrantsLPr(parser, userId);
19267                            }
19268                        }
19269                    } );
19270        } catch (Exception e) {
19271            if (DEBUG_BACKUP) {
19272                Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
19273            }
19274        }
19275    }
19276
19277    private void serializeRuntimePermissionGrantsLPr(XmlSerializer serializer, final int userId)
19278            throws IOException {
19279        serializer.startTag(null, TAG_ALL_GRANTS);
19280
19281        final int N = mSettings.mPackages.size();
19282        for (int i = 0; i < N; i++) {
19283            final PackageSetting ps = mSettings.mPackages.valueAt(i);
19284            boolean pkgGrantsKnown = false;
19285
19286            PermissionsState packagePerms = ps.getPermissionsState();
19287
19288            for (PermissionState state : packagePerms.getRuntimePermissionStates(userId)) {
19289                final int grantFlags = state.getFlags();
19290                // only look at grants that are not system/policy fixed
19291                if ((grantFlags & SYSTEM_RUNTIME_GRANT_MASK) == 0) {
19292                    final boolean isGranted = state.isGranted();
19293                    // And only back up the user-twiddled state bits
19294                    if (isGranted || (grantFlags & USER_RUNTIME_GRANT_MASK) != 0) {
19295                        final String packageName = mSettings.mPackages.keyAt(i);
19296                        if (!pkgGrantsKnown) {
19297                            serializer.startTag(null, TAG_GRANT);
19298                            serializer.attribute(null, ATTR_PACKAGE_NAME, packageName);
19299                            pkgGrantsKnown = true;
19300                        }
19301
19302                        final boolean userSet =
19303                                (grantFlags & FLAG_PERMISSION_USER_SET) != 0;
19304                        final boolean userFixed =
19305                                (grantFlags & FLAG_PERMISSION_USER_FIXED) != 0;
19306                        final boolean revoke =
19307                                (grantFlags & FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0;
19308
19309                        serializer.startTag(null, TAG_PERMISSION);
19310                        serializer.attribute(null, ATTR_PERMISSION_NAME, state.getName());
19311                        if (isGranted) {
19312                            serializer.attribute(null, ATTR_IS_GRANTED, "true");
19313                        }
19314                        if (userSet) {
19315                            serializer.attribute(null, ATTR_USER_SET, "true");
19316                        }
19317                        if (userFixed) {
19318                            serializer.attribute(null, ATTR_USER_FIXED, "true");
19319                        }
19320                        if (revoke) {
19321                            serializer.attribute(null, ATTR_REVOKE_ON_UPGRADE, "true");
19322                        }
19323                        serializer.endTag(null, TAG_PERMISSION);
19324                    }
19325                }
19326            }
19327
19328            if (pkgGrantsKnown) {
19329                serializer.endTag(null, TAG_GRANT);
19330            }
19331        }
19332
19333        serializer.endTag(null, TAG_ALL_GRANTS);
19334    }
19335
19336    private void processRestoredPermissionGrantsLPr(XmlPullParser parser, int userId)
19337            throws XmlPullParserException, IOException {
19338        String pkgName = null;
19339        int outerDepth = parser.getDepth();
19340        int type;
19341        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
19342                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
19343            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
19344                continue;
19345            }
19346
19347            final String tagName = parser.getName();
19348            if (tagName.equals(TAG_GRANT)) {
19349                pkgName = parser.getAttributeValue(null, ATTR_PACKAGE_NAME);
19350                if (DEBUG_BACKUP) {
19351                    Slog.v(TAG, "+++ Restoring grants for package " + pkgName);
19352                }
19353            } else if (tagName.equals(TAG_PERMISSION)) {
19354
19355                final boolean isGranted = "true".equals(parser.getAttributeValue(null, ATTR_IS_GRANTED));
19356                final String permName = parser.getAttributeValue(null, ATTR_PERMISSION_NAME);
19357
19358                int newFlagSet = 0;
19359                if ("true".equals(parser.getAttributeValue(null, ATTR_USER_SET))) {
19360                    newFlagSet |= FLAG_PERMISSION_USER_SET;
19361                }
19362                if ("true".equals(parser.getAttributeValue(null, ATTR_USER_FIXED))) {
19363                    newFlagSet |= FLAG_PERMISSION_USER_FIXED;
19364                }
19365                if ("true".equals(parser.getAttributeValue(null, ATTR_REVOKE_ON_UPGRADE))) {
19366                    newFlagSet |= FLAG_PERMISSION_REVOKE_ON_UPGRADE;
19367                }
19368                if (DEBUG_BACKUP) {
19369                    Slog.v(TAG, "  + Restoring grant: pkg=" + pkgName + " perm=" + permName
19370                            + " granted=" + isGranted + " bits=0x" + Integer.toHexString(newFlagSet));
19371                }
19372                final PackageSetting ps = mSettings.mPackages.get(pkgName);
19373                if (ps != null) {
19374                    // Already installed so we apply the grant immediately
19375                    if (DEBUG_BACKUP) {
19376                        Slog.v(TAG, "        + already installed; applying");
19377                    }
19378                    PermissionsState perms = ps.getPermissionsState();
19379                    BasePermission bp = mSettings.mPermissions.get(permName);
19380                    if (bp != null) {
19381                        if (isGranted) {
19382                            perms.grantRuntimePermission(bp, userId);
19383                        }
19384                        if (newFlagSet != 0) {
19385                            perms.updatePermissionFlags(bp, userId, USER_RUNTIME_GRANT_MASK, newFlagSet);
19386                        }
19387                    }
19388                } else {
19389                    // Need to wait for post-restore install to apply the grant
19390                    if (DEBUG_BACKUP) {
19391                        Slog.v(TAG, "        - not yet installed; saving for later");
19392                    }
19393                    mSettings.processRestoredPermissionGrantLPr(pkgName, permName,
19394                            isGranted, newFlagSet, userId);
19395                }
19396            } else {
19397                PackageManagerService.reportSettingsProblem(Log.WARN,
19398                        "Unknown element under <" + TAG_PERMISSION_BACKUP + ">: " + tagName);
19399                XmlUtils.skipCurrentTag(parser);
19400            }
19401        }
19402
19403        scheduleWriteSettingsLocked();
19404        mSettings.writeRuntimePermissionsForUserLPr(userId, false);
19405    }
19406
19407    @Override
19408    public void addCrossProfileIntentFilter(IntentFilter intentFilter, String ownerPackage,
19409            int sourceUserId, int targetUserId, int flags) {
19410        mContext.enforceCallingOrSelfPermission(
19411                        android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
19412        int callingUid = Binder.getCallingUid();
19413        enforceOwnerRights(ownerPackage, callingUid);
19414        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
19415        if (intentFilter.countActions() == 0) {
19416            Slog.w(TAG, "Cannot set a crossProfile intent filter with no filter actions");
19417            return;
19418        }
19419        synchronized (mPackages) {
19420            CrossProfileIntentFilter newFilter = new CrossProfileIntentFilter(intentFilter,
19421                    ownerPackage, targetUserId, flags);
19422            CrossProfileIntentResolver resolver =
19423                    mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
19424            ArrayList<CrossProfileIntentFilter> existing = resolver.findFilters(intentFilter);
19425            // We have all those whose filter is equal. Now checking if the rest is equal as well.
19426            if (existing != null) {
19427                int size = existing.size();
19428                for (int i = 0; i < size; i++) {
19429                    if (newFilter.equalsIgnoreFilter(existing.get(i))) {
19430                        return;
19431                    }
19432                }
19433            }
19434            resolver.addFilter(newFilter);
19435            scheduleWritePackageRestrictionsLocked(sourceUserId);
19436        }
19437    }
19438
19439    @Override
19440    public void clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage) {
19441        mContext.enforceCallingOrSelfPermission(
19442                        android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
19443        int callingUid = Binder.getCallingUid();
19444        enforceOwnerRights(ownerPackage, callingUid);
19445        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
19446        synchronized (mPackages) {
19447            CrossProfileIntentResolver resolver =
19448                    mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
19449            ArraySet<CrossProfileIntentFilter> set =
19450                    new ArraySet<CrossProfileIntentFilter>(resolver.filterSet());
19451            for (CrossProfileIntentFilter filter : set) {
19452                if (filter.getOwnerPackage().equals(ownerPackage)) {
19453                    resolver.removeFilter(filter);
19454                }
19455            }
19456            scheduleWritePackageRestrictionsLocked(sourceUserId);
19457        }
19458    }
19459
19460    // Enforcing that callingUid is owning pkg on userId
19461    private void enforceOwnerRights(String pkg, int callingUid) {
19462        // The system owns everything.
19463        if (UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) {
19464            return;
19465        }
19466        int callingUserId = UserHandle.getUserId(callingUid);
19467        PackageInfo pi = getPackageInfo(pkg, 0, callingUserId);
19468        if (pi == null) {
19469            throw new IllegalArgumentException("Unknown package " + pkg + " on user "
19470                    + callingUserId);
19471        }
19472        if (!UserHandle.isSameApp(pi.applicationInfo.uid, callingUid)) {
19473            throw new SecurityException("Calling uid " + callingUid
19474                    + " does not own package " + pkg);
19475        }
19476    }
19477
19478    @Override
19479    public ComponentName getHomeActivities(List<ResolveInfo> allHomeCandidates) {
19480        return getHomeActivitiesAsUser(allHomeCandidates, UserHandle.getCallingUserId());
19481    }
19482
19483    private Intent getHomeIntent() {
19484        Intent intent = new Intent(Intent.ACTION_MAIN);
19485        intent.addCategory(Intent.CATEGORY_HOME);
19486        intent.addCategory(Intent.CATEGORY_DEFAULT);
19487        return intent;
19488    }
19489
19490    private IntentFilter getHomeFilter() {
19491        IntentFilter filter = new IntentFilter(Intent.ACTION_MAIN);
19492        filter.addCategory(Intent.CATEGORY_HOME);
19493        filter.addCategory(Intent.CATEGORY_DEFAULT);
19494        return filter;
19495    }
19496
19497    ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates,
19498            int userId) {
19499        Intent intent  = getHomeIntent();
19500        List<ResolveInfo> list = queryIntentActivitiesInternal(intent, null,
19501                PackageManager.GET_META_DATA, userId);
19502        ResolveInfo preferred = findPreferredActivity(intent, null, 0, list, 0,
19503                true, false, false, userId);
19504
19505        allHomeCandidates.clear();
19506        if (list != null) {
19507            for (ResolveInfo ri : list) {
19508                allHomeCandidates.add(ri);
19509            }
19510        }
19511        return (preferred == null || preferred.activityInfo == null)
19512                ? null
19513                : new ComponentName(preferred.activityInfo.packageName,
19514                        preferred.activityInfo.name);
19515    }
19516
19517    @Override
19518    public void setHomeActivity(ComponentName comp, int userId) {
19519        ArrayList<ResolveInfo> homeActivities = new ArrayList<>();
19520        getHomeActivitiesAsUser(homeActivities, userId);
19521
19522        boolean found = false;
19523
19524        final int size = homeActivities.size();
19525        final ComponentName[] set = new ComponentName[size];
19526        for (int i = 0; i < size; i++) {
19527            final ResolveInfo candidate = homeActivities.get(i);
19528            final ActivityInfo info = candidate.activityInfo;
19529            final ComponentName activityName = new ComponentName(info.packageName, info.name);
19530            set[i] = activityName;
19531            if (!found && activityName.equals(comp)) {
19532                found = true;
19533            }
19534        }
19535        if (!found) {
19536            throw new IllegalArgumentException("Component " + comp + " cannot be home on user "
19537                    + userId);
19538        }
19539        replacePreferredActivity(getHomeFilter(), IntentFilter.MATCH_CATEGORY_EMPTY,
19540                set, comp, userId);
19541    }
19542
19543    private @Nullable String getSetupWizardPackageName() {
19544        final Intent intent = new Intent(Intent.ACTION_MAIN);
19545        intent.addCategory(Intent.CATEGORY_SETUP_WIZARD);
19546
19547        final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null,
19548                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE
19549                        | MATCH_DISABLED_COMPONENTS,
19550                UserHandle.myUserId());
19551        if (matches.size() == 1) {
19552            return matches.get(0).getComponentInfo().packageName;
19553        } else {
19554            Slog.e(TAG, "There should probably be exactly one setup wizard; found " + matches.size()
19555                    + ": matches=" + matches);
19556            return null;
19557        }
19558    }
19559
19560    private @Nullable String getStorageManagerPackageName() {
19561        final Intent intent = new Intent(StorageManager.ACTION_MANAGE_STORAGE);
19562
19563        final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null,
19564                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE
19565                        | MATCH_DISABLED_COMPONENTS,
19566                UserHandle.myUserId());
19567        if (matches.size() == 1) {
19568            return matches.get(0).getComponentInfo().packageName;
19569        } else {
19570            Slog.e(TAG, "There should probably be exactly one storage manager; found "
19571                    + matches.size() + ": matches=" + matches);
19572            return null;
19573        }
19574    }
19575
19576    @Override
19577    public void setApplicationEnabledSetting(String appPackageName,
19578            int newState, int flags, int userId, String callingPackage) {
19579        if (!sUserManager.exists(userId)) return;
19580        if (callingPackage == null) {
19581            callingPackage = Integer.toString(Binder.getCallingUid());
19582        }
19583        setEnabledSetting(appPackageName, null, newState, flags, userId, callingPackage);
19584    }
19585
19586    @Override
19587    public void setComponentEnabledSetting(ComponentName componentName,
19588            int newState, int flags, int userId) {
19589        if (!sUserManager.exists(userId)) return;
19590        setEnabledSetting(componentName.getPackageName(),
19591                componentName.getClassName(), newState, flags, userId, null);
19592    }
19593
19594    private void setEnabledSetting(final String packageName, String className, int newState,
19595            final int flags, int userId, String callingPackage) {
19596        if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT
19597              || newState == COMPONENT_ENABLED_STATE_ENABLED
19598              || newState == COMPONENT_ENABLED_STATE_DISABLED
19599              || newState == COMPONENT_ENABLED_STATE_DISABLED_USER
19600              || newState == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED)) {
19601            throw new IllegalArgumentException("Invalid new component state: "
19602                    + newState);
19603        }
19604        PackageSetting pkgSetting;
19605        final int uid = Binder.getCallingUid();
19606        final int permission;
19607        if (uid == Process.SYSTEM_UID) {
19608            permission = PackageManager.PERMISSION_GRANTED;
19609        } else {
19610            permission = mContext.checkCallingOrSelfPermission(
19611                    android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
19612        }
19613        enforceCrossUserPermission(uid, userId,
19614                false /* requireFullPermission */, true /* checkShell */, "set enabled");
19615        final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
19616        boolean sendNow = false;
19617        boolean isApp = (className == null);
19618        String componentName = isApp ? packageName : className;
19619        int packageUid = -1;
19620        ArrayList<String> components;
19621
19622        // writer
19623        synchronized (mPackages) {
19624            pkgSetting = mSettings.mPackages.get(packageName);
19625            if (pkgSetting == null) {
19626                if (className == null) {
19627                    throw new IllegalArgumentException("Unknown package: " + packageName);
19628                }
19629                throw new IllegalArgumentException(
19630                        "Unknown component: " + packageName + "/" + className);
19631            }
19632        }
19633
19634        // Limit who can change which apps
19635        if (!UserHandle.isSameApp(uid, pkgSetting.appId)) {
19636            // Don't allow apps that don't have permission to modify other apps
19637            if (!allowedByPermission) {
19638                throw new SecurityException(
19639                        "Permission Denial: attempt to change component state from pid="
19640                        + Binder.getCallingPid()
19641                        + ", uid=" + uid + ", package uid=" + pkgSetting.appId);
19642            }
19643            // Don't allow changing protected packages.
19644            if (mProtectedPackages.isPackageStateProtected(userId, packageName)) {
19645                throw new SecurityException("Cannot disable a protected package: " + packageName);
19646            }
19647        }
19648
19649        synchronized (mPackages) {
19650            if (uid == Process.SHELL_UID
19651                    && (pkgSetting.pkgFlags & ApplicationInfo.FLAG_TEST_ONLY) == 0) {
19652                // Shell can only change whole packages between ENABLED and DISABLED_USER states
19653                // unless it is a test package.
19654                int oldState = pkgSetting.getEnabled(userId);
19655                if (className == null
19656                    &&
19657                    (oldState == COMPONENT_ENABLED_STATE_DISABLED_USER
19658                     || oldState == COMPONENT_ENABLED_STATE_DEFAULT
19659                     || oldState == COMPONENT_ENABLED_STATE_ENABLED)
19660                    &&
19661                    (newState == COMPONENT_ENABLED_STATE_DISABLED_USER
19662                     || newState == COMPONENT_ENABLED_STATE_DEFAULT
19663                     || newState == COMPONENT_ENABLED_STATE_ENABLED)) {
19664                    // ok
19665                } else {
19666                    throw new SecurityException(
19667                            "Shell cannot change component state for " + packageName + "/"
19668                            + className + " to " + newState);
19669                }
19670            }
19671            if (className == null) {
19672                // We're dealing with an application/package level state change
19673                if (pkgSetting.getEnabled(userId) == newState) {
19674                    // Nothing to do
19675                    return;
19676                }
19677                if (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
19678                    || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {
19679                    // Don't care about who enables an app.
19680                    callingPackage = null;
19681                }
19682                pkgSetting.setEnabled(newState, userId, callingPackage);
19683                // pkgSetting.pkg.mSetEnabled = newState;
19684            } else {
19685                // We're dealing with a component level state change
19686                // First, verify that this is a valid class name.
19687                PackageParser.Package pkg = pkgSetting.pkg;
19688                if (pkg == null || !pkg.hasComponentClassName(className)) {
19689                    if (pkg != null &&
19690                            pkg.applicationInfo.targetSdkVersion >=
19691                                    Build.VERSION_CODES.JELLY_BEAN) {
19692                        throw new IllegalArgumentException("Component class " + className
19693                                + " does not exist in " + packageName);
19694                    } else {
19695                        Slog.w(TAG, "Failed setComponentEnabledSetting: component class "
19696                                + className + " does not exist in " + packageName);
19697                    }
19698                }
19699                switch (newState) {
19700                case COMPONENT_ENABLED_STATE_ENABLED:
19701                    if (!pkgSetting.enableComponentLPw(className, userId)) {
19702                        return;
19703                    }
19704                    break;
19705                case COMPONENT_ENABLED_STATE_DISABLED:
19706                    if (!pkgSetting.disableComponentLPw(className, userId)) {
19707                        return;
19708                    }
19709                    break;
19710                case COMPONENT_ENABLED_STATE_DEFAULT:
19711                    if (!pkgSetting.restoreComponentLPw(className, userId)) {
19712                        return;
19713                    }
19714                    break;
19715                default:
19716                    Slog.e(TAG, "Invalid new component state: " + newState);
19717                    return;
19718                }
19719            }
19720            scheduleWritePackageRestrictionsLocked(userId);
19721            components = mPendingBroadcasts.get(userId, packageName);
19722            final boolean newPackage = components == null;
19723            if (newPackage) {
19724                components = new ArrayList<String>();
19725            }
19726            if (!components.contains(componentName)) {
19727                components.add(componentName);
19728            }
19729            if ((flags&PackageManager.DONT_KILL_APP) == 0) {
19730                sendNow = true;
19731                // Purge entry from pending broadcast list if another one exists already
19732                // since we are sending one right away.
19733                mPendingBroadcasts.remove(userId, packageName);
19734            } else {
19735                if (newPackage) {
19736                    mPendingBroadcasts.put(userId, packageName, components);
19737                }
19738                if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) {
19739                    // Schedule a message
19740                    mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, BROADCAST_DELAY);
19741                }
19742            }
19743        }
19744
19745        long callingId = Binder.clearCallingIdentity();
19746        try {
19747            if (sendNow) {
19748                packageUid = UserHandle.getUid(userId, pkgSetting.appId);
19749                sendPackageChangedBroadcast(packageName,
19750                        (flags&PackageManager.DONT_KILL_APP) != 0, components, packageUid);
19751            }
19752        } finally {
19753            Binder.restoreCallingIdentity(callingId);
19754        }
19755    }
19756
19757    @Override
19758    public void flushPackageRestrictionsAsUser(int userId) {
19759        if (!sUserManager.exists(userId)) {
19760            return;
19761        }
19762        enforceCrossUserPermission(Binder.getCallingUid(), userId, false /* requireFullPermission*/,
19763                false /* checkShell */, "flushPackageRestrictions");
19764        synchronized (mPackages) {
19765            mSettings.writePackageRestrictionsLPr(userId);
19766            mDirtyUsers.remove(userId);
19767            if (mDirtyUsers.isEmpty()) {
19768                mHandler.removeMessages(WRITE_PACKAGE_RESTRICTIONS);
19769            }
19770        }
19771    }
19772
19773    private void sendPackageChangedBroadcast(String packageName,
19774            boolean killFlag, ArrayList<String> componentNames, int packageUid) {
19775        if (DEBUG_INSTALL)
19776            Log.v(TAG, "Sending package changed: package=" + packageName + " components="
19777                    + componentNames);
19778        Bundle extras = new Bundle(4);
19779        extras.putString(Intent.EXTRA_CHANGED_COMPONENT_NAME, componentNames.get(0));
19780        String nameList[] = new String[componentNames.size()];
19781        componentNames.toArray(nameList);
19782        extras.putStringArray(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST, nameList);
19783        extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, killFlag);
19784        extras.putInt(Intent.EXTRA_UID, packageUid);
19785        // If this is not reporting a change of the overall package, then only send it
19786        // to registered receivers.  We don't want to launch a swath of apps for every
19787        // little component state change.
19788        final int flags = !componentNames.contains(packageName)
19789                ? Intent.FLAG_RECEIVER_REGISTERED_ONLY : 0;
19790        sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED,  packageName, extras, flags, null, null,
19791                new int[] {UserHandle.getUserId(packageUid)});
19792    }
19793
19794    @Override
19795    public void setPackageStoppedState(String packageName, boolean stopped, int userId) {
19796        if (!sUserManager.exists(userId)) return;
19797        final int uid = Binder.getCallingUid();
19798        final int permission = mContext.checkCallingOrSelfPermission(
19799                android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
19800        final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
19801        enforceCrossUserPermission(uid, userId,
19802                true /* requireFullPermission */, true /* checkShell */, "stop package");
19803        // writer
19804        synchronized (mPackages) {
19805            if (mSettings.setPackageStoppedStateLPw(this, packageName, stopped,
19806                    allowedByPermission, uid, userId)) {
19807                scheduleWritePackageRestrictionsLocked(userId);
19808            }
19809        }
19810    }
19811
19812    @Override
19813    public String getInstallerPackageName(String packageName) {
19814        // reader
19815        synchronized (mPackages) {
19816            return mSettings.getInstallerPackageNameLPr(packageName);
19817        }
19818    }
19819
19820    public boolean isOrphaned(String packageName) {
19821        // reader
19822        synchronized (mPackages) {
19823            return mSettings.isOrphaned(packageName);
19824        }
19825    }
19826
19827    @Override
19828    public int getApplicationEnabledSetting(String packageName, int userId) {
19829        if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
19830        int uid = Binder.getCallingUid();
19831        enforceCrossUserPermission(uid, userId,
19832                false /* requireFullPermission */, false /* checkShell */, "get enabled");
19833        // reader
19834        synchronized (mPackages) {
19835            return mSettings.getApplicationEnabledSettingLPr(packageName, userId);
19836        }
19837    }
19838
19839    @Override
19840    public int getComponentEnabledSetting(ComponentName componentName, int userId) {
19841        if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
19842        int uid = Binder.getCallingUid();
19843        enforceCrossUserPermission(uid, userId,
19844                false /* requireFullPermission */, false /* checkShell */, "get component enabled");
19845        // reader
19846        synchronized (mPackages) {
19847            return mSettings.getComponentEnabledSettingLPr(componentName, userId);
19848        }
19849    }
19850
19851    @Override
19852    public void enterSafeMode() {
19853        enforceSystemOrRoot("Only the system can request entering safe mode");
19854
19855        if (!mSystemReady) {
19856            mSafeMode = true;
19857        }
19858    }
19859
19860    @Override
19861    public void systemReady() {
19862        mSystemReady = true;
19863
19864        // Disable any carrier apps. We do this very early in boot to prevent the apps from being
19865        // disabled after already being started.
19866        CarrierAppUtils.disableCarrierAppsUntilPrivileged(mContext.getOpPackageName(), this,
19867                mContext.getContentResolver(), UserHandle.USER_SYSTEM);
19868
19869        // Read the compatibilty setting when the system is ready.
19870        boolean compatibilityModeEnabled = android.provider.Settings.Global.getInt(
19871                mContext.getContentResolver(),
19872                android.provider.Settings.Global.COMPATIBILITY_MODE, 1) == 1;
19873        PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled);
19874        if (DEBUG_SETTINGS) {
19875            Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled);
19876        }
19877
19878        int[] grantPermissionsUserIds = EMPTY_INT_ARRAY;
19879
19880        synchronized (mPackages) {
19881            // Verify that all of the preferred activity components actually
19882            // exist.  It is possible for applications to be updated and at
19883            // that point remove a previously declared activity component that
19884            // had been set as a preferred activity.  We try to clean this up
19885            // the next time we encounter that preferred activity, but it is
19886            // possible for the user flow to never be able to return to that
19887            // situation so here we do a sanity check to make sure we haven't
19888            // left any junk around.
19889            ArrayList<PreferredActivity> removed = new ArrayList<PreferredActivity>();
19890            for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
19891                PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
19892                removed.clear();
19893                for (PreferredActivity pa : pir.filterSet()) {
19894                    if (mActivities.mActivities.get(pa.mPref.mComponent) == null) {
19895                        removed.add(pa);
19896                    }
19897                }
19898                if (removed.size() > 0) {
19899                    for (int r=0; r<removed.size(); r++) {
19900                        PreferredActivity pa = removed.get(r);
19901                        Slog.w(TAG, "Removing dangling preferred activity: "
19902                                + pa.mPref.mComponent);
19903                        pir.removeFilter(pa);
19904                    }
19905                    mSettings.writePackageRestrictionsLPr(
19906                            mSettings.mPreferredActivities.keyAt(i));
19907                }
19908            }
19909
19910            for (int userId : UserManagerService.getInstance().getUserIds()) {
19911                if (!mSettings.areDefaultRuntimePermissionsGrantedLPr(userId)) {
19912                    grantPermissionsUserIds = ArrayUtils.appendInt(
19913                            grantPermissionsUserIds, userId);
19914                }
19915            }
19916        }
19917        sUserManager.systemReady();
19918
19919        // If we upgraded grant all default permissions before kicking off.
19920        for (int userId : grantPermissionsUserIds) {
19921            mDefaultPermissionPolicy.grantDefaultPermissions(userId);
19922        }
19923
19924        // If we did not grant default permissions, we preload from this the
19925        // default permission exceptions lazily to ensure we don't hit the
19926        // disk on a new user creation.
19927        if (grantPermissionsUserIds == EMPTY_INT_ARRAY) {
19928            mDefaultPermissionPolicy.scheduleReadDefaultPermissionExceptions();
19929        }
19930
19931        // Kick off any messages waiting for system ready
19932        if (mPostSystemReadyMessages != null) {
19933            for (Message msg : mPostSystemReadyMessages) {
19934                msg.sendToTarget();
19935            }
19936            mPostSystemReadyMessages = null;
19937        }
19938
19939        // Watch for external volumes that come and go over time
19940        final StorageManager storage = mContext.getSystemService(StorageManager.class);
19941        storage.registerListener(mStorageListener);
19942
19943        mInstallerService.systemReady();
19944        mPackageDexOptimizer.systemReady();
19945
19946        StorageManagerInternal StorageManagerInternal = LocalServices.getService(
19947                StorageManagerInternal.class);
19948        StorageManagerInternal.addExternalStoragePolicy(
19949                new StorageManagerInternal.ExternalStorageMountPolicy() {
19950            @Override
19951            public int getMountMode(int uid, String packageName) {
19952                if (Process.isIsolated(uid)) {
19953                    return Zygote.MOUNT_EXTERNAL_NONE;
19954                }
19955                if (checkUidPermission(WRITE_MEDIA_STORAGE, uid) == PERMISSION_GRANTED) {
19956                    return Zygote.MOUNT_EXTERNAL_DEFAULT;
19957                }
19958                if (checkUidPermission(READ_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) {
19959                    return Zygote.MOUNT_EXTERNAL_DEFAULT;
19960                }
19961                if (checkUidPermission(WRITE_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) {
19962                    return Zygote.MOUNT_EXTERNAL_READ;
19963                }
19964                return Zygote.MOUNT_EXTERNAL_WRITE;
19965            }
19966
19967            @Override
19968            public boolean hasExternalStorage(int uid, String packageName) {
19969                return true;
19970            }
19971        });
19972
19973        // Now that we're mostly running, clean up stale users and apps
19974        reconcileUsers(StorageManager.UUID_PRIVATE_INTERNAL);
19975        reconcileApps(StorageManager.UUID_PRIVATE_INTERNAL);
19976    }
19977
19978    @Override
19979    public boolean isSafeMode() {
19980        return mSafeMode;
19981    }
19982
19983    @Override
19984    public boolean hasSystemUidErrors() {
19985        return mHasSystemUidErrors;
19986    }
19987
19988    static String arrayToString(int[] array) {
19989        StringBuffer buf = new StringBuffer(128);
19990        buf.append('[');
19991        if (array != null) {
19992            for (int i=0; i<array.length; i++) {
19993                if (i > 0) buf.append(", ");
19994                buf.append(array[i]);
19995            }
19996        }
19997        buf.append(']');
19998        return buf.toString();
19999    }
20000
20001    static class DumpState {
20002        public static final int DUMP_LIBS = 1 << 0;
20003        public static final int DUMP_FEATURES = 1 << 1;
20004        public static final int DUMP_ACTIVITY_RESOLVERS = 1 << 2;
20005        public static final int DUMP_SERVICE_RESOLVERS = 1 << 3;
20006        public static final int DUMP_RECEIVER_RESOLVERS = 1 << 4;
20007        public static final int DUMP_CONTENT_RESOLVERS = 1 << 5;
20008        public static final int DUMP_PERMISSIONS = 1 << 6;
20009        public static final int DUMP_PACKAGES = 1 << 7;
20010        public static final int DUMP_SHARED_USERS = 1 << 8;
20011        public static final int DUMP_MESSAGES = 1 << 9;
20012        public static final int DUMP_PROVIDERS = 1 << 10;
20013        public static final int DUMP_VERIFIERS = 1 << 11;
20014        public static final int DUMP_PREFERRED = 1 << 12;
20015        public static final int DUMP_PREFERRED_XML = 1 << 13;
20016        public static final int DUMP_KEYSETS = 1 << 14;
20017        public static final int DUMP_VERSION = 1 << 15;
20018        public static final int DUMP_INSTALLS = 1 << 16;
20019        public static final int DUMP_INTENT_FILTER_VERIFIERS = 1 << 17;
20020        public static final int DUMP_DOMAIN_PREFERRED = 1 << 18;
20021        public static final int DUMP_FROZEN = 1 << 19;
20022        public static final int DUMP_DEXOPT = 1 << 20;
20023        public static final int DUMP_COMPILER_STATS = 1 << 21;
20024
20025        public static final int OPTION_SHOW_FILTERS = 1 << 0;
20026
20027        private int mTypes;
20028
20029        private int mOptions;
20030
20031        private boolean mTitlePrinted;
20032
20033        private SharedUserSetting mSharedUser;
20034
20035        public boolean isDumping(int type) {
20036            if (mTypes == 0 && type != DUMP_PREFERRED_XML) {
20037                return true;
20038            }
20039
20040            return (mTypes & type) != 0;
20041        }
20042
20043        public void setDump(int type) {
20044            mTypes |= type;
20045        }
20046
20047        public boolean isOptionEnabled(int option) {
20048            return (mOptions & option) != 0;
20049        }
20050
20051        public void setOptionEnabled(int option) {
20052            mOptions |= option;
20053        }
20054
20055        public boolean onTitlePrinted() {
20056            final boolean printed = mTitlePrinted;
20057            mTitlePrinted = true;
20058            return printed;
20059        }
20060
20061        public boolean getTitlePrinted() {
20062            return mTitlePrinted;
20063        }
20064
20065        public void setTitlePrinted(boolean enabled) {
20066            mTitlePrinted = enabled;
20067        }
20068
20069        public SharedUserSetting getSharedUser() {
20070            return mSharedUser;
20071        }
20072
20073        public void setSharedUser(SharedUserSetting user) {
20074            mSharedUser = user;
20075        }
20076    }
20077
20078    @Override
20079    public void onShellCommand(FileDescriptor in, FileDescriptor out,
20080            FileDescriptor err, String[] args, ShellCallback callback,
20081            ResultReceiver resultReceiver) {
20082        (new PackageManagerShellCommand(this)).exec(
20083                this, in, out, err, args, callback, resultReceiver);
20084    }
20085
20086    @Override
20087    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
20088        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
20089                != PackageManager.PERMISSION_GRANTED) {
20090            pw.println("Permission Denial: can't dump ActivityManager from from pid="
20091                    + Binder.getCallingPid()
20092                    + ", uid=" + Binder.getCallingUid()
20093                    + " without permission "
20094                    + android.Manifest.permission.DUMP);
20095            return;
20096        }
20097
20098        DumpState dumpState = new DumpState();
20099        boolean fullPreferred = false;
20100        boolean checkin = false;
20101
20102        String packageName = null;
20103        ArraySet<String> permissionNames = null;
20104
20105        int opti = 0;
20106        while (opti < args.length) {
20107            String opt = args[opti];
20108            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
20109                break;
20110            }
20111            opti++;
20112
20113            if ("-a".equals(opt)) {
20114                // Right now we only know how to print all.
20115            } else if ("-h".equals(opt)) {
20116                pw.println("Package manager dump options:");
20117                pw.println("  [-h] [-f] [--checkin] [cmd] ...");
20118                pw.println("    --checkin: dump for a checkin");
20119                pw.println("    -f: print details of intent filters");
20120                pw.println("    -h: print this help");
20121                pw.println("  cmd may be one of:");
20122                pw.println("    l[ibraries]: list known shared libraries");
20123                pw.println("    f[eatures]: list device features");
20124                pw.println("    k[eysets]: print known keysets");
20125                pw.println("    r[esolvers] [activity|service|receiver|content]: dump intent resolvers");
20126                pw.println("    perm[issions]: dump permissions");
20127                pw.println("    permission [name ...]: dump declaration and use of given permission");
20128                pw.println("    pref[erred]: print preferred package settings");
20129                pw.println("    preferred-xml [--full]: print preferred package settings as xml");
20130                pw.println("    prov[iders]: dump content providers");
20131                pw.println("    p[ackages]: dump installed packages");
20132                pw.println("    s[hared-users]: dump shared user IDs");
20133                pw.println("    m[essages]: print collected runtime messages");
20134                pw.println("    v[erifiers]: print package verifier info");
20135                pw.println("    d[omain-preferred-apps]: print domains preferred apps");
20136                pw.println("    i[ntent-filter-verifiers]|ifv: print intent filter verifier info");
20137                pw.println("    version: print database version info");
20138                pw.println("    write: write current settings now");
20139                pw.println("    installs: details about install sessions");
20140                pw.println("    check-permission <permission> <package> [<user>]: does pkg hold perm?");
20141                pw.println("    dexopt: dump dexopt state");
20142                pw.println("    compiler-stats: dump compiler statistics");
20143                pw.println("    <package.name>: info about given package");
20144                return;
20145            } else if ("--checkin".equals(opt)) {
20146                checkin = true;
20147            } else if ("-f".equals(opt)) {
20148                dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
20149            } else {
20150                pw.println("Unknown argument: " + opt + "; use -h for help");
20151            }
20152        }
20153
20154        // Is the caller requesting to dump a particular piece of data?
20155        if (opti < args.length) {
20156            String cmd = args[opti];
20157            opti++;
20158            // Is this a package name?
20159            if ("android".equals(cmd) || cmd.contains(".")) {
20160                packageName = cmd;
20161                // When dumping a single package, we always dump all of its
20162                // filter information since the amount of data will be reasonable.
20163                dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
20164            } else if ("check-permission".equals(cmd)) {
20165                if (opti >= args.length) {
20166                    pw.println("Error: check-permission missing permission argument");
20167                    return;
20168                }
20169                String perm = args[opti];
20170                opti++;
20171                if (opti >= args.length) {
20172                    pw.println("Error: check-permission missing package argument");
20173                    return;
20174                }
20175
20176                String pkg = args[opti];
20177                opti++;
20178                int user = UserHandle.getUserId(Binder.getCallingUid());
20179                if (opti < args.length) {
20180                    try {
20181                        user = Integer.parseInt(args[opti]);
20182                    } catch (NumberFormatException e) {
20183                        pw.println("Error: check-permission user argument is not a number: "
20184                                + args[opti]);
20185                        return;
20186                    }
20187                }
20188
20189                // Normalize package name to handle renamed packages and static libs
20190                pkg = resolveInternalPackageNameLPr(pkg, PackageManager.VERSION_CODE_HIGHEST);
20191
20192                pw.println(checkPermission(perm, pkg, user));
20193                return;
20194            } else if ("l".equals(cmd) || "libraries".equals(cmd)) {
20195                dumpState.setDump(DumpState.DUMP_LIBS);
20196            } else if ("f".equals(cmd) || "features".equals(cmd)) {
20197                dumpState.setDump(DumpState.DUMP_FEATURES);
20198            } else if ("r".equals(cmd) || "resolvers".equals(cmd)) {
20199                if (opti >= args.length) {
20200                    dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS
20201                            | DumpState.DUMP_SERVICE_RESOLVERS
20202                            | DumpState.DUMP_RECEIVER_RESOLVERS
20203                            | DumpState.DUMP_CONTENT_RESOLVERS);
20204                } else {
20205                    while (opti < args.length) {
20206                        String name = args[opti];
20207                        if ("a".equals(name) || "activity".equals(name)) {
20208                            dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS);
20209                        } else if ("s".equals(name) || "service".equals(name)) {
20210                            dumpState.setDump(DumpState.DUMP_SERVICE_RESOLVERS);
20211                        } else if ("r".equals(name) || "receiver".equals(name)) {
20212                            dumpState.setDump(DumpState.DUMP_RECEIVER_RESOLVERS);
20213                        } else if ("c".equals(name) || "content".equals(name)) {
20214                            dumpState.setDump(DumpState.DUMP_CONTENT_RESOLVERS);
20215                        } else {
20216                            pw.println("Error: unknown resolver table type: " + name);
20217                            return;
20218                        }
20219                        opti++;
20220                    }
20221                }
20222            } else if ("perm".equals(cmd) || "permissions".equals(cmd)) {
20223                dumpState.setDump(DumpState.DUMP_PERMISSIONS);
20224            } else if ("permission".equals(cmd)) {
20225                if (opti >= args.length) {
20226                    pw.println("Error: permission requires permission name");
20227                    return;
20228                }
20229                permissionNames = new ArraySet<>();
20230                while (opti < args.length) {
20231                    permissionNames.add(args[opti]);
20232                    opti++;
20233                }
20234                dumpState.setDump(DumpState.DUMP_PERMISSIONS
20235                        | DumpState.DUMP_PACKAGES | DumpState.DUMP_SHARED_USERS);
20236            } else if ("pref".equals(cmd) || "preferred".equals(cmd)) {
20237                dumpState.setDump(DumpState.DUMP_PREFERRED);
20238            } else if ("preferred-xml".equals(cmd)) {
20239                dumpState.setDump(DumpState.DUMP_PREFERRED_XML);
20240                if (opti < args.length && "--full".equals(args[opti])) {
20241                    fullPreferred = true;
20242                    opti++;
20243                }
20244            } else if ("d".equals(cmd) || "domain-preferred-apps".equals(cmd)) {
20245                dumpState.setDump(DumpState.DUMP_DOMAIN_PREFERRED);
20246            } else if ("p".equals(cmd) || "packages".equals(cmd)) {
20247                dumpState.setDump(DumpState.DUMP_PACKAGES);
20248            } else if ("s".equals(cmd) || "shared-users".equals(cmd)) {
20249                dumpState.setDump(DumpState.DUMP_SHARED_USERS);
20250            } else if ("prov".equals(cmd) || "providers".equals(cmd)) {
20251                dumpState.setDump(DumpState.DUMP_PROVIDERS);
20252            } else if ("m".equals(cmd) || "messages".equals(cmd)) {
20253                dumpState.setDump(DumpState.DUMP_MESSAGES);
20254            } else if ("v".equals(cmd) || "verifiers".equals(cmd)) {
20255                dumpState.setDump(DumpState.DUMP_VERIFIERS);
20256            } else if ("i".equals(cmd) || "ifv".equals(cmd)
20257                    || "intent-filter-verifiers".equals(cmd)) {
20258                dumpState.setDump(DumpState.DUMP_INTENT_FILTER_VERIFIERS);
20259            } else if ("version".equals(cmd)) {
20260                dumpState.setDump(DumpState.DUMP_VERSION);
20261            } else if ("k".equals(cmd) || "keysets".equals(cmd)) {
20262                dumpState.setDump(DumpState.DUMP_KEYSETS);
20263            } else if ("installs".equals(cmd)) {
20264                dumpState.setDump(DumpState.DUMP_INSTALLS);
20265            } else if ("frozen".equals(cmd)) {
20266                dumpState.setDump(DumpState.DUMP_FROZEN);
20267            } else if ("dexopt".equals(cmd)) {
20268                dumpState.setDump(DumpState.DUMP_DEXOPT);
20269            } else if ("compiler-stats".equals(cmd)) {
20270                dumpState.setDump(DumpState.DUMP_COMPILER_STATS);
20271            } else if ("write".equals(cmd)) {
20272                synchronized (mPackages) {
20273                    mSettings.writeLPr();
20274                    pw.println("Settings written.");
20275                    return;
20276                }
20277            }
20278        }
20279
20280        if (checkin) {
20281            pw.println("vers,1");
20282        }
20283
20284        // reader
20285        synchronized (mPackages) {
20286            if (dumpState.isDumping(DumpState.DUMP_VERSION) && packageName == null) {
20287                if (!checkin) {
20288                    if (dumpState.onTitlePrinted())
20289                        pw.println();
20290                    pw.println("Database versions:");
20291                    mSettings.dumpVersionLPr(new IndentingPrintWriter(pw, "  "));
20292                }
20293            }
20294
20295            if (dumpState.isDumping(DumpState.DUMP_VERIFIERS) && packageName == null) {
20296                if (!checkin) {
20297                    if (dumpState.onTitlePrinted())
20298                        pw.println();
20299                    pw.println("Verifiers:");
20300                    pw.print("  Required: ");
20301                    pw.print(mRequiredVerifierPackage);
20302                    pw.print(" (uid=");
20303                    pw.print(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
20304                            UserHandle.USER_SYSTEM));
20305                    pw.println(")");
20306                } else if (mRequiredVerifierPackage != null) {
20307                    pw.print("vrfy,"); pw.print(mRequiredVerifierPackage);
20308                    pw.print(",");
20309                    pw.println(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
20310                            UserHandle.USER_SYSTEM));
20311                }
20312            }
20313
20314            if (dumpState.isDumping(DumpState.DUMP_INTENT_FILTER_VERIFIERS) &&
20315                    packageName == null) {
20316                if (mIntentFilterVerifierComponent != null) {
20317                    String verifierPackageName = mIntentFilterVerifierComponent.getPackageName();
20318                    if (!checkin) {
20319                        if (dumpState.onTitlePrinted())
20320                            pw.println();
20321                        pw.println("Intent Filter Verifier:");
20322                        pw.print("  Using: ");
20323                        pw.print(verifierPackageName);
20324                        pw.print(" (uid=");
20325                        pw.print(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING,
20326                                UserHandle.USER_SYSTEM));
20327                        pw.println(")");
20328                    } else if (verifierPackageName != null) {
20329                        pw.print("ifv,"); pw.print(verifierPackageName);
20330                        pw.print(",");
20331                        pw.println(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING,
20332                                UserHandle.USER_SYSTEM));
20333                    }
20334                } else {
20335                    pw.println();
20336                    pw.println("No Intent Filter Verifier available!");
20337                }
20338            }
20339
20340            if (dumpState.isDumping(DumpState.DUMP_LIBS) && packageName == null) {
20341                boolean printedHeader = false;
20342                final Iterator<String> it = mSharedLibraries.keySet().iterator();
20343                while (it.hasNext()) {
20344                    String libName = it.next();
20345                    SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(libName);
20346                    if (versionedLib == null) {
20347                        continue;
20348                    }
20349                    final int versionCount = versionedLib.size();
20350                    for (int i = 0; i < versionCount; i++) {
20351                        SharedLibraryEntry libEntry = versionedLib.valueAt(i);
20352                        if (!checkin) {
20353                            if (!printedHeader) {
20354                                if (dumpState.onTitlePrinted())
20355                                    pw.println();
20356                                pw.println("Libraries:");
20357                                printedHeader = true;
20358                            }
20359                            pw.print("  ");
20360                        } else {
20361                            pw.print("lib,");
20362                        }
20363                        pw.print(libEntry.info.getName());
20364                        if (libEntry.info.isStatic()) {
20365                            pw.print(" version=" + libEntry.info.getVersion());
20366                        }
20367                        if (!checkin) {
20368                            pw.print(" -> ");
20369                        }
20370                        if (libEntry.path != null) {
20371                            pw.print(" (jar) ");
20372                            pw.print(libEntry.path);
20373                        } else {
20374                            pw.print(" (apk) ");
20375                            pw.print(libEntry.apk);
20376                        }
20377                        pw.println();
20378                    }
20379                }
20380            }
20381
20382            if (dumpState.isDumping(DumpState.DUMP_FEATURES) && packageName == null) {
20383                if (dumpState.onTitlePrinted())
20384                    pw.println();
20385                if (!checkin) {
20386                    pw.println("Features:");
20387                }
20388
20389                synchronized (mAvailableFeatures) {
20390                    for (FeatureInfo feat : mAvailableFeatures.values()) {
20391                        if (checkin) {
20392                            pw.print("feat,");
20393                            pw.print(feat.name);
20394                            pw.print(",");
20395                            pw.println(feat.version);
20396                        } else {
20397                            pw.print("  ");
20398                            pw.print(feat.name);
20399                            if (feat.version > 0) {
20400                                pw.print(" version=");
20401                                pw.print(feat.version);
20402                            }
20403                            pw.println();
20404                        }
20405                    }
20406                }
20407            }
20408
20409            if (!checkin && dumpState.isDumping(DumpState.DUMP_ACTIVITY_RESOLVERS)) {
20410                if (mActivities.dump(pw, dumpState.getTitlePrinted() ? "\nActivity Resolver Table:"
20411                        : "Activity Resolver Table:", "  ", packageName,
20412                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
20413                    dumpState.setTitlePrinted(true);
20414                }
20415            }
20416            if (!checkin && dumpState.isDumping(DumpState.DUMP_RECEIVER_RESOLVERS)) {
20417                if (mReceivers.dump(pw, dumpState.getTitlePrinted() ? "\nReceiver Resolver Table:"
20418                        : "Receiver Resolver Table:", "  ", packageName,
20419                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
20420                    dumpState.setTitlePrinted(true);
20421                }
20422            }
20423            if (!checkin && dumpState.isDumping(DumpState.DUMP_SERVICE_RESOLVERS)) {
20424                if (mServices.dump(pw, dumpState.getTitlePrinted() ? "\nService Resolver Table:"
20425                        : "Service Resolver Table:", "  ", packageName,
20426                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
20427                    dumpState.setTitlePrinted(true);
20428                }
20429            }
20430            if (!checkin && dumpState.isDumping(DumpState.DUMP_CONTENT_RESOLVERS)) {
20431                if (mProviders.dump(pw, dumpState.getTitlePrinted() ? "\nProvider Resolver Table:"
20432                        : "Provider Resolver Table:", "  ", packageName,
20433                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
20434                    dumpState.setTitlePrinted(true);
20435                }
20436            }
20437
20438            if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED)) {
20439                for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
20440                    PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
20441                    int user = mSettings.mPreferredActivities.keyAt(i);
20442                    if (pir.dump(pw,
20443                            dumpState.getTitlePrinted()
20444                                ? "\nPreferred Activities User " + user + ":"
20445                                : "Preferred Activities User " + user + ":", "  ",
20446                            packageName, true, false)) {
20447                        dumpState.setTitlePrinted(true);
20448                    }
20449                }
20450            }
20451
20452            if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED_XML)) {
20453                pw.flush();
20454                FileOutputStream fout = new FileOutputStream(fd);
20455                BufferedOutputStream str = new BufferedOutputStream(fout);
20456                XmlSerializer serializer = new FastXmlSerializer();
20457                try {
20458                    serializer.setOutput(str, StandardCharsets.UTF_8.name());
20459                    serializer.startDocument(null, true);
20460                    serializer.setFeature(
20461                            "http://xmlpull.org/v1/doc/features.html#indent-output", true);
20462                    mSettings.writePreferredActivitiesLPr(serializer, 0, fullPreferred);
20463                    serializer.endDocument();
20464                    serializer.flush();
20465                } catch (IllegalArgumentException e) {
20466                    pw.println("Failed writing: " + e);
20467                } catch (IllegalStateException e) {
20468                    pw.println("Failed writing: " + e);
20469                } catch (IOException e) {
20470                    pw.println("Failed writing: " + e);
20471                }
20472            }
20473
20474            if (!checkin
20475                    && dumpState.isDumping(DumpState.DUMP_DOMAIN_PREFERRED)
20476                    && packageName == null) {
20477                pw.println();
20478                int count = mSettings.mPackages.size();
20479                if (count == 0) {
20480                    pw.println("No applications!");
20481                    pw.println();
20482                } else {
20483                    final String prefix = "  ";
20484                    Collection<PackageSetting> allPackageSettings = mSettings.mPackages.values();
20485                    if (allPackageSettings.size() == 0) {
20486                        pw.println("No domain preferred apps!");
20487                        pw.println();
20488                    } else {
20489                        pw.println("App verification status:");
20490                        pw.println();
20491                        count = 0;
20492                        for (PackageSetting ps : allPackageSettings) {
20493                            IntentFilterVerificationInfo ivi = ps.getIntentFilterVerificationInfo();
20494                            if (ivi == null || ivi.getPackageName() == null) continue;
20495                            pw.println(prefix + "Package: " + ivi.getPackageName());
20496                            pw.println(prefix + "Domains: " + ivi.getDomainsString());
20497                            pw.println(prefix + "Status:  " + ivi.getStatusString());
20498                            pw.println();
20499                            count++;
20500                        }
20501                        if (count == 0) {
20502                            pw.println(prefix + "No app verification established.");
20503                            pw.println();
20504                        }
20505                        for (int userId : sUserManager.getUserIds()) {
20506                            pw.println("App linkages for user " + userId + ":");
20507                            pw.println();
20508                            count = 0;
20509                            for (PackageSetting ps : allPackageSettings) {
20510                                final long status = ps.getDomainVerificationStatusForUser(userId);
20511                                if (status >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED
20512                                        && !DEBUG_DOMAIN_VERIFICATION) {
20513                                    continue;
20514                                }
20515                                pw.println(prefix + "Package: " + ps.name);
20516                                pw.println(prefix + "Domains: " + dumpDomainString(ps.name));
20517                                String statusStr = IntentFilterVerificationInfo.
20518                                        getStatusStringFromValue(status);
20519                                pw.println(prefix + "Status:  " + statusStr);
20520                                pw.println();
20521                                count++;
20522                            }
20523                            if (count == 0) {
20524                                pw.println(prefix + "No configured app linkages.");
20525                                pw.println();
20526                            }
20527                        }
20528                    }
20529                }
20530            }
20531
20532            if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) {
20533                mSettings.dumpPermissionsLPr(pw, packageName, permissionNames, dumpState);
20534                if (packageName == null && permissionNames == null) {
20535                    for (int iperm=0; iperm<mAppOpPermissionPackages.size(); iperm++) {
20536                        if (iperm == 0) {
20537                            if (dumpState.onTitlePrinted())
20538                                pw.println();
20539                            pw.println("AppOp Permissions:");
20540                        }
20541                        pw.print("  AppOp Permission ");
20542                        pw.print(mAppOpPermissionPackages.keyAt(iperm));
20543                        pw.println(":");
20544                        ArraySet<String> pkgs = mAppOpPermissionPackages.valueAt(iperm);
20545                        for (int ipkg=0; ipkg<pkgs.size(); ipkg++) {
20546                            pw.print("    "); pw.println(pkgs.valueAt(ipkg));
20547                        }
20548                    }
20549                }
20550            }
20551
20552            if (!checkin && dumpState.isDumping(DumpState.DUMP_PROVIDERS)) {
20553                boolean printedSomething = false;
20554                for (PackageParser.Provider p : mProviders.mProviders.values()) {
20555                    if (packageName != null && !packageName.equals(p.info.packageName)) {
20556                        continue;
20557                    }
20558                    if (!printedSomething) {
20559                        if (dumpState.onTitlePrinted())
20560                            pw.println();
20561                        pw.println("Registered ContentProviders:");
20562                        printedSomething = true;
20563                    }
20564                    pw.print("  "); p.printComponentShortName(pw); pw.println(":");
20565                    pw.print("    "); pw.println(p.toString());
20566                }
20567                printedSomething = false;
20568                for (Map.Entry<String, PackageParser.Provider> entry :
20569                        mProvidersByAuthority.entrySet()) {
20570                    PackageParser.Provider p = entry.getValue();
20571                    if (packageName != null && !packageName.equals(p.info.packageName)) {
20572                        continue;
20573                    }
20574                    if (!printedSomething) {
20575                        if (dumpState.onTitlePrinted())
20576                            pw.println();
20577                        pw.println("ContentProvider Authorities:");
20578                        printedSomething = true;
20579                    }
20580                    pw.print("  ["); pw.print(entry.getKey()); pw.println("]:");
20581                    pw.print("    "); pw.println(p.toString());
20582                    if (p.info != null && p.info.applicationInfo != null) {
20583                        final String appInfo = p.info.applicationInfo.toString();
20584                        pw.print("      applicationInfo="); pw.println(appInfo);
20585                    }
20586                }
20587            }
20588
20589            if (!checkin && dumpState.isDumping(DumpState.DUMP_KEYSETS)) {
20590                mSettings.mKeySetManagerService.dumpLPr(pw, packageName, dumpState);
20591            }
20592
20593            if (dumpState.isDumping(DumpState.DUMP_PACKAGES)) {
20594                mSettings.dumpPackagesLPr(pw, packageName, permissionNames, dumpState, checkin);
20595            }
20596
20597            if (dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) {
20598                mSettings.dumpSharedUsersLPr(pw, packageName, permissionNames, dumpState, checkin);
20599            }
20600
20601            if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS) && packageName == null) {
20602                mSettings.dumpRestoredPermissionGrantsLPr(pw, dumpState);
20603            }
20604
20605            if (!checkin && dumpState.isDumping(DumpState.DUMP_INSTALLS) && packageName == null) {
20606                // XXX should handle packageName != null by dumping only install data that
20607                // the given package is involved with.
20608                if (dumpState.onTitlePrinted()) pw.println();
20609                mInstallerService.dump(new IndentingPrintWriter(pw, "  ", 120));
20610            }
20611
20612            if (!checkin && dumpState.isDumping(DumpState.DUMP_FROZEN) && packageName == null) {
20613                // XXX should handle packageName != null by dumping only install data that
20614                // the given package is involved with.
20615                if (dumpState.onTitlePrinted()) pw.println();
20616
20617                final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ", 120);
20618                ipw.println();
20619                ipw.println("Frozen packages:");
20620                ipw.increaseIndent();
20621                if (mFrozenPackages.size() == 0) {
20622                    ipw.println("(none)");
20623                } else {
20624                    for (int i = 0; i < mFrozenPackages.size(); i++) {
20625                        ipw.println(mFrozenPackages.valueAt(i));
20626                    }
20627                }
20628                ipw.decreaseIndent();
20629            }
20630
20631            if (!checkin && dumpState.isDumping(DumpState.DUMP_DEXOPT)) {
20632                if (dumpState.onTitlePrinted()) pw.println();
20633                dumpDexoptStateLPr(pw, packageName);
20634            }
20635
20636            if (!checkin && dumpState.isDumping(DumpState.DUMP_COMPILER_STATS)) {
20637                if (dumpState.onTitlePrinted()) pw.println();
20638                dumpCompilerStatsLPr(pw, packageName);
20639            }
20640
20641            if (!checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES) && packageName == null) {
20642                if (dumpState.onTitlePrinted()) pw.println();
20643                mSettings.dumpReadMessagesLPr(pw, dumpState);
20644
20645                pw.println();
20646                pw.println("Package warning messages:");
20647                BufferedReader in = null;
20648                String line = null;
20649                try {
20650                    in = new BufferedReader(new FileReader(getSettingsProblemFile()));
20651                    while ((line = in.readLine()) != null) {
20652                        if (line.contains("ignored: updated version")) continue;
20653                        pw.println(line);
20654                    }
20655                } catch (IOException ignored) {
20656                } finally {
20657                    IoUtils.closeQuietly(in);
20658                }
20659            }
20660
20661            if (checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES)) {
20662                BufferedReader in = null;
20663                String line = null;
20664                try {
20665                    in = new BufferedReader(new FileReader(getSettingsProblemFile()));
20666                    while ((line = in.readLine()) != null) {
20667                        if (line.contains("ignored: updated version")) continue;
20668                        pw.print("msg,");
20669                        pw.println(line);
20670                    }
20671                } catch (IOException ignored) {
20672                } finally {
20673                    IoUtils.closeQuietly(in);
20674                }
20675            }
20676        }
20677    }
20678
20679    private void dumpDexoptStateLPr(PrintWriter pw, String packageName) {
20680        final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ", 120);
20681        ipw.println();
20682        ipw.println("Dexopt state:");
20683        ipw.increaseIndent();
20684        Collection<PackageParser.Package> packages = null;
20685        if (packageName != null) {
20686            PackageParser.Package targetPackage = mPackages.get(packageName);
20687            if (targetPackage != null) {
20688                packages = Collections.singletonList(targetPackage);
20689            } else {
20690                ipw.println("Unable to find package: " + packageName);
20691                return;
20692            }
20693        } else {
20694            packages = mPackages.values();
20695        }
20696
20697        for (PackageParser.Package pkg : packages) {
20698            ipw.println("[" + pkg.packageName + "]");
20699            ipw.increaseIndent();
20700            mPackageDexOptimizer.dumpDexoptState(ipw, pkg);
20701            ipw.decreaseIndent();
20702        }
20703    }
20704
20705    private void dumpCompilerStatsLPr(PrintWriter pw, String packageName) {
20706        final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ", 120);
20707        ipw.println();
20708        ipw.println("Compiler stats:");
20709        ipw.increaseIndent();
20710        Collection<PackageParser.Package> packages = null;
20711        if (packageName != null) {
20712            PackageParser.Package targetPackage = mPackages.get(packageName);
20713            if (targetPackage != null) {
20714                packages = Collections.singletonList(targetPackage);
20715            } else {
20716                ipw.println("Unable to find package: " + packageName);
20717                return;
20718            }
20719        } else {
20720            packages = mPackages.values();
20721        }
20722
20723        for (PackageParser.Package pkg : packages) {
20724            ipw.println("[" + pkg.packageName + "]");
20725            ipw.increaseIndent();
20726
20727            CompilerStats.PackageStats stats = getCompilerPackageStats(pkg.packageName);
20728            if (stats == null) {
20729                ipw.println("(No recorded stats)");
20730            } else {
20731                stats.dump(ipw);
20732            }
20733            ipw.decreaseIndent();
20734        }
20735    }
20736
20737    private String dumpDomainString(String packageName) {
20738        List<IntentFilterVerificationInfo> iviList = getIntentFilterVerifications(packageName)
20739                .getList();
20740        List<IntentFilter> filters = getAllIntentFilters(packageName).getList();
20741
20742        ArraySet<String> result = new ArraySet<>();
20743        if (iviList.size() > 0) {
20744            for (IntentFilterVerificationInfo ivi : iviList) {
20745                for (String host : ivi.getDomains()) {
20746                    result.add(host);
20747                }
20748            }
20749        }
20750        if (filters != null && filters.size() > 0) {
20751            for (IntentFilter filter : filters) {
20752                if (filter.hasCategory(Intent.CATEGORY_BROWSABLE)
20753                        && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) ||
20754                                filter.hasDataScheme(IntentFilter.SCHEME_HTTPS))) {
20755                    result.addAll(filter.getHostsList());
20756                }
20757            }
20758        }
20759
20760        StringBuilder sb = new StringBuilder(result.size() * 16);
20761        for (String domain : result) {
20762            if (sb.length() > 0) sb.append(" ");
20763            sb.append(domain);
20764        }
20765        return sb.toString();
20766    }
20767
20768    // ------- apps on sdcard specific code -------
20769    static final boolean DEBUG_SD_INSTALL = false;
20770
20771    private static final String SD_ENCRYPTION_KEYSTORE_NAME = "AppsOnSD";
20772
20773    private static final String SD_ENCRYPTION_ALGORITHM = "AES";
20774
20775    private boolean mMediaMounted = false;
20776
20777    static String getEncryptKey() {
20778        try {
20779            String sdEncKey = SystemKeyStore.getInstance().retrieveKeyHexString(
20780                    SD_ENCRYPTION_KEYSTORE_NAME);
20781            if (sdEncKey == null) {
20782                sdEncKey = SystemKeyStore.getInstance().generateNewKeyHexString(128,
20783                        SD_ENCRYPTION_ALGORITHM, SD_ENCRYPTION_KEYSTORE_NAME);
20784                if (sdEncKey == null) {
20785                    Slog.e(TAG, "Failed to create encryption keys");
20786                    return null;
20787                }
20788            }
20789            return sdEncKey;
20790        } catch (NoSuchAlgorithmException nsae) {
20791            Slog.e(TAG, "Failed to create encryption keys with exception: " + nsae);
20792            return null;
20793        } catch (IOException ioe) {
20794            Slog.e(TAG, "Failed to retrieve encryption keys with exception: " + ioe);
20795            return null;
20796        }
20797    }
20798
20799    /*
20800     * Update media status on PackageManager.
20801     */
20802    @Override
20803    public void updateExternalMediaStatus(final boolean mediaStatus, final boolean reportStatus) {
20804        int callingUid = Binder.getCallingUid();
20805        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
20806            throw new SecurityException("Media status can only be updated by the system");
20807        }
20808        // reader; this apparently protects mMediaMounted, but should probably
20809        // be a different lock in that case.
20810        synchronized (mPackages) {
20811            Log.i(TAG, "Updating external media status from "
20812                    + (mMediaMounted ? "mounted" : "unmounted") + " to "
20813                    + (mediaStatus ? "mounted" : "unmounted"));
20814            if (DEBUG_SD_INSTALL)
20815                Log.i(TAG, "updateExternalMediaStatus:: mediaStatus=" + mediaStatus
20816                        + ", mMediaMounted=" + mMediaMounted);
20817            if (mediaStatus == mMediaMounted) {
20818                final Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1
20819                        : 0, -1);
20820                mHandler.sendMessage(msg);
20821                return;
20822            }
20823            mMediaMounted = mediaStatus;
20824        }
20825        // Queue up an async operation since the package installation may take a
20826        // little while.
20827        mHandler.post(new Runnable() {
20828            public void run() {
20829                updateExternalMediaStatusInner(mediaStatus, reportStatus, true);
20830            }
20831        });
20832    }
20833
20834    /**
20835     * Called by StorageManagerService when the initial ASECs to scan are available.
20836     * Should block until all the ASEC containers are finished being scanned.
20837     */
20838    public void scanAvailableAsecs() {
20839        updateExternalMediaStatusInner(true, false, false);
20840    }
20841
20842    /*
20843     * Collect information of applications on external media, map them against
20844     * existing containers and update information based on current mount status.
20845     * Please note that we always have to report status if reportStatus has been
20846     * set to true especially when unloading packages.
20847     */
20848    private void updateExternalMediaStatusInner(boolean isMounted, boolean reportStatus,
20849            boolean externalStorage) {
20850        ArrayMap<AsecInstallArgs, String> processCids = new ArrayMap<>();
20851        int[] uidArr = EmptyArray.INT;
20852
20853        final String[] list = PackageHelper.getSecureContainerList();
20854        if (ArrayUtils.isEmpty(list)) {
20855            Log.i(TAG, "No secure containers found");
20856        } else {
20857            // Process list of secure containers and categorize them
20858            // as active or stale based on their package internal state.
20859
20860            // reader
20861            synchronized (mPackages) {
20862                for (String cid : list) {
20863                    // Leave stages untouched for now; installer service owns them
20864                    if (PackageInstallerService.isStageName(cid)) continue;
20865
20866                    if (DEBUG_SD_INSTALL)
20867                        Log.i(TAG, "Processing container " + cid);
20868                    String pkgName = getAsecPackageName(cid);
20869                    if (pkgName == null) {
20870                        Slog.i(TAG, "Found stale container " + cid + " with no package name");
20871                        continue;
20872                    }
20873                    if (DEBUG_SD_INSTALL)
20874                        Log.i(TAG, "Looking for pkg : " + pkgName);
20875
20876                    final PackageSetting ps = mSettings.mPackages.get(pkgName);
20877                    if (ps == null) {
20878                        Slog.i(TAG, "Found stale container " + cid + " with no matching settings");
20879                        continue;
20880                    }
20881
20882                    /*
20883                     * Skip packages that are not external if we're unmounting
20884                     * external storage.
20885                     */
20886                    if (externalStorage && !isMounted && !isExternal(ps)) {
20887                        continue;
20888                    }
20889
20890                    final AsecInstallArgs args = new AsecInstallArgs(cid,
20891                            getAppDexInstructionSets(ps), ps.isForwardLocked());
20892                    // The package status is changed only if the code path
20893                    // matches between settings and the container id.
20894                    if (ps.codePathString != null
20895                            && ps.codePathString.startsWith(args.getCodePath())) {
20896                        if (DEBUG_SD_INSTALL) {
20897                            Log.i(TAG, "Container : " + cid + " corresponds to pkg : " + pkgName
20898                                    + " at code path: " + ps.codePathString);
20899                        }
20900
20901                        // We do have a valid package installed on sdcard
20902                        processCids.put(args, ps.codePathString);
20903                        final int uid = ps.appId;
20904                        if (uid != -1) {
20905                            uidArr = ArrayUtils.appendInt(uidArr, uid);
20906                        }
20907                    } else {
20908                        Slog.i(TAG, "Found stale container " + cid + ": expected codePath="
20909                                + ps.codePathString);
20910                    }
20911                }
20912            }
20913
20914            Arrays.sort(uidArr);
20915        }
20916
20917        // Process packages with valid entries.
20918        if (isMounted) {
20919            if (DEBUG_SD_INSTALL)
20920                Log.i(TAG, "Loading packages");
20921            loadMediaPackages(processCids, uidArr, externalStorage);
20922            startCleaningPackages();
20923            mInstallerService.onSecureContainersAvailable();
20924        } else {
20925            if (DEBUG_SD_INSTALL)
20926                Log.i(TAG, "Unloading packages");
20927            unloadMediaPackages(processCids, uidArr, reportStatus);
20928        }
20929    }
20930
20931    private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
20932            ArrayList<ApplicationInfo> infos, IIntentReceiver finishedReceiver) {
20933        final int size = infos.size();
20934        final String[] packageNames = new String[size];
20935        final int[] packageUids = new int[size];
20936        for (int i = 0; i < size; i++) {
20937            final ApplicationInfo info = infos.get(i);
20938            packageNames[i] = info.packageName;
20939            packageUids[i] = info.uid;
20940        }
20941        sendResourcesChangedBroadcast(mediaStatus, replacing, packageNames, packageUids,
20942                finishedReceiver);
20943    }
20944
20945    private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
20946            ArrayList<String> pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
20947        sendResourcesChangedBroadcast(mediaStatus, replacing,
20948                pkgList.toArray(new String[pkgList.size()]), uidArr, finishedReceiver);
20949    }
20950
20951    private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
20952            String[] pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
20953        int size = pkgList.length;
20954        if (size > 0) {
20955            // Send broadcasts here
20956            Bundle extras = new Bundle();
20957            extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
20958            if (uidArr != null) {
20959                extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidArr);
20960            }
20961            if (replacing) {
20962                extras.putBoolean(Intent.EXTRA_REPLACING, replacing);
20963            }
20964            String action = mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE
20965                    : Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE;
20966            sendPackageBroadcast(action, null, extras, 0, null, finishedReceiver, null);
20967        }
20968    }
20969
20970   /*
20971     * Look at potentially valid container ids from processCids If package
20972     * information doesn't match the one on record or package scanning fails,
20973     * the cid is added to list of removeCids. We currently don't delete stale
20974     * containers.
20975     */
20976    private void loadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int[] uidArr,
20977            boolean externalStorage) {
20978        ArrayList<String> pkgList = new ArrayList<String>();
20979        Set<AsecInstallArgs> keys = processCids.keySet();
20980
20981        for (AsecInstallArgs args : keys) {
20982            String codePath = processCids.get(args);
20983            if (DEBUG_SD_INSTALL)
20984                Log.i(TAG, "Loading container : " + args.cid);
20985            int retCode = PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
20986            try {
20987                // Make sure there are no container errors first.
20988                if (args.doPreInstall(PackageManager.INSTALL_SUCCEEDED) != PackageManager.INSTALL_SUCCEEDED) {
20989                    Slog.e(TAG, "Failed to mount cid : " + args.cid
20990                            + " when installing from sdcard");
20991                    continue;
20992                }
20993                // Check code path here.
20994                if (codePath == null || !codePath.startsWith(args.getCodePath())) {
20995                    Slog.e(TAG, "Container " + args.cid + " cachepath " + args.getCodePath()
20996                            + " does not match one in settings " + codePath);
20997                    continue;
20998                }
20999                // Parse package
21000                int parseFlags = mDefParseFlags;
21001                if (args.isExternalAsec()) {
21002                    parseFlags |= PackageParser.PARSE_EXTERNAL_STORAGE;
21003                }
21004                if (args.isFwdLocked()) {
21005                    parseFlags |= PackageParser.PARSE_FORWARD_LOCK;
21006                }
21007
21008                synchronized (mInstallLock) {
21009                    PackageParser.Package pkg = null;
21010                    try {
21011                        // Sadly we don't know the package name yet to freeze it
21012                        pkg = scanPackageTracedLI(new File(codePath), parseFlags,
21013                                SCAN_IGNORE_FROZEN, 0, null);
21014                    } catch (PackageManagerException e) {
21015                        Slog.w(TAG, "Failed to scan " + codePath + ": " + e.getMessage());
21016                    }
21017                    // Scan the package
21018                    if (pkg != null) {
21019                        /*
21020                         * TODO why is the lock being held? doPostInstall is
21021                         * called in other places without the lock. This needs
21022                         * to be straightened out.
21023                         */
21024                        // writer
21025                        synchronized (mPackages) {
21026                            retCode = PackageManager.INSTALL_SUCCEEDED;
21027                            pkgList.add(pkg.packageName);
21028                            // Post process args
21029                            args.doPostInstall(PackageManager.INSTALL_SUCCEEDED,
21030                                    pkg.applicationInfo.uid);
21031                        }
21032                    } else {
21033                        Slog.i(TAG, "Failed to install pkg from  " + codePath + " from sdcard");
21034                    }
21035                }
21036
21037            } finally {
21038                if (retCode != PackageManager.INSTALL_SUCCEEDED) {
21039                    Log.w(TAG, "Container " + args.cid + " is stale, retCode=" + retCode);
21040                }
21041            }
21042        }
21043        // writer
21044        synchronized (mPackages) {
21045            // If the platform SDK has changed since the last time we booted,
21046            // we need to re-grant app permission to catch any new ones that
21047            // appear. This is really a hack, and means that apps can in some
21048            // cases get permissions that the user didn't initially explicitly
21049            // allow... it would be nice to have some better way to handle
21050            // this situation.
21051            final VersionInfo ver = externalStorage ? mSettings.getExternalVersion()
21052                    : mSettings.getInternalVersion();
21053            final String volumeUuid = externalStorage ? StorageManager.UUID_PRIMARY_PHYSICAL
21054                    : StorageManager.UUID_PRIVATE_INTERNAL;
21055
21056            int updateFlags = UPDATE_PERMISSIONS_ALL;
21057            if (ver.sdkVersion != mSdkVersion) {
21058                logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to "
21059                        + mSdkVersion + "; regranting permissions for external");
21060                updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
21061            }
21062            updatePermissionsLPw(null, null, volumeUuid, updateFlags);
21063
21064            // Yay, everything is now upgraded
21065            ver.forceCurrent();
21066
21067            // can downgrade to reader
21068            // Persist settings
21069            mSettings.writeLPr();
21070        }
21071        // Send a broadcast to let everyone know we are done processing
21072        if (pkgList.size() > 0) {
21073            sendResourcesChangedBroadcast(true, false, pkgList, uidArr, null);
21074        }
21075    }
21076
21077   /*
21078     * Utility method to unload a list of specified containers
21079     */
21080    private void unloadAllContainers(Set<AsecInstallArgs> cidArgs) {
21081        // Just unmount all valid containers.
21082        for (AsecInstallArgs arg : cidArgs) {
21083            synchronized (mInstallLock) {
21084                arg.doPostDeleteLI(false);
21085           }
21086       }
21087   }
21088
21089    /*
21090     * Unload packages mounted on external media. This involves deleting package
21091     * data from internal structures, sending broadcasts about disabled packages,
21092     * gc'ing to free up references, unmounting all secure containers
21093     * corresponding to packages on external media, and posting a
21094     * UPDATED_MEDIA_STATUS message if status has been requested. Please note
21095     * that we always have to post this message if status has been requested no
21096     * matter what.
21097     */
21098    private void unloadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int uidArr[],
21099            final boolean reportStatus) {
21100        if (DEBUG_SD_INSTALL)
21101            Log.i(TAG, "unloading media packages");
21102        ArrayList<String> pkgList = new ArrayList<String>();
21103        ArrayList<AsecInstallArgs> failedList = new ArrayList<AsecInstallArgs>();
21104        final Set<AsecInstallArgs> keys = processCids.keySet();
21105        for (AsecInstallArgs args : keys) {
21106            String pkgName = args.getPackageName();
21107            if (DEBUG_SD_INSTALL)
21108                Log.i(TAG, "Trying to unload pkg : " + pkgName);
21109            // Delete package internally
21110            PackageRemovedInfo outInfo = new PackageRemovedInfo();
21111            synchronized (mInstallLock) {
21112                final int deleteFlags = PackageManager.DELETE_KEEP_DATA;
21113                final boolean res;
21114                try (PackageFreezer freezer = freezePackageForDelete(pkgName, deleteFlags,
21115                        "unloadMediaPackages")) {
21116                    res = deletePackageLIF(pkgName, null, false, null, deleteFlags, outInfo, false,
21117                            null);
21118                }
21119                if (res) {
21120                    pkgList.add(pkgName);
21121                } else {
21122                    Slog.e(TAG, "Failed to delete pkg from sdcard : " + pkgName);
21123                    failedList.add(args);
21124                }
21125            }
21126        }
21127
21128        // reader
21129        synchronized (mPackages) {
21130            // We didn't update the settings after removing each package;
21131            // write them now for all packages.
21132            mSettings.writeLPr();
21133        }
21134
21135        // We have to absolutely send UPDATED_MEDIA_STATUS only
21136        // after confirming that all the receivers processed the ordered
21137        // broadcast when packages get disabled, force a gc to clean things up.
21138        // and unload all the containers.
21139        if (pkgList.size() > 0) {
21140            sendResourcesChangedBroadcast(false, false, pkgList, uidArr,
21141                    new IIntentReceiver.Stub() {
21142                public void performReceive(Intent intent, int resultCode, String data,
21143                        Bundle extras, boolean ordered, boolean sticky,
21144                        int sendingUser) throws RemoteException {
21145                    Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS,
21146                            reportStatus ? 1 : 0, 1, keys);
21147                    mHandler.sendMessage(msg);
21148                }
21149            });
21150        } else {
21151            Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1 : 0, -1,
21152                    keys);
21153            mHandler.sendMessage(msg);
21154        }
21155    }
21156
21157    private void loadPrivatePackages(final VolumeInfo vol) {
21158        mHandler.post(new Runnable() {
21159            @Override
21160            public void run() {
21161                loadPrivatePackagesInner(vol);
21162            }
21163        });
21164    }
21165
21166    private void loadPrivatePackagesInner(VolumeInfo vol) {
21167        final String volumeUuid = vol.fsUuid;
21168        if (TextUtils.isEmpty(volumeUuid)) {
21169            Slog.e(TAG, "Loading internal storage is probably a mistake; ignoring");
21170            return;
21171        }
21172
21173        final ArrayList<PackageFreezer> freezers = new ArrayList<>();
21174        final ArrayList<ApplicationInfo> loaded = new ArrayList<>();
21175        final int parseFlags = mDefParseFlags | PackageParser.PARSE_EXTERNAL_STORAGE;
21176
21177        final VersionInfo ver;
21178        final List<PackageSetting> packages;
21179        synchronized (mPackages) {
21180            ver = mSettings.findOrCreateVersion(volumeUuid);
21181            packages = mSettings.getVolumePackagesLPr(volumeUuid);
21182        }
21183
21184        for (PackageSetting ps : packages) {
21185            freezers.add(freezePackage(ps.name, "loadPrivatePackagesInner"));
21186            synchronized (mInstallLock) {
21187                final PackageParser.Package pkg;
21188                try {
21189                    pkg = scanPackageTracedLI(ps.codePath, parseFlags, SCAN_INITIAL, 0, null);
21190                    loaded.add(pkg.applicationInfo);
21191
21192                } catch (PackageManagerException e) {
21193                    Slog.w(TAG, "Failed to scan " + ps.codePath + ": " + e.getMessage());
21194                }
21195
21196                if (!Build.FINGERPRINT.equals(ver.fingerprint)) {
21197                    clearAppDataLIF(ps.pkg, UserHandle.USER_ALL,
21198                            StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE
21199                                    | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
21200                }
21201            }
21202        }
21203
21204        // Reconcile app data for all started/unlocked users
21205        final StorageManager sm = mContext.getSystemService(StorageManager.class);
21206        final UserManager um = mContext.getSystemService(UserManager.class);
21207        UserManagerInternal umInternal = getUserManagerInternal();
21208        for (UserInfo user : um.getUsers()) {
21209            final int flags;
21210            if (umInternal.isUserUnlockingOrUnlocked(user.id)) {
21211                flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
21212            } else if (umInternal.isUserRunning(user.id)) {
21213                flags = StorageManager.FLAG_STORAGE_DE;
21214            } else {
21215                continue;
21216            }
21217
21218            try {
21219                sm.prepareUserStorage(volumeUuid, user.id, user.serialNumber, flags);
21220                synchronized (mInstallLock) {
21221                    reconcileAppsDataLI(volumeUuid, user.id, flags, true /* migrateAppData */);
21222                }
21223            } catch (IllegalStateException e) {
21224                // Device was probably ejected, and we'll process that event momentarily
21225                Slog.w(TAG, "Failed to prepare storage: " + e);
21226            }
21227        }
21228
21229        synchronized (mPackages) {
21230            int updateFlags = UPDATE_PERMISSIONS_ALL;
21231            if (ver.sdkVersion != mSdkVersion) {
21232                logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to "
21233                        + mSdkVersion + "; regranting permissions for " + volumeUuid);
21234                updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
21235            }
21236            updatePermissionsLPw(null, null, volumeUuid, updateFlags);
21237
21238            // Yay, everything is now upgraded
21239            ver.forceCurrent();
21240
21241            mSettings.writeLPr();
21242        }
21243
21244        for (PackageFreezer freezer : freezers) {
21245            freezer.close();
21246        }
21247
21248        if (DEBUG_INSTALL) Slog.d(TAG, "Loaded packages " + loaded);
21249        sendResourcesChangedBroadcast(true, false, loaded, null);
21250    }
21251
21252    private void unloadPrivatePackages(final VolumeInfo vol) {
21253        mHandler.post(new Runnable() {
21254            @Override
21255            public void run() {
21256                unloadPrivatePackagesInner(vol);
21257            }
21258        });
21259    }
21260
21261    private void unloadPrivatePackagesInner(VolumeInfo vol) {
21262        final String volumeUuid = vol.fsUuid;
21263        if (TextUtils.isEmpty(volumeUuid)) {
21264            Slog.e(TAG, "Unloading internal storage is probably a mistake; ignoring");
21265            return;
21266        }
21267
21268        final ArrayList<ApplicationInfo> unloaded = new ArrayList<>();
21269        synchronized (mInstallLock) {
21270        synchronized (mPackages) {
21271            final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(volumeUuid);
21272            for (PackageSetting ps : packages) {
21273                if (ps.pkg == null) continue;
21274
21275                final ApplicationInfo info = ps.pkg.applicationInfo;
21276                final int deleteFlags = PackageManager.DELETE_KEEP_DATA;
21277                final PackageRemovedInfo outInfo = new PackageRemovedInfo();
21278
21279                try (PackageFreezer freezer = freezePackageForDelete(ps.name, deleteFlags,
21280                        "unloadPrivatePackagesInner")) {
21281                    if (deletePackageLIF(ps.name, null, false, null, deleteFlags, outInfo,
21282                            false, null)) {
21283                        unloaded.add(info);
21284                    } else {
21285                        Slog.w(TAG, "Failed to unload " + ps.codePath);
21286                    }
21287                }
21288
21289                // Try very hard to release any references to this package
21290                // so we don't risk the system server being killed due to
21291                // open FDs
21292                AttributeCache.instance().removePackage(ps.name);
21293            }
21294
21295            mSettings.writeLPr();
21296        }
21297        }
21298
21299        if (DEBUG_INSTALL) Slog.d(TAG, "Unloaded packages " + unloaded);
21300        sendResourcesChangedBroadcast(false, false, unloaded, null);
21301
21302        // Try very hard to release any references to this path so we don't risk
21303        // the system server being killed due to open FDs
21304        ResourcesManager.getInstance().invalidatePath(vol.getPath().getAbsolutePath());
21305
21306        for (int i = 0; i < 3; i++) {
21307            System.gc();
21308            System.runFinalization();
21309        }
21310    }
21311
21312    /**
21313     * Examine all users present on given mounted volume, and destroy data
21314     * belonging to users that are no longer valid, or whose user ID has been
21315     * recycled.
21316     */
21317    private void reconcileUsers(String volumeUuid) {
21318        final List<File> files = new ArrayList<>();
21319        Collections.addAll(files, FileUtils
21320                .listFilesOrEmpty(Environment.getDataUserDeDirectory(volumeUuid)));
21321        Collections.addAll(files, FileUtils
21322                .listFilesOrEmpty(Environment.getDataUserCeDirectory(volumeUuid)));
21323        Collections.addAll(files, FileUtils
21324                .listFilesOrEmpty(Environment.getDataSystemDeDirectory()));
21325        Collections.addAll(files, FileUtils
21326                .listFilesOrEmpty(Environment.getDataSystemCeDirectory()));
21327        Collections.addAll(files, FileUtils
21328                .listFilesOrEmpty(Environment.getDataMiscCeDirectory()));
21329        for (File file : files) {
21330            if (!file.isDirectory()) continue;
21331
21332            final int userId;
21333            final UserInfo info;
21334            try {
21335                userId = Integer.parseInt(file.getName());
21336                info = sUserManager.getUserInfo(userId);
21337            } catch (NumberFormatException e) {
21338                Slog.w(TAG, "Invalid user directory " + file);
21339                continue;
21340            }
21341
21342            boolean destroyUser = false;
21343            if (info == null) {
21344                logCriticalInfo(Log.WARN, "Destroying user directory " + file
21345                        + " because no matching user was found");
21346                destroyUser = true;
21347            } else if (!mOnlyCore) {
21348                try {
21349                    UserManagerService.enforceSerialNumber(file, info.serialNumber);
21350                } catch (IOException e) {
21351                    logCriticalInfo(Log.WARN, "Destroying user directory " + file
21352                            + " because we failed to enforce serial number: " + e);
21353                    destroyUser = true;
21354                }
21355            }
21356
21357            if (destroyUser) {
21358                synchronized (mInstallLock) {
21359                    mUserDataPreparer.destroyUserDataLI(volumeUuid, userId,
21360                            StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
21361                }
21362            }
21363        }
21364    }
21365
21366    private void assertPackageKnown(String volumeUuid, String packageName)
21367            throws PackageManagerException {
21368        synchronized (mPackages) {
21369            // Normalize package name to handle renamed packages
21370            packageName = normalizePackageNameLPr(packageName);
21371
21372            final PackageSetting ps = mSettings.mPackages.get(packageName);
21373            if (ps == null) {
21374                throw new PackageManagerException("Package " + packageName + " is unknown");
21375            } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) {
21376                throw new PackageManagerException(
21377                        "Package " + packageName + " found on unknown volume " + volumeUuid
21378                                + "; expected volume " + ps.volumeUuid);
21379            }
21380        }
21381    }
21382
21383    private void assertPackageKnownAndInstalled(String volumeUuid, String packageName, int userId)
21384            throws PackageManagerException {
21385        synchronized (mPackages) {
21386            // Normalize package name to handle renamed packages
21387            packageName = normalizePackageNameLPr(packageName);
21388
21389            final PackageSetting ps = mSettings.mPackages.get(packageName);
21390            if (ps == null) {
21391                throw new PackageManagerException("Package " + packageName + " is unknown");
21392            } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) {
21393                throw new PackageManagerException(
21394                        "Package " + packageName + " found on unknown volume " + volumeUuid
21395                                + "; expected volume " + ps.volumeUuid);
21396            } else if (!ps.getInstalled(userId)) {
21397                throw new PackageManagerException(
21398                        "Package " + packageName + " not installed for user " + userId);
21399            }
21400        }
21401    }
21402
21403    private List<String> collectAbsoluteCodePaths() {
21404        synchronized (mPackages) {
21405            List<String> codePaths = new ArrayList<>();
21406            final int packageCount = mSettings.mPackages.size();
21407            for (int i = 0; i < packageCount; i++) {
21408                final PackageSetting ps = mSettings.mPackages.valueAt(i);
21409                codePaths.add(ps.codePath.getAbsolutePath());
21410            }
21411            return codePaths;
21412        }
21413    }
21414
21415    /**
21416     * Examine all apps present on given mounted volume, and destroy apps that
21417     * aren't expected, either due to uninstallation or reinstallation on
21418     * another volume.
21419     */
21420    private void reconcileApps(String volumeUuid) {
21421        List<String> absoluteCodePaths = collectAbsoluteCodePaths();
21422        List<File> filesToDelete = null;
21423
21424        final File[] files = FileUtils.listFilesOrEmpty(
21425                Environment.getDataAppDirectory(volumeUuid));
21426        for (File file : files) {
21427            final boolean isPackage = (isApkFile(file) || file.isDirectory())
21428                    && !PackageInstallerService.isStageName(file.getName());
21429            if (!isPackage) {
21430                // Ignore entries which are not packages
21431                continue;
21432            }
21433
21434            String absolutePath = file.getAbsolutePath();
21435
21436            boolean pathValid = false;
21437            final int absoluteCodePathCount = absoluteCodePaths.size();
21438            for (int i = 0; i < absoluteCodePathCount; i++) {
21439                String absoluteCodePath = absoluteCodePaths.get(i);
21440                if (absolutePath.startsWith(absoluteCodePath)) {
21441                    pathValid = true;
21442                    break;
21443                }
21444            }
21445
21446            if (!pathValid) {
21447                if (filesToDelete == null) {
21448                    filesToDelete = new ArrayList<>();
21449                }
21450                filesToDelete.add(file);
21451            }
21452        }
21453
21454        if (filesToDelete != null) {
21455            final int fileToDeleteCount = filesToDelete.size();
21456            for (int i = 0; i < fileToDeleteCount; i++) {
21457                File fileToDelete = filesToDelete.get(i);
21458                logCriticalInfo(Log.WARN, "Destroying orphaned" + fileToDelete);
21459                synchronized (mInstallLock) {
21460                    removeCodePathLI(fileToDelete);
21461                }
21462            }
21463        }
21464    }
21465
21466    /**
21467     * Reconcile all app data for the given user.
21468     * <p>
21469     * Verifies that directories exist and that ownership and labeling is
21470     * correct for all installed apps on all mounted volumes.
21471     */
21472    void reconcileAppsData(int userId, int flags, boolean migrateAppsData) {
21473        final StorageManager storage = mContext.getSystemService(StorageManager.class);
21474        for (VolumeInfo vol : storage.getWritablePrivateVolumes()) {
21475            final String volumeUuid = vol.getFsUuid();
21476            synchronized (mInstallLock) {
21477                reconcileAppsDataLI(volumeUuid, userId, flags, migrateAppsData);
21478            }
21479        }
21480    }
21481
21482    /**
21483     * Reconcile all app data on given mounted volume.
21484     * <p>
21485     * Destroys app data that isn't expected, either due to uninstallation or
21486     * reinstallation on another volume.
21487     * <p>
21488     * Verifies that directories exist and that ownership and labeling is
21489     * correct for all installed apps.
21490     */
21491    private void reconcileAppsDataLI(String volumeUuid, int userId, int flags,
21492            boolean migrateAppData) {
21493        Slog.v(TAG, "reconcileAppsData for " + volumeUuid + " u" + userId + " 0x"
21494                + Integer.toHexString(flags) + " migrateAppData=" + migrateAppData);
21495
21496        final File ceDir = Environment.getDataUserCeDirectory(volumeUuid, userId);
21497        final File deDir = Environment.getDataUserDeDirectory(volumeUuid, userId);
21498
21499        // First look for stale data that doesn't belong, and check if things
21500        // have changed since we did our last restorecon
21501        if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
21502            if (StorageManager.isFileEncryptedNativeOrEmulated()
21503                    && !StorageManager.isUserKeyUnlocked(userId)) {
21504                throw new RuntimeException(
21505                        "Yikes, someone asked us to reconcile CE storage while " + userId
21506                                + " was still locked; this would have caused massive data loss!");
21507            }
21508
21509            final File[] files = FileUtils.listFilesOrEmpty(ceDir);
21510            for (File file : files) {
21511                final String packageName = file.getName();
21512                try {
21513                    assertPackageKnownAndInstalled(volumeUuid, packageName, userId);
21514                } catch (PackageManagerException e) {
21515                    logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e);
21516                    try {
21517                        mInstaller.destroyAppData(volumeUuid, packageName, userId,
21518                                StorageManager.FLAG_STORAGE_CE, 0);
21519                    } catch (InstallerException e2) {
21520                        logCriticalInfo(Log.WARN, "Failed to destroy: " + e2);
21521                    }
21522                }
21523            }
21524        }
21525        if ((flags & StorageManager.FLAG_STORAGE_DE) != 0) {
21526            final File[] files = FileUtils.listFilesOrEmpty(deDir);
21527            for (File file : files) {
21528                final String packageName = file.getName();
21529                try {
21530                    assertPackageKnownAndInstalled(volumeUuid, packageName, userId);
21531                } catch (PackageManagerException e) {
21532                    logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e);
21533                    try {
21534                        mInstaller.destroyAppData(volumeUuid, packageName, userId,
21535                                StorageManager.FLAG_STORAGE_DE, 0);
21536                    } catch (InstallerException e2) {
21537                        logCriticalInfo(Log.WARN, "Failed to destroy: " + e2);
21538                    }
21539                }
21540            }
21541        }
21542
21543        // Ensure that data directories are ready to roll for all packages
21544        // installed for this volume and user
21545        final List<PackageSetting> packages;
21546        synchronized (mPackages) {
21547            packages = mSettings.getVolumePackagesLPr(volumeUuid);
21548        }
21549        int preparedCount = 0;
21550        for (PackageSetting ps : packages) {
21551            final String packageName = ps.name;
21552            if (ps.pkg == null) {
21553                Slog.w(TAG, "Odd, missing scanned package " + packageName);
21554                // TODO: might be due to legacy ASEC apps; we should circle back
21555                // and reconcile again once they're scanned
21556                continue;
21557            }
21558
21559            if (ps.getInstalled(userId)) {
21560                prepareAppDataLIF(ps.pkg, userId, flags);
21561
21562                if (migrateAppData && maybeMigrateAppDataLIF(ps.pkg, userId)) {
21563                    // We may have just shuffled around app data directories, so
21564                    // prepare them one more time
21565                    prepareAppDataLIF(ps.pkg, userId, flags);
21566                }
21567
21568                preparedCount++;
21569            }
21570        }
21571
21572        Slog.v(TAG, "reconcileAppsData finished " + preparedCount + " packages");
21573    }
21574
21575    /**
21576     * Prepare app data for the given app just after it was installed or
21577     * upgraded. This method carefully only touches users that it's installed
21578     * for, and it forces a restorecon to handle any seinfo changes.
21579     * <p>
21580     * Verifies that directories exist and that ownership and labeling is
21581     * correct for all installed apps. If there is an ownership mismatch, it
21582     * will try recovering system apps by wiping data; third-party app data is
21583     * left intact.
21584     * <p>
21585     * <em>Note: To avoid a deadlock, do not call this method with {@code mPackages} lock held</em>
21586     */
21587    private void prepareAppDataAfterInstallLIF(PackageParser.Package pkg) {
21588        final PackageSetting ps;
21589        synchronized (mPackages) {
21590            ps = mSettings.mPackages.get(pkg.packageName);
21591            mSettings.writeKernelMappingLPr(ps);
21592        }
21593
21594        final UserManager um = mContext.getSystemService(UserManager.class);
21595        UserManagerInternal umInternal = getUserManagerInternal();
21596        for (UserInfo user : um.getUsers()) {
21597            final int flags;
21598            if (umInternal.isUserUnlockingOrUnlocked(user.id)) {
21599                flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
21600            } else if (umInternal.isUserRunning(user.id)) {
21601                flags = StorageManager.FLAG_STORAGE_DE;
21602            } else {
21603                continue;
21604            }
21605
21606            if (ps.getInstalled(user.id)) {
21607                // TODO: when user data is locked, mark that we're still dirty
21608                prepareAppDataLIF(pkg, user.id, flags);
21609            }
21610        }
21611    }
21612
21613    /**
21614     * Prepare app data for the given app.
21615     * <p>
21616     * Verifies that directories exist and that ownership and labeling is
21617     * correct for all installed apps. If there is an ownership mismatch, this
21618     * will try recovering system apps by wiping data; third-party app data is
21619     * left intact.
21620     */
21621    private void prepareAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
21622        if (pkg == null) {
21623            Slog.wtf(TAG, "Package was null!", new Throwable());
21624            return;
21625        }
21626        prepareAppDataLeafLIF(pkg, userId, flags);
21627        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
21628        for (int i = 0; i < childCount; i++) {
21629            prepareAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
21630        }
21631    }
21632
21633    private void prepareAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
21634        if (DEBUG_APP_DATA) {
21635            Slog.v(TAG, "prepareAppData for " + pkg.packageName + " u" + userId + " 0x"
21636                    + Integer.toHexString(flags));
21637        }
21638
21639        final String volumeUuid = pkg.volumeUuid;
21640        final String packageName = pkg.packageName;
21641        final ApplicationInfo app = pkg.applicationInfo;
21642        final int appId = UserHandle.getAppId(app.uid);
21643
21644        Preconditions.checkNotNull(app.seinfo);
21645
21646        long ceDataInode = -1;
21647        try {
21648            ceDataInode = mInstaller.createAppData(volumeUuid, packageName, userId, flags,
21649                    appId, app.seinfo, app.targetSdkVersion);
21650        } catch (InstallerException e) {
21651            if (app.isSystemApp()) {
21652                logCriticalInfo(Log.ERROR, "Failed to create app data for " + packageName
21653                        + ", but trying to recover: " + e);
21654                destroyAppDataLeafLIF(pkg, userId, flags);
21655                try {
21656                    ceDataInode = mInstaller.createAppData(volumeUuid, packageName, userId, flags,
21657                            appId, app.seinfo, app.targetSdkVersion);
21658                    logCriticalInfo(Log.DEBUG, "Recovery succeeded!");
21659                } catch (InstallerException e2) {
21660                    logCriticalInfo(Log.DEBUG, "Recovery failed!");
21661                }
21662            } else {
21663                Slog.e(TAG, "Failed to create app data for " + packageName + ": " + e);
21664            }
21665        }
21666
21667        if ((flags & StorageManager.FLAG_STORAGE_CE) != 0 && ceDataInode != -1) {
21668            // TODO: mark this structure as dirty so we persist it!
21669            synchronized (mPackages) {
21670                final PackageSetting ps = mSettings.mPackages.get(packageName);
21671                if (ps != null) {
21672                    ps.setCeDataInode(ceDataInode, userId);
21673                }
21674            }
21675        }
21676
21677        prepareAppDataContentsLeafLIF(pkg, userId, flags);
21678    }
21679
21680    private void prepareAppDataContentsLIF(PackageParser.Package pkg, int userId, int flags) {
21681        if (pkg == null) {
21682            Slog.wtf(TAG, "Package was null!", new Throwable());
21683            return;
21684        }
21685        prepareAppDataContentsLeafLIF(pkg, userId, flags);
21686        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
21687        for (int i = 0; i < childCount; i++) {
21688            prepareAppDataContentsLeafLIF(pkg.childPackages.get(i), userId, flags);
21689        }
21690    }
21691
21692    private void prepareAppDataContentsLeafLIF(PackageParser.Package pkg, int userId, int flags) {
21693        final String volumeUuid = pkg.volumeUuid;
21694        final String packageName = pkg.packageName;
21695        final ApplicationInfo app = pkg.applicationInfo;
21696
21697        if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
21698            // Create a native library symlink only if we have native libraries
21699            // and if the native libraries are 32 bit libraries. We do not provide
21700            // this symlink for 64 bit libraries.
21701            if (app.primaryCpuAbi != null && !VMRuntime.is64BitAbi(app.primaryCpuAbi)) {
21702                final String nativeLibPath = app.nativeLibraryDir;
21703                try {
21704                    mInstaller.linkNativeLibraryDirectory(volumeUuid, packageName,
21705                            nativeLibPath, userId);
21706                } catch (InstallerException e) {
21707                    Slog.e(TAG, "Failed to link native for " + packageName + ": " + e);
21708                }
21709            }
21710        }
21711    }
21712
21713    /**
21714     * For system apps on non-FBE devices, this method migrates any existing
21715     * CE/DE data to match the {@code defaultToDeviceProtectedStorage} flag
21716     * requested by the app.
21717     */
21718    private boolean maybeMigrateAppDataLIF(PackageParser.Package pkg, int userId) {
21719        if (pkg.isSystemApp() && !StorageManager.isFileEncryptedNativeOrEmulated()
21720                && PackageManager.APPLY_DEFAULT_TO_DEVICE_PROTECTED_STORAGE) {
21721            final int storageTarget = pkg.applicationInfo.isDefaultToDeviceProtectedStorage()
21722                    ? StorageManager.FLAG_STORAGE_DE : StorageManager.FLAG_STORAGE_CE;
21723            try {
21724                mInstaller.migrateAppData(pkg.volumeUuid, pkg.packageName, userId,
21725                        storageTarget);
21726            } catch (InstallerException e) {
21727                logCriticalInfo(Log.WARN,
21728                        "Failed to migrate " + pkg.packageName + ": " + e.getMessage());
21729            }
21730            return true;
21731        } else {
21732            return false;
21733        }
21734    }
21735
21736    public PackageFreezer freezePackage(String packageName, String killReason) {
21737        return freezePackage(packageName, UserHandle.USER_ALL, killReason);
21738    }
21739
21740    public PackageFreezer freezePackage(String packageName, int userId, String killReason) {
21741        return new PackageFreezer(packageName, userId, killReason);
21742    }
21743
21744    public PackageFreezer freezePackageForInstall(String packageName, int installFlags,
21745            String killReason) {
21746        return freezePackageForInstall(packageName, UserHandle.USER_ALL, installFlags, killReason);
21747    }
21748
21749    public PackageFreezer freezePackageForInstall(String packageName, int userId, int installFlags,
21750            String killReason) {
21751        if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) {
21752            return new PackageFreezer();
21753        } else {
21754            return freezePackage(packageName, userId, killReason);
21755        }
21756    }
21757
21758    public PackageFreezer freezePackageForDelete(String packageName, int deleteFlags,
21759            String killReason) {
21760        return freezePackageForDelete(packageName, UserHandle.USER_ALL, deleteFlags, killReason);
21761    }
21762
21763    public PackageFreezer freezePackageForDelete(String packageName, int userId, int deleteFlags,
21764            String killReason) {
21765        if ((deleteFlags & PackageManager.DELETE_DONT_KILL_APP) != 0) {
21766            return new PackageFreezer();
21767        } else {
21768            return freezePackage(packageName, userId, killReason);
21769        }
21770    }
21771
21772    /**
21773     * Class that freezes and kills the given package upon creation, and
21774     * unfreezes it upon closing. This is typically used when doing surgery on
21775     * app code/data to prevent the app from running while you're working.
21776     */
21777    private class PackageFreezer implements AutoCloseable {
21778        private final String mPackageName;
21779        private final PackageFreezer[] mChildren;
21780
21781        private final boolean mWeFroze;
21782
21783        private final AtomicBoolean mClosed = new AtomicBoolean();
21784        private final CloseGuard mCloseGuard = CloseGuard.get();
21785
21786        /**
21787         * Create and return a stub freezer that doesn't actually do anything,
21788         * typically used when someone requested
21789         * {@link PackageManager#INSTALL_DONT_KILL_APP} or
21790         * {@link PackageManager#DELETE_DONT_KILL_APP}.
21791         */
21792        public PackageFreezer() {
21793            mPackageName = null;
21794            mChildren = null;
21795            mWeFroze = false;
21796            mCloseGuard.open("close");
21797        }
21798
21799        public PackageFreezer(String packageName, int userId, String killReason) {
21800            synchronized (mPackages) {
21801                mPackageName = packageName;
21802                mWeFroze = mFrozenPackages.add(mPackageName);
21803
21804                final PackageSetting ps = mSettings.mPackages.get(mPackageName);
21805                if (ps != null) {
21806                    killApplication(ps.name, ps.appId, userId, killReason);
21807                }
21808
21809                final PackageParser.Package p = mPackages.get(packageName);
21810                if (p != null && p.childPackages != null) {
21811                    final int N = p.childPackages.size();
21812                    mChildren = new PackageFreezer[N];
21813                    for (int i = 0; i < N; i++) {
21814                        mChildren[i] = new PackageFreezer(p.childPackages.get(i).packageName,
21815                                userId, killReason);
21816                    }
21817                } else {
21818                    mChildren = null;
21819                }
21820            }
21821            mCloseGuard.open("close");
21822        }
21823
21824        @Override
21825        protected void finalize() throws Throwable {
21826            try {
21827                mCloseGuard.warnIfOpen();
21828                close();
21829            } finally {
21830                super.finalize();
21831            }
21832        }
21833
21834        @Override
21835        public void close() {
21836            mCloseGuard.close();
21837            if (mClosed.compareAndSet(false, true)) {
21838                synchronized (mPackages) {
21839                    if (mWeFroze) {
21840                        mFrozenPackages.remove(mPackageName);
21841                    }
21842
21843                    if (mChildren != null) {
21844                        for (PackageFreezer freezer : mChildren) {
21845                            freezer.close();
21846                        }
21847                    }
21848                }
21849            }
21850        }
21851    }
21852
21853    /**
21854     * Verify that given package is currently frozen.
21855     */
21856    private void checkPackageFrozen(String packageName) {
21857        synchronized (mPackages) {
21858            if (!mFrozenPackages.contains(packageName)) {
21859                Slog.wtf(TAG, "Expected " + packageName + " to be frozen!", new Throwable());
21860            }
21861        }
21862    }
21863
21864    @Override
21865    public int movePackage(final String packageName, final String volumeUuid) {
21866        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
21867
21868        final UserHandle user = new UserHandle(UserHandle.getCallingUserId());
21869        final int moveId = mNextMoveId.getAndIncrement();
21870        mHandler.post(new Runnable() {
21871            @Override
21872            public void run() {
21873                try {
21874                    movePackageInternal(packageName, volumeUuid, moveId, user);
21875                } catch (PackageManagerException e) {
21876                    Slog.w(TAG, "Failed to move " + packageName, e);
21877                    mMoveCallbacks.notifyStatusChanged(moveId,
21878                            PackageManager.MOVE_FAILED_INTERNAL_ERROR);
21879                }
21880            }
21881        });
21882        return moveId;
21883    }
21884
21885    private void movePackageInternal(final String packageName, final String volumeUuid,
21886            final int moveId, UserHandle user) throws PackageManagerException {
21887        final StorageManager storage = mContext.getSystemService(StorageManager.class);
21888        final PackageManager pm = mContext.getPackageManager();
21889
21890        final boolean currentAsec;
21891        final String currentVolumeUuid;
21892        final File codeFile;
21893        final String installerPackageName;
21894        final String packageAbiOverride;
21895        final int appId;
21896        final String seinfo;
21897        final String label;
21898        final int targetSdkVersion;
21899        final PackageFreezer freezer;
21900        final int[] installedUserIds;
21901
21902        // reader
21903        synchronized (mPackages) {
21904            final PackageParser.Package pkg = mPackages.get(packageName);
21905            final PackageSetting ps = mSettings.mPackages.get(packageName);
21906            if (pkg == null || ps == null) {
21907                throw new PackageManagerException(MOVE_FAILED_DOESNT_EXIST, "Missing package");
21908            }
21909
21910            if (pkg.applicationInfo.isSystemApp()) {
21911                throw new PackageManagerException(MOVE_FAILED_SYSTEM_PACKAGE,
21912                        "Cannot move system application");
21913            }
21914
21915            final boolean isInternalStorage = VolumeInfo.ID_PRIVATE_INTERNAL.equals(volumeUuid);
21916            final boolean allow3rdPartyOnInternal = mContext.getResources().getBoolean(
21917                    com.android.internal.R.bool.config_allow3rdPartyAppOnInternal);
21918            if (isInternalStorage && !allow3rdPartyOnInternal) {
21919                throw new PackageManagerException(MOVE_FAILED_3RD_PARTY_NOT_ALLOWED_ON_INTERNAL,
21920                        "3rd party apps are not allowed on internal storage");
21921            }
21922
21923            if (pkg.applicationInfo.isExternalAsec()) {
21924                currentAsec = true;
21925                currentVolumeUuid = StorageManager.UUID_PRIMARY_PHYSICAL;
21926            } else if (pkg.applicationInfo.isForwardLocked()) {
21927                currentAsec = true;
21928                currentVolumeUuid = "forward_locked";
21929            } else {
21930                currentAsec = false;
21931                currentVolumeUuid = ps.volumeUuid;
21932
21933                final File probe = new File(pkg.codePath);
21934                final File probeOat = new File(probe, "oat");
21935                if (!probe.isDirectory() || !probeOat.isDirectory()) {
21936                    throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
21937                            "Move only supported for modern cluster style installs");
21938                }
21939            }
21940
21941            if (Objects.equals(currentVolumeUuid, volumeUuid)) {
21942                throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
21943                        "Package already moved to " + volumeUuid);
21944            }
21945            if (pkg.applicationInfo.isInternal() && isPackageDeviceAdminOnAnyUser(packageName)) {
21946                throw new PackageManagerException(MOVE_FAILED_DEVICE_ADMIN,
21947                        "Device admin cannot be moved");
21948            }
21949
21950            if (mFrozenPackages.contains(packageName)) {
21951                throw new PackageManagerException(MOVE_FAILED_OPERATION_PENDING,
21952                        "Failed to move already frozen package");
21953            }
21954
21955            codeFile = new File(pkg.codePath);
21956            installerPackageName = ps.installerPackageName;
21957            packageAbiOverride = ps.cpuAbiOverrideString;
21958            appId = UserHandle.getAppId(pkg.applicationInfo.uid);
21959            seinfo = pkg.applicationInfo.seinfo;
21960            label = String.valueOf(pm.getApplicationLabel(pkg.applicationInfo));
21961            targetSdkVersion = pkg.applicationInfo.targetSdkVersion;
21962            freezer = freezePackage(packageName, "movePackageInternal");
21963            installedUserIds = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
21964        }
21965
21966        final Bundle extras = new Bundle();
21967        extras.putString(Intent.EXTRA_PACKAGE_NAME, packageName);
21968        extras.putString(Intent.EXTRA_TITLE, label);
21969        mMoveCallbacks.notifyCreated(moveId, extras);
21970
21971        int installFlags;
21972        final boolean moveCompleteApp;
21973        final File measurePath;
21974
21975        if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, volumeUuid)) {
21976            installFlags = INSTALL_INTERNAL;
21977            moveCompleteApp = !currentAsec;
21978            measurePath = Environment.getDataAppDirectory(volumeUuid);
21979        } else if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, volumeUuid)) {
21980            installFlags = INSTALL_EXTERNAL;
21981            moveCompleteApp = false;
21982            measurePath = storage.getPrimaryPhysicalVolume().getPath();
21983        } else {
21984            final VolumeInfo volume = storage.findVolumeByUuid(volumeUuid);
21985            if (volume == null || volume.getType() != VolumeInfo.TYPE_PRIVATE
21986                    || !volume.isMountedWritable()) {
21987                freezer.close();
21988                throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
21989                        "Move location not mounted private volume");
21990            }
21991
21992            Preconditions.checkState(!currentAsec);
21993
21994            installFlags = INSTALL_INTERNAL;
21995            moveCompleteApp = true;
21996            measurePath = Environment.getDataAppDirectory(volumeUuid);
21997        }
21998
21999        final PackageStats stats = new PackageStats(null, -1);
22000        synchronized (mInstaller) {
22001            for (int userId : installedUserIds) {
22002                if (!getPackageSizeInfoLI(packageName, userId, stats)) {
22003                    freezer.close();
22004                    throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
22005                            "Failed to measure package size");
22006                }
22007            }
22008        }
22009
22010        if (DEBUG_INSTALL) Slog.d(TAG, "Measured code size " + stats.codeSize + ", data size "
22011                + stats.dataSize);
22012
22013        final long startFreeBytes = measurePath.getFreeSpace();
22014        final long sizeBytes;
22015        if (moveCompleteApp) {
22016            sizeBytes = stats.codeSize + stats.dataSize;
22017        } else {
22018            sizeBytes = stats.codeSize;
22019        }
22020
22021        if (sizeBytes > storage.getStorageBytesUntilLow(measurePath)) {
22022            freezer.close();
22023            throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
22024                    "Not enough free space to move");
22025        }
22026
22027        mMoveCallbacks.notifyStatusChanged(moveId, 10);
22028
22029        final CountDownLatch installedLatch = new CountDownLatch(1);
22030        final IPackageInstallObserver2 installObserver = new IPackageInstallObserver2.Stub() {
22031            @Override
22032            public void onUserActionRequired(Intent intent) throws RemoteException {
22033                throw new IllegalStateException();
22034            }
22035
22036            @Override
22037            public void onPackageInstalled(String basePackageName, int returnCode, String msg,
22038                    Bundle extras) throws RemoteException {
22039                if (DEBUG_INSTALL) Slog.d(TAG, "Install result for move: "
22040                        + PackageManager.installStatusToString(returnCode, msg));
22041
22042                installedLatch.countDown();
22043                freezer.close();
22044
22045                final int status = PackageManager.installStatusToPublicStatus(returnCode);
22046                switch (status) {
22047                    case PackageInstaller.STATUS_SUCCESS:
22048                        mMoveCallbacks.notifyStatusChanged(moveId,
22049                                PackageManager.MOVE_SUCCEEDED);
22050                        break;
22051                    case PackageInstaller.STATUS_FAILURE_STORAGE:
22052                        mMoveCallbacks.notifyStatusChanged(moveId,
22053                                PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE);
22054                        break;
22055                    default:
22056                        mMoveCallbacks.notifyStatusChanged(moveId,
22057                                PackageManager.MOVE_FAILED_INTERNAL_ERROR);
22058                        break;
22059                }
22060            }
22061        };
22062
22063        final MoveInfo move;
22064        if (moveCompleteApp) {
22065            // Kick off a thread to report progress estimates
22066            new Thread() {
22067                @Override
22068                public void run() {
22069                    while (true) {
22070                        try {
22071                            if (installedLatch.await(1, TimeUnit.SECONDS)) {
22072                                break;
22073                            }
22074                        } catch (InterruptedException ignored) {
22075                        }
22076
22077                        final long deltaFreeBytes = startFreeBytes - measurePath.getFreeSpace();
22078                        final int progress = 10 + (int) MathUtils.constrain(
22079                                ((deltaFreeBytes * 80) / sizeBytes), 0, 80);
22080                        mMoveCallbacks.notifyStatusChanged(moveId, progress);
22081                    }
22082                }
22083            }.start();
22084
22085            final String dataAppName = codeFile.getName();
22086            move = new MoveInfo(moveId, currentVolumeUuid, volumeUuid, packageName,
22087                    dataAppName, appId, seinfo, targetSdkVersion);
22088        } else {
22089            move = null;
22090        }
22091
22092        installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
22093
22094        final Message msg = mHandler.obtainMessage(INIT_COPY);
22095        final OriginInfo origin = OriginInfo.fromExistingFile(codeFile);
22096        final InstallParams params = new InstallParams(origin, move, installObserver, installFlags,
22097                installerPackageName, volumeUuid, null /*verificationInfo*/, user,
22098                packageAbiOverride, null /*grantedPermissions*/, null /*certificates*/,
22099                PackageManager.INSTALL_REASON_UNKNOWN);
22100        params.setTraceMethod("movePackage").setTraceCookie(System.identityHashCode(params));
22101        msg.obj = params;
22102
22103        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "movePackage",
22104                System.identityHashCode(msg.obj));
22105        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
22106                System.identityHashCode(msg.obj));
22107
22108        mHandler.sendMessage(msg);
22109    }
22110
22111    @Override
22112    public int movePrimaryStorage(String volumeUuid) throws RemoteException {
22113        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
22114
22115        final int realMoveId = mNextMoveId.getAndIncrement();
22116        final Bundle extras = new Bundle();
22117        extras.putString(VolumeRecord.EXTRA_FS_UUID, volumeUuid);
22118        mMoveCallbacks.notifyCreated(realMoveId, extras);
22119
22120        final IPackageMoveObserver callback = new IPackageMoveObserver.Stub() {
22121            @Override
22122            public void onCreated(int moveId, Bundle extras) {
22123                // Ignored
22124            }
22125
22126            @Override
22127            public void onStatusChanged(int moveId, int status, long estMillis) {
22128                mMoveCallbacks.notifyStatusChanged(realMoveId, status, estMillis);
22129            }
22130        };
22131
22132        final StorageManager storage = mContext.getSystemService(StorageManager.class);
22133        storage.setPrimaryStorageUuid(volumeUuid, callback);
22134        return realMoveId;
22135    }
22136
22137    @Override
22138    public int getMoveStatus(int moveId) {
22139        mContext.enforceCallingOrSelfPermission(
22140                android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
22141        return mMoveCallbacks.mLastStatus.get(moveId);
22142    }
22143
22144    @Override
22145    public void registerMoveCallback(IPackageMoveObserver callback) {
22146        mContext.enforceCallingOrSelfPermission(
22147                android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
22148        mMoveCallbacks.register(callback);
22149    }
22150
22151    @Override
22152    public void unregisterMoveCallback(IPackageMoveObserver callback) {
22153        mContext.enforceCallingOrSelfPermission(
22154                android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
22155        mMoveCallbacks.unregister(callback);
22156    }
22157
22158    @Override
22159    public boolean setInstallLocation(int loc) {
22160        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS,
22161                null);
22162        if (getInstallLocation() == loc) {
22163            return true;
22164        }
22165        if (loc == PackageHelper.APP_INSTALL_AUTO || loc == PackageHelper.APP_INSTALL_INTERNAL
22166                || loc == PackageHelper.APP_INSTALL_EXTERNAL) {
22167            android.provider.Settings.Global.putInt(mContext.getContentResolver(),
22168                    android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, loc);
22169            return true;
22170        }
22171        return false;
22172   }
22173
22174    @Override
22175    public int getInstallLocation() {
22176        return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
22177                android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION,
22178                PackageHelper.APP_INSTALL_AUTO);
22179    }
22180
22181    /** Called by UserManagerService */
22182    void cleanUpUser(UserManagerService userManager, int userHandle) {
22183        synchronized (mPackages) {
22184            mDirtyUsers.remove(userHandle);
22185            mUserNeedsBadging.delete(userHandle);
22186            mSettings.removeUserLPw(userHandle);
22187            mPendingBroadcasts.remove(userHandle);
22188            mInstantAppRegistry.onUserRemovedLPw(userHandle);
22189            removeUnusedPackagesLPw(userManager, userHandle);
22190        }
22191    }
22192
22193    /**
22194     * We're removing userHandle and would like to remove any downloaded packages
22195     * that are no longer in use by any other user.
22196     * @param userHandle the user being removed
22197     */
22198    private void removeUnusedPackagesLPw(UserManagerService userManager, final int userHandle) {
22199        final boolean DEBUG_CLEAN_APKS = false;
22200        int [] users = userManager.getUserIds();
22201        Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
22202        while (psit.hasNext()) {
22203            PackageSetting ps = psit.next();
22204            if (ps.pkg == null) {
22205                continue;
22206            }
22207            final String packageName = ps.pkg.packageName;
22208            // Skip over if system app
22209            if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) {
22210                continue;
22211            }
22212            if (DEBUG_CLEAN_APKS) {
22213                Slog.i(TAG, "Checking package " + packageName);
22214            }
22215            boolean keep = shouldKeepUninstalledPackageLPr(packageName);
22216            if (keep) {
22217                if (DEBUG_CLEAN_APKS) {
22218                    Slog.i(TAG, "  Keeping package " + packageName + " - requested by DO");
22219                }
22220            } else {
22221                for (int i = 0; i < users.length; i++) {
22222                    if (users[i] != userHandle && ps.getInstalled(users[i])) {
22223                        keep = true;
22224                        if (DEBUG_CLEAN_APKS) {
22225                            Slog.i(TAG, "  Keeping package " + packageName + " for user "
22226                                    + users[i]);
22227                        }
22228                        break;
22229                    }
22230                }
22231            }
22232            if (!keep) {
22233                if (DEBUG_CLEAN_APKS) {
22234                    Slog.i(TAG, "  Removing package " + packageName);
22235                }
22236                mHandler.post(new Runnable() {
22237                    public void run() {
22238                        deletePackageX(packageName, PackageManager.VERSION_CODE_HIGHEST,
22239                                userHandle, 0);
22240                    } //end run
22241                });
22242            }
22243        }
22244    }
22245
22246    /** Called by UserManagerService */
22247    void createNewUser(int userId, String[] disallowedPackages) {
22248        synchronized (mInstallLock) {
22249            mSettings.createNewUserLI(this, mInstaller, userId, disallowedPackages);
22250        }
22251        synchronized (mPackages) {
22252            scheduleWritePackageRestrictionsLocked(userId);
22253            scheduleWritePackageListLocked(userId);
22254            applyFactoryDefaultBrowserLPw(userId);
22255            primeDomainVerificationsLPw(userId);
22256        }
22257    }
22258
22259    void onNewUserCreated(final int userId) {
22260        mDefaultPermissionPolicy.grantDefaultPermissions(userId);
22261        // If permission review for legacy apps is required, we represent
22262        // dagerous permissions for such apps as always granted runtime
22263        // permissions to keep per user flag state whether review is needed.
22264        // Hence, if a new user is added we have to propagate dangerous
22265        // permission grants for these legacy apps.
22266        if (mPermissionReviewRequired) {
22267            updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL
22268                    | UPDATE_PERMISSIONS_REPLACE_ALL);
22269        }
22270    }
22271
22272    @Override
22273    public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException {
22274        mContext.enforceCallingOrSelfPermission(
22275                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
22276                "Only package verification agents can read the verifier device identity");
22277
22278        synchronized (mPackages) {
22279            return mSettings.getVerifierDeviceIdentityLPw();
22280        }
22281    }
22282
22283    @Override
22284    public void setPermissionEnforced(String permission, boolean enforced) {
22285        // TODO: Now that we no longer change GID for storage, this should to away.
22286        mContext.enforceCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
22287                "setPermissionEnforced");
22288        if (READ_EXTERNAL_STORAGE.equals(permission)) {
22289            synchronized (mPackages) {
22290                if (mSettings.mReadExternalStorageEnforced == null
22291                        || mSettings.mReadExternalStorageEnforced != enforced) {
22292                    mSettings.mReadExternalStorageEnforced = enforced;
22293                    mSettings.writeLPr();
22294                }
22295            }
22296            // kill any non-foreground processes so we restart them and
22297            // grant/revoke the GID.
22298            final IActivityManager am = ActivityManager.getService();
22299            if (am != null) {
22300                final long token = Binder.clearCallingIdentity();
22301                try {
22302                    am.killProcessesBelowForeground("setPermissionEnforcement");
22303                } catch (RemoteException e) {
22304                } finally {
22305                    Binder.restoreCallingIdentity(token);
22306                }
22307            }
22308        } else {
22309            throw new IllegalArgumentException("No selective enforcement for " + permission);
22310        }
22311    }
22312
22313    @Override
22314    @Deprecated
22315    public boolean isPermissionEnforced(String permission) {
22316        return true;
22317    }
22318
22319    @Override
22320    public boolean isStorageLow() {
22321        final long token = Binder.clearCallingIdentity();
22322        try {
22323            final DeviceStorageMonitorInternal
22324                    dsm = LocalServices.getService(DeviceStorageMonitorInternal.class);
22325            if (dsm != null) {
22326                return dsm.isMemoryLow();
22327            } else {
22328                return false;
22329            }
22330        } finally {
22331            Binder.restoreCallingIdentity(token);
22332        }
22333    }
22334
22335    @Override
22336    public IPackageInstaller getPackageInstaller() {
22337        return mInstallerService;
22338    }
22339
22340    private boolean userNeedsBadging(int userId) {
22341        int index = mUserNeedsBadging.indexOfKey(userId);
22342        if (index < 0) {
22343            final UserInfo userInfo;
22344            final long token = Binder.clearCallingIdentity();
22345            try {
22346                userInfo = sUserManager.getUserInfo(userId);
22347            } finally {
22348                Binder.restoreCallingIdentity(token);
22349            }
22350            final boolean b;
22351            if (userInfo != null && userInfo.isManagedProfile()) {
22352                b = true;
22353            } else {
22354                b = false;
22355            }
22356            mUserNeedsBadging.put(userId, b);
22357            return b;
22358        }
22359        return mUserNeedsBadging.valueAt(index);
22360    }
22361
22362    @Override
22363    public KeySet getKeySetByAlias(String packageName, String alias) {
22364        if (packageName == null || alias == null) {
22365            return null;
22366        }
22367        synchronized(mPackages) {
22368            final PackageParser.Package pkg = mPackages.get(packageName);
22369            if (pkg == null) {
22370                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
22371                throw new IllegalArgumentException("Unknown package: " + packageName);
22372            }
22373            KeySetManagerService ksms = mSettings.mKeySetManagerService;
22374            return new KeySet(ksms.getKeySetByAliasAndPackageNameLPr(packageName, alias));
22375        }
22376    }
22377
22378    @Override
22379    public KeySet getSigningKeySet(String packageName) {
22380        if (packageName == null) {
22381            return null;
22382        }
22383        synchronized(mPackages) {
22384            final PackageParser.Package pkg = mPackages.get(packageName);
22385            if (pkg == null) {
22386                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
22387                throw new IllegalArgumentException("Unknown package: " + packageName);
22388            }
22389            if (pkg.applicationInfo.uid != Binder.getCallingUid()
22390                    && Process.SYSTEM_UID != Binder.getCallingUid()) {
22391                throw new SecurityException("May not access signing KeySet of other apps.");
22392            }
22393            KeySetManagerService ksms = mSettings.mKeySetManagerService;
22394            return new KeySet(ksms.getSigningKeySetByPackageNameLPr(packageName));
22395        }
22396    }
22397
22398    @Override
22399    public boolean isPackageSignedByKeySet(String packageName, KeySet ks) {
22400        if (packageName == null || ks == null) {
22401            return false;
22402        }
22403        synchronized(mPackages) {
22404            final PackageParser.Package pkg = mPackages.get(packageName);
22405            if (pkg == null) {
22406                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
22407                throw new IllegalArgumentException("Unknown package: " + packageName);
22408            }
22409            IBinder ksh = ks.getToken();
22410            if (ksh instanceof KeySetHandle) {
22411                KeySetManagerService ksms = mSettings.mKeySetManagerService;
22412                return ksms.packageIsSignedByLPr(packageName, (KeySetHandle) ksh);
22413            }
22414            return false;
22415        }
22416    }
22417
22418    @Override
22419    public boolean isPackageSignedByKeySetExactly(String packageName, KeySet ks) {
22420        if (packageName == null || ks == null) {
22421            return false;
22422        }
22423        synchronized(mPackages) {
22424            final PackageParser.Package pkg = mPackages.get(packageName);
22425            if (pkg == null) {
22426                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
22427                throw new IllegalArgumentException("Unknown package: " + packageName);
22428            }
22429            IBinder ksh = ks.getToken();
22430            if (ksh instanceof KeySetHandle) {
22431                KeySetManagerService ksms = mSettings.mKeySetManagerService;
22432                return ksms.packageIsSignedByExactlyLPr(packageName, (KeySetHandle) ksh);
22433            }
22434            return false;
22435        }
22436    }
22437
22438    private void deletePackageIfUnusedLPr(final String packageName) {
22439        PackageSetting ps = mSettings.mPackages.get(packageName);
22440        if (ps == null) {
22441            return;
22442        }
22443        if (!ps.isAnyInstalled(sUserManager.getUserIds())) {
22444            // TODO Implement atomic delete if package is unused
22445            // It is currently possible that the package will be deleted even if it is installed
22446            // after this method returns.
22447            mHandler.post(new Runnable() {
22448                public void run() {
22449                    deletePackageX(packageName, PackageManager.VERSION_CODE_HIGHEST,
22450                            0, PackageManager.DELETE_ALL_USERS);
22451                }
22452            });
22453        }
22454    }
22455
22456    /**
22457     * Check and throw if the given before/after packages would be considered a
22458     * downgrade.
22459     */
22460    private static void checkDowngrade(PackageParser.Package before, PackageInfoLite after)
22461            throws PackageManagerException {
22462        if (after.versionCode < before.mVersionCode) {
22463            throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
22464                    "Update version code " + after.versionCode + " is older than current "
22465                    + before.mVersionCode);
22466        } else if (after.versionCode == before.mVersionCode) {
22467            if (after.baseRevisionCode < before.baseRevisionCode) {
22468                throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
22469                        "Update base revision code " + after.baseRevisionCode
22470                        + " is older than current " + before.baseRevisionCode);
22471            }
22472
22473            if (!ArrayUtils.isEmpty(after.splitNames)) {
22474                for (int i = 0; i < after.splitNames.length; i++) {
22475                    final String splitName = after.splitNames[i];
22476                    final int j = ArrayUtils.indexOf(before.splitNames, splitName);
22477                    if (j != -1) {
22478                        if (after.splitRevisionCodes[i] < before.splitRevisionCodes[j]) {
22479                            throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
22480                                    "Update split " + splitName + " revision code "
22481                                    + after.splitRevisionCodes[i] + " is older than current "
22482                                    + before.splitRevisionCodes[j]);
22483                        }
22484                    }
22485                }
22486            }
22487        }
22488    }
22489
22490    private static class MoveCallbacks extends Handler {
22491        private static final int MSG_CREATED = 1;
22492        private static final int MSG_STATUS_CHANGED = 2;
22493
22494        private final RemoteCallbackList<IPackageMoveObserver>
22495                mCallbacks = new RemoteCallbackList<>();
22496
22497        private final SparseIntArray mLastStatus = new SparseIntArray();
22498
22499        public MoveCallbacks(Looper looper) {
22500            super(looper);
22501        }
22502
22503        public void register(IPackageMoveObserver callback) {
22504            mCallbacks.register(callback);
22505        }
22506
22507        public void unregister(IPackageMoveObserver callback) {
22508            mCallbacks.unregister(callback);
22509        }
22510
22511        @Override
22512        public void handleMessage(Message msg) {
22513            final SomeArgs args = (SomeArgs) msg.obj;
22514            final int n = mCallbacks.beginBroadcast();
22515            for (int i = 0; i < n; i++) {
22516                final IPackageMoveObserver callback = mCallbacks.getBroadcastItem(i);
22517                try {
22518                    invokeCallback(callback, msg.what, args);
22519                } catch (RemoteException ignored) {
22520                }
22521            }
22522            mCallbacks.finishBroadcast();
22523            args.recycle();
22524        }
22525
22526        private void invokeCallback(IPackageMoveObserver callback, int what, SomeArgs args)
22527                throws RemoteException {
22528            switch (what) {
22529                case MSG_CREATED: {
22530                    callback.onCreated(args.argi1, (Bundle) args.arg2);
22531                    break;
22532                }
22533                case MSG_STATUS_CHANGED: {
22534                    callback.onStatusChanged(args.argi1, args.argi2, (long) args.arg3);
22535                    break;
22536                }
22537            }
22538        }
22539
22540        private void notifyCreated(int moveId, Bundle extras) {
22541            Slog.v(TAG, "Move " + moveId + " created " + extras.toString());
22542
22543            final SomeArgs args = SomeArgs.obtain();
22544            args.argi1 = moveId;
22545            args.arg2 = extras;
22546            obtainMessage(MSG_CREATED, args).sendToTarget();
22547        }
22548
22549        private void notifyStatusChanged(int moveId, int status) {
22550            notifyStatusChanged(moveId, status, -1);
22551        }
22552
22553        private void notifyStatusChanged(int moveId, int status, long estMillis) {
22554            Slog.v(TAG, "Move " + moveId + " status " + status);
22555
22556            final SomeArgs args = SomeArgs.obtain();
22557            args.argi1 = moveId;
22558            args.argi2 = status;
22559            args.arg3 = estMillis;
22560            obtainMessage(MSG_STATUS_CHANGED, args).sendToTarget();
22561
22562            synchronized (mLastStatus) {
22563                mLastStatus.put(moveId, status);
22564            }
22565        }
22566    }
22567
22568    private final static class OnPermissionChangeListeners extends Handler {
22569        private static final int MSG_ON_PERMISSIONS_CHANGED = 1;
22570
22571        private final RemoteCallbackList<IOnPermissionsChangeListener> mPermissionListeners =
22572                new RemoteCallbackList<>();
22573
22574        public OnPermissionChangeListeners(Looper looper) {
22575            super(looper);
22576        }
22577
22578        @Override
22579        public void handleMessage(Message msg) {
22580            switch (msg.what) {
22581                case MSG_ON_PERMISSIONS_CHANGED: {
22582                    final int uid = msg.arg1;
22583                    handleOnPermissionsChanged(uid);
22584                } break;
22585            }
22586        }
22587
22588        public void addListenerLocked(IOnPermissionsChangeListener listener) {
22589            mPermissionListeners.register(listener);
22590
22591        }
22592
22593        public void removeListenerLocked(IOnPermissionsChangeListener listener) {
22594            mPermissionListeners.unregister(listener);
22595        }
22596
22597        public void onPermissionsChanged(int uid) {
22598            if (mPermissionListeners.getRegisteredCallbackCount() > 0) {
22599                obtainMessage(MSG_ON_PERMISSIONS_CHANGED, uid, 0).sendToTarget();
22600            }
22601        }
22602
22603        private void handleOnPermissionsChanged(int uid) {
22604            final int count = mPermissionListeners.beginBroadcast();
22605            try {
22606                for (int i = 0; i < count; i++) {
22607                    IOnPermissionsChangeListener callback = mPermissionListeners
22608                            .getBroadcastItem(i);
22609                    try {
22610                        callback.onPermissionsChanged(uid);
22611                    } catch (RemoteException e) {
22612                        Log.e(TAG, "Permission listener is dead", e);
22613                    }
22614                }
22615            } finally {
22616                mPermissionListeners.finishBroadcast();
22617            }
22618        }
22619    }
22620
22621    private class PackageManagerInternalImpl extends PackageManagerInternal {
22622        @Override
22623        public void setLocationPackagesProvider(PackagesProvider provider) {
22624            synchronized (mPackages) {
22625                mDefaultPermissionPolicy.setLocationPackagesProviderLPw(provider);
22626            }
22627        }
22628
22629        @Override
22630        public void setVoiceInteractionPackagesProvider(PackagesProvider provider) {
22631            synchronized (mPackages) {
22632                mDefaultPermissionPolicy.setVoiceInteractionPackagesProviderLPw(provider);
22633            }
22634        }
22635
22636        @Override
22637        public void setSmsAppPackagesProvider(PackagesProvider provider) {
22638            synchronized (mPackages) {
22639                mDefaultPermissionPolicy.setSmsAppPackagesProviderLPw(provider);
22640            }
22641        }
22642
22643        @Override
22644        public void setDialerAppPackagesProvider(PackagesProvider provider) {
22645            synchronized (mPackages) {
22646                mDefaultPermissionPolicy.setDialerAppPackagesProviderLPw(provider);
22647            }
22648        }
22649
22650        @Override
22651        public void setSimCallManagerPackagesProvider(PackagesProvider provider) {
22652            synchronized (mPackages) {
22653                mDefaultPermissionPolicy.setSimCallManagerPackagesProviderLPw(provider);
22654            }
22655        }
22656
22657        @Override
22658        public void setSyncAdapterPackagesprovider(SyncAdapterPackagesProvider provider) {
22659            synchronized (mPackages) {
22660                mDefaultPermissionPolicy.setSyncAdapterPackagesProviderLPw(provider);
22661            }
22662        }
22663
22664        @Override
22665        public void grantDefaultPermissionsToDefaultSmsApp(String packageName, int userId) {
22666            synchronized (mPackages) {
22667                mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSmsAppLPr(
22668                        packageName, userId);
22669            }
22670        }
22671
22672        @Override
22673        public void grantDefaultPermissionsToDefaultDialerApp(String packageName, int userId) {
22674            synchronized (mPackages) {
22675                mSettings.setDefaultDialerPackageNameLPw(packageName, userId);
22676                mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultDialerAppLPr(
22677                        packageName, userId);
22678            }
22679        }
22680
22681        @Override
22682        public void grantDefaultPermissionsToDefaultSimCallManager(String packageName, int userId) {
22683            synchronized (mPackages) {
22684                mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSimCallManagerLPr(
22685                        packageName, userId);
22686            }
22687        }
22688
22689        @Override
22690        public void setKeepUninstalledPackages(final List<String> packageList) {
22691            Preconditions.checkNotNull(packageList);
22692            List<String> removedFromList = null;
22693            synchronized (mPackages) {
22694                if (mKeepUninstalledPackages != null) {
22695                    final int packagesCount = mKeepUninstalledPackages.size();
22696                    for (int i = 0; i < packagesCount; i++) {
22697                        String oldPackage = mKeepUninstalledPackages.get(i);
22698                        if (packageList != null && packageList.contains(oldPackage)) {
22699                            continue;
22700                        }
22701                        if (removedFromList == null) {
22702                            removedFromList = new ArrayList<>();
22703                        }
22704                        removedFromList.add(oldPackage);
22705                    }
22706                }
22707                mKeepUninstalledPackages = new ArrayList<>(packageList);
22708                if (removedFromList != null) {
22709                    final int removedCount = removedFromList.size();
22710                    for (int i = 0; i < removedCount; i++) {
22711                        deletePackageIfUnusedLPr(removedFromList.get(i));
22712                    }
22713                }
22714            }
22715        }
22716
22717        @Override
22718        public boolean isPermissionsReviewRequired(String packageName, int userId) {
22719            synchronized (mPackages) {
22720                // If we do not support permission review, done.
22721                if (!mPermissionReviewRequired) {
22722                    return false;
22723                }
22724
22725                PackageSetting packageSetting = mSettings.mPackages.get(packageName);
22726                if (packageSetting == null) {
22727                    return false;
22728                }
22729
22730                // Permission review applies only to apps not supporting the new permission model.
22731                if (packageSetting.pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.M) {
22732                    return false;
22733                }
22734
22735                // Legacy apps have the permission and get user consent on launch.
22736                PermissionsState permissionsState = packageSetting.getPermissionsState();
22737                return permissionsState.isPermissionReviewRequired(userId);
22738            }
22739        }
22740
22741        @Override
22742        public ApplicationInfo getApplicationInfo(String packageName, int userId) {
22743            return PackageManagerService.this.getApplicationInfo(packageName, 0 /*flags*/, userId);
22744        }
22745
22746        @Override
22747        public ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates,
22748                int userId) {
22749            return PackageManagerService.this.getHomeActivitiesAsUser(allHomeCandidates, userId);
22750        }
22751
22752        @Override
22753        public void setDeviceAndProfileOwnerPackages(
22754                int deviceOwnerUserId, String deviceOwnerPackage,
22755                SparseArray<String> profileOwnerPackages) {
22756            mProtectedPackages.setDeviceAndProfileOwnerPackages(
22757                    deviceOwnerUserId, deviceOwnerPackage, profileOwnerPackages);
22758        }
22759
22760        @Override
22761        public boolean isPackageDataProtected(int userId, String packageName) {
22762            return mProtectedPackages.isPackageDataProtected(userId, packageName);
22763        }
22764
22765        @Override
22766        public boolean isPackageEphemeral(int userId, String packageName) {
22767            synchronized (mPackages) {
22768                PackageParser.Package p = mPackages.get(packageName);
22769                return p != null ? p.applicationInfo.isInstantApp() : false;
22770            }
22771        }
22772
22773        @Override
22774        public boolean wasPackageEverLaunched(String packageName, int userId) {
22775            synchronized (mPackages) {
22776                return mSettings.wasPackageEverLaunchedLPr(packageName, userId);
22777            }
22778        }
22779
22780        @Override
22781        public void grantRuntimePermission(String packageName, String name, int userId,
22782                boolean overridePolicy) {
22783            PackageManagerService.this.grantRuntimePermission(packageName, name, userId,
22784                    overridePolicy);
22785        }
22786
22787        @Override
22788        public void revokeRuntimePermission(String packageName, String name, int userId,
22789                boolean overridePolicy) {
22790            PackageManagerService.this.revokeRuntimePermission(packageName, name, userId,
22791                    overridePolicy);
22792        }
22793
22794        @Override
22795        public String getNameForUid(int uid) {
22796            return PackageManagerService.this.getNameForUid(uid);
22797        }
22798
22799        @Override
22800        public void requestEphemeralResolutionPhaseTwo(EphemeralResponse responseObj,
22801                Intent origIntent, String resolvedType, Intent launchIntent,
22802                String callingPackage, int userId) {
22803            PackageManagerService.this.requestEphemeralResolutionPhaseTwo(
22804                    responseObj, origIntent, resolvedType, launchIntent, callingPackage, userId);
22805        }
22806
22807        @Override
22808        public void grantEphemeralAccess(int userId, Intent intent,
22809                int targetAppId, int ephemeralAppId) {
22810            synchronized (mPackages) {
22811                mInstantAppRegistry.grantInstantAccessLPw(userId, intent,
22812                        targetAppId, ephemeralAppId);
22813            }
22814        }
22815
22816        @Override
22817        public void pruneInstantApps() {
22818            synchronized (mPackages) {
22819                mInstantAppRegistry.pruneInstantAppsLPw();
22820            }
22821        }
22822
22823        @Override
22824        public String getSetupWizardPackageName() {
22825            return mSetupWizardPackage;
22826        }
22827
22828        public void setExternalSourcesPolicy(ExternalSourcesPolicy policy) {
22829            if (policy != null) {
22830                mExternalSourcesPolicy = policy;
22831            }
22832        }
22833
22834        @Override
22835        public List<PackageInfo> getOverlayPackages(int userId) {
22836            final ArrayList<PackageInfo> overlayPackages = new ArrayList<PackageInfo>();
22837            synchronized (mPackages) {
22838                for (PackageParser.Package p : mPackages.values()) {
22839                    if (p.mOverlayTarget != null) {
22840                        PackageInfo pkg = generatePackageInfo((PackageSetting)p.mExtras, 0, userId);
22841                        if (pkg != null) {
22842                            overlayPackages.add(pkg);
22843                        }
22844                    }
22845                }
22846            }
22847            return overlayPackages;
22848        }
22849
22850        @Override
22851        public List<String> getTargetPackageNames(int userId) {
22852            List<String> targetPackages = new ArrayList<>();
22853            synchronized (mPackages) {
22854                for (PackageParser.Package p : mPackages.values()) {
22855                    if (p.mOverlayTarget == null) {
22856                        targetPackages.add(p.packageName);
22857                    }
22858                }
22859            }
22860            return targetPackages;
22861        }
22862
22863
22864        @Override
22865        public boolean setEnabledOverlayPackages(int userId, String targetPackageName,
22866                List<String> overlayPackageNames) {
22867            // TODO: implement when we integrate OMS properly
22868            return false;
22869        }
22870    }
22871
22872    @Override
22873    public void grantDefaultPermissionsToEnabledCarrierApps(String[] packageNames, int userId) {
22874        enforceSystemOrPhoneCaller("grantPermissionsToEnabledCarrierApps");
22875        synchronized (mPackages) {
22876            final long identity = Binder.clearCallingIdentity();
22877            try {
22878                mDefaultPermissionPolicy.grantDefaultPermissionsToEnabledCarrierAppsLPr(
22879                        packageNames, userId);
22880            } finally {
22881                Binder.restoreCallingIdentity(identity);
22882            }
22883        }
22884    }
22885
22886    @Override
22887    public void grantDefaultPermissionsToEnabledImsServices(String[] packageNames, int userId) {
22888        enforceSystemOrPhoneCaller("grantDefaultPermissionsToEnabledImsServices");
22889        synchronized (mPackages) {
22890            final long identity = Binder.clearCallingIdentity();
22891            try {
22892                mDefaultPermissionPolicy.grantDefaultPermissionsToEnabledImsServicesLPr(
22893                        packageNames, userId);
22894            } finally {
22895                Binder.restoreCallingIdentity(identity);
22896            }
22897        }
22898    }
22899
22900    private static void enforceSystemOrPhoneCaller(String tag) {
22901        int callingUid = Binder.getCallingUid();
22902        if (callingUid != Process.PHONE_UID && callingUid != Process.SYSTEM_UID) {
22903            throw new SecurityException(
22904                    "Cannot call " + tag + " from UID " + callingUid);
22905        }
22906    }
22907
22908    boolean isHistoricalPackageUsageAvailable() {
22909        return mPackageUsage.isHistoricalPackageUsageAvailable();
22910    }
22911
22912    /**
22913     * Return a <b>copy</b> of the collection of packages known to the package manager.
22914     * @return A copy of the values of mPackages.
22915     */
22916    Collection<PackageParser.Package> getPackages() {
22917        synchronized (mPackages) {
22918            return new ArrayList<>(mPackages.values());
22919        }
22920    }
22921
22922    /**
22923     * Logs process start information (including base APK hash) to the security log.
22924     * @hide
22925     */
22926    public void logAppProcessStartIfNeeded(String processName, int uid, String seinfo,
22927            String apkFile, int pid) {
22928        if (!SecurityLog.isLoggingEnabled()) {
22929            return;
22930        }
22931        Bundle data = new Bundle();
22932        data.putLong("startTimestamp", System.currentTimeMillis());
22933        data.putString("processName", processName);
22934        data.putInt("uid", uid);
22935        data.putString("seinfo", seinfo);
22936        data.putString("apkFile", apkFile);
22937        data.putInt("pid", pid);
22938        Message msg = mProcessLoggingHandler.obtainMessage(
22939                ProcessLoggingHandler.LOG_APP_PROCESS_START_MSG);
22940        msg.setData(data);
22941        mProcessLoggingHandler.sendMessage(msg);
22942    }
22943
22944    public CompilerStats.PackageStats getCompilerPackageStats(String pkgName) {
22945        return mCompilerStats.getPackageStats(pkgName);
22946    }
22947
22948    public CompilerStats.PackageStats getOrCreateCompilerPackageStats(PackageParser.Package pkg) {
22949        return getOrCreateCompilerPackageStats(pkg.packageName);
22950    }
22951
22952    public CompilerStats.PackageStats getOrCreateCompilerPackageStats(String pkgName) {
22953        return mCompilerStats.getOrCreatePackageStats(pkgName);
22954    }
22955
22956    public void deleteCompilerPackageStats(String pkgName) {
22957        mCompilerStats.deletePackageStats(pkgName);
22958    }
22959
22960    @Override
22961    public int getInstallReason(String packageName, int userId) {
22962        enforceCrossUserPermission(Binder.getCallingUid(), userId,
22963                true /* requireFullPermission */, false /* checkShell */,
22964                "get install reason");
22965        synchronized (mPackages) {
22966            final PackageSetting ps = mSettings.mPackages.get(packageName);
22967            if (ps != null) {
22968                return ps.getInstallReason(userId);
22969            }
22970        }
22971        return PackageManager.INSTALL_REASON_UNKNOWN;
22972    }
22973
22974    @Override
22975    public boolean canRequestPackageInstalls(String packageName, int userId) {
22976        int callingUid = Binder.getCallingUid();
22977        int uid = getPackageUid(packageName, 0, userId);
22978        if (callingUid != uid && callingUid != Process.ROOT_UID
22979                && callingUid != Process.SYSTEM_UID) {
22980            throw new SecurityException(
22981                    "Caller uid " + callingUid + " does not own package " + packageName);
22982        }
22983        ApplicationInfo info = getApplicationInfo(packageName, 0, userId);
22984        if (info == null) {
22985            return false;
22986        }
22987        if (info.targetSdkVersion < Build.VERSION_CODES.O) {
22988            throw new UnsupportedOperationException(
22989                    "Operation only supported on apps targeting Android O or higher");
22990        }
22991        String appOpPermission = Manifest.permission.REQUEST_INSTALL_PACKAGES;
22992        String[] packagesDeclaringPermission = getAppOpPermissionPackages(appOpPermission);
22993        if (!ArrayUtils.contains(packagesDeclaringPermission, packageName)) {
22994            throw new SecurityException("Need to declare " + appOpPermission + " to call this api");
22995        }
22996        if (sUserManager.hasUserRestriction(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, userId)) {
22997            return false;
22998        }
22999        if (mExternalSourcesPolicy != null) {
23000            int isTrusted = mExternalSourcesPolicy.getPackageTrustedToInstallApps(packageName, uid);
23001            if (isTrusted != PackageManagerInternal.ExternalSourcesPolicy.USER_DEFAULT) {
23002                return isTrusted == PackageManagerInternal.ExternalSourcesPolicy.USER_TRUSTED;
23003            }
23004        }
23005        return checkUidPermission(appOpPermission, uid) == PERMISSION_GRANTED;
23006    }
23007}
23008