PackageManagerService.java revision 879f879d6bb32d2b24a06e6e9b4cbd0d0482c0f4
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.MANAGE_PROFILE_AND_DEVICE_OWNERS;
20import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
21import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
22import static android.Manifest.permission.WRITE_MEDIA_STORAGE;
23import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
24import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
25import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED;
26import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER;
27import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
28import static android.content.pm.PackageManager.DELETE_KEEP_DATA;
29import static android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
30import static android.content.pm.PackageManager.FLAG_PERMISSION_POLICY_FIXED;
31import static android.content.pm.PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
32import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE;
33import static android.content.pm.PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
34import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_FIXED;
35import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET;
36import static android.content.pm.PackageManager.INSTALL_EXTERNAL;
37import static android.content.pm.PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
38import static android.content.pm.PackageManager.INSTALL_FAILED_CONFLICTING_PROVIDER;
39import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE;
40import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION;
41import static android.content.pm.PackageManager.INSTALL_FAILED_EPHEMERAL_INVALID;
42import static android.content.pm.PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
43import static android.content.pm.PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
44import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_APK;
45import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
46import static android.content.pm.PackageManager.INSTALL_FAILED_MISSING_SHARED_LIBRARY;
47import static android.content.pm.PackageManager.INSTALL_FAILED_PACKAGE_CHANGED;
48import static android.content.pm.PackageManager.INSTALL_FAILED_REPLACE_COULDNT_DELETE;
49import static android.content.pm.PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE;
50import static android.content.pm.PackageManager.INSTALL_FAILED_TEST_ONLY;
51import static android.content.pm.PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE;
52import static android.content.pm.PackageManager.INSTALL_FAILED_USER_RESTRICTED;
53import static android.content.pm.PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
54import static android.content.pm.PackageManager.INSTALL_FORWARD_LOCK;
55import static android.content.pm.PackageManager.INSTALL_INTERNAL;
56import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
57import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
58import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK;
59import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK;
60import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER;
61import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
62import static android.content.pm.PackageManager.MATCH_ALL;
63import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
64import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
65import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
66import static android.content.pm.PackageManager.MATCH_DISABLED_COMPONENTS;
67import static android.content.pm.PackageManager.MATCH_FACTORY_ONLY;
68import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
69import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
70import static android.content.pm.PackageManager.MOVE_FAILED_DEVICE_ADMIN;
71import static android.content.pm.PackageManager.MOVE_FAILED_DOESNT_EXIST;
72import static android.content.pm.PackageManager.MOVE_FAILED_INTERNAL_ERROR;
73import static android.content.pm.PackageManager.MOVE_FAILED_OPERATION_PENDING;
74import static android.content.pm.PackageManager.MOVE_FAILED_SYSTEM_PACKAGE;
75import static android.content.pm.PackageManager.PERMISSION_DENIED;
76import static android.content.pm.PackageManager.PERMISSION_GRANTED;
77import static android.content.pm.PackageParser.PARSE_IS_PRIVILEGED;
78import static android.content.pm.PackageParser.isApkFile;
79import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
80import static android.system.OsConstants.O_CREAT;
81import static android.system.OsConstants.O_RDWR;
82
83import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE;
84import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_PARENT;
85import static com.android.internal.content.NativeLibraryHelper.LIB64_DIR_NAME;
86import static com.android.internal.content.NativeLibraryHelper.LIB_DIR_NAME;
87import static com.android.internal.util.ArrayUtils.appendInt;
88import static com.android.server.pm.Installer.DEXOPT_PUBLIC;
89import static com.android.server.pm.InstructionSets.getAppDexInstructionSets;
90import static com.android.server.pm.InstructionSets.getDexCodeInstructionSet;
91import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets;
92import static com.android.server.pm.InstructionSets.getPreferredInstructionSet;
93import static com.android.server.pm.InstructionSets.getPrimaryInstructionSet;
94import static com.android.server.pm.PackageManagerServiceCompilerMapping.getCompilerFilterForReason;
95import static com.android.server.pm.PackageManagerServiceCompilerMapping.getFullCompilerFilter;
96import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_FAILURE;
97import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_SUCCESS;
98import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED;
99
100import static dalvik.system.DexFile.getNonProfileGuidedCompilerFilter;
101
102import android.Manifest;
103import android.annotation.NonNull;
104import android.annotation.Nullable;
105import android.app.ActivityManager;
106import android.app.ActivityManagerNative;
107import android.app.IActivityManager;
108import android.app.ResourcesManager;
109import android.app.admin.IDevicePolicyManager;
110import android.app.admin.SecurityLog;
111import android.app.backup.IBackupManager;
112import android.content.BroadcastReceiver;
113import android.content.ComponentName;
114import android.content.ContentResolver;
115import android.content.Context;
116import android.content.IIntentReceiver;
117import android.content.Intent;
118import android.content.IntentFilter;
119import android.content.IntentSender;
120import android.content.IntentSender.SendIntentException;
121import android.content.ServiceConnection;
122import android.content.pm.ActivityInfo;
123import android.content.pm.ApplicationInfo;
124import android.content.pm.AppsQueryHelper;
125import android.content.pm.ComponentInfo;
126import android.content.pm.EphemeralApplicationInfo;
127import android.content.pm.EphemeralResolveInfo;
128import android.content.pm.EphemeralResolveInfo.EphemeralDigest;
129import android.content.pm.EphemeralResolveInfo.EphemeralResolveIntentInfo;
130import android.content.pm.FeatureInfo;
131import android.content.pm.IOnPermissionsChangeListener;
132import android.content.pm.IPackageDataObserver;
133import android.content.pm.IPackageDeleteObserver;
134import android.content.pm.IPackageDeleteObserver2;
135import android.content.pm.IPackageInstallObserver2;
136import android.content.pm.IPackageInstaller;
137import android.content.pm.IPackageManager;
138import android.content.pm.IPackageMoveObserver;
139import android.content.pm.IPackageStatsObserver;
140import android.content.pm.InstrumentationInfo;
141import android.content.pm.IntentFilterVerificationInfo;
142import android.content.pm.KeySet;
143import android.content.pm.PackageCleanItem;
144import android.content.pm.PackageInfo;
145import android.content.pm.PackageInfoLite;
146import android.content.pm.PackageInstaller;
147import android.content.pm.PackageManager;
148import android.content.pm.PackageManager.LegacyPackageDeleteObserver;
149import android.content.pm.PackageManagerInternal;
150import android.content.pm.PackageParser;
151import android.content.pm.PackageParser.ActivityIntentInfo;
152import android.content.pm.PackageParser.PackageLite;
153import android.content.pm.PackageParser.PackageParserException;
154import android.content.pm.PackageStats;
155import android.content.pm.PackageUserState;
156import android.content.pm.ParceledListSlice;
157import android.content.pm.PermissionGroupInfo;
158import android.content.pm.PermissionInfo;
159import android.content.pm.ProviderInfo;
160import android.content.pm.ResolveInfo;
161import android.content.pm.ServiceInfo;
162import android.content.pm.Signature;
163import android.content.pm.UserInfo;
164import android.content.pm.VerifierDeviceIdentity;
165import android.content.pm.VerifierInfo;
166import android.content.res.Resources;
167import android.graphics.Bitmap;
168import android.hardware.display.DisplayManager;
169import android.net.Uri;
170import android.os.Binder;
171import android.os.Build;
172import android.os.Bundle;
173import android.os.Debug;
174import android.os.Environment;
175import android.os.Environment.UserEnvironment;
176import android.os.FileUtils;
177import android.os.Handler;
178import android.os.IBinder;
179import android.os.Looper;
180import android.os.Message;
181import android.os.Parcel;
182import android.os.ParcelFileDescriptor;
183import android.os.PatternMatcher;
184import android.os.Process;
185import android.os.RemoteCallbackList;
186import android.os.RemoteException;
187import android.os.ResultReceiver;
188import android.os.SELinux;
189import android.os.ServiceManager;
190import android.os.SystemClock;
191import android.os.SystemProperties;
192import android.os.Trace;
193import android.os.UserHandle;
194import android.os.UserManager;
195import android.os.UserManagerInternal;
196import android.os.storage.IMountService;
197import android.os.storage.MountServiceInternal;
198import android.os.storage.StorageEventListener;
199import android.os.storage.StorageManager;
200import android.os.storage.VolumeInfo;
201import android.os.storage.VolumeRecord;
202import android.provider.Settings.Global;
203import android.provider.Settings.Secure;
204import android.security.KeyStore;
205import android.security.SystemKeyStore;
206import android.system.ErrnoException;
207import android.system.Os;
208import android.text.TextUtils;
209import android.text.format.DateUtils;
210import android.util.ArrayMap;
211import android.util.ArraySet;
212import android.util.DisplayMetrics;
213import android.util.EventLog;
214import android.util.ExceptionUtils;
215import android.util.Log;
216import android.util.LogPrinter;
217import android.util.MathUtils;
218import android.util.Pair;
219import android.util.PrintStreamPrinter;
220import android.util.Slog;
221import android.util.SparseArray;
222import android.util.SparseBooleanArray;
223import android.util.SparseIntArray;
224import android.util.Xml;
225import android.util.jar.StrictJarFile;
226import android.view.Display;
227
228import com.android.internal.R;
229import com.android.internal.annotations.GuardedBy;
230import com.android.internal.app.IMediaContainerService;
231import com.android.internal.app.ResolverActivity;
232import com.android.internal.content.NativeLibraryHelper;
233import com.android.internal.content.PackageHelper;
234import com.android.internal.logging.MetricsLogger;
235import com.android.internal.os.IParcelFileDescriptorFactory;
236import com.android.internal.os.SomeArgs;
237import com.android.internal.os.Zygote;
238import com.android.internal.telephony.CarrierAppUtils;
239import com.android.internal.util.ArrayUtils;
240import com.android.internal.util.FastPrintWriter;
241import com.android.internal.util.FastXmlSerializer;
242import com.android.internal.util.IndentingPrintWriter;
243import com.android.internal.util.Preconditions;
244import com.android.internal.util.XmlUtils;
245import com.android.server.AttributeCache;
246import com.android.server.EventLogTags;
247import com.android.server.FgThread;
248import com.android.server.IntentResolver;
249import com.android.server.LocalServices;
250import com.android.server.ServiceThread;
251import com.android.server.SystemConfig;
252import com.android.server.Watchdog;
253import com.android.server.net.NetworkPolicyManagerInternal;
254import com.android.server.pm.Installer.InstallerException;
255import com.android.server.pm.PermissionsState.PermissionState;
256import com.android.server.pm.Settings.DatabaseVersion;
257import com.android.server.pm.Settings.VersionInfo;
258import com.android.server.pm.dex.DexManager;
259import com.android.server.storage.DeviceStorageMonitorInternal;
260
261import dalvik.system.CloseGuard;
262import dalvik.system.DexFile;
263import dalvik.system.VMRuntime;
264
265import libcore.io.IoUtils;
266import libcore.util.EmptyArray;
267
268import org.xmlpull.v1.XmlPullParser;
269import org.xmlpull.v1.XmlPullParserException;
270import org.xmlpull.v1.XmlSerializer;
271
272import java.io.BufferedOutputStream;
273import java.io.BufferedReader;
274import java.io.ByteArrayInputStream;
275import java.io.ByteArrayOutputStream;
276import java.io.File;
277import java.io.FileDescriptor;
278import java.io.FileInputStream;
279import java.io.FileNotFoundException;
280import java.io.FileOutputStream;
281import java.io.FileReader;
282import java.io.FilenameFilter;
283import java.io.IOException;
284import java.io.PrintWriter;
285import java.nio.charset.StandardCharsets;
286import java.security.DigestInputStream;
287import java.security.MessageDigest;
288import java.security.NoSuchAlgorithmException;
289import java.security.PublicKey;
290import java.security.cert.Certificate;
291import java.security.cert.CertificateEncodingException;
292import java.security.cert.CertificateException;
293import java.text.SimpleDateFormat;
294import java.util.ArrayList;
295import java.util.Arrays;
296import java.util.Collection;
297import java.util.Collections;
298import java.util.Comparator;
299import java.util.Date;
300import java.util.HashSet;
301import java.util.HashMap;
302import java.util.Iterator;
303import java.util.List;
304import java.util.Map;
305import java.util.Objects;
306import java.util.Set;
307import java.util.concurrent.CountDownLatch;
308import java.util.concurrent.TimeUnit;
309import java.util.concurrent.atomic.AtomicBoolean;
310import java.util.concurrent.atomic.AtomicInteger;
311
312/**
313 * Keep track of all those APKs everywhere.
314 * <p>
315 * Internally there are two important locks:
316 * <ul>
317 * <li>{@link #mPackages} is used to guard all in-memory parsed package details
318 * and other related state. It is a fine-grained lock that should only be held
319 * momentarily, as it's one of the most contended locks in the system.
320 * <li>{@link #mInstallLock} is used to guard all {@code installd} access, whose
321 * operations typically involve heavy lifting of application data on disk. Since
322 * {@code installd} is single-threaded, and it's operations can often be slow,
323 * this lock should never be acquired while already holding {@link #mPackages}.
324 * Conversely, it's safe to acquire {@link #mPackages} momentarily while already
325 * holding {@link #mInstallLock}.
326 * </ul>
327 * Many internal methods rely on the caller to hold the appropriate locks, and
328 * this contract is expressed through method name suffixes:
329 * <ul>
330 * <li>fooLI(): the caller must hold {@link #mInstallLock}
331 * <li>fooLIF(): the caller must hold {@link #mInstallLock} and the package
332 * being modified must be frozen
333 * <li>fooLPr(): the caller must hold {@link #mPackages} for reading
334 * <li>fooLPw(): the caller must hold {@link #mPackages} for writing
335 * </ul>
336 * <p>
337 * Because this class is very central to the platform's security; please run all
338 * CTS and unit tests whenever making modifications:
339 *
340 * <pre>
341 * $ runtest -c android.content.pm.PackageManagerTests frameworks-core
342 * $ cts-tradefed run commandAndExit cts -m AppSecurityTests
343 * </pre>
344 */
345public class PackageManagerService extends IPackageManager.Stub {
346    static final String TAG = "PackageManager";
347    static final boolean DEBUG_SETTINGS = false;
348    static final boolean DEBUG_PREFERRED = false;
349    static final boolean DEBUG_UPGRADE = false;
350    static final boolean DEBUG_DOMAIN_VERIFICATION = false;
351    private static final boolean DEBUG_BACKUP = false;
352    private static final boolean DEBUG_INSTALL = false;
353    private static final boolean DEBUG_REMOVE = false;
354    private static final boolean DEBUG_BROADCASTS = false;
355    private static final boolean DEBUG_SHOW_INFO = false;
356    private static final boolean DEBUG_PACKAGE_INFO = false;
357    private static final boolean DEBUG_INTENT_MATCHING = false;
358    private static final boolean DEBUG_PACKAGE_SCANNING = false;
359    private static final boolean DEBUG_VERIFY = false;
360    private static final boolean DEBUG_FILTERS = false;
361
362    // Debug output for dexopting. This is shared between PackageManagerService, OtaDexoptService
363    // and PackageDexOptimizer. All these classes have their own flag to allow switching a single
364    // user, but by default initialize to this.
365    static final boolean DEBUG_DEXOPT = false;
366
367    private static final boolean DEBUG_ABI_SELECTION = false;
368    private static final boolean DEBUG_EPHEMERAL = Build.IS_DEBUGGABLE;
369    private static final boolean DEBUG_TRIAGED_MISSING = false;
370    private static final boolean DEBUG_APP_DATA = false;
371
372    static final boolean CLEAR_RUNTIME_PERMISSIONS_ON_UPGRADE = false;
373
374    private static final boolean DISABLE_EPHEMERAL_APPS = false;
375    private static final boolean HIDE_EPHEMERAL_APIS = true;
376
377    private static final boolean ENABLE_QUOTA =
378            SystemProperties.getBoolean("persist.fw.quota", false);
379
380    private static final int RADIO_UID = Process.PHONE_UID;
381    private static final int LOG_UID = Process.LOG_UID;
382    private static final int NFC_UID = Process.NFC_UID;
383    private static final int BLUETOOTH_UID = Process.BLUETOOTH_UID;
384    private static final int SHELL_UID = Process.SHELL_UID;
385
386    // Cap the size of permission trees that 3rd party apps can define
387    private static final int MAX_PERMISSION_TREE_FOOTPRINT = 32768;     // characters of text
388
389    // Suffix used during package installation when copying/moving
390    // package apks to install directory.
391    private static final String INSTALL_PACKAGE_SUFFIX = "-";
392
393    static final int SCAN_NO_DEX = 1<<1;
394    static final int SCAN_FORCE_DEX = 1<<2;
395    static final int SCAN_UPDATE_SIGNATURE = 1<<3;
396    static final int SCAN_NEW_INSTALL = 1<<4;
397    static final int SCAN_NO_PATHS = 1<<5;
398    static final int SCAN_UPDATE_TIME = 1<<6;
399    static final int SCAN_DEFER_DEX = 1<<7;
400    static final int SCAN_BOOTING = 1<<8;
401    static final int SCAN_TRUSTED_OVERLAY = 1<<9;
402    static final int SCAN_DELETE_DATA_ON_FAILURES = 1<<10;
403    static final int SCAN_REPLACING = 1<<11;
404    static final int SCAN_REQUIRE_KNOWN = 1<<12;
405    static final int SCAN_MOVE = 1<<13;
406    static final int SCAN_INITIAL = 1<<14;
407    static final int SCAN_CHECK_ONLY = 1<<15;
408    static final int SCAN_DONT_KILL_APP = 1<<17;
409    static final int SCAN_IGNORE_FROZEN = 1<<18;
410
411    static final int REMOVE_CHATTY = 1<<16;
412
413    private static final int[] EMPTY_INT_ARRAY = new int[0];
414
415    /**
416     * Timeout (in milliseconds) after which the watchdog should declare that
417     * our handler thread is wedged.  The usual default for such things is one
418     * minute but we sometimes do very lengthy I/O operations on this thread,
419     * such as installing multi-gigabyte applications, so ours needs to be longer.
420     */
421    private static final long WATCHDOG_TIMEOUT = 1000*60*10;     // ten minutes
422
423    /**
424     * Wall-clock timeout (in milliseconds) after which we *require* that an fstrim
425     * be run on this device.  We use the value in the Settings.Global.MANDATORY_FSTRIM_INTERVAL
426     * settings entry if available, otherwise we use the hardcoded default.  If it's been
427     * more than this long since the last fstrim, we force one during the boot sequence.
428     *
429     * This backstops other fstrim scheduling:  if the device is alive at midnight+idle,
430     * one gets run at the next available charging+idle time.  This final mandatory
431     * no-fstrim check kicks in only of the other scheduling criteria is never met.
432     */
433    private static final long DEFAULT_MANDATORY_FSTRIM_INTERVAL = 3 * DateUtils.DAY_IN_MILLIS;
434
435    /**
436     * Whether verification is enabled by default.
437     */
438    private static final boolean DEFAULT_VERIFY_ENABLE = true;
439
440    /**
441     * The default maximum time to wait for the verification agent to return in
442     * milliseconds.
443     */
444    private static final long DEFAULT_VERIFICATION_TIMEOUT = 10 * 1000;
445
446    /**
447     * The default response for package verification timeout.
448     *
449     * This can be either PackageManager.VERIFICATION_ALLOW or
450     * PackageManager.VERIFICATION_REJECT.
451     */
452    private static final int DEFAULT_VERIFICATION_RESPONSE = PackageManager.VERIFICATION_ALLOW;
453
454    static final String PLATFORM_PACKAGE_NAME = "android";
455
456    static final String DEFAULT_CONTAINER_PACKAGE = "com.android.defcontainer";
457
458    static final ComponentName DEFAULT_CONTAINER_COMPONENT = new ComponentName(
459            DEFAULT_CONTAINER_PACKAGE,
460            "com.android.defcontainer.DefaultContainerService");
461
462    private static final String KILL_APP_REASON_GIDS_CHANGED =
463            "permission grant or revoke changed gids";
464
465    private static final String KILL_APP_REASON_PERMISSIONS_REVOKED =
466            "permissions revoked";
467
468    private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive";
469
470    private static final String PACKAGE_SCHEME = "package";
471
472    private static final String VENDOR_OVERLAY_DIR = "/vendor/overlay";
473    /**
474     * If VENDOR_OVERLAY_THEME_PROPERTY is set, search for runtime resource overlay APKs also in
475     * VENDOR_OVERLAY_DIR/<value of VENDOR_OVERLAY_THEME_PROPERTY> in addition to
476     * VENDOR_OVERLAY_DIR.
477     */
478    private static final String VENDOR_OVERLAY_THEME_PROPERTY = "ro.boot.vendor.overlay.theme";
479
480    private static int DEFAULT_EPHEMERAL_HASH_PREFIX_MASK = 0xFFFFF000;
481    private static int DEFAULT_EPHEMERAL_HASH_PREFIX_COUNT = 5;
482
483    /** Permission grant: not grant the permission. */
484    private static final int GRANT_DENIED = 1;
485
486    /** Permission grant: grant the permission as an install permission. */
487    private static final int GRANT_INSTALL = 2;
488
489    /** Permission grant: grant the permission as a runtime one. */
490    private static final int GRANT_RUNTIME = 3;
491
492    /** Permission grant: grant as runtime a permission that was granted as an install time one. */
493    private static final int GRANT_UPGRADE = 4;
494
495    /** Canonical intent used to identify what counts as a "web browser" app */
496    private static final Intent sBrowserIntent;
497    static {
498        sBrowserIntent = new Intent();
499        sBrowserIntent.setAction(Intent.ACTION_VIEW);
500        sBrowserIntent.addCategory(Intent.CATEGORY_BROWSABLE);
501        sBrowserIntent.setData(Uri.parse("http:"));
502    }
503
504    /**
505     * The set of all protected actions [i.e. those actions for which a high priority
506     * intent filter is disallowed].
507     */
508    private static final Set<String> PROTECTED_ACTIONS = new ArraySet<>();
509    static {
510        PROTECTED_ACTIONS.add(Intent.ACTION_SEND);
511        PROTECTED_ACTIONS.add(Intent.ACTION_SENDTO);
512        PROTECTED_ACTIONS.add(Intent.ACTION_SEND_MULTIPLE);
513        PROTECTED_ACTIONS.add(Intent.ACTION_VIEW);
514    }
515
516    // Compilation reasons.
517    public static final int REASON_FIRST_BOOT = 0;
518    public static final int REASON_BOOT = 1;
519    public static final int REASON_INSTALL = 2;
520    public static final int REASON_BACKGROUND_DEXOPT = 3;
521    public static final int REASON_AB_OTA = 4;
522    public static final int REASON_NON_SYSTEM_LIBRARY = 5;
523    public static final int REASON_SHARED_APK = 6;
524    public static final int REASON_FORCED_DEXOPT = 7;
525    public static final int REASON_CORE_APP = 8;
526
527    public static final int REASON_LAST = REASON_CORE_APP;
528
529    final ServiceThread mHandlerThread;
530
531    final PackageHandler mHandler;
532
533    private final ProcessLoggingHandler mProcessLoggingHandler;
534
535    /**
536     * Messages for {@link #mHandler} that need to wait for system ready before
537     * being dispatched.
538     */
539    private ArrayList<Message> mPostSystemReadyMessages;
540
541    final int mSdkVersion = Build.VERSION.SDK_INT;
542
543    final Context mContext;
544    final boolean mFactoryTest;
545    final boolean mOnlyCore;
546    final DisplayMetrics mMetrics;
547    final int mDefParseFlags;
548    final String[] mSeparateProcesses;
549    final boolean mIsUpgrade;
550    final boolean mIsPreNUpgrade;
551    final boolean mIsPreNMR1Upgrade;
552
553    @GuardedBy("mPackages")
554    private boolean mDexOptDialogShown;
555
556    /** The location for ASEC container files on internal storage. */
557    final String mAsecInternalPath;
558
559    // Used for privilege escalation. MUST NOT BE CALLED WITH mPackages
560    // LOCK HELD.  Can be called with mInstallLock held.
561    @GuardedBy("mInstallLock")
562    final Installer mInstaller;
563
564    /** Directory where installed third-party apps stored */
565    final File mAppInstallDir;
566    final File mEphemeralInstallDir;
567
568    /**
569     * Directory to which applications installed internally have their
570     * 32 bit native libraries copied.
571     */
572    private File mAppLib32InstallDir;
573
574    // Directory containing the private parts (e.g. code and non-resource assets) of forward-locked
575    // apps.
576    final File mDrmAppPrivateInstallDir;
577
578    // ----------------------------------------------------------------
579
580    // Lock for state used when installing and doing other long running
581    // operations.  Methods that must be called with this lock held have
582    // the suffix "LI".
583    final Object mInstallLock = new Object();
584
585    // ----------------------------------------------------------------
586
587    // Keys are String (package name), values are Package.  This also serves
588    // as the lock for the global state.  Methods that must be called with
589    // this lock held have the prefix "LP".
590    @GuardedBy("mPackages")
591    final ArrayMap<String, PackageParser.Package> mPackages =
592            new ArrayMap<String, PackageParser.Package>();
593
594    final ArrayMap<String, Set<String>> mKnownCodebase =
595            new ArrayMap<String, Set<String>>();
596
597    // Tracks available target package names -> overlay package paths.
598    final ArrayMap<String, ArrayMap<String, PackageParser.Package>> mOverlays =
599        new ArrayMap<String, ArrayMap<String, PackageParser.Package>>();
600
601    /**
602     * Tracks new system packages [received in an OTA] that we expect to
603     * find updated user-installed versions. Keys are package name, values
604     * are package location.
605     */
606    final private ArrayMap<String, File> mExpectingBetter = new ArrayMap<>();
607    /**
608     * Tracks high priority intent filters for protected actions. During boot, certain
609     * filter actions are protected and should never be allowed to have a high priority
610     * intent filter for them. However, there is one, and only one exception -- the
611     * setup wizard. It must be able to define a high priority intent filter for these
612     * actions to ensure there are no escapes from the wizard. We need to delay processing
613     * of these during boot as we need to look at all of the system packages in order
614     * to know which component is the setup wizard.
615     */
616    private final List<PackageParser.ActivityIntentInfo> mProtectedFilters = new ArrayList<>();
617    /**
618     * Whether or not processing protected filters should be deferred.
619     */
620    private boolean mDeferProtectedFilters = true;
621
622    /**
623     * Tracks existing system packages prior to receiving an OTA. Keys are package name.
624     */
625    final private ArraySet<String> mExistingSystemPackages = new ArraySet<>();
626    /**
627     * Whether or not system app permissions should be promoted from install to runtime.
628     */
629    boolean mPromoteSystemApps;
630
631    @GuardedBy("mPackages")
632    final Settings mSettings;
633
634    /**
635     * Set of package names that are currently "frozen", which means active
636     * surgery is being done on the code/data for that package. The platform
637     * will refuse to launch frozen packages to avoid race conditions.
638     *
639     * @see PackageFreezer
640     */
641    @GuardedBy("mPackages")
642    final ArraySet<String> mFrozenPackages = new ArraySet<>();
643
644    final ProtectedPackages mProtectedPackages;
645
646    boolean mFirstBoot;
647
648    // System configuration read by SystemConfig.
649    final int[] mGlobalGids;
650    final SparseArray<ArraySet<String>> mSystemPermissions;
651    final ArrayMap<String, FeatureInfo> mAvailableFeatures;
652
653    // If mac_permissions.xml was found for seinfo labeling.
654    boolean mFoundPolicyFile;
655
656    private final EphemeralApplicationRegistry mEphemeralApplicationRegistry;
657
658    public static final class SharedLibraryEntry {
659        public final String path;
660        public final String apk;
661
662        SharedLibraryEntry(String _path, String _apk) {
663            path = _path;
664            apk = _apk;
665        }
666    }
667
668    // Currently known shared libraries.
669    final ArrayMap<String, SharedLibraryEntry> mSharedLibraries =
670            new ArrayMap<String, SharedLibraryEntry>();
671
672    // All available activities, for your resolving pleasure.
673    final ActivityIntentResolver mActivities =
674            new ActivityIntentResolver();
675
676    // All available receivers, for your resolving pleasure.
677    final ActivityIntentResolver mReceivers =
678            new ActivityIntentResolver();
679
680    // All available services, for your resolving pleasure.
681    final ServiceIntentResolver mServices = new ServiceIntentResolver();
682
683    // All available providers, for your resolving pleasure.
684    final ProviderIntentResolver mProviders = new ProviderIntentResolver();
685
686    // Mapping from provider base names (first directory in content URI codePath)
687    // to the provider information.
688    final ArrayMap<String, PackageParser.Provider> mProvidersByAuthority =
689            new ArrayMap<String, PackageParser.Provider>();
690
691    // Mapping from instrumentation class names to info about them.
692    final ArrayMap<ComponentName, PackageParser.Instrumentation> mInstrumentation =
693            new ArrayMap<ComponentName, PackageParser.Instrumentation>();
694
695    // Mapping from permission names to info about them.
696    final ArrayMap<String, PackageParser.PermissionGroup> mPermissionGroups =
697            new ArrayMap<String, PackageParser.PermissionGroup>();
698
699    // Packages whose data we have transfered into another package, thus
700    // should no longer exist.
701    final ArraySet<String> mTransferedPackages = new ArraySet<String>();
702
703    // Broadcast actions that are only available to the system.
704    final ArraySet<String> mProtectedBroadcasts = new ArraySet<String>();
705
706    /** List of packages waiting for verification. */
707    final SparseArray<PackageVerificationState> mPendingVerification
708            = new SparseArray<PackageVerificationState>();
709
710    /** Set of packages associated with each app op permission. */
711    final ArrayMap<String, ArraySet<String>> mAppOpPermissionPackages = new ArrayMap<>();
712
713    final PackageInstallerService mInstallerService;
714
715    private final PackageDexOptimizer mPackageDexOptimizer;
716    // DexManager handles the usage of dex files (e.g. secondary files, whether or not a package
717    // is used by other apps).
718    private final DexManager mDexManager;
719
720    private AtomicInteger mNextMoveId = new AtomicInteger();
721    private final MoveCallbacks mMoveCallbacks;
722
723    private final OnPermissionChangeListeners mOnPermissionChangeListeners;
724
725    // Cache of users who need badging.
726    SparseBooleanArray mUserNeedsBadging = new SparseBooleanArray();
727
728    /** Token for keys in mPendingVerification. */
729    private int mPendingVerificationToken = 0;
730
731    volatile boolean mSystemReady;
732    volatile boolean mSafeMode;
733    volatile boolean mHasSystemUidErrors;
734
735    ApplicationInfo mAndroidApplication;
736    final ActivityInfo mResolveActivity = new ActivityInfo();
737    final ResolveInfo mResolveInfo = new ResolveInfo();
738    ComponentName mResolveComponentName;
739    PackageParser.Package mPlatformPackage;
740    ComponentName mCustomResolverComponentName;
741
742    boolean mResolverReplaced = false;
743
744    private final @Nullable ComponentName mIntentFilterVerifierComponent;
745    private final @Nullable IntentFilterVerifier<ActivityIntentInfo> mIntentFilterVerifier;
746
747    private int mIntentFilterVerificationToken = 0;
748
749    /** Component that knows whether or not an ephemeral application exists */
750    final ComponentName mEphemeralResolverComponent;
751    /** The service connection to the ephemeral resolver */
752    final EphemeralResolverConnection mEphemeralResolverConnection;
753
754    /** Component used to install ephemeral applications */
755    final ComponentName mEphemeralInstallerComponent;
756    final ActivityInfo mEphemeralInstallerActivity = new ActivityInfo();
757    final ResolveInfo mEphemeralInstallerInfo = new ResolveInfo();
758
759    final SparseArray<IntentFilterVerificationState> mIntentFilterVerificationStates
760            = new SparseArray<IntentFilterVerificationState>();
761
762    final DefaultPermissionGrantPolicy mDefaultPermissionPolicy;
763
764    // List of packages names to keep cached, even if they are uninstalled for all users
765    private List<String> mKeepUninstalledPackages;
766
767    private UserManagerInternal mUserManagerInternal;
768
769    private static class IFVerificationParams {
770        PackageParser.Package pkg;
771        boolean replacing;
772        int userId;
773        int verifierUid;
774
775        public IFVerificationParams(PackageParser.Package _pkg, boolean _replacing,
776                int _userId, int _verifierUid) {
777            pkg = _pkg;
778            replacing = _replacing;
779            userId = _userId;
780            replacing = _replacing;
781            verifierUid = _verifierUid;
782        }
783    }
784
785    private interface IntentFilterVerifier<T extends IntentFilter> {
786        boolean addOneIntentFilterVerification(int verifierId, int userId, int verificationId,
787                                               T filter, String packageName);
788        void startVerifications(int userId);
789        void receiveVerificationResponse(int verificationId);
790    }
791
792    private class IntentVerifierProxy implements IntentFilterVerifier<ActivityIntentInfo> {
793        private Context mContext;
794        private ComponentName mIntentFilterVerifierComponent;
795        private ArrayList<Integer> mCurrentIntentFilterVerifications = new ArrayList<Integer>();
796
797        public IntentVerifierProxy(Context context, ComponentName verifierComponent) {
798            mContext = context;
799            mIntentFilterVerifierComponent = verifierComponent;
800        }
801
802        private String getDefaultScheme() {
803            return IntentFilter.SCHEME_HTTPS;
804        }
805
806        @Override
807        public void startVerifications(int userId) {
808            // Launch verifications requests
809            int count = mCurrentIntentFilterVerifications.size();
810            for (int n=0; n<count; n++) {
811                int verificationId = mCurrentIntentFilterVerifications.get(n);
812                final IntentFilterVerificationState ivs =
813                        mIntentFilterVerificationStates.get(verificationId);
814
815                String packageName = ivs.getPackageName();
816
817                ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters();
818                final int filterCount = filters.size();
819                ArraySet<String> domainsSet = new ArraySet<>();
820                for (int m=0; m<filterCount; m++) {
821                    PackageParser.ActivityIntentInfo filter = filters.get(m);
822                    domainsSet.addAll(filter.getHostsList());
823                }
824                ArrayList<String> domainsList = new ArrayList<>(domainsSet);
825                synchronized (mPackages) {
826                    if (mSettings.createIntentFilterVerificationIfNeededLPw(
827                            packageName, domainsList) != null) {
828                        scheduleWriteSettingsLocked();
829                    }
830                }
831                sendVerificationRequest(userId, verificationId, ivs);
832            }
833            mCurrentIntentFilterVerifications.clear();
834        }
835
836        private void sendVerificationRequest(int userId, int verificationId,
837                IntentFilterVerificationState ivs) {
838
839            Intent verificationIntent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION);
840            verificationIntent.putExtra(
841                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_ID,
842                    verificationId);
843            verificationIntent.putExtra(
844                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_URI_SCHEME,
845                    getDefaultScheme());
846            verificationIntent.putExtra(
847                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_HOSTS,
848                    ivs.getHostsString());
849            verificationIntent.putExtra(
850                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_PACKAGE_NAME,
851                    ivs.getPackageName());
852            verificationIntent.setComponent(mIntentFilterVerifierComponent);
853            verificationIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
854
855            UserHandle user = new UserHandle(userId);
856            mContext.sendBroadcastAsUser(verificationIntent, user);
857            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
858                    "Sending IntentFilter verification broadcast");
859        }
860
861        public void receiveVerificationResponse(int verificationId) {
862            IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId);
863
864            final boolean verified = ivs.isVerified();
865
866            ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters();
867            final int count = filters.size();
868            if (DEBUG_DOMAIN_VERIFICATION) {
869                Slog.i(TAG, "Received verification response " + verificationId
870                        + " for " + count + " filters, verified=" + verified);
871            }
872            for (int n=0; n<count; n++) {
873                PackageParser.ActivityIntentInfo filter = filters.get(n);
874                filter.setVerified(verified);
875
876                if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "IntentFilter " + filter.toString()
877                        + " verified with result:" + verified + " and hosts:"
878                        + ivs.getHostsString());
879            }
880
881            mIntentFilterVerificationStates.remove(verificationId);
882
883            final String packageName = ivs.getPackageName();
884            IntentFilterVerificationInfo ivi = null;
885
886            synchronized (mPackages) {
887                ivi = mSettings.getIntentFilterVerificationLPr(packageName);
888            }
889            if (ivi == null) {
890                Slog.w(TAG, "IntentFilterVerificationInfo not found for verificationId:"
891                        + verificationId + " packageName:" + packageName);
892                return;
893            }
894            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
895                    "Updating IntentFilterVerificationInfo for package " + packageName
896                            +" verificationId:" + verificationId);
897
898            synchronized (mPackages) {
899                if (verified) {
900                    ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS);
901                } else {
902                    ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK);
903                }
904                scheduleWriteSettingsLocked();
905
906                final int userId = ivs.getUserId();
907                if (userId != UserHandle.USER_ALL) {
908                    final int userStatus =
909                            mSettings.getIntentFilterVerificationStatusLPr(packageName, userId);
910
911                    int updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
912                    boolean needUpdate = false;
913
914                    // We cannot override the STATUS_ALWAYS / STATUS_NEVER states if they have
915                    // already been set by the User thru the Disambiguation dialog
916                    switch (userStatus) {
917                        case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED:
918                            if (verified) {
919                                updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
920                            } else {
921                                updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK;
922                            }
923                            needUpdate = true;
924                            break;
925
926                        case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK:
927                            if (verified) {
928                                updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
929                                needUpdate = true;
930                            }
931                            break;
932
933                        default:
934                            // Nothing to do
935                    }
936
937                    if (needUpdate) {
938                        mSettings.updateIntentFilterVerificationStatusLPw(
939                                packageName, updatedStatus, userId);
940                        scheduleWritePackageRestrictionsLocked(userId);
941                    }
942                }
943            }
944        }
945
946        @Override
947        public boolean addOneIntentFilterVerification(int verifierUid, int userId, int verificationId,
948                    ActivityIntentInfo filter, String packageName) {
949            if (!hasValidDomains(filter)) {
950                return false;
951            }
952            IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId);
953            if (ivs == null) {
954                ivs = createDomainVerificationState(verifierUid, userId, verificationId,
955                        packageName);
956            }
957            if (DEBUG_DOMAIN_VERIFICATION) {
958                Slog.d(TAG, "Adding verification filter for " + packageName + ": " + filter);
959            }
960            ivs.addFilter(filter);
961            return true;
962        }
963
964        private IntentFilterVerificationState createDomainVerificationState(int verifierUid,
965                int userId, int verificationId, String packageName) {
966            IntentFilterVerificationState ivs = new IntentFilterVerificationState(
967                    verifierUid, userId, packageName);
968            ivs.setPendingState();
969            synchronized (mPackages) {
970                mIntentFilterVerificationStates.append(verificationId, ivs);
971                mCurrentIntentFilterVerifications.add(verificationId);
972            }
973            return ivs;
974        }
975    }
976
977    private static boolean hasValidDomains(ActivityIntentInfo filter) {
978        return filter.hasCategory(Intent.CATEGORY_BROWSABLE)
979                && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) ||
980                        filter.hasDataScheme(IntentFilter.SCHEME_HTTPS));
981    }
982
983    // Set of pending broadcasts for aggregating enable/disable of components.
984    static class PendingPackageBroadcasts {
985        // for each user id, a map of <package name -> components within that package>
986        final SparseArray<ArrayMap<String, ArrayList<String>>> mUidMap;
987
988        public PendingPackageBroadcasts() {
989            mUidMap = new SparseArray<ArrayMap<String, ArrayList<String>>>(2);
990        }
991
992        public ArrayList<String> get(int userId, String packageName) {
993            ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId);
994            return packages.get(packageName);
995        }
996
997        public void put(int userId, String packageName, ArrayList<String> components) {
998            ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId);
999            packages.put(packageName, components);
1000        }
1001
1002        public void remove(int userId, String packageName) {
1003            ArrayMap<String, ArrayList<String>> packages = mUidMap.get(userId);
1004            if (packages != null) {
1005                packages.remove(packageName);
1006            }
1007        }
1008
1009        public void remove(int userId) {
1010            mUidMap.remove(userId);
1011        }
1012
1013        public int userIdCount() {
1014            return mUidMap.size();
1015        }
1016
1017        public int userIdAt(int n) {
1018            return mUidMap.keyAt(n);
1019        }
1020
1021        public ArrayMap<String, ArrayList<String>> packagesForUserId(int userId) {
1022            return mUidMap.get(userId);
1023        }
1024
1025        public int size() {
1026            // total number of pending broadcast entries across all userIds
1027            int num = 0;
1028            for (int i = 0; i< mUidMap.size(); i++) {
1029                num += mUidMap.valueAt(i).size();
1030            }
1031            return num;
1032        }
1033
1034        public void clear() {
1035            mUidMap.clear();
1036        }
1037
1038        private ArrayMap<String, ArrayList<String>> getOrAllocate(int userId) {
1039            ArrayMap<String, ArrayList<String>> map = mUidMap.get(userId);
1040            if (map == null) {
1041                map = new ArrayMap<String, ArrayList<String>>();
1042                mUidMap.put(userId, map);
1043            }
1044            return map;
1045        }
1046    }
1047    final PendingPackageBroadcasts mPendingBroadcasts = new PendingPackageBroadcasts();
1048
1049    // Service Connection to remote media container service to copy
1050    // package uri's from external media onto secure containers
1051    // or internal storage.
1052    private IMediaContainerService mContainerService = null;
1053
1054    static final int SEND_PENDING_BROADCAST = 1;
1055    static final int MCS_BOUND = 3;
1056    static final int END_COPY = 4;
1057    static final int INIT_COPY = 5;
1058    static final int MCS_UNBIND = 6;
1059    static final int START_CLEANING_PACKAGE = 7;
1060    static final int FIND_INSTALL_LOC = 8;
1061    static final int POST_INSTALL = 9;
1062    static final int MCS_RECONNECT = 10;
1063    static final int MCS_GIVE_UP = 11;
1064    static final int UPDATED_MEDIA_STATUS = 12;
1065    static final int WRITE_SETTINGS = 13;
1066    static final int WRITE_PACKAGE_RESTRICTIONS = 14;
1067    static final int PACKAGE_VERIFIED = 15;
1068    static final int CHECK_PENDING_VERIFICATION = 16;
1069    static final int START_INTENT_FILTER_VERIFICATIONS = 17;
1070    static final int INTENT_FILTER_VERIFIED = 18;
1071    static final int WRITE_PACKAGE_LIST = 19;
1072
1073    static final int WRITE_SETTINGS_DELAY = 10*1000;  // 10 seconds
1074
1075    // Delay time in millisecs
1076    static final int BROADCAST_DELAY = 10 * 1000;
1077
1078    static UserManagerService sUserManager;
1079
1080    // Stores a list of users whose package restrictions file needs to be updated
1081    private ArraySet<Integer> mDirtyUsers = new ArraySet<Integer>();
1082
1083    final private DefaultContainerConnection mDefContainerConn =
1084            new DefaultContainerConnection();
1085    class DefaultContainerConnection implements ServiceConnection {
1086        public void onServiceConnected(ComponentName name, IBinder service) {
1087            if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceConnected");
1088            IMediaContainerService imcs =
1089                IMediaContainerService.Stub.asInterface(service);
1090            mHandler.sendMessage(mHandler.obtainMessage(MCS_BOUND, imcs));
1091        }
1092
1093        public void onServiceDisconnected(ComponentName name) {
1094            if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceDisconnected");
1095        }
1096    }
1097
1098    // Recordkeeping of restore-after-install operations that are currently in flight
1099    // between the Package Manager and the Backup Manager
1100    static class PostInstallData {
1101        public InstallArgs args;
1102        public PackageInstalledInfo res;
1103
1104        PostInstallData(InstallArgs _a, PackageInstalledInfo _r) {
1105            args = _a;
1106            res = _r;
1107        }
1108    }
1109
1110    final SparseArray<PostInstallData> mRunningInstalls = new SparseArray<PostInstallData>();
1111    int mNextInstallToken = 1;  // nonzero; will be wrapped back to 1 when ++ overflows
1112
1113    // XML tags for backup/restore of various bits of state
1114    private static final String TAG_PREFERRED_BACKUP = "pa";
1115    private static final String TAG_DEFAULT_APPS = "da";
1116    private static final String TAG_INTENT_FILTER_VERIFICATION = "iv";
1117
1118    private static final String TAG_PERMISSION_BACKUP = "perm-grant-backup";
1119    private static final String TAG_ALL_GRANTS = "rt-grants";
1120    private static final String TAG_GRANT = "grant";
1121    private static final String ATTR_PACKAGE_NAME = "pkg";
1122
1123    private static final String TAG_PERMISSION = "perm";
1124    private static final String ATTR_PERMISSION_NAME = "name";
1125    private static final String ATTR_IS_GRANTED = "g";
1126    private static final String ATTR_USER_SET = "set";
1127    private static final String ATTR_USER_FIXED = "fixed";
1128    private static final String ATTR_REVOKE_ON_UPGRADE = "rou";
1129
1130    // System/policy permission grants are not backed up
1131    private static final int SYSTEM_RUNTIME_GRANT_MASK =
1132            FLAG_PERMISSION_POLICY_FIXED
1133            | FLAG_PERMISSION_SYSTEM_FIXED
1134            | FLAG_PERMISSION_GRANTED_BY_DEFAULT;
1135
1136    // And we back up these user-adjusted states
1137    private static final int USER_RUNTIME_GRANT_MASK =
1138            FLAG_PERMISSION_USER_SET
1139            | FLAG_PERMISSION_USER_FIXED
1140            | FLAG_PERMISSION_REVOKE_ON_UPGRADE;
1141
1142    final @Nullable String mRequiredVerifierPackage;
1143    final @NonNull String mRequiredInstallerPackage;
1144    final @NonNull String mRequiredUninstallerPackage;
1145    final @Nullable String mSetupWizardPackage;
1146    final @Nullable String mStorageManagerPackage;
1147    final @NonNull String mServicesSystemSharedLibraryPackageName;
1148    final @NonNull String mSharedSystemSharedLibraryPackageName;
1149
1150    final boolean mPermissionReviewRequired;
1151
1152    private final PackageUsage mPackageUsage = new PackageUsage();
1153    private final CompilerStats mCompilerStats = new CompilerStats();
1154
1155    class PackageHandler extends Handler {
1156        private boolean mBound = false;
1157        final ArrayList<HandlerParams> mPendingInstalls =
1158            new ArrayList<HandlerParams>();
1159
1160        private boolean connectToService() {
1161            if (DEBUG_SD_INSTALL) Log.i(TAG, "Trying to bind to" +
1162                    " DefaultContainerService");
1163            Intent service = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
1164            Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1165            if (mContext.bindServiceAsUser(service, mDefContainerConn,
1166                    Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) {
1167                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1168                mBound = true;
1169                return true;
1170            }
1171            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1172            return false;
1173        }
1174
1175        private void disconnectService() {
1176            mContainerService = null;
1177            mBound = false;
1178            Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1179            mContext.unbindService(mDefContainerConn);
1180            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1181        }
1182
1183        PackageHandler(Looper looper) {
1184            super(looper);
1185        }
1186
1187        public void handleMessage(Message msg) {
1188            try {
1189                doHandleMessage(msg);
1190            } finally {
1191                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1192            }
1193        }
1194
1195        void doHandleMessage(Message msg) {
1196            switch (msg.what) {
1197                case INIT_COPY: {
1198                    HandlerParams params = (HandlerParams) msg.obj;
1199                    int idx = mPendingInstalls.size();
1200                    if (DEBUG_INSTALL) Slog.i(TAG, "init_copy idx=" + idx + ": " + params);
1201                    // If a bind was already initiated we dont really
1202                    // need to do anything. The pending install
1203                    // will be processed later on.
1204                    if (!mBound) {
1205                        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1206                                System.identityHashCode(mHandler));
1207                        // If this is the only one pending we might
1208                        // have to bind to the service again.
1209                        if (!connectToService()) {
1210                            Slog.e(TAG, "Failed to bind to media container service");
1211                            params.serviceError();
1212                            Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1213                                    System.identityHashCode(mHandler));
1214                            if (params.traceMethod != null) {
1215                                Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, params.traceMethod,
1216                                        params.traceCookie);
1217                            }
1218                            return;
1219                        } else {
1220                            // Once we bind to the service, the first
1221                            // pending request will be processed.
1222                            mPendingInstalls.add(idx, params);
1223                        }
1224                    } else {
1225                        mPendingInstalls.add(idx, params);
1226                        // Already bound to the service. Just make
1227                        // sure we trigger off processing the first request.
1228                        if (idx == 0) {
1229                            mHandler.sendEmptyMessage(MCS_BOUND);
1230                        }
1231                    }
1232                    break;
1233                }
1234                case MCS_BOUND: {
1235                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_bound");
1236                    if (msg.obj != null) {
1237                        mContainerService = (IMediaContainerService) msg.obj;
1238                        Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1239                                System.identityHashCode(mHandler));
1240                    }
1241                    if (mContainerService == null) {
1242                        if (!mBound) {
1243                            // Something seriously wrong since we are not bound and we are not
1244                            // waiting for connection. Bail out.
1245                            Slog.e(TAG, "Cannot bind to media container service");
1246                            for (HandlerParams params : mPendingInstalls) {
1247                                // Indicate service bind error
1248                                params.serviceError();
1249                                Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1250                                        System.identityHashCode(params));
1251                                if (params.traceMethod != null) {
1252                                    Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER,
1253                                            params.traceMethod, params.traceCookie);
1254                                }
1255                                return;
1256                            }
1257                            mPendingInstalls.clear();
1258                        } else {
1259                            Slog.w(TAG, "Waiting to connect to media container service");
1260                        }
1261                    } else if (mPendingInstalls.size() > 0) {
1262                        HandlerParams params = mPendingInstalls.get(0);
1263                        if (params != null) {
1264                            Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1265                                    System.identityHashCode(params));
1266                            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "startCopy");
1267                            if (params.startCopy()) {
1268                                // We are done...  look for more work or to
1269                                // go idle.
1270                                if (DEBUG_SD_INSTALL) Log.i(TAG,
1271                                        "Checking for more work or unbind...");
1272                                // Delete pending install
1273                                if (mPendingInstalls.size() > 0) {
1274                                    mPendingInstalls.remove(0);
1275                                }
1276                                if (mPendingInstalls.size() == 0) {
1277                                    if (mBound) {
1278                                        if (DEBUG_SD_INSTALL) Log.i(TAG,
1279                                                "Posting delayed MCS_UNBIND");
1280                                        removeMessages(MCS_UNBIND);
1281                                        Message ubmsg = obtainMessage(MCS_UNBIND);
1282                                        // Unbind after a little delay, to avoid
1283                                        // continual thrashing.
1284                                        sendMessageDelayed(ubmsg, 10000);
1285                                    }
1286                                } else {
1287                                    // There are more pending requests in queue.
1288                                    // Just post MCS_BOUND message to trigger processing
1289                                    // of next pending install.
1290                                    if (DEBUG_SD_INSTALL) Log.i(TAG,
1291                                            "Posting MCS_BOUND for next work");
1292                                    mHandler.sendEmptyMessage(MCS_BOUND);
1293                                }
1294                            }
1295                            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
1296                        }
1297                    } else {
1298                        // Should never happen ideally.
1299                        Slog.w(TAG, "Empty queue");
1300                    }
1301                    break;
1302                }
1303                case MCS_RECONNECT: {
1304                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_reconnect");
1305                    if (mPendingInstalls.size() > 0) {
1306                        if (mBound) {
1307                            disconnectService();
1308                        }
1309                        if (!connectToService()) {
1310                            Slog.e(TAG, "Failed to bind to media container service");
1311                            for (HandlerParams params : mPendingInstalls) {
1312                                // Indicate service bind error
1313                                params.serviceError();
1314                                Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1315                                        System.identityHashCode(params));
1316                            }
1317                            mPendingInstalls.clear();
1318                        }
1319                    }
1320                    break;
1321                }
1322                case MCS_UNBIND: {
1323                    // If there is no actual work left, then time to unbind.
1324                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_unbind");
1325
1326                    if (mPendingInstalls.size() == 0 && mPendingVerification.size() == 0) {
1327                        if (mBound) {
1328                            if (DEBUG_INSTALL) Slog.i(TAG, "calling disconnectService()");
1329
1330                            disconnectService();
1331                        }
1332                    } else if (mPendingInstalls.size() > 0) {
1333                        // There are more pending requests in queue.
1334                        // Just post MCS_BOUND message to trigger processing
1335                        // of next pending install.
1336                        mHandler.sendEmptyMessage(MCS_BOUND);
1337                    }
1338
1339                    break;
1340                }
1341                case MCS_GIVE_UP: {
1342                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_giveup too many retries");
1343                    HandlerParams params = mPendingInstalls.remove(0);
1344                    Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1345                            System.identityHashCode(params));
1346                    break;
1347                }
1348                case SEND_PENDING_BROADCAST: {
1349                    String packages[];
1350                    ArrayList<String> components[];
1351                    int size = 0;
1352                    int uids[];
1353                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1354                    synchronized (mPackages) {
1355                        if (mPendingBroadcasts == null) {
1356                            return;
1357                        }
1358                        size = mPendingBroadcasts.size();
1359                        if (size <= 0) {
1360                            // Nothing to be done. Just return
1361                            return;
1362                        }
1363                        packages = new String[size];
1364                        components = new ArrayList[size];
1365                        uids = new int[size];
1366                        int i = 0;  // filling out the above arrays
1367
1368                        for (int n = 0; n < mPendingBroadcasts.userIdCount(); n++) {
1369                            int packageUserId = mPendingBroadcasts.userIdAt(n);
1370                            Iterator<Map.Entry<String, ArrayList<String>>> it
1371                                    = mPendingBroadcasts.packagesForUserId(packageUserId)
1372                                            .entrySet().iterator();
1373                            while (it.hasNext() && i < size) {
1374                                Map.Entry<String, ArrayList<String>> ent = it.next();
1375                                packages[i] = ent.getKey();
1376                                components[i] = ent.getValue();
1377                                PackageSetting ps = mSettings.mPackages.get(ent.getKey());
1378                                uids[i] = (ps != null)
1379                                        ? UserHandle.getUid(packageUserId, ps.appId)
1380                                        : -1;
1381                                i++;
1382                            }
1383                        }
1384                        size = i;
1385                        mPendingBroadcasts.clear();
1386                    }
1387                    // Send broadcasts
1388                    for (int i = 0; i < size; i++) {
1389                        sendPackageChangedBroadcast(packages[i], true, components[i], uids[i]);
1390                    }
1391                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1392                    break;
1393                }
1394                case START_CLEANING_PACKAGE: {
1395                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1396                    final String packageName = (String)msg.obj;
1397                    final int userId = msg.arg1;
1398                    final boolean andCode = msg.arg2 != 0;
1399                    synchronized (mPackages) {
1400                        if (userId == UserHandle.USER_ALL) {
1401                            int[] users = sUserManager.getUserIds();
1402                            for (int user : users) {
1403                                mSettings.addPackageToCleanLPw(
1404                                        new PackageCleanItem(user, packageName, andCode));
1405                            }
1406                        } else {
1407                            mSettings.addPackageToCleanLPw(
1408                                    new PackageCleanItem(userId, packageName, andCode));
1409                        }
1410                    }
1411                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1412                    startCleaningPackages();
1413                } break;
1414                case POST_INSTALL: {
1415                    if (DEBUG_INSTALL) Log.v(TAG, "Handling post-install for " + msg.arg1);
1416
1417                    PostInstallData data = mRunningInstalls.get(msg.arg1);
1418                    final boolean didRestore = (msg.arg2 != 0);
1419                    mRunningInstalls.delete(msg.arg1);
1420
1421                    if (data != null) {
1422                        InstallArgs args = data.args;
1423                        PackageInstalledInfo parentRes = data.res;
1424
1425                        final boolean grantPermissions = (args.installFlags
1426                                & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0;
1427                        final boolean killApp = (args.installFlags
1428                                & PackageManager.INSTALL_DONT_KILL_APP) == 0;
1429                        final String[] grantedPermissions = args.installGrantPermissions;
1430
1431                        // Handle the parent package
1432                        handlePackagePostInstall(parentRes, grantPermissions, killApp,
1433                                grantedPermissions, didRestore, args.installerPackageName,
1434                                args.observer);
1435
1436                        // Handle the child packages
1437                        final int childCount = (parentRes.addedChildPackages != null)
1438                                ? parentRes.addedChildPackages.size() : 0;
1439                        for (int i = 0; i < childCount; i++) {
1440                            PackageInstalledInfo childRes = parentRes.addedChildPackages.valueAt(i);
1441                            handlePackagePostInstall(childRes, grantPermissions, killApp,
1442                                    grantedPermissions, false, args.installerPackageName,
1443                                    args.observer);
1444                        }
1445
1446                        // Log tracing if needed
1447                        if (args.traceMethod != null) {
1448                            Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, args.traceMethod,
1449                                    args.traceCookie);
1450                        }
1451                    } else {
1452                        Slog.e(TAG, "Bogus post-install token " + msg.arg1);
1453                    }
1454
1455                    Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "postInstall", msg.arg1);
1456                } break;
1457                case UPDATED_MEDIA_STATUS: {
1458                    if (DEBUG_SD_INSTALL) Log.i(TAG, "Got message UPDATED_MEDIA_STATUS");
1459                    boolean reportStatus = msg.arg1 == 1;
1460                    boolean doGc = msg.arg2 == 1;
1461                    if (DEBUG_SD_INSTALL) Log.i(TAG, "reportStatus=" + reportStatus + ", doGc = " + doGc);
1462                    if (doGc) {
1463                        // Force a gc to clear up stale containers.
1464                        Runtime.getRuntime().gc();
1465                    }
1466                    if (msg.obj != null) {
1467                        @SuppressWarnings("unchecked")
1468                        Set<AsecInstallArgs> args = (Set<AsecInstallArgs>) msg.obj;
1469                        if (DEBUG_SD_INSTALL) Log.i(TAG, "Unloading all containers");
1470                        // Unload containers
1471                        unloadAllContainers(args);
1472                    }
1473                    if (reportStatus) {
1474                        try {
1475                            if (DEBUG_SD_INSTALL) Log.i(TAG, "Invoking MountService call back");
1476                            PackageHelper.getMountService().finishMediaUpdate();
1477                        } catch (RemoteException e) {
1478                            Log.e(TAG, "MountService not running?");
1479                        }
1480                    }
1481                } break;
1482                case WRITE_SETTINGS: {
1483                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1484                    synchronized (mPackages) {
1485                        removeMessages(WRITE_SETTINGS);
1486                        removeMessages(WRITE_PACKAGE_RESTRICTIONS);
1487                        mSettings.writeLPr();
1488                        mDirtyUsers.clear();
1489                    }
1490                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1491                } break;
1492                case WRITE_PACKAGE_RESTRICTIONS: {
1493                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1494                    synchronized (mPackages) {
1495                        removeMessages(WRITE_PACKAGE_RESTRICTIONS);
1496                        for (int userId : mDirtyUsers) {
1497                            mSettings.writePackageRestrictionsLPr(userId);
1498                        }
1499                        mDirtyUsers.clear();
1500                    }
1501                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1502                } break;
1503                case WRITE_PACKAGE_LIST: {
1504                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1505                    synchronized (mPackages) {
1506                        removeMessages(WRITE_PACKAGE_LIST);
1507                        mSettings.writePackageListLPr(msg.arg1);
1508                    }
1509                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1510                } break;
1511                case CHECK_PENDING_VERIFICATION: {
1512                    final int verificationId = msg.arg1;
1513                    final PackageVerificationState state = mPendingVerification.get(verificationId);
1514
1515                    if ((state != null) && !state.timeoutExtended()) {
1516                        final InstallArgs args = state.getInstallArgs();
1517                        final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
1518
1519                        Slog.i(TAG, "Verification timed out for " + originUri);
1520                        mPendingVerification.remove(verificationId);
1521
1522                        int ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
1523
1524                        if (getDefaultVerificationResponse() == PackageManager.VERIFICATION_ALLOW) {
1525                            Slog.i(TAG, "Continuing with installation of " + originUri);
1526                            state.setVerifierResponse(Binder.getCallingUid(),
1527                                    PackageManager.VERIFICATION_ALLOW_WITHOUT_SUFFICIENT);
1528                            broadcastPackageVerified(verificationId, originUri,
1529                                    PackageManager.VERIFICATION_ALLOW,
1530                                    state.getInstallArgs().getUser());
1531                            try {
1532                                ret = args.copyApk(mContainerService, true);
1533                            } catch (RemoteException e) {
1534                                Slog.e(TAG, "Could not contact the ContainerService");
1535                            }
1536                        } else {
1537                            broadcastPackageVerified(verificationId, originUri,
1538                                    PackageManager.VERIFICATION_REJECT,
1539                                    state.getInstallArgs().getUser());
1540                        }
1541
1542                        Trace.asyncTraceEnd(
1543                                TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
1544
1545                        processPendingInstall(args, ret);
1546                        mHandler.sendEmptyMessage(MCS_UNBIND);
1547                    }
1548                    break;
1549                }
1550                case PACKAGE_VERIFIED: {
1551                    final int verificationId = msg.arg1;
1552
1553                    final PackageVerificationState state = mPendingVerification.get(verificationId);
1554                    if (state == null) {
1555                        Slog.w(TAG, "Invalid verification token " + verificationId + " received");
1556                        break;
1557                    }
1558
1559                    final PackageVerificationResponse response = (PackageVerificationResponse) msg.obj;
1560
1561                    state.setVerifierResponse(response.callerUid, response.code);
1562
1563                    if (state.isVerificationComplete()) {
1564                        mPendingVerification.remove(verificationId);
1565
1566                        final InstallArgs args = state.getInstallArgs();
1567                        final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
1568
1569                        int ret;
1570                        if (state.isInstallAllowed()) {
1571                            ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
1572                            broadcastPackageVerified(verificationId, originUri,
1573                                    response.code, state.getInstallArgs().getUser());
1574                            try {
1575                                ret = args.copyApk(mContainerService, true);
1576                            } catch (RemoteException e) {
1577                                Slog.e(TAG, "Could not contact the ContainerService");
1578                            }
1579                        } else {
1580                            ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
1581                        }
1582
1583                        Trace.asyncTraceEnd(
1584                                TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
1585
1586                        processPendingInstall(args, ret);
1587                        mHandler.sendEmptyMessage(MCS_UNBIND);
1588                    }
1589
1590                    break;
1591                }
1592                case START_INTENT_FILTER_VERIFICATIONS: {
1593                    IFVerificationParams params = (IFVerificationParams) msg.obj;
1594                    verifyIntentFiltersIfNeeded(params.userId, params.verifierUid,
1595                            params.replacing, params.pkg);
1596                    break;
1597                }
1598                case INTENT_FILTER_VERIFIED: {
1599                    final int verificationId = msg.arg1;
1600
1601                    final IntentFilterVerificationState state = mIntentFilterVerificationStates.get(
1602                            verificationId);
1603                    if (state == null) {
1604                        Slog.w(TAG, "Invalid IntentFilter verification token "
1605                                + verificationId + " received");
1606                        break;
1607                    }
1608
1609                    final int userId = state.getUserId();
1610
1611                    if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1612                            "Processing IntentFilter verification with token:"
1613                            + verificationId + " and userId:" + userId);
1614
1615                    final IntentFilterVerificationResponse response =
1616                            (IntentFilterVerificationResponse) msg.obj;
1617
1618                    state.setVerifierResponse(response.callerUid, response.code);
1619
1620                    if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1621                            "IntentFilter verification with token:" + verificationId
1622                            + " and userId:" + userId
1623                            + " is settings verifier response with response code:"
1624                            + response.code);
1625
1626                    if (response.code == PackageManager.INTENT_FILTER_VERIFICATION_FAILURE) {
1627                        if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Domains failing verification: "
1628                                + response.getFailedDomainsString());
1629                    }
1630
1631                    if (state.isVerificationComplete()) {
1632                        mIntentFilterVerifier.receiveVerificationResponse(verificationId);
1633                    } else {
1634                        if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1635                                "IntentFilter verification with token:" + verificationId
1636                                + " was not said to be complete");
1637                    }
1638
1639                    break;
1640                }
1641            }
1642        }
1643    }
1644
1645    private void handlePackagePostInstall(PackageInstalledInfo res, boolean grantPermissions,
1646            boolean killApp, String[] grantedPermissions,
1647            boolean launchedForRestore, String installerPackage,
1648            IPackageInstallObserver2 installObserver) {
1649        if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
1650            // Send the removed broadcasts
1651            if (res.removedInfo != null) {
1652                res.removedInfo.sendPackageRemovedBroadcasts(killApp);
1653            }
1654
1655            // Now that we successfully installed the package, grant runtime
1656            // permissions if requested before broadcasting the install.
1657            if (grantPermissions && res.pkg.applicationInfo.targetSdkVersion
1658                    >= Build.VERSION_CODES.M) {
1659                grantRequestedRuntimePermissions(res.pkg, res.newUsers, grantedPermissions);
1660            }
1661
1662            final boolean update = res.removedInfo != null
1663                    && res.removedInfo.removedPackage != null;
1664
1665            // If this is the first time we have child packages for a disabled privileged
1666            // app that had no children, we grant requested runtime permissions to the new
1667            // children if the parent on the system image had them already granted.
1668            if (res.pkg.parentPackage != null) {
1669                synchronized (mPackages) {
1670                    grantRuntimePermissionsGrantedToDisabledPrivSysPackageParentLPw(res.pkg);
1671                }
1672            }
1673
1674            synchronized (mPackages) {
1675                mEphemeralApplicationRegistry.onPackageInstalledLPw(res.pkg);
1676            }
1677
1678            final String packageName = res.pkg.applicationInfo.packageName;
1679            Bundle extras = new Bundle(1);
1680            extras.putInt(Intent.EXTRA_UID, res.uid);
1681
1682            // Determine the set of users who are adding this package for
1683            // the first time vs. those who are seeing an update.
1684            int[] firstUsers = EMPTY_INT_ARRAY;
1685            int[] updateUsers = EMPTY_INT_ARRAY;
1686            if (res.origUsers == null || res.origUsers.length == 0) {
1687                firstUsers = res.newUsers;
1688            } else {
1689                for (int newUser : res.newUsers) {
1690                    boolean isNew = true;
1691                    for (int origUser : res.origUsers) {
1692                        if (origUser == newUser) {
1693                            isNew = false;
1694                            break;
1695                        }
1696                    }
1697                    if (isNew) {
1698                        firstUsers = ArrayUtils.appendInt(firstUsers, newUser);
1699                    } else {
1700                        updateUsers = ArrayUtils.appendInt(updateUsers, newUser);
1701                    }
1702                }
1703            }
1704
1705            // Send installed broadcasts if the install/update is not ephemeral
1706            if (!isEphemeral(res.pkg)) {
1707                mProcessLoggingHandler.invalidateProcessLoggingBaseApkHash(res.pkg.baseCodePath);
1708
1709                // Send added for users that see the package for the first time
1710                sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
1711                        extras, 0 /*flags*/, null /*targetPackage*/,
1712                        null /*finishedReceiver*/, firstUsers);
1713
1714                // Send added for users that don't see the package for the first time
1715                if (update) {
1716                    extras.putBoolean(Intent.EXTRA_REPLACING, true);
1717                }
1718                sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
1719                        extras, 0 /*flags*/, null /*targetPackage*/,
1720                        null /*finishedReceiver*/, updateUsers);
1721
1722                // Send replaced for users that don't see the package for the first time
1723                if (update) {
1724                    sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
1725                            packageName, extras, 0 /*flags*/,
1726                            null /*targetPackage*/, null /*finishedReceiver*/,
1727                            updateUsers);
1728                    sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
1729                            null /*package*/, null /*extras*/, 0 /*flags*/,
1730                            packageName /*targetPackage*/,
1731                            null /*finishedReceiver*/, updateUsers);
1732                } else if (launchedForRestore && !isSystemApp(res.pkg)) {
1733                    // First-install and we did a restore, so we're responsible for the
1734                    // first-launch broadcast.
1735                    if (DEBUG_BACKUP) {
1736                        Slog.i(TAG, "Post-restore of " + packageName
1737                                + " sending FIRST_LAUNCH in " + Arrays.toString(firstUsers));
1738                    }
1739                    sendFirstLaunchBroadcast(packageName, installerPackage, firstUsers);
1740                }
1741
1742                // Send broadcast package appeared if forward locked/external for all users
1743                // treat asec-hosted packages like removable media on upgrade
1744                if (res.pkg.isForwardLocked() || isExternal(res.pkg)) {
1745                    if (DEBUG_INSTALL) {
1746                        Slog.i(TAG, "upgrading pkg " + res.pkg
1747                                + " is ASEC-hosted -> AVAILABLE");
1748                    }
1749                    final int[] uidArray = new int[]{res.pkg.applicationInfo.uid};
1750                    ArrayList<String> pkgList = new ArrayList<>(1);
1751                    pkgList.add(packageName);
1752                    sendResourcesChangedBroadcast(true, true, pkgList, uidArray, null);
1753                }
1754            }
1755
1756            // Work that needs to happen on first install within each user
1757            if (firstUsers != null && firstUsers.length > 0) {
1758                synchronized (mPackages) {
1759                    for (int userId : firstUsers) {
1760                        // If this app is a browser and it's newly-installed for some
1761                        // users, clear any default-browser state in those users. The
1762                        // app's nature doesn't depend on the user, so we can just check
1763                        // its browser nature in any user and generalize.
1764                        if (packageIsBrowser(packageName, userId)) {
1765                            mSettings.setDefaultBrowserPackageNameLPw(null, userId);
1766                        }
1767
1768                        // We may also need to apply pending (restored) runtime
1769                        // permission grants within these users.
1770                        mSettings.applyPendingPermissionGrantsLPw(packageName, userId);
1771                    }
1772                }
1773            }
1774
1775            // Log current value of "unknown sources" setting
1776            EventLog.writeEvent(EventLogTags.UNKNOWN_SOURCES_ENABLED,
1777                    getUnknownSourcesSettings());
1778
1779            // Force a gc to clear up things
1780            Runtime.getRuntime().gc();
1781
1782            // Remove the replaced package's older resources safely now
1783            // We delete after a gc for applications  on sdcard.
1784            if (res.removedInfo != null && res.removedInfo.args != null) {
1785                synchronized (mInstallLock) {
1786                    res.removedInfo.args.doPostDeleteLI(true);
1787                }
1788            }
1789
1790            if (!isEphemeral(res.pkg)) {
1791                // Notify DexManager that the package was installed for new users.
1792                // The updated users should already be indexed and the package code paths
1793                // should not change.
1794                // Don't notify the manager for ephemeral apps as they are not expected to
1795                // survive long enough to benefit of background optimizations.
1796                for (int userId : firstUsers) {
1797                    PackageInfo info = getPackageInfo(packageName, /*flags*/ 0, userId);
1798                    mDexManager.notifyPackageInstalled(info, userId);
1799                }
1800            }
1801        }
1802
1803        // If someone is watching installs - notify them
1804        if (installObserver != null) {
1805            try {
1806                Bundle extras = extrasForInstallResult(res);
1807                installObserver.onPackageInstalled(res.name, res.returnCode,
1808                        res.returnMsg, extras);
1809            } catch (RemoteException e) {
1810                Slog.i(TAG, "Observer no longer exists.");
1811            }
1812        }
1813    }
1814
1815    private void grantRuntimePermissionsGrantedToDisabledPrivSysPackageParentLPw(
1816            PackageParser.Package pkg) {
1817        if (pkg.parentPackage == null) {
1818            return;
1819        }
1820        if (pkg.requestedPermissions == null) {
1821            return;
1822        }
1823        final PackageSetting disabledSysParentPs = mSettings
1824                .getDisabledSystemPkgLPr(pkg.parentPackage.packageName);
1825        if (disabledSysParentPs == null || disabledSysParentPs.pkg == null
1826                || !disabledSysParentPs.isPrivileged()
1827                || (disabledSysParentPs.childPackageNames != null
1828                        && !disabledSysParentPs.childPackageNames.isEmpty())) {
1829            return;
1830        }
1831        final int[] allUserIds = sUserManager.getUserIds();
1832        final int permCount = pkg.requestedPermissions.size();
1833        for (int i = 0; i < permCount; i++) {
1834            String permission = pkg.requestedPermissions.get(i);
1835            BasePermission bp = mSettings.mPermissions.get(permission);
1836            if (bp == null || !(bp.isRuntime() || bp.isDevelopment())) {
1837                continue;
1838            }
1839            for (int userId : allUserIds) {
1840                if (disabledSysParentPs.getPermissionsState().hasRuntimePermission(
1841                        permission, userId)) {
1842                    grantRuntimePermission(pkg.packageName, permission, userId);
1843                }
1844            }
1845        }
1846    }
1847
1848    private StorageEventListener mStorageListener = new StorageEventListener() {
1849        @Override
1850        public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState) {
1851            if (vol.type == VolumeInfo.TYPE_PRIVATE) {
1852                if (vol.state == VolumeInfo.STATE_MOUNTED) {
1853                    final String volumeUuid = vol.getFsUuid();
1854
1855                    // Clean up any users or apps that were removed or recreated
1856                    // while this volume was missing
1857                    reconcileUsers(volumeUuid);
1858                    reconcileApps(volumeUuid);
1859
1860                    // Clean up any install sessions that expired or were
1861                    // cancelled while this volume was missing
1862                    mInstallerService.onPrivateVolumeMounted(volumeUuid);
1863
1864                    loadPrivatePackages(vol);
1865
1866                } else if (vol.state == VolumeInfo.STATE_EJECTING) {
1867                    unloadPrivatePackages(vol);
1868                }
1869            }
1870
1871            if (vol.type == VolumeInfo.TYPE_PUBLIC && vol.isPrimary()) {
1872                if (vol.state == VolumeInfo.STATE_MOUNTED) {
1873                    updateExternalMediaStatus(true, false);
1874                } else if (vol.state == VolumeInfo.STATE_EJECTING) {
1875                    updateExternalMediaStatus(false, false);
1876                }
1877            }
1878        }
1879
1880        @Override
1881        public void onVolumeForgotten(String fsUuid) {
1882            if (TextUtils.isEmpty(fsUuid)) {
1883                Slog.e(TAG, "Forgetting internal storage is probably a mistake; ignoring");
1884                return;
1885            }
1886
1887            // Remove any apps installed on the forgotten volume
1888            synchronized (mPackages) {
1889                final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(fsUuid);
1890                for (PackageSetting ps : packages) {
1891                    Slog.d(TAG, "Destroying " + ps.name + " because volume was forgotten");
1892                    deletePackage(ps.name, new LegacyPackageDeleteObserver(null).getBinder(),
1893                            UserHandle.USER_SYSTEM, PackageManager.DELETE_ALL_USERS);
1894                }
1895
1896                mSettings.onVolumeForgotten(fsUuid);
1897                mSettings.writeLPr();
1898            }
1899        }
1900    };
1901
1902    private void grantRequestedRuntimePermissions(PackageParser.Package pkg, int[] userIds,
1903            String[] grantedPermissions) {
1904        for (int userId : userIds) {
1905            grantRequestedRuntimePermissionsForUser(pkg, userId, grantedPermissions);
1906        }
1907
1908        // We could have touched GID membership, so flush out packages.list
1909        synchronized (mPackages) {
1910            mSettings.writePackageListLPr();
1911        }
1912    }
1913
1914    private void grantRequestedRuntimePermissionsForUser(PackageParser.Package pkg, int userId,
1915            String[] grantedPermissions) {
1916        SettingBase sb = (SettingBase) pkg.mExtras;
1917        if (sb == null) {
1918            return;
1919        }
1920
1921        PermissionsState permissionsState = sb.getPermissionsState();
1922
1923        final int immutableFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
1924                | PackageManager.FLAG_PERMISSION_POLICY_FIXED;
1925
1926        for (String permission : pkg.requestedPermissions) {
1927            final BasePermission bp;
1928            synchronized (mPackages) {
1929                bp = mSettings.mPermissions.get(permission);
1930            }
1931            if (bp != null && (bp.isRuntime() || bp.isDevelopment())
1932                    && (grantedPermissions == null
1933                           || ArrayUtils.contains(grantedPermissions, permission))) {
1934                final int flags = permissionsState.getPermissionFlags(permission, userId);
1935                // Installer cannot change immutable permissions.
1936                if ((flags & immutableFlags) == 0) {
1937                    grantRuntimePermission(pkg.packageName, permission, userId);
1938                }
1939            }
1940        }
1941    }
1942
1943    Bundle extrasForInstallResult(PackageInstalledInfo res) {
1944        Bundle extras = null;
1945        switch (res.returnCode) {
1946            case PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION: {
1947                extras = new Bundle();
1948                extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PERMISSION,
1949                        res.origPermission);
1950                extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PACKAGE,
1951                        res.origPackage);
1952                break;
1953            }
1954            case PackageManager.INSTALL_SUCCEEDED: {
1955                extras = new Bundle();
1956                extras.putBoolean(Intent.EXTRA_REPLACING,
1957                        res.removedInfo != null && res.removedInfo.removedPackage != null);
1958                break;
1959            }
1960        }
1961        return extras;
1962    }
1963
1964    void scheduleWriteSettingsLocked() {
1965        if (!mHandler.hasMessages(WRITE_SETTINGS)) {
1966            mHandler.sendEmptyMessageDelayed(WRITE_SETTINGS, WRITE_SETTINGS_DELAY);
1967        }
1968    }
1969
1970    void scheduleWritePackageListLocked(int userId) {
1971        if (!mHandler.hasMessages(WRITE_PACKAGE_LIST)) {
1972            Message msg = mHandler.obtainMessage(WRITE_PACKAGE_LIST);
1973            msg.arg1 = userId;
1974            mHandler.sendMessageDelayed(msg, WRITE_SETTINGS_DELAY);
1975        }
1976    }
1977
1978    void scheduleWritePackageRestrictionsLocked(UserHandle user) {
1979        final int userId = user == null ? UserHandle.USER_ALL : user.getIdentifier();
1980        scheduleWritePackageRestrictionsLocked(userId);
1981    }
1982
1983    void scheduleWritePackageRestrictionsLocked(int userId) {
1984        final int[] userIds = (userId == UserHandle.USER_ALL)
1985                ? sUserManager.getUserIds() : new int[]{userId};
1986        for (int nextUserId : userIds) {
1987            if (!sUserManager.exists(nextUserId)) return;
1988            mDirtyUsers.add(nextUserId);
1989            if (!mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) {
1990                mHandler.sendEmptyMessageDelayed(WRITE_PACKAGE_RESTRICTIONS, WRITE_SETTINGS_DELAY);
1991            }
1992        }
1993    }
1994
1995    public static PackageManagerService main(Context context, Installer installer,
1996            boolean factoryTest, boolean onlyCore) {
1997        // Self-check for initial settings.
1998        PackageManagerServiceCompilerMapping.checkProperties();
1999
2000        PackageManagerService m = new PackageManagerService(context, installer,
2001                factoryTest, onlyCore);
2002        m.enableSystemUserPackages();
2003        ServiceManager.addService("package", m);
2004        return m;
2005    }
2006
2007    private void enableSystemUserPackages() {
2008        if (!UserManager.isSplitSystemUser()) {
2009            return;
2010        }
2011        // For system user, enable apps based on the following conditions:
2012        // - app is whitelisted or belong to one of these groups:
2013        //   -- system app which has no launcher icons
2014        //   -- system app which has INTERACT_ACROSS_USERS permission
2015        //   -- system IME app
2016        // - app is not in the blacklist
2017        AppsQueryHelper queryHelper = new AppsQueryHelper(this);
2018        Set<String> enableApps = new ArraySet<>();
2019        enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_NON_LAUNCHABLE_APPS
2020                | AppsQueryHelper.GET_APPS_WITH_INTERACT_ACROSS_USERS_PERM
2021                | AppsQueryHelper.GET_IMES, /* systemAppsOnly */ true, UserHandle.SYSTEM));
2022        ArraySet<String> wlApps = SystemConfig.getInstance().getSystemUserWhitelistedApps();
2023        enableApps.addAll(wlApps);
2024        enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_REQUIRED_FOR_SYSTEM_USER,
2025                /* systemAppsOnly */ false, UserHandle.SYSTEM));
2026        ArraySet<String> blApps = SystemConfig.getInstance().getSystemUserBlacklistedApps();
2027        enableApps.removeAll(blApps);
2028        Log.i(TAG, "Applications installed for system user: " + enableApps);
2029        List<String> allAps = queryHelper.queryApps(0, /* systemAppsOnly */ false,
2030                UserHandle.SYSTEM);
2031        final int allAppsSize = allAps.size();
2032        synchronized (mPackages) {
2033            for (int i = 0; i < allAppsSize; i++) {
2034                String pName = allAps.get(i);
2035                PackageSetting pkgSetting = mSettings.mPackages.get(pName);
2036                // Should not happen, but we shouldn't be failing if it does
2037                if (pkgSetting == null) {
2038                    continue;
2039                }
2040                boolean install = enableApps.contains(pName);
2041                if (pkgSetting.getInstalled(UserHandle.USER_SYSTEM) != install) {
2042                    Log.i(TAG, (install ? "Installing " : "Uninstalling ") + pName
2043                            + " for system user");
2044                    pkgSetting.setInstalled(install, UserHandle.USER_SYSTEM);
2045                }
2046            }
2047        }
2048    }
2049
2050    private static void getDefaultDisplayMetrics(Context context, DisplayMetrics metrics) {
2051        DisplayManager displayManager = (DisplayManager) context.getSystemService(
2052                Context.DISPLAY_SERVICE);
2053        displayManager.getDisplay(Display.DEFAULT_DISPLAY).getMetrics(metrics);
2054    }
2055
2056    /**
2057     * Requests that files preopted on a secondary system partition be copied to the data partition
2058     * if possible.  Note that the actual copying of the files is accomplished by init for security
2059     * reasons. This simply requests that the copy takes place and awaits confirmation of its
2060     * completion. See platform/system/extras/cppreopt/ for the implementation of the actual copy.
2061     */
2062    private static void requestCopyPreoptedFiles() {
2063        final int WAIT_TIME_MS = 100;
2064        final String CP_PREOPT_PROPERTY = "sys.cppreopt";
2065        if (SystemProperties.getInt("ro.cp_system_other_odex", 0) == 1) {
2066            SystemProperties.set(CP_PREOPT_PROPERTY, "requested");
2067            // We will wait for up to 100 seconds.
2068            final long timeEnd = SystemClock.uptimeMillis() + 100 * 1000;
2069            while (!SystemProperties.get(CP_PREOPT_PROPERTY).equals("finished")) {
2070                try {
2071                    Thread.sleep(WAIT_TIME_MS);
2072                } catch (InterruptedException e) {
2073                    // Do nothing
2074                }
2075                if (SystemClock.uptimeMillis() > timeEnd) {
2076                    SystemProperties.set(CP_PREOPT_PROPERTY, "timed-out");
2077                    Slog.wtf(TAG, "cppreopt did not finish!");
2078                    break;
2079                }
2080            }
2081        }
2082    }
2083
2084    public PackageManagerService(Context context, Installer installer,
2085            boolean factoryTest, boolean onlyCore) {
2086        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START,
2087                SystemClock.uptimeMillis());
2088
2089        if (mSdkVersion <= 0) {
2090            Slog.w(TAG, "**** ro.build.version.sdk not set!");
2091        }
2092
2093        mContext = context;
2094
2095        mPermissionReviewRequired = context.getResources().getBoolean(
2096                R.bool.config_permissionReviewRequired);
2097
2098        mFactoryTest = factoryTest;
2099        mOnlyCore = onlyCore;
2100        mMetrics = new DisplayMetrics();
2101        mSettings = new Settings(mPackages);
2102        mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID,
2103                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2104        mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID,
2105                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2106        mSettings.addSharedUserLPw("android.uid.log", LOG_UID,
2107                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2108        mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID,
2109                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2110        mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID,
2111                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2112        mSettings.addSharedUserLPw("android.uid.shell", SHELL_UID,
2113                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2114
2115        String separateProcesses = SystemProperties.get("debug.separate_processes");
2116        if (separateProcesses != null && separateProcesses.length() > 0) {
2117            if ("*".equals(separateProcesses)) {
2118                mDefParseFlags = PackageParser.PARSE_IGNORE_PROCESSES;
2119                mSeparateProcesses = null;
2120                Slog.w(TAG, "Running with debug.separate_processes: * (ALL)");
2121            } else {
2122                mDefParseFlags = 0;
2123                mSeparateProcesses = separateProcesses.split(",");
2124                Slog.w(TAG, "Running with debug.separate_processes: "
2125                        + separateProcesses);
2126            }
2127        } else {
2128            mDefParseFlags = 0;
2129            mSeparateProcesses = null;
2130        }
2131
2132        mInstaller = installer;
2133        mPackageDexOptimizer = new PackageDexOptimizer(installer, mInstallLock, context,
2134                "*dexopt*");
2135        mDexManager = new DexManager(this, mPackageDexOptimizer, installer, mInstallLock);
2136        mMoveCallbacks = new MoveCallbacks(FgThread.get().getLooper());
2137
2138        mOnPermissionChangeListeners = new OnPermissionChangeListeners(
2139                FgThread.get().getLooper());
2140
2141        getDefaultDisplayMetrics(context, mMetrics);
2142
2143        SystemConfig systemConfig = SystemConfig.getInstance();
2144        mGlobalGids = systemConfig.getGlobalGids();
2145        mSystemPermissions = systemConfig.getSystemPermissions();
2146        mAvailableFeatures = systemConfig.getAvailableFeatures();
2147
2148        mProtectedPackages = new ProtectedPackages(mContext);
2149
2150        synchronized (mInstallLock) {
2151        // writer
2152        synchronized (mPackages) {
2153            mHandlerThread = new ServiceThread(TAG,
2154                    Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
2155            mHandlerThread.start();
2156            mHandler = new PackageHandler(mHandlerThread.getLooper());
2157            mProcessLoggingHandler = new ProcessLoggingHandler();
2158            Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT);
2159
2160            mDefaultPermissionPolicy = new DefaultPermissionGrantPolicy(this);
2161
2162            File dataDir = Environment.getDataDirectory();
2163            mAppInstallDir = new File(dataDir, "app");
2164            mAppLib32InstallDir = new File(dataDir, "app-lib");
2165            mEphemeralInstallDir = new File(dataDir, "app-ephemeral");
2166            mAsecInternalPath = new File(dataDir, "app-asec").getPath();
2167            mDrmAppPrivateInstallDir = new File(dataDir, "app-private");
2168
2169            sUserManager = new UserManagerService(context, this, mPackages);
2170
2171            // Propagate permission configuration in to package manager.
2172            ArrayMap<String, SystemConfig.PermissionEntry> permConfig
2173                    = systemConfig.getPermissions();
2174            for (int i=0; i<permConfig.size(); i++) {
2175                SystemConfig.PermissionEntry perm = permConfig.valueAt(i);
2176                BasePermission bp = mSettings.mPermissions.get(perm.name);
2177                if (bp == null) {
2178                    bp = new BasePermission(perm.name, "android", BasePermission.TYPE_BUILTIN);
2179                    mSettings.mPermissions.put(perm.name, bp);
2180                }
2181                if (perm.gids != null) {
2182                    bp.setGids(perm.gids, perm.perUser);
2183                }
2184            }
2185
2186            ArrayMap<String, String> libConfig = systemConfig.getSharedLibraries();
2187            for (int i=0; i<libConfig.size(); i++) {
2188                mSharedLibraries.put(libConfig.keyAt(i),
2189                        new SharedLibraryEntry(libConfig.valueAt(i), null));
2190            }
2191
2192            mFoundPolicyFile = SELinuxMMAC.readInstallPolicy();
2193
2194            mFirstBoot = !mSettings.readLPw(sUserManager.getUsers(false));
2195
2196            // Clean up orphaned packages for which the code path doesn't exist
2197            // and they are an update to a system app - caused by bug/32321269
2198            final int packageSettingCount = mSettings.mPackages.size();
2199            for (int i = packageSettingCount - 1; i >= 0; i--) {
2200                PackageSetting ps = mSettings.mPackages.valueAt(i);
2201                if (!isExternal(ps) && (ps.codePath == null || !ps.codePath.exists())
2202                        && mSettings.getDisabledSystemPkgLPr(ps.name) != null) {
2203                    mSettings.mPackages.removeAt(i);
2204                    mSettings.enableSystemPackageLPw(ps.name);
2205                }
2206            }
2207
2208            if (mFirstBoot) {
2209                requestCopyPreoptedFiles();
2210            }
2211
2212            String customResolverActivity = Resources.getSystem().getString(
2213                    R.string.config_customResolverActivity);
2214            if (TextUtils.isEmpty(customResolverActivity)) {
2215                customResolverActivity = null;
2216            } else {
2217                mCustomResolverComponentName = ComponentName.unflattenFromString(
2218                        customResolverActivity);
2219            }
2220
2221            long startTime = SystemClock.uptimeMillis();
2222
2223            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START,
2224                    startTime);
2225
2226            // Set flag to monitor and not change apk file paths when
2227            // scanning install directories.
2228            final int scanFlags = SCAN_NO_PATHS | SCAN_DEFER_DEX | SCAN_BOOTING | SCAN_INITIAL;
2229
2230            final String bootClassPath = System.getenv("BOOTCLASSPATH");
2231            final String systemServerClassPath = System.getenv("SYSTEMSERVERCLASSPATH");
2232
2233            if (bootClassPath == null) {
2234                Slog.w(TAG, "No BOOTCLASSPATH found!");
2235            }
2236
2237            if (systemServerClassPath == null) {
2238                Slog.w(TAG, "No SYSTEMSERVERCLASSPATH found!");
2239            }
2240
2241            final List<String> allInstructionSets = InstructionSets.getAllInstructionSets();
2242            final String[] dexCodeInstructionSets =
2243                    getDexCodeInstructionSets(
2244                            allInstructionSets.toArray(new String[allInstructionSets.size()]));
2245
2246            /**
2247             * Ensure all external libraries have had dexopt run on them.
2248             */
2249            if (mSharedLibraries.size() > 0) {
2250                // NOTE: For now, we're compiling these system "shared libraries"
2251                // (and framework jars) into all available architectures. It's possible
2252                // to compile them only when we come across an app that uses them (there's
2253                // already logic for that in scanPackageLI) but that adds some complexity.
2254                for (String dexCodeInstructionSet : dexCodeInstructionSets) {
2255                    for (SharedLibraryEntry libEntry : mSharedLibraries.values()) {
2256                        final String lib = libEntry.path;
2257                        if (lib == null) {
2258                            continue;
2259                        }
2260
2261                        try {
2262                            // Shared libraries do not have profiles so we perform a full
2263                            // AOT compilation (if needed).
2264                            int dexoptNeeded = DexFile.getDexOptNeeded(
2265                                    lib, dexCodeInstructionSet,
2266                                    getCompilerFilterForReason(REASON_SHARED_APK),
2267                                    false /* newProfile */);
2268                            if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) {
2269                                mInstaller.dexopt(lib, Process.SYSTEM_UID, "*",
2270                                        dexCodeInstructionSet, dexoptNeeded, null,
2271                                        DEXOPT_PUBLIC,
2272                                        getCompilerFilterForReason(REASON_SHARED_APK),
2273                                        StorageManager.UUID_PRIVATE_INTERNAL,
2274                                        PackageDexOptimizer.SKIP_SHARED_LIBRARY_CHECK);
2275                            }
2276                        } catch (FileNotFoundException e) {
2277                            Slog.w(TAG, "Library not found: " + lib);
2278                        } catch (IOException | InstallerException e) {
2279                            Slog.w(TAG, "Cannot dexopt " + lib + "; is it an APK or JAR? "
2280                                    + e.getMessage());
2281                        }
2282                    }
2283                }
2284            }
2285
2286            File frameworkDir = new File(Environment.getRootDirectory(), "framework");
2287
2288            final VersionInfo ver = mSettings.getInternalVersion();
2289            mIsUpgrade = !Build.FINGERPRINT.equals(ver.fingerprint);
2290
2291            // when upgrading from pre-M, promote system app permissions from install to runtime
2292            mPromoteSystemApps =
2293                    mIsUpgrade && ver.sdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1;
2294
2295            // When upgrading from pre-N, we need to handle package extraction like first boot,
2296            // as there is no profiling data available.
2297            mIsPreNUpgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N;
2298
2299            mIsPreNMR1Upgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N_MR1;
2300
2301            // save off the names of pre-existing system packages prior to scanning; we don't
2302            // want to automatically grant runtime permissions for new system apps
2303            if (mPromoteSystemApps) {
2304                Iterator<PackageSetting> pkgSettingIter = mSettings.mPackages.values().iterator();
2305                while (pkgSettingIter.hasNext()) {
2306                    PackageSetting ps = pkgSettingIter.next();
2307                    if (isSystemApp(ps)) {
2308                        mExistingSystemPackages.add(ps.name);
2309                    }
2310                }
2311            }
2312
2313            // Collect vendor overlay packages. (Do this before scanning any apps.)
2314            // For security and version matching reason, only consider
2315            // overlay packages if they reside in the right directory.
2316            String overlayThemeDir = SystemProperties.get(VENDOR_OVERLAY_THEME_PROPERTY);
2317            if (!overlayThemeDir.isEmpty()) {
2318                scanDirTracedLI(new File(VENDOR_OVERLAY_DIR, overlayThemeDir), mDefParseFlags
2319                        | PackageParser.PARSE_IS_SYSTEM
2320                        | PackageParser.PARSE_IS_SYSTEM_DIR
2321                        | PackageParser.PARSE_TRUSTED_OVERLAY, scanFlags | SCAN_TRUSTED_OVERLAY, 0);
2322            }
2323            scanDirTracedLI(new File(VENDOR_OVERLAY_DIR), mDefParseFlags
2324                    | PackageParser.PARSE_IS_SYSTEM
2325                    | PackageParser.PARSE_IS_SYSTEM_DIR
2326                    | PackageParser.PARSE_TRUSTED_OVERLAY, scanFlags | SCAN_TRUSTED_OVERLAY, 0);
2327
2328            // Find base frameworks (resource packages without code).
2329            scanDirTracedLI(frameworkDir, mDefParseFlags
2330                    | PackageParser.PARSE_IS_SYSTEM
2331                    | PackageParser.PARSE_IS_SYSTEM_DIR
2332                    | PackageParser.PARSE_IS_PRIVILEGED,
2333                    scanFlags | SCAN_NO_DEX, 0);
2334
2335            // Collected privileged system packages.
2336            final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app");
2337            scanDirTracedLI(privilegedAppDir, mDefParseFlags
2338                    | PackageParser.PARSE_IS_SYSTEM
2339                    | PackageParser.PARSE_IS_SYSTEM_DIR
2340                    | PackageParser.PARSE_IS_PRIVILEGED, scanFlags, 0);
2341
2342            // Collect ordinary system packages.
2343            final File systemAppDir = new File(Environment.getRootDirectory(), "app");
2344            scanDirTracedLI(systemAppDir, mDefParseFlags
2345                    | PackageParser.PARSE_IS_SYSTEM
2346                    | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
2347
2348            // Collect all vendor packages.
2349            File vendorAppDir = new File("/vendor/app");
2350            try {
2351                vendorAppDir = vendorAppDir.getCanonicalFile();
2352            } catch (IOException e) {
2353                // failed to look up canonical path, continue with original one
2354            }
2355            scanDirTracedLI(vendorAppDir, mDefParseFlags
2356                    | PackageParser.PARSE_IS_SYSTEM
2357                    | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
2358
2359            // Collect all OEM packages.
2360            final File oemAppDir = new File(Environment.getOemDirectory(), "app");
2361            scanDirTracedLI(oemAppDir, mDefParseFlags
2362                    | PackageParser.PARSE_IS_SYSTEM
2363                    | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
2364
2365            // Prune any system packages that no longer exist.
2366            final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<String>();
2367            if (!mOnlyCore) {
2368                Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
2369                while (psit.hasNext()) {
2370                    PackageSetting ps = psit.next();
2371
2372                    /*
2373                     * If this is not a system app, it can't be a
2374                     * disable system app.
2375                     */
2376                    if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
2377                        continue;
2378                    }
2379
2380                    /*
2381                     * If the package is scanned, it's not erased.
2382                     */
2383                    final PackageParser.Package scannedPkg = mPackages.get(ps.name);
2384                    if (scannedPkg != null) {
2385                        /*
2386                         * If the system app is both scanned and in the
2387                         * disabled packages list, then it must have been
2388                         * added via OTA. Remove it from the currently
2389                         * scanned package so the previously user-installed
2390                         * application can be scanned.
2391                         */
2392                        if (mSettings.isDisabledSystemPackageLPr(ps.name)) {
2393                            logCriticalInfo(Log.WARN, "Expecting better updated system app for "
2394                                    + ps.name + "; removing system app.  Last known codePath="
2395                                    + ps.codePathString + ", installStatus=" + ps.installStatus
2396                                    + ", versionCode=" + ps.versionCode + "; scanned versionCode="
2397                                    + scannedPkg.mVersionCode);
2398                            removePackageLI(scannedPkg, true);
2399                            mExpectingBetter.put(ps.name, ps.codePath);
2400                        }
2401
2402                        continue;
2403                    }
2404
2405                    if (!mSettings.isDisabledSystemPackageLPr(ps.name)) {
2406                        psit.remove();
2407                        logCriticalInfo(Log.WARN, "System package " + ps.name
2408                                + " no longer exists; it's data will be wiped");
2409                        // Actual deletion of code and data will be handled by later
2410                        // reconciliation step
2411                    } else {
2412                        final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(ps.name);
2413                        if (disabledPs.codePath == null || !disabledPs.codePath.exists()) {
2414                            possiblyDeletedUpdatedSystemApps.add(ps.name);
2415                        }
2416                    }
2417                }
2418            }
2419
2420            //look for any incomplete package installations
2421            ArrayList<PackageSetting> deletePkgsList = mSettings.getListOfIncompleteInstallPackagesLPr();
2422            for (int i = 0; i < deletePkgsList.size(); i++) {
2423                // Actual deletion of code and data will be handled by later
2424                // reconciliation step
2425                final String packageName = deletePkgsList.get(i).name;
2426                logCriticalInfo(Log.WARN, "Cleaning up incompletely installed app: " + packageName);
2427                synchronized (mPackages) {
2428                    mSettings.removePackageLPw(packageName);
2429                }
2430            }
2431
2432            //delete tmp files
2433            deleteTempPackageFiles();
2434
2435            // Remove any shared userIDs that have no associated packages
2436            mSettings.pruneSharedUsersLPw();
2437
2438            if (!mOnlyCore) {
2439                EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,
2440                        SystemClock.uptimeMillis());
2441                scanDirTracedLI(mAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0);
2442
2443                scanDirTracedLI(mDrmAppPrivateInstallDir, mDefParseFlags
2444                        | PackageParser.PARSE_FORWARD_LOCK,
2445                        scanFlags | SCAN_REQUIRE_KNOWN, 0);
2446
2447                scanDirLI(mEphemeralInstallDir, mDefParseFlags
2448                        | PackageParser.PARSE_IS_EPHEMERAL,
2449                        scanFlags | SCAN_REQUIRE_KNOWN, 0);
2450
2451                /**
2452                 * Remove disable package settings for any updated system
2453                 * apps that were removed via an OTA. If they're not a
2454                 * previously-updated app, remove them completely.
2455                 * Otherwise, just revoke their system-level permissions.
2456                 */
2457                for (String deletedAppName : possiblyDeletedUpdatedSystemApps) {
2458                    PackageParser.Package deletedPkg = mPackages.get(deletedAppName);
2459                    mSettings.removeDisabledSystemPackageLPw(deletedAppName);
2460
2461                    String msg;
2462                    if (deletedPkg == null) {
2463                        msg = "Updated system package " + deletedAppName
2464                                + " no longer exists; it's data will be wiped";
2465                        // Actual deletion of code and data will be handled by later
2466                        // reconciliation step
2467                    } else {
2468                        msg = "Updated system app + " + deletedAppName
2469                                + " no longer present; removing system privileges for "
2470                                + deletedAppName;
2471
2472                        deletedPkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM;
2473
2474                        PackageSetting deletedPs = mSettings.mPackages.get(deletedAppName);
2475                        deletedPs.pkgFlags &= ~ApplicationInfo.FLAG_SYSTEM;
2476                    }
2477                    logCriticalInfo(Log.WARN, msg);
2478                }
2479
2480                /**
2481                 * Make sure all system apps that we expected to appear on
2482                 * the userdata partition actually showed up. If they never
2483                 * appeared, crawl back and revive the system version.
2484                 */
2485                for (int i = 0; i < mExpectingBetter.size(); i++) {
2486                    final String packageName = mExpectingBetter.keyAt(i);
2487                    if (!mPackages.containsKey(packageName)) {
2488                        final File scanFile = mExpectingBetter.valueAt(i);
2489
2490                        logCriticalInfo(Log.WARN, "Expected better " + packageName
2491                                + " but never showed up; reverting to system");
2492
2493                        int reparseFlags = mDefParseFlags;
2494                        if (FileUtils.contains(privilegedAppDir, scanFile)) {
2495                            reparseFlags = PackageParser.PARSE_IS_SYSTEM
2496                                    | PackageParser.PARSE_IS_SYSTEM_DIR
2497                                    | PackageParser.PARSE_IS_PRIVILEGED;
2498                        } else if (FileUtils.contains(systemAppDir, scanFile)) {
2499                            reparseFlags = PackageParser.PARSE_IS_SYSTEM
2500                                    | PackageParser.PARSE_IS_SYSTEM_DIR;
2501                        } else if (FileUtils.contains(vendorAppDir, scanFile)) {
2502                            reparseFlags = PackageParser.PARSE_IS_SYSTEM
2503                                    | PackageParser.PARSE_IS_SYSTEM_DIR;
2504                        } else if (FileUtils.contains(oemAppDir, scanFile)) {
2505                            reparseFlags = PackageParser.PARSE_IS_SYSTEM
2506                                    | PackageParser.PARSE_IS_SYSTEM_DIR;
2507                        } else {
2508                            Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile);
2509                            continue;
2510                        }
2511
2512                        mSettings.enableSystemPackageLPw(packageName);
2513
2514                        try {
2515                            scanPackageTracedLI(scanFile, reparseFlags, scanFlags, 0, null);
2516                        } catch (PackageManagerException e) {
2517                            Slog.e(TAG, "Failed to parse original system package: "
2518                                    + e.getMessage());
2519                        }
2520                    }
2521                }
2522            }
2523            mExpectingBetter.clear();
2524
2525            // Resolve the storage manager.
2526            mStorageManagerPackage = getStorageManagerPackageName();
2527
2528            // Resolve protected action filters. Only the setup wizard is allowed to
2529            // have a high priority filter for these actions.
2530            mSetupWizardPackage = getSetupWizardPackageName();
2531            if (mProtectedFilters.size() > 0) {
2532                if (DEBUG_FILTERS && mSetupWizardPackage == null) {
2533                    Slog.i(TAG, "No setup wizard;"
2534                        + " All protected intents capped to priority 0");
2535                }
2536                for (ActivityIntentInfo filter : mProtectedFilters) {
2537                    if (filter.activity.info.packageName.equals(mSetupWizardPackage)) {
2538                        if (DEBUG_FILTERS) {
2539                            Slog.i(TAG, "Found setup wizard;"
2540                                + " allow priority " + filter.getPriority() + ";"
2541                                + " package: " + filter.activity.info.packageName
2542                                + " activity: " + filter.activity.className
2543                                + " priority: " + filter.getPriority());
2544                        }
2545                        // skip setup wizard; allow it to keep the high priority filter
2546                        continue;
2547                    }
2548                    Slog.w(TAG, "Protected action; cap priority to 0;"
2549                            + " package: " + filter.activity.info.packageName
2550                            + " activity: " + filter.activity.className
2551                            + " origPrio: " + filter.getPriority());
2552                    filter.setPriority(0);
2553                }
2554            }
2555            mDeferProtectedFilters = false;
2556            mProtectedFilters.clear();
2557
2558            // Now that we know all of the shared libraries, update all clients to have
2559            // the correct library paths.
2560            updateAllSharedLibrariesLPw();
2561
2562            for (SharedUserSetting setting : mSettings.getAllSharedUsersLPw()) {
2563                // NOTE: We ignore potential failures here during a system scan (like
2564                // the rest of the commands above) because there's precious little we
2565                // can do about it. A settings error is reported, though.
2566                adjustCpuAbisForSharedUserLPw(setting.packages, null /* scanned package */,
2567                        false /* boot complete */);
2568            }
2569
2570            // Now that we know all the packages we are keeping,
2571            // read and update their last usage times.
2572            mPackageUsage.read(mPackages);
2573            mCompilerStats.read();
2574
2575            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END,
2576                    SystemClock.uptimeMillis());
2577            Slog.i(TAG, "Time to scan packages: "
2578                    + ((SystemClock.uptimeMillis()-startTime)/1000f)
2579                    + " seconds");
2580
2581            // If the platform SDK has changed since the last time we booted,
2582            // we need to re-grant app permission to catch any new ones that
2583            // appear.  This is really a hack, and means that apps can in some
2584            // cases get permissions that the user didn't initially explicitly
2585            // allow...  it would be nice to have some better way to handle
2586            // this situation.
2587            int updateFlags = UPDATE_PERMISSIONS_ALL;
2588            if (ver.sdkVersion != mSdkVersion) {
2589                Slog.i(TAG, "Platform changed from " + ver.sdkVersion + " to "
2590                        + mSdkVersion + "; regranting permissions for internal storage");
2591                updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
2592            }
2593            updatePermissionsLPw(null, null, StorageManager.UUID_PRIVATE_INTERNAL, updateFlags);
2594            ver.sdkVersion = mSdkVersion;
2595
2596            // If this is the first boot or an update from pre-M, and it is a normal
2597            // boot, then we need to initialize the default preferred apps across
2598            // all defined users.
2599            if (!onlyCore && (mPromoteSystemApps || mFirstBoot)) {
2600                for (UserInfo user : sUserManager.getUsers(true)) {
2601                    mSettings.applyDefaultPreferredAppsLPw(this, user.id);
2602                    applyFactoryDefaultBrowserLPw(user.id);
2603                    primeDomainVerificationsLPw(user.id);
2604                }
2605            }
2606
2607            // Prepare storage for system user really early during boot,
2608            // since core system apps like SettingsProvider and SystemUI
2609            // can't wait for user to start
2610            final int storageFlags;
2611            if (StorageManager.isFileEncryptedNativeOrEmulated()) {
2612                storageFlags = StorageManager.FLAG_STORAGE_DE;
2613            } else {
2614                storageFlags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
2615            }
2616            reconcileAppsDataLI(StorageManager.UUID_PRIVATE_INTERNAL, UserHandle.USER_SYSTEM,
2617                    storageFlags);
2618
2619            // If this is first boot after an OTA, and a normal boot, then
2620            // we need to clear code cache directories.
2621            // Note that we do *not* clear the application profiles. These remain valid
2622            // across OTAs and are used to drive profile verification (post OTA) and
2623            // profile compilation (without waiting to collect a fresh set of profiles).
2624            if (mIsUpgrade && !onlyCore) {
2625                Slog.i(TAG, "Build fingerprint changed; clearing code caches");
2626                for (int i = 0; i < mSettings.mPackages.size(); i++) {
2627                    final PackageSetting ps = mSettings.mPackages.valueAt(i);
2628                    if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, ps.volumeUuid)) {
2629                        // No apps are running this early, so no need to freeze
2630                        clearAppDataLIF(ps.pkg, UserHandle.USER_ALL,
2631                                StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE
2632                                        | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
2633                    }
2634                }
2635                ver.fingerprint = Build.FINGERPRINT;
2636            }
2637
2638            checkDefaultBrowser();
2639
2640            // clear only after permissions and other defaults have been updated
2641            mExistingSystemPackages.clear();
2642            mPromoteSystemApps = false;
2643
2644            // All the changes are done during package scanning.
2645            ver.databaseVersion = Settings.CURRENT_DATABASE_VERSION;
2646
2647            // can downgrade to reader
2648            mSettings.writeLPr();
2649
2650            // Perform dexopt on all apps that mark themselves as coreApps. We do this pretty
2651            // early on (before the package manager declares itself as early) because other
2652            // components in the system server might ask for package contexts for these apps.
2653            //
2654            // Note that "onlyCore" in this context means the system is encrypted or encrypting
2655            // (i.e, that the data partition is unavailable).
2656            if ((isFirstBoot() || isUpgrade() || VMRuntime.didPruneDalvikCache()) && !onlyCore) {
2657                long start = System.nanoTime();
2658                List<PackageParser.Package> coreApps = new ArrayList<>();
2659                for (PackageParser.Package pkg : mPackages.values()) {
2660                    if (pkg.coreApp) {
2661                        coreApps.add(pkg);
2662                    }
2663                }
2664
2665                int[] stats = performDexOptUpgrade(coreApps, false,
2666                        getCompilerFilterForReason(REASON_CORE_APP));
2667
2668                final int elapsedTimeSeconds =
2669                        (int) TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - start);
2670                MetricsLogger.histogram(mContext, "opt_coreapps_time_s", elapsedTimeSeconds);
2671
2672                if (DEBUG_DEXOPT) {
2673                    Slog.i(TAG, "Dex-opt core apps took : " + elapsedTimeSeconds + " seconds (" +
2674                            stats[0] + ", " + stats[1] + ", " + stats[2] + ")");
2675                }
2676
2677
2678                // TODO: Should we log these stats to tron too ?
2679                // MetricsLogger.histogram(mContext, "opt_coreapps_num_dexopted", stats[0]);
2680                // MetricsLogger.histogram(mContext, "opt_coreapps_num_skipped", stats[1]);
2681                // MetricsLogger.histogram(mContext, "opt_coreapps_num_failed", stats[2]);
2682                // MetricsLogger.histogram(mContext, "opt_coreapps_num_total", coreApps.size());
2683            }
2684
2685            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY,
2686                    SystemClock.uptimeMillis());
2687
2688            if (!mOnlyCore) {
2689                mRequiredVerifierPackage = getRequiredButNotReallyRequiredVerifierLPr();
2690                mRequiredInstallerPackage = getRequiredInstallerLPr();
2691                mRequiredUninstallerPackage = getRequiredUninstallerLPr();
2692                mIntentFilterVerifierComponent = getIntentFilterVerifierComponentNameLPr();
2693                mIntentFilterVerifier = new IntentVerifierProxy(mContext,
2694                        mIntentFilterVerifierComponent);
2695                mServicesSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr(
2696                        PackageManager.SYSTEM_SHARED_LIBRARY_SERVICES);
2697                mSharedSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr(
2698                        PackageManager.SYSTEM_SHARED_LIBRARY_SHARED);
2699            } else {
2700                mRequiredVerifierPackage = null;
2701                mRequiredInstallerPackage = null;
2702                mRequiredUninstallerPackage = null;
2703                mIntentFilterVerifierComponent = null;
2704                mIntentFilterVerifier = null;
2705                mServicesSystemSharedLibraryPackageName = null;
2706                mSharedSystemSharedLibraryPackageName = null;
2707            }
2708
2709            mInstallerService = new PackageInstallerService(context, this);
2710
2711            final ComponentName ephemeralResolverComponent = getEphemeralResolverLPr();
2712            final ComponentName ephemeralInstallerComponent = getEphemeralInstallerLPr();
2713            // both the installer and resolver must be present to enable ephemeral
2714            if (ephemeralInstallerComponent != null && ephemeralResolverComponent != null) {
2715                if (DEBUG_EPHEMERAL) {
2716                    Slog.i(TAG, "Ephemeral activated; resolver: " + ephemeralResolverComponent
2717                            + " installer:" + ephemeralInstallerComponent);
2718                }
2719                mEphemeralResolverComponent = ephemeralResolverComponent;
2720                mEphemeralInstallerComponent = ephemeralInstallerComponent;
2721                setUpEphemeralInstallerActivityLP(mEphemeralInstallerComponent);
2722                mEphemeralResolverConnection =
2723                        new EphemeralResolverConnection(mContext, mEphemeralResolverComponent);
2724            } else {
2725                if (DEBUG_EPHEMERAL) {
2726                    final String missingComponent =
2727                            (ephemeralResolverComponent == null)
2728                            ? (ephemeralInstallerComponent == null)
2729                                    ? "resolver and installer"
2730                                    : "resolver"
2731                            : "installer";
2732                    Slog.i(TAG, "Ephemeral deactivated; missing " + missingComponent);
2733                }
2734                mEphemeralResolverComponent = null;
2735                mEphemeralInstallerComponent = null;
2736                mEphemeralResolverConnection = null;
2737            }
2738
2739            mEphemeralApplicationRegistry = new EphemeralApplicationRegistry(this);
2740
2741            // Read and update the usage of dex files.
2742            // Do this at the end of PM init so that all the packages have their
2743            // data directory reconciled.
2744            // At this point we know the code paths of the packages, so we can validate
2745            // the disk file and build the internal cache.
2746            // The usage file is expected to be small so loading and verifying it
2747            // should take a fairly small time compare to the other activities (e.g. package
2748            // scanning).
2749            final Map<Integer, List<PackageInfo>> userPackages = new HashMap<>();
2750            final int[] currentUserIds = UserManagerService.getInstance().getUserIds();
2751            for (int userId : currentUserIds) {
2752                userPackages.put(userId, getInstalledPackages(/*flags*/ 0, userId).getList());
2753            }
2754            mDexManager.load(userPackages);
2755        } // synchronized (mPackages)
2756        } // synchronized (mInstallLock)
2757
2758        // Now after opening every single application zip, make sure they
2759        // are all flushed.  Not really needed, but keeps things nice and
2760        // tidy.
2761        Runtime.getRuntime().gc();
2762
2763        // The initial scanning above does many calls into installd while
2764        // holding the mPackages lock, but we're mostly interested in yelling
2765        // once we have a booted system.
2766        mInstaller.setWarnIfHeld(mPackages);
2767
2768        // Expose private service for system components to use.
2769        LocalServices.addService(PackageManagerInternal.class, new PackageManagerInternalImpl());
2770    }
2771
2772    @Override
2773    public boolean isFirstBoot() {
2774        return mFirstBoot;
2775    }
2776
2777    @Override
2778    public boolean isOnlyCoreApps() {
2779        return mOnlyCore;
2780    }
2781
2782    @Override
2783    public boolean isUpgrade() {
2784        return mIsUpgrade;
2785    }
2786
2787    private @Nullable String getRequiredButNotReallyRequiredVerifierLPr() {
2788        final Intent intent = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
2789
2790        final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE,
2791                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
2792                UserHandle.USER_SYSTEM);
2793        if (matches.size() == 1) {
2794            return matches.get(0).getComponentInfo().packageName;
2795        } else if (matches.size() == 0) {
2796            Log.e(TAG, "There should probably be a verifier, but, none were found");
2797            return null;
2798        }
2799        throw new RuntimeException("There must be exactly one verifier; found " + matches);
2800    }
2801
2802    private @NonNull String getRequiredSharedLibraryLPr(String libraryName) {
2803        synchronized (mPackages) {
2804            SharedLibraryEntry libraryEntry = mSharedLibraries.get(libraryName);
2805            if (libraryEntry == null) {
2806                throw new IllegalStateException("Missing required shared library:" + libraryName);
2807            }
2808            return libraryEntry.apk;
2809        }
2810    }
2811
2812    private @NonNull String getRequiredInstallerLPr() {
2813        final Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
2814        intent.addCategory(Intent.CATEGORY_DEFAULT);
2815        intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE);
2816
2817        final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
2818                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
2819                UserHandle.USER_SYSTEM);
2820        if (matches.size() == 1) {
2821            ResolveInfo resolveInfo = matches.get(0);
2822            if (!resolveInfo.activityInfo.applicationInfo.isPrivilegedApp()) {
2823                throw new RuntimeException("The installer must be a privileged app");
2824            }
2825            return matches.get(0).getComponentInfo().packageName;
2826        } else {
2827            throw new RuntimeException("There must be exactly one installer; found " + matches);
2828        }
2829    }
2830
2831    private @NonNull String getRequiredUninstallerLPr() {
2832        final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE);
2833        intent.addCategory(Intent.CATEGORY_DEFAULT);
2834        intent.setData(Uri.fromParts(PACKAGE_SCHEME, "foo.bar", null));
2835
2836        final ResolveInfo resolveInfo = resolveIntent(intent, null,
2837                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
2838                UserHandle.USER_SYSTEM);
2839        if (resolveInfo == null ||
2840                mResolveActivity.name.equals(resolveInfo.getComponentInfo().name)) {
2841            throw new RuntimeException("There must be exactly one uninstaller; found "
2842                    + resolveInfo);
2843        }
2844        return resolveInfo.getComponentInfo().packageName;
2845    }
2846
2847    private @NonNull ComponentName getIntentFilterVerifierComponentNameLPr() {
2848        final Intent intent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION);
2849
2850        final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE,
2851                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
2852                UserHandle.USER_SYSTEM);
2853        ResolveInfo best = null;
2854        final int N = matches.size();
2855        for (int i = 0; i < N; i++) {
2856            final ResolveInfo cur = matches.get(i);
2857            final String packageName = cur.getComponentInfo().packageName;
2858            if (checkPermission(android.Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT,
2859                    packageName, UserHandle.USER_SYSTEM) != PackageManager.PERMISSION_GRANTED) {
2860                continue;
2861            }
2862
2863            if (best == null || cur.priority > best.priority) {
2864                best = cur;
2865            }
2866        }
2867
2868        if (best != null) {
2869            return best.getComponentInfo().getComponentName();
2870        } else {
2871            throw new RuntimeException("There must be at least one intent filter verifier");
2872        }
2873    }
2874
2875    private @Nullable ComponentName getEphemeralResolverLPr() {
2876        final String[] packageArray =
2877                mContext.getResources().getStringArray(R.array.config_ephemeralResolverPackage);
2878        if (packageArray.length == 0 && !Build.IS_DEBUGGABLE) {
2879            if (DEBUG_EPHEMERAL) {
2880                Slog.d(TAG, "Ephemeral resolver NOT found; empty package list");
2881            }
2882            return null;
2883        }
2884
2885        final int resolveFlags =
2886                MATCH_DIRECT_BOOT_AWARE
2887                | MATCH_DIRECT_BOOT_UNAWARE
2888                | (!Build.IS_DEBUGGABLE ? MATCH_SYSTEM_ONLY : 0);
2889        final Intent resolverIntent = new Intent(Intent.ACTION_RESOLVE_EPHEMERAL_PACKAGE);
2890        final List<ResolveInfo> resolvers = queryIntentServicesInternal(resolverIntent, null,
2891                resolveFlags, UserHandle.USER_SYSTEM);
2892
2893        final int N = resolvers.size();
2894        if (N == 0) {
2895            if (DEBUG_EPHEMERAL) {
2896                Slog.d(TAG, "Ephemeral resolver NOT found; no matching intent filters");
2897            }
2898            return null;
2899        }
2900
2901        final Set<String> possiblePackages = new ArraySet<>(Arrays.asList(packageArray));
2902        for (int i = 0; i < N; i++) {
2903            final ResolveInfo info = resolvers.get(i);
2904
2905            if (info.serviceInfo == null) {
2906                continue;
2907            }
2908
2909            final String packageName = info.serviceInfo.packageName;
2910            if (!possiblePackages.contains(packageName) && !Build.IS_DEBUGGABLE) {
2911                if (DEBUG_EPHEMERAL) {
2912                    Slog.d(TAG, "Ephemeral resolver not in allowed package list;"
2913                            + " pkg: " + packageName + ", info:" + info);
2914                }
2915                continue;
2916            }
2917
2918            if (DEBUG_EPHEMERAL) {
2919                Slog.v(TAG, "Ephemeral resolver found;"
2920                        + " pkg: " + packageName + ", info:" + info);
2921            }
2922            return new ComponentName(packageName, info.serviceInfo.name);
2923        }
2924        if (DEBUG_EPHEMERAL) {
2925            Slog.v(TAG, "Ephemeral resolver NOT found");
2926        }
2927        return null;
2928    }
2929
2930    private @Nullable ComponentName getEphemeralInstallerLPr() {
2931        final Intent intent = new Intent(Intent.ACTION_INSTALL_EPHEMERAL_PACKAGE);
2932        intent.addCategory(Intent.CATEGORY_DEFAULT);
2933        intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE);
2934
2935        final int resolveFlags =
2936                MATCH_DIRECT_BOOT_AWARE
2937                | MATCH_DIRECT_BOOT_UNAWARE
2938                | (!Build.IS_DEBUGGABLE ? MATCH_SYSTEM_ONLY : 0);
2939        final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
2940                resolveFlags, UserHandle.USER_SYSTEM);
2941        if (matches.size() == 0) {
2942            return null;
2943        } else if (matches.size() == 1) {
2944            return matches.get(0).getComponentInfo().getComponentName();
2945        } else {
2946            throw new RuntimeException(
2947                    "There must be at most one ephemeral installer; found " + matches);
2948        }
2949    }
2950
2951    private void primeDomainVerificationsLPw(int userId) {
2952        if (DEBUG_DOMAIN_VERIFICATION) {
2953            Slog.d(TAG, "Priming domain verifications in user " + userId);
2954        }
2955
2956        SystemConfig systemConfig = SystemConfig.getInstance();
2957        ArraySet<String> packages = systemConfig.getLinkedApps();
2958        ArraySet<String> domains = new ArraySet<String>();
2959
2960        for (String packageName : packages) {
2961            PackageParser.Package pkg = mPackages.get(packageName);
2962            if (pkg != null) {
2963                if (!pkg.isSystemApp()) {
2964                    Slog.w(TAG, "Non-system app '" + packageName + "' in sysconfig <app-link>");
2965                    continue;
2966                }
2967
2968                domains.clear();
2969                for (PackageParser.Activity a : pkg.activities) {
2970                    for (ActivityIntentInfo filter : a.intents) {
2971                        if (hasValidDomains(filter)) {
2972                            domains.addAll(filter.getHostsList());
2973                        }
2974                    }
2975                }
2976
2977                if (domains.size() > 0) {
2978                    if (DEBUG_DOMAIN_VERIFICATION) {
2979                        Slog.v(TAG, "      + " + packageName);
2980                    }
2981                    // 'Undefined' in the global IntentFilterVerificationInfo, i.e. the usual
2982                    // state w.r.t. the formal app-linkage "no verification attempted" state;
2983                    // and then 'always' in the per-user state actually used for intent resolution.
2984                    final IntentFilterVerificationInfo ivi;
2985                    ivi = mSettings.createIntentFilterVerificationIfNeededLPw(packageName,
2986                            new ArrayList<String>(domains));
2987                    ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED);
2988                    mSettings.updateIntentFilterVerificationStatusLPw(packageName,
2989                            INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS, userId);
2990                } else {
2991                    Slog.w(TAG, "Sysconfig <app-link> package '" + packageName
2992                            + "' does not handle web links");
2993                }
2994            } else {
2995                Slog.w(TAG, "Unknown package " + packageName + " in sysconfig <app-link>");
2996            }
2997        }
2998
2999        scheduleWritePackageRestrictionsLocked(userId);
3000        scheduleWriteSettingsLocked();
3001    }
3002
3003    private void applyFactoryDefaultBrowserLPw(int userId) {
3004        // The default browser app's package name is stored in a string resource,
3005        // with a product-specific overlay used for vendor customization.
3006        String browserPkg = mContext.getResources().getString(
3007                com.android.internal.R.string.default_browser);
3008        if (!TextUtils.isEmpty(browserPkg)) {
3009            // non-empty string => required to be a known package
3010            PackageSetting ps = mSettings.mPackages.get(browserPkg);
3011            if (ps == null) {
3012                Slog.e(TAG, "Product default browser app does not exist: " + browserPkg);
3013                browserPkg = null;
3014            } else {
3015                mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId);
3016            }
3017        }
3018
3019        // Nothing valid explicitly set? Make the factory-installed browser the explicit
3020        // default.  If there's more than one, just leave everything alone.
3021        if (browserPkg == null) {
3022            calculateDefaultBrowserLPw(userId);
3023        }
3024    }
3025
3026    private void calculateDefaultBrowserLPw(int userId) {
3027        List<String> allBrowsers = resolveAllBrowserApps(userId);
3028        final String browserPkg = (allBrowsers.size() == 1) ? allBrowsers.get(0) : null;
3029        mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId);
3030    }
3031
3032    private List<String> resolveAllBrowserApps(int userId) {
3033        // Resolve the canonical browser intent and check that the handleAllWebDataURI boolean is set
3034        List<ResolveInfo> list = queryIntentActivitiesInternal(sBrowserIntent, null,
3035                PackageManager.MATCH_ALL, userId);
3036
3037        final int count = list.size();
3038        List<String> result = new ArrayList<String>(count);
3039        for (int i=0; i<count; i++) {
3040            ResolveInfo info = list.get(i);
3041            if (info.activityInfo == null
3042                    || !info.handleAllWebDataURI
3043                    || (info.activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0
3044                    || result.contains(info.activityInfo.packageName)) {
3045                continue;
3046            }
3047            result.add(info.activityInfo.packageName);
3048        }
3049
3050        return result;
3051    }
3052
3053    private boolean packageIsBrowser(String packageName, int userId) {
3054        List<ResolveInfo> list = queryIntentActivitiesInternal(sBrowserIntent, null,
3055                PackageManager.MATCH_ALL, userId);
3056        final int N = list.size();
3057        for (int i = 0; i < N; i++) {
3058            ResolveInfo info = list.get(i);
3059            if (packageName.equals(info.activityInfo.packageName)) {
3060                return true;
3061            }
3062        }
3063        return false;
3064    }
3065
3066    private void checkDefaultBrowser() {
3067        final int myUserId = UserHandle.myUserId();
3068        final String packageName = getDefaultBrowserPackageName(myUserId);
3069        if (packageName != null) {
3070            PackageInfo info = getPackageInfo(packageName, 0, myUserId);
3071            if (info == null) {
3072                Slog.w(TAG, "Default browser no longer installed: " + packageName);
3073                synchronized (mPackages) {
3074                    applyFactoryDefaultBrowserLPw(myUserId);    // leaves ambiguous when > 1
3075                }
3076            }
3077        }
3078    }
3079
3080    @Override
3081    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
3082            throws RemoteException {
3083        try {
3084            return super.onTransact(code, data, reply, flags);
3085        } catch (RuntimeException e) {
3086            if (!(e instanceof SecurityException) && !(e instanceof IllegalArgumentException)) {
3087                Slog.wtf(TAG, "Package Manager Crash", e);
3088            }
3089            throw e;
3090        }
3091    }
3092
3093    static int[] appendInts(int[] cur, int[] add) {
3094        if (add == null) return cur;
3095        if (cur == null) return add;
3096        final int N = add.length;
3097        for (int i=0; i<N; i++) {
3098            cur = appendInt(cur, add[i]);
3099        }
3100        return cur;
3101    }
3102
3103    private PackageInfo generatePackageInfo(PackageSetting ps, int flags, int userId) {
3104        if (!sUserManager.exists(userId)) return null;
3105        if (ps == null) {
3106            return null;
3107        }
3108        final PackageParser.Package p = ps.pkg;
3109        if (p == null) {
3110            return null;
3111        }
3112
3113        final PermissionsState permissionsState = ps.getPermissionsState();
3114
3115        // Compute GIDs only if requested
3116        final int[] gids = (flags & PackageManager.GET_GIDS) == 0
3117                ? EMPTY_INT_ARRAY : permissionsState.computeGids(userId);
3118        // Compute granted permissions only if package has requested permissions
3119        final Set<String> permissions = ArrayUtils.isEmpty(p.requestedPermissions)
3120                ? Collections.<String>emptySet() : permissionsState.getPermissions(userId);
3121        final PackageUserState state = ps.readUserState(userId);
3122
3123        return PackageParser.generatePackageInfo(p, gids, flags,
3124                ps.firstInstallTime, ps.lastUpdateTime, permissions, state, userId);
3125    }
3126
3127    @Override
3128    public void checkPackageStartable(String packageName, int userId) {
3129        final boolean userKeyUnlocked = StorageManager.isUserKeyUnlocked(userId);
3130
3131        synchronized (mPackages) {
3132            final PackageSetting ps = mSettings.mPackages.get(packageName);
3133            if (ps == null) {
3134                throw new SecurityException("Package " + packageName + " was not found!");
3135            }
3136
3137            if (!ps.getInstalled(userId)) {
3138                throw new SecurityException(
3139                        "Package " + packageName + " was not installed for user " + userId + "!");
3140            }
3141
3142            if (mSafeMode && !ps.isSystem()) {
3143                throw new SecurityException("Package " + packageName + " not a system app!");
3144            }
3145
3146            if (mFrozenPackages.contains(packageName)) {
3147                throw new SecurityException("Package " + packageName + " is currently frozen!");
3148            }
3149
3150            if (!userKeyUnlocked && !(ps.pkg.applicationInfo.isDirectBootAware()
3151                    || ps.pkg.applicationInfo.isPartiallyDirectBootAware())) {
3152                throw new SecurityException("Package " + packageName + " is not encryption aware!");
3153            }
3154        }
3155    }
3156
3157    @Override
3158    public boolean isPackageAvailable(String packageName, int userId) {
3159        if (!sUserManager.exists(userId)) return false;
3160        enforceCrossUserPermission(Binder.getCallingUid(), userId,
3161                false /* requireFullPermission */, false /* checkShell */, "is package available");
3162        synchronized (mPackages) {
3163            PackageParser.Package p = mPackages.get(packageName);
3164            if (p != null) {
3165                final PackageSetting ps = (PackageSetting) p.mExtras;
3166                if (ps != null) {
3167                    final PackageUserState state = ps.readUserState(userId);
3168                    if (state != null) {
3169                        return PackageParser.isAvailable(state);
3170                    }
3171                }
3172            }
3173        }
3174        return false;
3175    }
3176
3177    @Override
3178    public PackageInfo getPackageInfo(String packageName, int flags, int userId) {
3179        if (!sUserManager.exists(userId)) return null;
3180        flags = updateFlagsForPackage(flags, userId, packageName);
3181        enforceCrossUserPermission(Binder.getCallingUid(), userId,
3182                false /* requireFullPermission */, false /* checkShell */, "get package info");
3183
3184        // reader
3185        synchronized (mPackages) {
3186            // Normalize package name to hanlde renamed packages
3187            packageName = normalizePackageNameLPr(packageName);
3188
3189            final boolean matchFactoryOnly = (flags & MATCH_FACTORY_ONLY) != 0;
3190            PackageParser.Package p = null;
3191            if (matchFactoryOnly) {
3192                final PackageSetting ps = mSettings.getDisabledSystemPkgLPr(packageName);
3193                if (ps != null) {
3194                    return generatePackageInfo(ps, flags, userId);
3195                }
3196            }
3197            if (p == null) {
3198                p = mPackages.get(packageName);
3199                if (matchFactoryOnly && p != null && !isSystemApp(p)) {
3200                    return null;
3201                }
3202            }
3203            if (DEBUG_PACKAGE_INFO)
3204                Log.v(TAG, "getPackageInfo " + packageName + ": " + p);
3205            if (p != null) {
3206                return generatePackageInfo((PackageSetting)p.mExtras, flags, userId);
3207            }
3208            if (!matchFactoryOnly && (flags & MATCH_UNINSTALLED_PACKAGES) != 0) {
3209                final PackageSetting ps = mSettings.mPackages.get(packageName);
3210                return generatePackageInfo(ps, flags, userId);
3211            }
3212        }
3213        return null;
3214    }
3215
3216    @Override
3217    public String[] currentToCanonicalPackageNames(String[] names) {
3218        String[] out = new String[names.length];
3219        // reader
3220        synchronized (mPackages) {
3221            for (int i=names.length-1; i>=0; i--) {
3222                PackageSetting ps = mSettings.mPackages.get(names[i]);
3223                out[i] = ps != null && ps.realName != null ? ps.realName : names[i];
3224            }
3225        }
3226        return out;
3227    }
3228
3229    @Override
3230    public String[] canonicalToCurrentPackageNames(String[] names) {
3231        String[] out = new String[names.length];
3232        // reader
3233        synchronized (mPackages) {
3234            for (int i=names.length-1; i>=0; i--) {
3235                String cur = mSettings.mRenamedPackages.get(names[i]);
3236                out[i] = cur != null ? cur : names[i];
3237            }
3238        }
3239        return out;
3240    }
3241
3242    @Override
3243    public int getPackageUid(String packageName, int flags, int userId) {
3244        if (!sUserManager.exists(userId)) return -1;
3245        flags = updateFlagsForPackage(flags, userId, packageName);
3246        enforceCrossUserPermission(Binder.getCallingUid(), userId,
3247                false /* requireFullPermission */, false /* checkShell */, "get package uid");
3248
3249        // reader
3250        synchronized (mPackages) {
3251            final PackageParser.Package p = mPackages.get(packageName);
3252            if (p != null && p.isMatch(flags)) {
3253                return UserHandle.getUid(userId, p.applicationInfo.uid);
3254            }
3255            if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0) {
3256                final PackageSetting ps = mSettings.mPackages.get(packageName);
3257                if (ps != null && ps.isMatch(flags)) {
3258                    return UserHandle.getUid(userId, ps.appId);
3259                }
3260            }
3261        }
3262
3263        return -1;
3264    }
3265
3266    @Override
3267    public int[] getPackageGids(String packageName, int flags, int userId) {
3268        if (!sUserManager.exists(userId)) return null;
3269        flags = updateFlagsForPackage(flags, userId, packageName);
3270        enforceCrossUserPermission(Binder.getCallingUid(), userId,
3271                false /* requireFullPermission */, false /* checkShell */,
3272                "getPackageGids");
3273
3274        // reader
3275        synchronized (mPackages) {
3276            final PackageParser.Package p = mPackages.get(packageName);
3277            if (p != null && p.isMatch(flags)) {
3278                PackageSetting ps = (PackageSetting) p.mExtras;
3279                return ps.getPermissionsState().computeGids(userId);
3280            }
3281            if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0) {
3282                final PackageSetting ps = mSettings.mPackages.get(packageName);
3283                if (ps != null && ps.isMatch(flags)) {
3284                    return ps.getPermissionsState().computeGids(userId);
3285                }
3286            }
3287        }
3288
3289        return null;
3290    }
3291
3292    static PermissionInfo generatePermissionInfo(BasePermission bp, int flags) {
3293        if (bp.perm != null) {
3294            return PackageParser.generatePermissionInfo(bp.perm, flags);
3295        }
3296        PermissionInfo pi = new PermissionInfo();
3297        pi.name = bp.name;
3298        pi.packageName = bp.sourcePackage;
3299        pi.nonLocalizedLabel = bp.name;
3300        pi.protectionLevel = bp.protectionLevel;
3301        return pi;
3302    }
3303
3304    @Override
3305    public PermissionInfo getPermissionInfo(String name, int flags) {
3306        // reader
3307        synchronized (mPackages) {
3308            final BasePermission p = mSettings.mPermissions.get(name);
3309            if (p != null) {
3310                return generatePermissionInfo(p, flags);
3311            }
3312            return null;
3313        }
3314    }
3315
3316    @Override
3317    public @Nullable ParceledListSlice<PermissionInfo> queryPermissionsByGroup(String group,
3318            int flags) {
3319        // reader
3320        synchronized (mPackages) {
3321            if (group != null && !mPermissionGroups.containsKey(group)) {
3322                // This is thrown as NameNotFoundException
3323                return null;
3324            }
3325
3326            ArrayList<PermissionInfo> out = new ArrayList<PermissionInfo>(10);
3327            for (BasePermission p : mSettings.mPermissions.values()) {
3328                if (group == null) {
3329                    if (p.perm == null || p.perm.info.group == null) {
3330                        out.add(generatePermissionInfo(p, flags));
3331                    }
3332                } else {
3333                    if (p.perm != null && group.equals(p.perm.info.group)) {
3334                        out.add(PackageParser.generatePermissionInfo(p.perm, flags));
3335                    }
3336                }
3337            }
3338            return new ParceledListSlice<>(out);
3339        }
3340    }
3341
3342    @Override
3343    public PermissionGroupInfo getPermissionGroupInfo(String name, int flags) {
3344        // reader
3345        synchronized (mPackages) {
3346            return PackageParser.generatePermissionGroupInfo(
3347                    mPermissionGroups.get(name), flags);
3348        }
3349    }
3350
3351    @Override
3352    public @NonNull ParceledListSlice<PermissionGroupInfo> getAllPermissionGroups(int flags) {
3353        // reader
3354        synchronized (mPackages) {
3355            final int N = mPermissionGroups.size();
3356            ArrayList<PermissionGroupInfo> out
3357                    = new ArrayList<PermissionGroupInfo>(N);
3358            for (PackageParser.PermissionGroup pg : mPermissionGroups.values()) {
3359                out.add(PackageParser.generatePermissionGroupInfo(pg, flags));
3360            }
3361            return new ParceledListSlice<>(out);
3362        }
3363    }
3364
3365    private ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName, int flags,
3366            int userId) {
3367        if (!sUserManager.exists(userId)) return null;
3368        PackageSetting ps = mSettings.mPackages.get(packageName);
3369        if (ps != null) {
3370            if (ps.pkg == null) {
3371                final PackageInfo pInfo = generatePackageInfo(ps, flags, userId);
3372                if (pInfo != null) {
3373                    return pInfo.applicationInfo;
3374                }
3375                return null;
3376            }
3377            return PackageParser.generateApplicationInfo(ps.pkg, flags,
3378                    ps.readUserState(userId), userId);
3379        }
3380        return null;
3381    }
3382
3383    @Override
3384    public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) {
3385        if (!sUserManager.exists(userId)) return null;
3386        flags = updateFlagsForApplication(flags, userId, packageName);
3387        enforceCrossUserPermission(Binder.getCallingUid(), userId,
3388                false /* requireFullPermission */, false /* checkShell */, "get application info");
3389
3390        // writer
3391        synchronized (mPackages) {
3392            // Normalize package name to hanlde renamed packages
3393            packageName = normalizePackageNameLPr(packageName);
3394
3395            PackageParser.Package p = mPackages.get(packageName);
3396            if (DEBUG_PACKAGE_INFO) Log.v(
3397                    TAG, "getApplicationInfo " + packageName
3398                    + ": " + p);
3399            if (p != null) {
3400                PackageSetting ps = mSettings.mPackages.get(packageName);
3401                if (ps == null) return null;
3402                // Note: isEnabledLP() does not apply here - always return info
3403                return PackageParser.generateApplicationInfo(
3404                        p, flags, ps.readUserState(userId), userId);
3405            }
3406            if ("android".equals(packageName)||"system".equals(packageName)) {
3407                return mAndroidApplication;
3408            }
3409            if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0) {
3410                return generateApplicationInfoFromSettingsLPw(packageName, flags, userId);
3411            }
3412        }
3413        return null;
3414    }
3415
3416    private String normalizePackageNameLPr(String packageName) {
3417        String normalizedPackageName = mSettings.mRenamedPackages.get(packageName);
3418        return normalizedPackageName != null ? normalizedPackageName : packageName;
3419    }
3420
3421    @Override
3422    public void freeStorageAndNotify(final String volumeUuid, final long freeStorageSize,
3423            final IPackageDataObserver observer) {
3424        mContext.enforceCallingOrSelfPermission(
3425                android.Manifest.permission.CLEAR_APP_CACHE, null);
3426        // Queue up an async operation since clearing cache may take a little while.
3427        mHandler.post(new Runnable() {
3428            public void run() {
3429                mHandler.removeCallbacks(this);
3430                boolean success = true;
3431                synchronized (mInstallLock) {
3432                    try {
3433                        mInstaller.freeCache(volumeUuid, freeStorageSize, 0);
3434                    } catch (InstallerException e) {
3435                        Slog.w(TAG, "Couldn't clear application caches: " + e);
3436                        success = false;
3437                    }
3438                }
3439                if (observer != null) {
3440                    try {
3441                        observer.onRemoveCompleted(null, success);
3442                    } catch (RemoteException e) {
3443                        Slog.w(TAG, "RemoveException when invoking call back");
3444                    }
3445                }
3446            }
3447        });
3448    }
3449
3450    @Override
3451    public void freeStorage(final String volumeUuid, final long freeStorageSize,
3452            final IntentSender pi) {
3453        mContext.enforceCallingOrSelfPermission(
3454                android.Manifest.permission.CLEAR_APP_CACHE, null);
3455        // Queue up an async operation since clearing cache may take a little while.
3456        mHandler.post(new Runnable() {
3457            public void run() {
3458                mHandler.removeCallbacks(this);
3459                boolean success = true;
3460                synchronized (mInstallLock) {
3461                    try {
3462                        mInstaller.freeCache(volumeUuid, freeStorageSize, 0);
3463                    } catch (InstallerException e) {
3464                        Slog.w(TAG, "Couldn't clear application caches: " + e);
3465                        success = false;
3466                    }
3467                }
3468                if(pi != null) {
3469                    try {
3470                        // Callback via pending intent
3471                        int code = success ? 1 : 0;
3472                        pi.sendIntent(null, code, null,
3473                                null, null);
3474                    } catch (SendIntentException e1) {
3475                        Slog.i(TAG, "Failed to send pending intent");
3476                    }
3477                }
3478            }
3479        });
3480    }
3481
3482    void freeStorage(String volumeUuid, long freeStorageSize) throws IOException {
3483        synchronized (mInstallLock) {
3484            try {
3485                mInstaller.freeCache(volumeUuid, freeStorageSize, 0);
3486            } catch (InstallerException e) {
3487                throw new IOException("Failed to free enough space", e);
3488            }
3489        }
3490    }
3491
3492    /**
3493     * Update given flags based on encryption status of current user.
3494     */
3495    private int updateFlags(int flags, int userId) {
3496        if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
3497                | PackageManager.MATCH_DIRECT_BOOT_AWARE)) != 0) {
3498            // Caller expressed an explicit opinion about what encryption
3499            // aware/unaware components they want to see, so fall through and
3500            // give them what they want
3501        } else {
3502            // Caller expressed no opinion, so match based on user state
3503            if (getUserManagerInternal().isUserUnlockingOrUnlocked(userId)) {
3504                flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE;
3505            } else {
3506                flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE;
3507            }
3508        }
3509        return flags;
3510    }
3511
3512    private UserManagerInternal getUserManagerInternal() {
3513        if (mUserManagerInternal == null) {
3514            mUserManagerInternal = LocalServices.getService(UserManagerInternal.class);
3515        }
3516        return mUserManagerInternal;
3517    }
3518
3519    /**
3520     * Update given flags when being used to request {@link PackageInfo}.
3521     */
3522    private int updateFlagsForPackage(int flags, int userId, Object cookie) {
3523        boolean triaged = true;
3524        if ((flags & (PackageManager.GET_ACTIVITIES | PackageManager.GET_RECEIVERS
3525                | PackageManager.GET_SERVICES | PackageManager.GET_PROVIDERS)) != 0) {
3526            // Caller is asking for component details, so they'd better be
3527            // asking for specific encryption matching behavior, or be triaged
3528            if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
3529                    | PackageManager.MATCH_DIRECT_BOOT_AWARE
3530                    | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
3531                triaged = false;
3532            }
3533        }
3534        if ((flags & (PackageManager.MATCH_UNINSTALLED_PACKAGES
3535                | PackageManager.MATCH_SYSTEM_ONLY
3536                | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
3537            triaged = false;
3538        }
3539        if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) {
3540            Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie
3541                    + " with flags 0x" + Integer.toHexString(flags), new Throwable());
3542        }
3543        return updateFlags(flags, userId);
3544    }
3545
3546    /**
3547     * Update given flags when being used to request {@link ApplicationInfo}.
3548     */
3549    private int updateFlagsForApplication(int flags, int userId, Object cookie) {
3550        return updateFlagsForPackage(flags, userId, cookie);
3551    }
3552
3553    /**
3554     * Update given flags when being used to request {@link ComponentInfo}.
3555     */
3556    private int updateFlagsForComponent(int flags, int userId, Object cookie) {
3557        if (cookie instanceof Intent) {
3558            if ((((Intent) cookie).getFlags() & Intent.FLAG_DEBUG_TRIAGED_MISSING) != 0) {
3559                flags |= PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
3560            }
3561        }
3562
3563        boolean triaged = true;
3564        // Caller is asking for component details, so they'd better be
3565        // asking for specific encryption matching behavior, or be triaged
3566        if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
3567                | PackageManager.MATCH_DIRECT_BOOT_AWARE
3568                | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
3569            triaged = false;
3570        }
3571        if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) {
3572            Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie
3573                    + " with flags 0x" + Integer.toHexString(flags), new Throwable());
3574        }
3575
3576        return updateFlags(flags, userId);
3577    }
3578
3579    /**
3580     * Update given flags when being used to request {@link ResolveInfo}.
3581     */
3582    int updateFlagsForResolve(int flags, int userId, Object cookie) {
3583        // Safe mode means we shouldn't match any third-party components
3584        if (mSafeMode) {
3585            flags |= PackageManager.MATCH_SYSTEM_ONLY;
3586        }
3587
3588        return updateFlagsForComponent(flags, userId, cookie);
3589    }
3590
3591    @Override
3592    public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) {
3593        if (!sUserManager.exists(userId)) return null;
3594        flags = updateFlagsForComponent(flags, userId, component);
3595        enforceCrossUserPermission(Binder.getCallingUid(), userId,
3596                false /* requireFullPermission */, false /* checkShell */, "get activity info");
3597        synchronized (mPackages) {
3598            PackageParser.Activity a = mActivities.mActivities.get(component);
3599
3600            if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a);
3601            if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) {
3602                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
3603                if (ps == null) return null;
3604                return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId),
3605                        userId);
3606            }
3607            if (mResolveComponentName.equals(component)) {
3608                return PackageParser.generateActivityInfo(mResolveActivity, flags,
3609                        new PackageUserState(), userId);
3610            }
3611        }
3612        return null;
3613    }
3614
3615    @Override
3616    public boolean activitySupportsIntent(ComponentName component, Intent intent,
3617            String resolvedType) {
3618        synchronized (mPackages) {
3619            if (component.equals(mResolveComponentName)) {
3620                // The resolver supports EVERYTHING!
3621                return true;
3622            }
3623            PackageParser.Activity a = mActivities.mActivities.get(component);
3624            if (a == null) {
3625                return false;
3626            }
3627            for (int i=0; i<a.intents.size(); i++) {
3628                if (a.intents.get(i).match(intent.getAction(), resolvedType, intent.getScheme(),
3629                        intent.getData(), intent.getCategories(), TAG) >= 0) {
3630                    return true;
3631                }
3632            }
3633            return false;
3634        }
3635    }
3636
3637    @Override
3638    public ActivityInfo getReceiverInfo(ComponentName component, int flags, int userId) {
3639        if (!sUserManager.exists(userId)) return null;
3640        flags = updateFlagsForComponent(flags, userId, component);
3641        enforceCrossUserPermission(Binder.getCallingUid(), userId,
3642                false /* requireFullPermission */, false /* checkShell */, "get receiver info");
3643        synchronized (mPackages) {
3644            PackageParser.Activity a = mReceivers.mActivities.get(component);
3645            if (DEBUG_PACKAGE_INFO) Log.v(
3646                TAG, "getReceiverInfo " + component + ": " + a);
3647            if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) {
3648                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
3649                if (ps == null) return null;
3650                return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId),
3651                        userId);
3652            }
3653        }
3654        return null;
3655    }
3656
3657    @Override
3658    public ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) {
3659        if (!sUserManager.exists(userId)) return null;
3660        flags = updateFlagsForComponent(flags, userId, component);
3661        enforceCrossUserPermission(Binder.getCallingUid(), userId,
3662                false /* requireFullPermission */, false /* checkShell */, "get service info");
3663        synchronized (mPackages) {
3664            PackageParser.Service s = mServices.mServices.get(component);
3665            if (DEBUG_PACKAGE_INFO) Log.v(
3666                TAG, "getServiceInfo " + component + ": " + s);
3667            if (s != null && mSettings.isEnabledAndMatchLPr(s.info, flags, userId)) {
3668                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
3669                if (ps == null) return null;
3670                return PackageParser.generateServiceInfo(s, flags, ps.readUserState(userId),
3671                        userId);
3672            }
3673        }
3674        return null;
3675    }
3676
3677    @Override
3678    public ProviderInfo getProviderInfo(ComponentName component, int flags, int userId) {
3679        if (!sUserManager.exists(userId)) return null;
3680        flags = updateFlagsForComponent(flags, userId, component);
3681        enforceCrossUserPermission(Binder.getCallingUid(), userId,
3682                false /* requireFullPermission */, false /* checkShell */, "get provider info");
3683        synchronized (mPackages) {
3684            PackageParser.Provider p = mProviders.mProviders.get(component);
3685            if (DEBUG_PACKAGE_INFO) Log.v(
3686                TAG, "getProviderInfo " + component + ": " + p);
3687            if (p != null && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) {
3688                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
3689                if (ps == null) return null;
3690                return PackageParser.generateProviderInfo(p, flags, ps.readUserState(userId),
3691                        userId);
3692            }
3693        }
3694        return null;
3695    }
3696
3697    @Override
3698    public String[] getSystemSharedLibraryNames() {
3699        Set<String> libSet;
3700        synchronized (mPackages) {
3701            libSet = mSharedLibraries.keySet();
3702            int size = libSet.size();
3703            if (size > 0) {
3704                String[] libs = new String[size];
3705                libSet.toArray(libs);
3706                return libs;
3707            }
3708        }
3709        return null;
3710    }
3711
3712    @Override
3713    public @NonNull String getServicesSystemSharedLibraryPackageName() {
3714        synchronized (mPackages) {
3715            return mServicesSystemSharedLibraryPackageName;
3716        }
3717    }
3718
3719    @Override
3720    public @NonNull String getSharedSystemSharedLibraryPackageName() {
3721        synchronized (mPackages) {
3722            return mSharedSystemSharedLibraryPackageName;
3723        }
3724    }
3725
3726    @Override
3727    public @NonNull ParceledListSlice<FeatureInfo> getSystemAvailableFeatures() {
3728        synchronized (mPackages) {
3729            final ArrayList<FeatureInfo> res = new ArrayList<>(mAvailableFeatures.values());
3730
3731            final FeatureInfo fi = new FeatureInfo();
3732            fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version",
3733                    FeatureInfo.GL_ES_VERSION_UNDEFINED);
3734            res.add(fi);
3735
3736            return new ParceledListSlice<>(res);
3737        }
3738    }
3739
3740    @Override
3741    public boolean hasSystemFeature(String name, int version) {
3742        synchronized (mPackages) {
3743            final FeatureInfo feat = mAvailableFeatures.get(name);
3744            if (feat == null) {
3745                return false;
3746            } else {
3747                return feat.version >= version;
3748            }
3749        }
3750    }
3751
3752    @Override
3753    public int checkPermission(String permName, String pkgName, int userId) {
3754        if (!sUserManager.exists(userId)) {
3755            return PackageManager.PERMISSION_DENIED;
3756        }
3757
3758        synchronized (mPackages) {
3759            final PackageParser.Package p = mPackages.get(pkgName);
3760            if (p != null && p.mExtras != null) {
3761                final PackageSetting ps = (PackageSetting) p.mExtras;
3762                final PermissionsState permissionsState = ps.getPermissionsState();
3763                if (permissionsState.hasPermission(permName, userId)) {
3764                    return PackageManager.PERMISSION_GRANTED;
3765                }
3766                // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION
3767                if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState
3768                        .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) {
3769                    return PackageManager.PERMISSION_GRANTED;
3770                }
3771            }
3772        }
3773
3774        return PackageManager.PERMISSION_DENIED;
3775    }
3776
3777    @Override
3778    public int checkUidPermission(String permName, int uid) {
3779        final int userId = UserHandle.getUserId(uid);
3780
3781        if (!sUserManager.exists(userId)) {
3782            return PackageManager.PERMISSION_DENIED;
3783        }
3784
3785        synchronized (mPackages) {
3786            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
3787            if (obj != null) {
3788                final SettingBase ps = (SettingBase) obj;
3789                final PermissionsState permissionsState = ps.getPermissionsState();
3790                if (permissionsState.hasPermission(permName, userId)) {
3791                    return PackageManager.PERMISSION_GRANTED;
3792                }
3793                // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION
3794                if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState
3795                        .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) {
3796                    return PackageManager.PERMISSION_GRANTED;
3797                }
3798            } else {
3799                ArraySet<String> perms = mSystemPermissions.get(uid);
3800                if (perms != null) {
3801                    if (perms.contains(permName)) {
3802                        return PackageManager.PERMISSION_GRANTED;
3803                    }
3804                    if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && perms
3805                            .contains(Manifest.permission.ACCESS_FINE_LOCATION)) {
3806                        return PackageManager.PERMISSION_GRANTED;
3807                    }
3808                }
3809            }
3810        }
3811
3812        return PackageManager.PERMISSION_DENIED;
3813    }
3814
3815    @Override
3816    public boolean isPermissionRevokedByPolicy(String permission, String packageName, int userId) {
3817        if (UserHandle.getCallingUserId() != userId) {
3818            mContext.enforceCallingPermission(
3819                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
3820                    "isPermissionRevokedByPolicy for user " + userId);
3821        }
3822
3823        if (checkPermission(permission, packageName, userId)
3824                == PackageManager.PERMISSION_GRANTED) {
3825            return false;
3826        }
3827
3828        final long identity = Binder.clearCallingIdentity();
3829        try {
3830            final int flags = getPermissionFlags(permission, packageName, userId);
3831            return (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0;
3832        } finally {
3833            Binder.restoreCallingIdentity(identity);
3834        }
3835    }
3836
3837    @Override
3838    public String getPermissionControllerPackageName() {
3839        synchronized (mPackages) {
3840            return mRequiredInstallerPackage;
3841        }
3842    }
3843
3844    /**
3845     * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS
3846     * or INTERACT_ACROSS_USERS_FULL permissions, if the userid is not for the caller.
3847     * @param checkShell whether to prevent shell from access if there's a debugging restriction
3848     * @param message the message to log on security exception
3849     */
3850    void enforceCrossUserPermission(int callingUid, int userId, boolean requireFullPermission,
3851            boolean checkShell, String message) {
3852        if (userId < 0) {
3853            throw new IllegalArgumentException("Invalid userId " + userId);
3854        }
3855        if (checkShell) {
3856            enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId);
3857        }
3858        if (userId == UserHandle.getUserId(callingUid)) return;
3859        if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
3860            if (requireFullPermission) {
3861                mContext.enforceCallingOrSelfPermission(
3862                        android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
3863            } else {
3864                try {
3865                    mContext.enforceCallingOrSelfPermission(
3866                            android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
3867                } catch (SecurityException se) {
3868                    mContext.enforceCallingOrSelfPermission(
3869                            android.Manifest.permission.INTERACT_ACROSS_USERS, message);
3870                }
3871            }
3872        }
3873    }
3874
3875    void enforceShellRestriction(String restriction, int callingUid, int userHandle) {
3876        if (callingUid == Process.SHELL_UID) {
3877            if (userHandle >= 0
3878                    && sUserManager.hasUserRestriction(restriction, userHandle)) {
3879                throw new SecurityException("Shell does not have permission to access user "
3880                        + userHandle);
3881            } else if (userHandle < 0) {
3882                Slog.e(TAG, "Unable to check shell permission for user " + userHandle + "\n\t"
3883                        + Debug.getCallers(3));
3884            }
3885        }
3886    }
3887
3888    private BasePermission findPermissionTreeLP(String permName) {
3889        for(BasePermission bp : mSettings.mPermissionTrees.values()) {
3890            if (permName.startsWith(bp.name) &&
3891                    permName.length() > bp.name.length() &&
3892                    permName.charAt(bp.name.length()) == '.') {
3893                return bp;
3894            }
3895        }
3896        return null;
3897    }
3898
3899    private BasePermission checkPermissionTreeLP(String permName) {
3900        if (permName != null) {
3901            BasePermission bp = findPermissionTreeLP(permName);
3902            if (bp != null) {
3903                if (bp.uid == UserHandle.getAppId(Binder.getCallingUid())) {
3904                    return bp;
3905                }
3906                throw new SecurityException("Calling uid "
3907                        + Binder.getCallingUid()
3908                        + " is not allowed to add to permission tree "
3909                        + bp.name + " owned by uid " + bp.uid);
3910            }
3911        }
3912        throw new SecurityException("No permission tree found for " + permName);
3913    }
3914
3915    static boolean compareStrings(CharSequence s1, CharSequence s2) {
3916        if (s1 == null) {
3917            return s2 == null;
3918        }
3919        if (s2 == null) {
3920            return false;
3921        }
3922        if (s1.getClass() != s2.getClass()) {
3923            return false;
3924        }
3925        return s1.equals(s2);
3926    }
3927
3928    static boolean comparePermissionInfos(PermissionInfo pi1, PermissionInfo pi2) {
3929        if (pi1.icon != pi2.icon) return false;
3930        if (pi1.logo != pi2.logo) return false;
3931        if (pi1.protectionLevel != pi2.protectionLevel) return false;
3932        if (!compareStrings(pi1.name, pi2.name)) return false;
3933        if (!compareStrings(pi1.nonLocalizedLabel, pi2.nonLocalizedLabel)) return false;
3934        // We'll take care of setting this one.
3935        if (!compareStrings(pi1.packageName, pi2.packageName)) return false;
3936        // These are not currently stored in settings.
3937        //if (!compareStrings(pi1.group, pi2.group)) return false;
3938        //if (!compareStrings(pi1.nonLocalizedDescription, pi2.nonLocalizedDescription)) return false;
3939        //if (pi1.labelRes != pi2.labelRes) return false;
3940        //if (pi1.descriptionRes != pi2.descriptionRes) return false;
3941        return true;
3942    }
3943
3944    int permissionInfoFootprint(PermissionInfo info) {
3945        int size = info.name.length();
3946        if (info.nonLocalizedLabel != null) size += info.nonLocalizedLabel.length();
3947        if (info.nonLocalizedDescription != null) size += info.nonLocalizedDescription.length();
3948        return size;
3949    }
3950
3951    int calculateCurrentPermissionFootprintLocked(BasePermission tree) {
3952        int size = 0;
3953        for (BasePermission perm : mSettings.mPermissions.values()) {
3954            if (perm.uid == tree.uid) {
3955                size += perm.name.length() + permissionInfoFootprint(perm.perm.info);
3956            }
3957        }
3958        return size;
3959    }
3960
3961    void enforcePermissionCapLocked(PermissionInfo info, BasePermission tree) {
3962        // We calculate the max size of permissions defined by this uid and throw
3963        // if that plus the size of 'info' would exceed our stated maximum.
3964        if (tree.uid != Process.SYSTEM_UID) {
3965            final int curTreeSize = calculateCurrentPermissionFootprintLocked(tree);
3966            if (curTreeSize + permissionInfoFootprint(info) > MAX_PERMISSION_TREE_FOOTPRINT) {
3967                throw new SecurityException("Permission tree size cap exceeded");
3968            }
3969        }
3970    }
3971
3972    boolean addPermissionLocked(PermissionInfo info, boolean async) {
3973        if (info.labelRes == 0 && info.nonLocalizedLabel == null) {
3974            throw new SecurityException("Label must be specified in permission");
3975        }
3976        BasePermission tree = checkPermissionTreeLP(info.name);
3977        BasePermission bp = mSettings.mPermissions.get(info.name);
3978        boolean added = bp == null;
3979        boolean changed = true;
3980        int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel);
3981        if (added) {
3982            enforcePermissionCapLocked(info, tree);
3983            bp = new BasePermission(info.name, tree.sourcePackage,
3984                    BasePermission.TYPE_DYNAMIC);
3985        } else if (bp.type != BasePermission.TYPE_DYNAMIC) {
3986            throw new SecurityException(
3987                    "Not allowed to modify non-dynamic permission "
3988                    + info.name);
3989        } else {
3990            if (bp.protectionLevel == fixedLevel
3991                    && bp.perm.owner.equals(tree.perm.owner)
3992                    && bp.uid == tree.uid
3993                    && comparePermissionInfos(bp.perm.info, info)) {
3994                changed = false;
3995            }
3996        }
3997        bp.protectionLevel = fixedLevel;
3998        info = new PermissionInfo(info);
3999        info.protectionLevel = fixedLevel;
4000        bp.perm = new PackageParser.Permission(tree.perm.owner, info);
4001        bp.perm.info.packageName = tree.perm.info.packageName;
4002        bp.uid = tree.uid;
4003        if (added) {
4004            mSettings.mPermissions.put(info.name, bp);
4005        }
4006        if (changed) {
4007            if (!async) {
4008                mSettings.writeLPr();
4009            } else {
4010                scheduleWriteSettingsLocked();
4011            }
4012        }
4013        return added;
4014    }
4015
4016    @Override
4017    public boolean addPermission(PermissionInfo info) {
4018        synchronized (mPackages) {
4019            return addPermissionLocked(info, false);
4020        }
4021    }
4022
4023    @Override
4024    public boolean addPermissionAsync(PermissionInfo info) {
4025        synchronized (mPackages) {
4026            return addPermissionLocked(info, true);
4027        }
4028    }
4029
4030    @Override
4031    public void removePermission(String name) {
4032        synchronized (mPackages) {
4033            checkPermissionTreeLP(name);
4034            BasePermission bp = mSettings.mPermissions.get(name);
4035            if (bp != null) {
4036                if (bp.type != BasePermission.TYPE_DYNAMIC) {
4037                    throw new SecurityException(
4038                            "Not allowed to modify non-dynamic permission "
4039                            + name);
4040                }
4041                mSettings.mPermissions.remove(name);
4042                mSettings.writeLPr();
4043            }
4044        }
4045    }
4046
4047    private static void enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(PackageParser.Package pkg,
4048            BasePermission bp) {
4049        int index = pkg.requestedPermissions.indexOf(bp.name);
4050        if (index == -1) {
4051            throw new SecurityException("Package " + pkg.packageName
4052                    + " has not requested permission " + bp.name);
4053        }
4054        if (!bp.isRuntime() && !bp.isDevelopment()) {
4055            throw new SecurityException("Permission " + bp.name
4056                    + " is not a changeable permission type");
4057        }
4058    }
4059
4060    @Override
4061    public void grantRuntimePermission(String packageName, String name, final int userId) {
4062        if (!sUserManager.exists(userId)) {
4063            Log.e(TAG, "No such user:" + userId);
4064            return;
4065        }
4066
4067        mContext.enforceCallingOrSelfPermission(
4068                android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
4069                "grantRuntimePermission");
4070
4071        enforceCrossUserPermission(Binder.getCallingUid(), userId,
4072                true /* requireFullPermission */, true /* checkShell */,
4073                "grantRuntimePermission");
4074
4075        final int uid;
4076        final SettingBase sb;
4077
4078        synchronized (mPackages) {
4079            final PackageParser.Package pkg = mPackages.get(packageName);
4080            if (pkg == null) {
4081                throw new IllegalArgumentException("Unknown package: " + packageName);
4082            }
4083
4084            final BasePermission bp = mSettings.mPermissions.get(name);
4085            if (bp == null) {
4086                throw new IllegalArgumentException("Unknown permission: " + name);
4087            }
4088
4089            enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(pkg, bp);
4090
4091            // If a permission review is required for legacy apps we represent
4092            // their permissions as always granted runtime ones since we need
4093            // to keep the review required permission flag per user while an
4094            // install permission's state is shared across all users.
4095            if ((mPermissionReviewRequired || Build.PERMISSIONS_REVIEW_REQUIRED)
4096                    && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
4097                    && bp.isRuntime()) {
4098                return;
4099            }
4100
4101            uid = UserHandle.getUid(userId, pkg.applicationInfo.uid);
4102            sb = (SettingBase) pkg.mExtras;
4103            if (sb == null) {
4104                throw new IllegalArgumentException("Unknown package: " + packageName);
4105            }
4106
4107            final PermissionsState permissionsState = sb.getPermissionsState();
4108
4109            final int flags = permissionsState.getPermissionFlags(name, userId);
4110            if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
4111                throw new SecurityException("Cannot grant system fixed permission "
4112                        + name + " for package " + packageName);
4113            }
4114
4115            if (bp.isDevelopment()) {
4116                // Development permissions must be handled specially, since they are not
4117                // normal runtime permissions.  For now they apply to all users.
4118                if (permissionsState.grantInstallPermission(bp) !=
4119                        PermissionsState.PERMISSION_OPERATION_FAILURE) {
4120                    scheduleWriteSettingsLocked();
4121                }
4122                return;
4123            }
4124
4125            if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
4126                Slog.w(TAG, "Cannot grant runtime permission to a legacy app");
4127                return;
4128            }
4129
4130            final int result = permissionsState.grantRuntimePermission(bp, userId);
4131            switch (result) {
4132                case PermissionsState.PERMISSION_OPERATION_FAILURE: {
4133                    return;
4134                }
4135
4136                case PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
4137                    final int appId = UserHandle.getAppId(pkg.applicationInfo.uid);
4138                    mHandler.post(new Runnable() {
4139                        @Override
4140                        public void run() {
4141                            killUid(appId, userId, KILL_APP_REASON_GIDS_CHANGED);
4142                        }
4143                    });
4144                }
4145                break;
4146            }
4147
4148            mOnPermissionChangeListeners.onPermissionsChanged(uid);
4149
4150            // Not critical if that is lost - app has to request again.
4151            mSettings.writeRuntimePermissionsForUserLPr(userId, false);
4152        }
4153
4154        // Only need to do this if user is initialized. Otherwise it's a new user
4155        // and there are no processes running as the user yet and there's no need
4156        // to make an expensive call to remount processes for the changed permissions.
4157        if (READ_EXTERNAL_STORAGE.equals(name)
4158                || WRITE_EXTERNAL_STORAGE.equals(name)) {
4159            final long token = Binder.clearCallingIdentity();
4160            try {
4161                if (sUserManager.isInitialized(userId)) {
4162                    MountServiceInternal mountServiceInternal = LocalServices.getService(
4163                            MountServiceInternal.class);
4164                    mountServiceInternal.onExternalStoragePolicyChanged(uid, packageName);
4165                }
4166            } finally {
4167                Binder.restoreCallingIdentity(token);
4168            }
4169        }
4170    }
4171
4172    @Override
4173    public void revokeRuntimePermission(String packageName, String name, int userId) {
4174        if (!sUserManager.exists(userId)) {
4175            Log.e(TAG, "No such user:" + userId);
4176            return;
4177        }
4178
4179        mContext.enforceCallingOrSelfPermission(
4180                android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
4181                "revokeRuntimePermission");
4182
4183        enforceCrossUserPermission(Binder.getCallingUid(), userId,
4184                true /* requireFullPermission */, true /* checkShell */,
4185                "revokeRuntimePermission");
4186
4187        final int appId;
4188
4189        synchronized (mPackages) {
4190            final PackageParser.Package pkg = mPackages.get(packageName);
4191            if (pkg == null) {
4192                throw new IllegalArgumentException("Unknown package: " + packageName);
4193            }
4194
4195            final BasePermission bp = mSettings.mPermissions.get(name);
4196            if (bp == null) {
4197                throw new IllegalArgumentException("Unknown permission: " + name);
4198            }
4199
4200            enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(pkg, bp);
4201
4202            // If a permission review is required for legacy apps we represent
4203            // their permissions as always granted runtime ones since we need
4204            // to keep the review required permission flag per user while an
4205            // install permission's state is shared across all users.
4206            if ((mPermissionReviewRequired || Build.PERMISSIONS_REVIEW_REQUIRED)
4207                    && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
4208                    && bp.isRuntime()) {
4209                return;
4210            }
4211
4212            SettingBase sb = (SettingBase) pkg.mExtras;
4213            if (sb == null) {
4214                throw new IllegalArgumentException("Unknown package: " + packageName);
4215            }
4216
4217            final PermissionsState permissionsState = sb.getPermissionsState();
4218
4219            final int flags = permissionsState.getPermissionFlags(name, userId);
4220            if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
4221                throw new SecurityException("Cannot revoke system fixed permission "
4222                        + name + " for package " + packageName);
4223            }
4224
4225            if (bp.isDevelopment()) {
4226                // Development permissions must be handled specially, since they are not
4227                // normal runtime permissions.  For now they apply to all users.
4228                if (permissionsState.revokeInstallPermission(bp) !=
4229                        PermissionsState.PERMISSION_OPERATION_FAILURE) {
4230                    scheduleWriteSettingsLocked();
4231                }
4232                return;
4233            }
4234
4235            if (permissionsState.revokeRuntimePermission(bp, userId) ==
4236                    PermissionsState.PERMISSION_OPERATION_FAILURE) {
4237                return;
4238            }
4239
4240            mOnPermissionChangeListeners.onPermissionsChanged(pkg.applicationInfo.uid);
4241
4242            // Critical, after this call app should never have the permission.
4243            mSettings.writeRuntimePermissionsForUserLPr(userId, true);
4244
4245            appId = UserHandle.getAppId(pkg.applicationInfo.uid);
4246        }
4247
4248        killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED);
4249    }
4250
4251    @Override
4252    public void resetRuntimePermissions() {
4253        mContext.enforceCallingOrSelfPermission(
4254                android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
4255                "revokeRuntimePermission");
4256
4257        int callingUid = Binder.getCallingUid();
4258        if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
4259            mContext.enforceCallingOrSelfPermission(
4260                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
4261                    "resetRuntimePermissions");
4262        }
4263
4264        synchronized (mPackages) {
4265            updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL);
4266            for (int userId : UserManagerService.getInstance().getUserIds()) {
4267                final int packageCount = mPackages.size();
4268                for (int i = 0; i < packageCount; i++) {
4269                    PackageParser.Package pkg = mPackages.valueAt(i);
4270                    if (!(pkg.mExtras instanceof PackageSetting)) {
4271                        continue;
4272                    }
4273                    PackageSetting ps = (PackageSetting) pkg.mExtras;
4274                    resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
4275                }
4276            }
4277        }
4278    }
4279
4280    @Override
4281    public int getPermissionFlags(String name, String packageName, int userId) {
4282        if (!sUserManager.exists(userId)) {
4283            return 0;
4284        }
4285
4286        enforceGrantRevokeRuntimePermissionPermissions("getPermissionFlags");
4287
4288        enforceCrossUserPermission(Binder.getCallingUid(), userId,
4289                true /* requireFullPermission */, false /* checkShell */,
4290                "getPermissionFlags");
4291
4292        synchronized (mPackages) {
4293            final PackageParser.Package pkg = mPackages.get(packageName);
4294            if (pkg == null) {
4295                return 0;
4296            }
4297
4298            final BasePermission bp = mSettings.mPermissions.get(name);
4299            if (bp == null) {
4300                return 0;
4301            }
4302
4303            SettingBase sb = (SettingBase) pkg.mExtras;
4304            if (sb == null) {
4305                return 0;
4306            }
4307
4308            PermissionsState permissionsState = sb.getPermissionsState();
4309            return permissionsState.getPermissionFlags(name, userId);
4310        }
4311    }
4312
4313    @Override
4314    public void updatePermissionFlags(String name, String packageName, int flagMask,
4315            int flagValues, int userId) {
4316        if (!sUserManager.exists(userId)) {
4317            return;
4318        }
4319
4320        enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlags");
4321
4322        enforceCrossUserPermission(Binder.getCallingUid(), userId,
4323                true /* requireFullPermission */, true /* checkShell */,
4324                "updatePermissionFlags");
4325
4326        // Only the system can change these flags and nothing else.
4327        if (getCallingUid() != Process.SYSTEM_UID) {
4328            flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
4329            flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
4330            flagMask &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
4331            flagValues &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
4332            flagValues &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
4333        }
4334
4335        synchronized (mPackages) {
4336            final PackageParser.Package pkg = mPackages.get(packageName);
4337            if (pkg == null) {
4338                throw new IllegalArgumentException("Unknown package: " + packageName);
4339            }
4340
4341            final BasePermission bp = mSettings.mPermissions.get(name);
4342            if (bp == null) {
4343                throw new IllegalArgumentException("Unknown permission: " + name);
4344            }
4345
4346            SettingBase sb = (SettingBase) pkg.mExtras;
4347            if (sb == null) {
4348                throw new IllegalArgumentException("Unknown package: " + packageName);
4349            }
4350
4351            PermissionsState permissionsState = sb.getPermissionsState();
4352
4353            boolean hadState = permissionsState.getRuntimePermissionState(name, userId) != null;
4354
4355            if (permissionsState.updatePermissionFlags(bp, userId, flagMask, flagValues)) {
4356                // Install and runtime permissions are stored in different places,
4357                // so figure out what permission changed and persist the change.
4358                if (permissionsState.getInstallPermissionState(name) != null) {
4359                    scheduleWriteSettingsLocked();
4360                } else if (permissionsState.getRuntimePermissionState(name, userId) != null
4361                        || hadState) {
4362                    mSettings.writeRuntimePermissionsForUserLPr(userId, false);
4363                }
4364            }
4365        }
4366    }
4367
4368    /**
4369     * Update the permission flags for all packages and runtime permissions of a user in order
4370     * to allow device or profile owner to remove POLICY_FIXED.
4371     */
4372    @Override
4373    public void updatePermissionFlagsForAllApps(int flagMask, int flagValues, int userId) {
4374        if (!sUserManager.exists(userId)) {
4375            return;
4376        }
4377
4378        enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlagsForAllApps");
4379
4380        enforceCrossUserPermission(Binder.getCallingUid(), userId,
4381                true /* requireFullPermission */, true /* checkShell */,
4382                "updatePermissionFlagsForAllApps");
4383
4384        // Only the system can change system fixed flags.
4385        if (getCallingUid() != Process.SYSTEM_UID) {
4386            flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
4387            flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
4388        }
4389
4390        synchronized (mPackages) {
4391            boolean changed = false;
4392            final int packageCount = mPackages.size();
4393            for (int pkgIndex = 0; pkgIndex < packageCount; pkgIndex++) {
4394                final PackageParser.Package pkg = mPackages.valueAt(pkgIndex);
4395                SettingBase sb = (SettingBase) pkg.mExtras;
4396                if (sb == null) {
4397                    continue;
4398                }
4399                PermissionsState permissionsState = sb.getPermissionsState();
4400                changed |= permissionsState.updatePermissionFlagsForAllPermissions(
4401                        userId, flagMask, flagValues);
4402            }
4403            if (changed) {
4404                mSettings.writeRuntimePermissionsForUserLPr(userId, false);
4405            }
4406        }
4407    }
4408
4409    private void enforceGrantRevokeRuntimePermissionPermissions(String message) {
4410        if (mContext.checkCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS)
4411                != PackageManager.PERMISSION_GRANTED
4412            && mContext.checkCallingOrSelfPermission(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS)
4413                != PackageManager.PERMISSION_GRANTED) {
4414            throw new SecurityException(message + " requires "
4415                    + Manifest.permission.GRANT_RUNTIME_PERMISSIONS + " or "
4416                    + Manifest.permission.REVOKE_RUNTIME_PERMISSIONS);
4417        }
4418    }
4419
4420    @Override
4421    public boolean shouldShowRequestPermissionRationale(String permissionName,
4422            String packageName, int userId) {
4423        if (UserHandle.getCallingUserId() != userId) {
4424            mContext.enforceCallingPermission(
4425                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
4426                    "canShowRequestPermissionRationale for user " + userId);
4427        }
4428
4429        final int uid = getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
4430        if (UserHandle.getAppId(getCallingUid()) != UserHandle.getAppId(uid)) {
4431            return false;
4432        }
4433
4434        if (checkPermission(permissionName, packageName, userId)
4435                == PackageManager.PERMISSION_GRANTED) {
4436            return false;
4437        }
4438
4439        final int flags;
4440
4441        final long identity = Binder.clearCallingIdentity();
4442        try {
4443            flags = getPermissionFlags(permissionName,
4444                    packageName, userId);
4445        } finally {
4446            Binder.restoreCallingIdentity(identity);
4447        }
4448
4449        final int fixedFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
4450                | PackageManager.FLAG_PERMISSION_POLICY_FIXED
4451                | PackageManager.FLAG_PERMISSION_USER_FIXED;
4452
4453        if ((flags & fixedFlags) != 0) {
4454            return false;
4455        }
4456
4457        return (flags & PackageManager.FLAG_PERMISSION_USER_SET) != 0;
4458    }
4459
4460    @Override
4461    public void addOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
4462        mContext.enforceCallingOrSelfPermission(
4463                Manifest.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS,
4464                "addOnPermissionsChangeListener");
4465
4466        synchronized (mPackages) {
4467            mOnPermissionChangeListeners.addListenerLocked(listener);
4468        }
4469    }
4470
4471    @Override
4472    public void removeOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
4473        synchronized (mPackages) {
4474            mOnPermissionChangeListeners.removeListenerLocked(listener);
4475        }
4476    }
4477
4478    @Override
4479    public boolean isProtectedBroadcast(String actionName) {
4480        synchronized (mPackages) {
4481            if (mProtectedBroadcasts.contains(actionName)) {
4482                return true;
4483            } else if (actionName != null) {
4484                // TODO: remove these terrible hacks
4485                if (actionName.startsWith("android.net.netmon.lingerExpired")
4486                        || actionName.startsWith("com.android.server.sip.SipWakeupTimer")
4487                        || actionName.startsWith("com.android.internal.telephony.data-reconnect")
4488                        || actionName.startsWith("android.net.netmon.launchCaptivePortalApp")) {
4489                    return true;
4490                }
4491            }
4492        }
4493        return false;
4494    }
4495
4496    @Override
4497    public int checkSignatures(String pkg1, String pkg2) {
4498        synchronized (mPackages) {
4499            final PackageParser.Package p1 = mPackages.get(pkg1);
4500            final PackageParser.Package p2 = mPackages.get(pkg2);
4501            if (p1 == null || p1.mExtras == null
4502                    || p2 == null || p2.mExtras == null) {
4503                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
4504            }
4505            return compareSignatures(p1.mSignatures, p2.mSignatures);
4506        }
4507    }
4508
4509    @Override
4510    public int checkUidSignatures(int uid1, int uid2) {
4511        // Map to base uids.
4512        uid1 = UserHandle.getAppId(uid1);
4513        uid2 = UserHandle.getAppId(uid2);
4514        // reader
4515        synchronized (mPackages) {
4516            Signature[] s1;
4517            Signature[] s2;
4518            Object obj = mSettings.getUserIdLPr(uid1);
4519            if (obj != null) {
4520                if (obj instanceof SharedUserSetting) {
4521                    s1 = ((SharedUserSetting)obj).signatures.mSignatures;
4522                } else if (obj instanceof PackageSetting) {
4523                    s1 = ((PackageSetting)obj).signatures.mSignatures;
4524                } else {
4525                    return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
4526                }
4527            } else {
4528                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
4529            }
4530            obj = mSettings.getUserIdLPr(uid2);
4531            if (obj != null) {
4532                if (obj instanceof SharedUserSetting) {
4533                    s2 = ((SharedUserSetting)obj).signatures.mSignatures;
4534                } else if (obj instanceof PackageSetting) {
4535                    s2 = ((PackageSetting)obj).signatures.mSignatures;
4536                } else {
4537                    return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
4538                }
4539            } else {
4540                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
4541            }
4542            return compareSignatures(s1, s2);
4543        }
4544    }
4545
4546    /**
4547     * This method should typically only be used when granting or revoking
4548     * permissions, since the app may immediately restart after this call.
4549     * <p>
4550     * If you're doing surgery on app code/data, use {@link PackageFreezer} to
4551     * guard your work against the app being relaunched.
4552     */
4553    private void killUid(int appId, int userId, String reason) {
4554        final long identity = Binder.clearCallingIdentity();
4555        try {
4556            IActivityManager am = ActivityManagerNative.getDefault();
4557            if (am != null) {
4558                try {
4559                    am.killUid(appId, userId, reason);
4560                } catch (RemoteException e) {
4561                    /* ignore - same process */
4562                }
4563            }
4564        } finally {
4565            Binder.restoreCallingIdentity(identity);
4566        }
4567    }
4568
4569    /**
4570     * Compares two sets of signatures. Returns:
4571     * <br />
4572     * {@link PackageManager#SIGNATURE_NEITHER_SIGNED}: if both signature sets are null,
4573     * <br />
4574     * {@link PackageManager#SIGNATURE_FIRST_NOT_SIGNED}: if the first signature set is null,
4575     * <br />
4576     * {@link PackageManager#SIGNATURE_SECOND_NOT_SIGNED}: if the second signature set is null,
4577     * <br />
4578     * {@link PackageManager#SIGNATURE_MATCH}: if the two signature sets are identical,
4579     * <br />
4580     * {@link PackageManager#SIGNATURE_NO_MATCH}: if the two signature sets differ.
4581     */
4582    static int compareSignatures(Signature[] s1, Signature[] s2) {
4583        if (s1 == null) {
4584            return s2 == null
4585                    ? PackageManager.SIGNATURE_NEITHER_SIGNED
4586                    : PackageManager.SIGNATURE_FIRST_NOT_SIGNED;
4587        }
4588
4589        if (s2 == null) {
4590            return PackageManager.SIGNATURE_SECOND_NOT_SIGNED;
4591        }
4592
4593        if (s1.length != s2.length) {
4594            return PackageManager.SIGNATURE_NO_MATCH;
4595        }
4596
4597        // Since both signature sets are of size 1, we can compare without HashSets.
4598        if (s1.length == 1) {
4599            return s1[0].equals(s2[0]) ?
4600                    PackageManager.SIGNATURE_MATCH :
4601                    PackageManager.SIGNATURE_NO_MATCH;
4602        }
4603
4604        ArraySet<Signature> set1 = new ArraySet<Signature>();
4605        for (Signature sig : s1) {
4606            set1.add(sig);
4607        }
4608        ArraySet<Signature> set2 = new ArraySet<Signature>();
4609        for (Signature sig : s2) {
4610            set2.add(sig);
4611        }
4612        // Make sure s2 contains all signatures in s1.
4613        if (set1.equals(set2)) {
4614            return PackageManager.SIGNATURE_MATCH;
4615        }
4616        return PackageManager.SIGNATURE_NO_MATCH;
4617    }
4618
4619    /**
4620     * If the database version for this type of package (internal storage or
4621     * external storage) is less than the version where package signatures
4622     * were updated, return true.
4623     */
4624    private boolean isCompatSignatureUpdateNeeded(PackageParser.Package scannedPkg) {
4625        final VersionInfo ver = getSettingsVersionForPackage(scannedPkg);
4626        return ver.databaseVersion < DatabaseVersion.SIGNATURE_END_ENTITY;
4627    }
4628
4629    /**
4630     * Used for backward compatibility to make sure any packages with
4631     * certificate chains get upgraded to the new style. {@code existingSigs}
4632     * will be in the old format (since they were stored on disk from before the
4633     * system upgrade) and {@code scannedSigs} will be in the newer format.
4634     */
4635    private int compareSignaturesCompat(PackageSignatures existingSigs,
4636            PackageParser.Package scannedPkg) {
4637        if (!isCompatSignatureUpdateNeeded(scannedPkg)) {
4638            return PackageManager.SIGNATURE_NO_MATCH;
4639        }
4640
4641        ArraySet<Signature> existingSet = new ArraySet<Signature>();
4642        for (Signature sig : existingSigs.mSignatures) {
4643            existingSet.add(sig);
4644        }
4645        ArraySet<Signature> scannedCompatSet = new ArraySet<Signature>();
4646        for (Signature sig : scannedPkg.mSignatures) {
4647            try {
4648                Signature[] chainSignatures = sig.getChainSignatures();
4649                for (Signature chainSig : chainSignatures) {
4650                    scannedCompatSet.add(chainSig);
4651                }
4652            } catch (CertificateEncodingException e) {
4653                scannedCompatSet.add(sig);
4654            }
4655        }
4656        /*
4657         * Make sure the expanded scanned set contains all signatures in the
4658         * existing one.
4659         */
4660        if (scannedCompatSet.equals(existingSet)) {
4661            // Migrate the old signatures to the new scheme.
4662            existingSigs.assignSignatures(scannedPkg.mSignatures);
4663            // The new KeySets will be re-added later in the scanning process.
4664            synchronized (mPackages) {
4665                mSettings.mKeySetManagerService.removeAppKeySetDataLPw(scannedPkg.packageName);
4666            }
4667            return PackageManager.SIGNATURE_MATCH;
4668        }
4669        return PackageManager.SIGNATURE_NO_MATCH;
4670    }
4671
4672    private boolean isRecoverSignatureUpdateNeeded(PackageParser.Package scannedPkg) {
4673        final VersionInfo ver = getSettingsVersionForPackage(scannedPkg);
4674        return ver.databaseVersion < DatabaseVersion.SIGNATURE_MALFORMED_RECOVER;
4675    }
4676
4677    private int compareSignaturesRecover(PackageSignatures existingSigs,
4678            PackageParser.Package scannedPkg) {
4679        if (!isRecoverSignatureUpdateNeeded(scannedPkg)) {
4680            return PackageManager.SIGNATURE_NO_MATCH;
4681        }
4682
4683        String msg = null;
4684        try {
4685            if (Signature.areEffectiveMatch(existingSigs.mSignatures, scannedPkg.mSignatures)) {
4686                logCriticalInfo(Log.INFO, "Recovered effectively matching certificates for "
4687                        + scannedPkg.packageName);
4688                return PackageManager.SIGNATURE_MATCH;
4689            }
4690        } catch (CertificateException e) {
4691            msg = e.getMessage();
4692        }
4693
4694        logCriticalInfo(Log.INFO,
4695                "Failed to recover certificates for " + scannedPkg.packageName + ": " + msg);
4696        return PackageManager.SIGNATURE_NO_MATCH;
4697    }
4698
4699    @Override
4700    public List<String> getAllPackages() {
4701        synchronized (mPackages) {
4702            return new ArrayList<String>(mPackages.keySet());
4703        }
4704    }
4705
4706    @Override
4707    public String[] getPackagesForUid(int uid) {
4708        final int userId = UserHandle.getUserId(uid);
4709        uid = UserHandle.getAppId(uid);
4710        // reader
4711        synchronized (mPackages) {
4712            Object obj = mSettings.getUserIdLPr(uid);
4713            if (obj instanceof SharedUserSetting) {
4714                final SharedUserSetting sus = (SharedUserSetting) obj;
4715                final int N = sus.packages.size();
4716                String[] res = new String[N];
4717                final Iterator<PackageSetting> it = sus.packages.iterator();
4718                int i = 0;
4719                while (it.hasNext()) {
4720                    PackageSetting ps = it.next();
4721                    if (ps.getInstalled(userId)) {
4722                        res[i++] = ps.name;
4723                    } else {
4724                        res = ArrayUtils.removeElement(String.class, res, res[i]);
4725                    }
4726                }
4727                return res;
4728            } else if (obj instanceof PackageSetting) {
4729                final PackageSetting ps = (PackageSetting) obj;
4730                return new String[] { ps.name };
4731            }
4732        }
4733        return null;
4734    }
4735
4736    @Override
4737    public String getNameForUid(int uid) {
4738        // reader
4739        synchronized (mPackages) {
4740            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
4741            if (obj instanceof SharedUserSetting) {
4742                final SharedUserSetting sus = (SharedUserSetting) obj;
4743                return sus.name + ":" + sus.userId;
4744            } else if (obj instanceof PackageSetting) {
4745                final PackageSetting ps = (PackageSetting) obj;
4746                return ps.name;
4747            }
4748        }
4749        return null;
4750    }
4751
4752    @Override
4753    public int getUidForSharedUser(String sharedUserName) {
4754        if(sharedUserName == null) {
4755            return -1;
4756        }
4757        // reader
4758        synchronized (mPackages) {
4759            final SharedUserSetting suid = mSettings.getSharedUserLPw(sharedUserName, 0, 0, false);
4760            if (suid == null) {
4761                return -1;
4762            }
4763            return suid.userId;
4764        }
4765    }
4766
4767    @Override
4768    public int getFlagsForUid(int uid) {
4769        synchronized (mPackages) {
4770            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
4771            if (obj instanceof SharedUserSetting) {
4772                final SharedUserSetting sus = (SharedUserSetting) obj;
4773                return sus.pkgFlags;
4774            } else if (obj instanceof PackageSetting) {
4775                final PackageSetting ps = (PackageSetting) obj;
4776                return ps.pkgFlags;
4777            }
4778        }
4779        return 0;
4780    }
4781
4782    @Override
4783    public int getPrivateFlagsForUid(int uid) {
4784        synchronized (mPackages) {
4785            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
4786            if (obj instanceof SharedUserSetting) {
4787                final SharedUserSetting sus = (SharedUserSetting) obj;
4788                return sus.pkgPrivateFlags;
4789            } else if (obj instanceof PackageSetting) {
4790                final PackageSetting ps = (PackageSetting) obj;
4791                return ps.pkgPrivateFlags;
4792            }
4793        }
4794        return 0;
4795    }
4796
4797    @Override
4798    public boolean isUidPrivileged(int uid) {
4799        uid = UserHandle.getAppId(uid);
4800        // reader
4801        synchronized (mPackages) {
4802            Object obj = mSettings.getUserIdLPr(uid);
4803            if (obj instanceof SharedUserSetting) {
4804                final SharedUserSetting sus = (SharedUserSetting) obj;
4805                final Iterator<PackageSetting> it = sus.packages.iterator();
4806                while (it.hasNext()) {
4807                    if (it.next().isPrivileged()) {
4808                        return true;
4809                    }
4810                }
4811            } else if (obj instanceof PackageSetting) {
4812                final PackageSetting ps = (PackageSetting) obj;
4813                return ps.isPrivileged();
4814            }
4815        }
4816        return false;
4817    }
4818
4819    @Override
4820    public String[] getAppOpPermissionPackages(String permissionName) {
4821        synchronized (mPackages) {
4822            ArraySet<String> pkgs = mAppOpPermissionPackages.get(permissionName);
4823            if (pkgs == null) {
4824                return null;
4825            }
4826            return pkgs.toArray(new String[pkgs.size()]);
4827        }
4828    }
4829
4830    @Override
4831    public ResolveInfo resolveIntent(Intent intent, String resolvedType,
4832            int flags, int userId) {
4833        try {
4834            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveIntent");
4835
4836            if (!sUserManager.exists(userId)) return null;
4837            flags = updateFlagsForResolve(flags, userId, intent);
4838            enforceCrossUserPermission(Binder.getCallingUid(), userId,
4839                    false /*requireFullPermission*/, false /*checkShell*/, "resolve intent");
4840
4841            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities");
4842            final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType,
4843                    flags, userId);
4844            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
4845
4846            final ResolveInfo bestChoice =
4847                    chooseBestActivity(intent, resolvedType, flags, query, userId);
4848            return bestChoice;
4849        } finally {
4850            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
4851        }
4852    }
4853
4854    @Override
4855    public void setLastChosenActivity(Intent intent, String resolvedType, int flags,
4856            IntentFilter filter, int match, ComponentName activity) {
4857        final int userId = UserHandle.getCallingUserId();
4858        if (DEBUG_PREFERRED) {
4859            Log.v(TAG, "setLastChosenActivity intent=" + intent
4860                + " resolvedType=" + resolvedType
4861                + " flags=" + flags
4862                + " filter=" + filter
4863                + " match=" + match
4864                + " activity=" + activity);
4865            filter.dump(new PrintStreamPrinter(System.out), "    ");
4866        }
4867        intent.setComponent(null);
4868        final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
4869                userId);
4870        // Find any earlier preferred or last chosen entries and nuke them
4871        findPreferredActivity(intent, resolvedType,
4872                flags, query, 0, false, true, false, userId);
4873        // Add the new activity as the last chosen for this filter
4874        addPreferredActivityInternal(filter, match, null, activity, false, userId,
4875                "Setting last chosen");
4876    }
4877
4878    @Override
4879    public ResolveInfo getLastChosenActivity(Intent intent, String resolvedType, int flags) {
4880        final int userId = UserHandle.getCallingUserId();
4881        if (DEBUG_PREFERRED) Log.v(TAG, "Querying last chosen activity for " + intent);
4882        final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
4883                userId);
4884        return findPreferredActivity(intent, resolvedType, flags, query, 0,
4885                false, false, false, userId);
4886    }
4887
4888    private boolean isEphemeralDisabled() {
4889        // ephemeral apps have been disabled across the board
4890        if (DISABLE_EPHEMERAL_APPS) {
4891            return true;
4892        }
4893        // system isn't up yet; can't read settings, so, assume no ephemeral apps
4894        if (!mSystemReady) {
4895            return true;
4896        }
4897        // we can't get a content resolver until the system is ready; these checks must happen last
4898        final ContentResolver resolver = mContext.getContentResolver();
4899        if (Global.getInt(resolver, Global.ENABLE_EPHEMERAL_FEATURE, 1) == 0) {
4900            return true;
4901        }
4902        return Secure.getInt(resolver, Secure.WEB_ACTION_ENABLED, 1) == 0;
4903    }
4904
4905    private boolean isEphemeralAllowed(
4906            Intent intent, List<ResolveInfo> resolvedActivities, int userId,
4907            boolean skipPackageCheck) {
4908        // Short circuit and return early if possible.
4909        if (isEphemeralDisabled()) {
4910            return false;
4911        }
4912        final int callingUser = UserHandle.getCallingUserId();
4913        if (callingUser != UserHandle.USER_SYSTEM) {
4914            return false;
4915        }
4916        if (mEphemeralResolverConnection == null) {
4917            return false;
4918        }
4919        if (intent.getComponent() != null) {
4920            return false;
4921        }
4922        if ((intent.getFlags() & Intent.FLAG_IGNORE_EPHEMERAL) != 0) {
4923            return false;
4924        }
4925        if (!skipPackageCheck && intent.getPackage() != null) {
4926            return false;
4927        }
4928        final boolean isWebUri = hasWebURI(intent);
4929        if (!isWebUri || intent.getData().getHost() == null) {
4930            return false;
4931        }
4932        // Deny ephemeral apps if the user chose _ALWAYS or _ALWAYS_ASK for intent resolution.
4933        synchronized (mPackages) {
4934            final int count = (resolvedActivities == null ? 0 : resolvedActivities.size());
4935            for (int n = 0; n < count; n++) {
4936                ResolveInfo info = resolvedActivities.get(n);
4937                String packageName = info.activityInfo.packageName;
4938                PackageSetting ps = mSettings.mPackages.get(packageName);
4939                if (ps != null) {
4940                    // Try to get the status from User settings first
4941                    long packedStatus = getDomainVerificationStatusLPr(ps, userId);
4942                    int status = (int) (packedStatus >> 32);
4943                    if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS
4944                            || status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
4945                        if (DEBUG_EPHEMERAL) {
4946                            Slog.v(TAG, "DENY ephemeral apps;"
4947                                + " pkg: " + packageName + ", status: " + status);
4948                        }
4949                        return false;
4950                    }
4951                }
4952            }
4953        }
4954        // We've exhausted all ways to deny ephemeral application; let the system look for them.
4955        return true;
4956    }
4957
4958    private static EphemeralResolveInfo getEphemeralResolveInfo(
4959            Context context, EphemeralResolverConnection resolverConnection, Intent intent,
4960            String resolvedType, int userId, String packageName) {
4961        final int ephemeralPrefixMask = Global.getInt(context.getContentResolver(),
4962                Global.EPHEMERAL_HASH_PREFIX_MASK, DEFAULT_EPHEMERAL_HASH_PREFIX_MASK);
4963        final int ephemeralPrefixCount = Global.getInt(context.getContentResolver(),
4964                Global.EPHEMERAL_HASH_PREFIX_COUNT, DEFAULT_EPHEMERAL_HASH_PREFIX_COUNT);
4965        final EphemeralDigest digest = new EphemeralDigest(intent.getData(), ephemeralPrefixMask,
4966                ephemeralPrefixCount);
4967        final int[] shaPrefix = digest.getDigestPrefix();
4968        final byte[][] digestBytes = digest.getDigestBytes();
4969        final List<EphemeralResolveInfo> ephemeralResolveInfoList =
4970                resolverConnection.getEphemeralResolveInfoList(shaPrefix, ephemeralPrefixMask);
4971        if (ephemeralResolveInfoList == null || ephemeralResolveInfoList.size() == 0) {
4972            // No hash prefix match; there are no ephemeral apps for this domain.
4973            return null;
4974        }
4975
4976        // Go in reverse order so we match the narrowest scope first.
4977        for (int i = shaPrefix.length - 1; i >= 0 ; --i) {
4978            for (EphemeralResolveInfo ephemeralApplication : ephemeralResolveInfoList) {
4979                if (!Arrays.equals(digestBytes[i], ephemeralApplication.getDigestBytes())) {
4980                    continue;
4981                }
4982                final List<IntentFilter> filters = ephemeralApplication.getFilters();
4983                // No filters; this should never happen.
4984                if (filters.isEmpty()) {
4985                    continue;
4986                }
4987                if (packageName != null
4988                        && !packageName.equals(ephemeralApplication.getPackageName())) {
4989                    continue;
4990                }
4991                // We have a domain match; resolve the filters to see if anything matches.
4992                final EphemeralIntentResolver ephemeralResolver = new EphemeralIntentResolver();
4993                for (int j = filters.size() - 1; j >= 0; --j) {
4994                    final EphemeralResolveIntentInfo intentInfo =
4995                            new EphemeralResolveIntentInfo(filters.get(j), ephemeralApplication);
4996                    ephemeralResolver.addFilter(intentInfo);
4997                }
4998                List<EphemeralResolveInfo> matchedResolveInfoList = ephemeralResolver.queryIntent(
4999                        intent, resolvedType, false /*defaultOnly*/, userId);
5000                if (!matchedResolveInfoList.isEmpty()) {
5001                    return matchedResolveInfoList.get(0);
5002                }
5003            }
5004        }
5005        // Hash or filter mis-match; no ephemeral apps for this domain.
5006        return null;
5007    }
5008
5009    private ResolveInfo chooseBestActivity(Intent intent, String resolvedType,
5010            int flags, List<ResolveInfo> query, int userId) {
5011        if (query != null) {
5012            final int N = query.size();
5013            if (N == 1) {
5014                return query.get(0);
5015            } else if (N > 1) {
5016                final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
5017                // If there is more than one activity with the same priority,
5018                // then let the user decide between them.
5019                ResolveInfo r0 = query.get(0);
5020                ResolveInfo r1 = query.get(1);
5021                if (DEBUG_INTENT_MATCHING || debug) {
5022                    Slog.v(TAG, r0.activityInfo.name + "=" + r0.priority + " vs "
5023                            + r1.activityInfo.name + "=" + r1.priority);
5024                }
5025                // If the first activity has a higher priority, or a different
5026                // default, then it is always desirable to pick it.
5027                if (r0.priority != r1.priority
5028                        || r0.preferredOrder != r1.preferredOrder
5029                        || r0.isDefault != r1.isDefault) {
5030                    return query.get(0);
5031                }
5032                // If we have saved a preference for a preferred activity for
5033                // this Intent, use that.
5034                ResolveInfo ri = findPreferredActivity(intent, resolvedType,
5035                        flags, query, r0.priority, true, false, debug, userId);
5036                if (ri != null) {
5037                    return ri;
5038                }
5039                ri = new ResolveInfo(mResolveInfo);
5040                ri.activityInfo = new ActivityInfo(ri.activityInfo);
5041                ri.activityInfo.labelRes = ResolverActivity.getLabelRes(intent.getAction());
5042                // If all of the options come from the same package, show the application's
5043                // label and icon instead of the generic resolver's.
5044                // Some calls like Intent.resolveActivityInfo query the ResolveInfo from here
5045                // and then throw away the ResolveInfo itself, meaning that the caller loses
5046                // the resolvePackageName. Therefore the activityInfo.labelRes above provides
5047                // a fallback for this case; we only set the target package's resources on
5048                // the ResolveInfo, not the ActivityInfo.
5049                final String intentPackage = intent.getPackage();
5050                if (!TextUtils.isEmpty(intentPackage) && allHavePackage(query, intentPackage)) {
5051                    final ApplicationInfo appi = query.get(0).activityInfo.applicationInfo;
5052                    ri.resolvePackageName = intentPackage;
5053                    if (userNeedsBadging(userId)) {
5054                        ri.noResourceId = true;
5055                    } else {
5056                        ri.icon = appi.icon;
5057                    }
5058                    ri.iconResourceId = appi.icon;
5059                    ri.labelRes = appi.labelRes;
5060                }
5061                ri.activityInfo.applicationInfo = new ApplicationInfo(
5062                        ri.activityInfo.applicationInfo);
5063                if (userId != 0) {
5064                    ri.activityInfo.applicationInfo.uid = UserHandle.getUid(userId,
5065                            UserHandle.getAppId(ri.activityInfo.applicationInfo.uid));
5066                }
5067                // Make sure that the resolver is displayable in car mode
5068                if (ri.activityInfo.metaData == null) ri.activityInfo.metaData = new Bundle();
5069                ri.activityInfo.metaData.putBoolean(Intent.METADATA_DOCK_HOME, true);
5070                return ri;
5071            }
5072        }
5073        return null;
5074    }
5075
5076    /**
5077     * Return true if the given list is not empty and all of its contents have
5078     * an activityInfo with the given package name.
5079     */
5080    private boolean allHavePackage(List<ResolveInfo> list, String packageName) {
5081        if (ArrayUtils.isEmpty(list)) {
5082            return false;
5083        }
5084        for (int i = 0, N = list.size(); i < N; i++) {
5085            final ResolveInfo ri = list.get(i);
5086            final ActivityInfo ai = ri != null ? ri.activityInfo : null;
5087            if (ai == null || !packageName.equals(ai.packageName)) {
5088                return false;
5089            }
5090        }
5091        return true;
5092    }
5093
5094    private ResolveInfo findPersistentPreferredActivityLP(Intent intent, String resolvedType,
5095            int flags, List<ResolveInfo> query, boolean debug, int userId) {
5096        final int N = query.size();
5097        PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
5098                .get(userId);
5099        // Get the list of persistent preferred activities that handle the intent
5100        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for presistent preferred activities...");
5101        List<PersistentPreferredActivity> pprefs = ppir != null
5102                ? ppir.queryIntent(intent, resolvedType,
5103                        (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId)
5104                : null;
5105        if (pprefs != null && pprefs.size() > 0) {
5106            final int M = pprefs.size();
5107            for (int i=0; i<M; i++) {
5108                final PersistentPreferredActivity ppa = pprefs.get(i);
5109                if (DEBUG_PREFERRED || debug) {
5110                    Slog.v(TAG, "Checking PersistentPreferredActivity ds="
5111                            + (ppa.countDataSchemes() > 0 ? ppa.getDataScheme(0) : "<none>")
5112                            + "\n  component=" + ppa.mComponent);
5113                    ppa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
5114                }
5115                final ActivityInfo ai = getActivityInfo(ppa.mComponent,
5116                        flags | MATCH_DISABLED_COMPONENTS, userId);
5117                if (DEBUG_PREFERRED || debug) {
5118                    Slog.v(TAG, "Found persistent preferred activity:");
5119                    if (ai != null) {
5120                        ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
5121                    } else {
5122                        Slog.v(TAG, "  null");
5123                    }
5124                }
5125                if (ai == null) {
5126                    // This previously registered persistent preferred activity
5127                    // component is no longer known. Ignore it and do NOT remove it.
5128                    continue;
5129                }
5130                for (int j=0; j<N; j++) {
5131                    final ResolveInfo ri = query.get(j);
5132                    if (!ri.activityInfo.applicationInfo.packageName
5133                            .equals(ai.applicationInfo.packageName)) {
5134                        continue;
5135                    }
5136                    if (!ri.activityInfo.name.equals(ai.name)) {
5137                        continue;
5138                    }
5139                    //  Found a persistent preference that can handle the intent.
5140                    if (DEBUG_PREFERRED || debug) {
5141                        Slog.v(TAG, "Returning persistent preferred activity: " +
5142                                ri.activityInfo.packageName + "/" + ri.activityInfo.name);
5143                    }
5144                    return ri;
5145                }
5146            }
5147        }
5148        return null;
5149    }
5150
5151    // TODO: handle preferred activities missing while user has amnesia
5152    ResolveInfo findPreferredActivity(Intent intent, String resolvedType, int flags,
5153            List<ResolveInfo> query, int priority, boolean always,
5154            boolean removeMatches, boolean debug, int userId) {
5155        if (!sUserManager.exists(userId)) return null;
5156        flags = updateFlagsForResolve(flags, userId, intent);
5157        // writer
5158        synchronized (mPackages) {
5159            if (intent.getSelector() != null) {
5160                intent = intent.getSelector();
5161            }
5162            if (DEBUG_PREFERRED) intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION);
5163
5164            // Try to find a matching persistent preferred activity.
5165            ResolveInfo pri = findPersistentPreferredActivityLP(intent, resolvedType, flags, query,
5166                    debug, userId);
5167
5168            // If a persistent preferred activity matched, use it.
5169            if (pri != null) {
5170                return pri;
5171            }
5172
5173            PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
5174            // Get the list of preferred activities that handle the intent
5175            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for preferred activities...");
5176            List<PreferredActivity> prefs = pir != null
5177                    ? pir.queryIntent(intent, resolvedType,
5178                            (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId)
5179                    : null;
5180            if (prefs != null && prefs.size() > 0) {
5181                boolean changed = false;
5182                try {
5183                    // First figure out how good the original match set is.
5184                    // We will only allow preferred activities that came
5185                    // from the same match quality.
5186                    int match = 0;
5187
5188                    if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Figuring out best match...");
5189
5190                    final int N = query.size();
5191                    for (int j=0; j<N; j++) {
5192                        final ResolveInfo ri = query.get(j);
5193                        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Match for " + ri.activityInfo
5194                                + ": 0x" + Integer.toHexString(match));
5195                        if (ri.match > match) {
5196                            match = ri.match;
5197                        }
5198                    }
5199
5200                    if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Best match: 0x"
5201                            + Integer.toHexString(match));
5202
5203                    match &= IntentFilter.MATCH_CATEGORY_MASK;
5204                    final int M = prefs.size();
5205                    for (int i=0; i<M; i++) {
5206                        final PreferredActivity pa = prefs.get(i);
5207                        if (DEBUG_PREFERRED || debug) {
5208                            Slog.v(TAG, "Checking PreferredActivity ds="
5209                                    + (pa.countDataSchemes() > 0 ? pa.getDataScheme(0) : "<none>")
5210                                    + "\n  component=" + pa.mPref.mComponent);
5211                            pa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
5212                        }
5213                        if (pa.mPref.mMatch != match) {
5214                            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping bad match "
5215                                    + Integer.toHexString(pa.mPref.mMatch));
5216                            continue;
5217                        }
5218                        // If it's not an "always" type preferred activity and that's what we're
5219                        // looking for, skip it.
5220                        if (always && !pa.mPref.mAlways) {
5221                            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping mAlways=false entry");
5222                            continue;
5223                        }
5224                        final ActivityInfo ai = getActivityInfo(
5225                                pa.mPref.mComponent, flags | MATCH_DISABLED_COMPONENTS
5226                                        | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
5227                                userId);
5228                        if (DEBUG_PREFERRED || debug) {
5229                            Slog.v(TAG, "Found preferred activity:");
5230                            if (ai != null) {
5231                                ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
5232                            } else {
5233                                Slog.v(TAG, "  null");
5234                            }
5235                        }
5236                        if (ai == null) {
5237                            // This previously registered preferred activity
5238                            // component is no longer known.  Most likely an update
5239                            // to the app was installed and in the new version this
5240                            // component no longer exists.  Clean it up by removing
5241                            // it from the preferred activities list, and skip it.
5242                            Slog.w(TAG, "Removing dangling preferred activity: "
5243                                    + pa.mPref.mComponent);
5244                            pir.removeFilter(pa);
5245                            changed = true;
5246                            continue;
5247                        }
5248                        for (int j=0; j<N; j++) {
5249                            final ResolveInfo ri = query.get(j);
5250                            if (!ri.activityInfo.applicationInfo.packageName
5251                                    .equals(ai.applicationInfo.packageName)) {
5252                                continue;
5253                            }
5254                            if (!ri.activityInfo.name.equals(ai.name)) {
5255                                continue;
5256                            }
5257
5258                            if (removeMatches) {
5259                                pir.removeFilter(pa);
5260                                changed = true;
5261                                if (DEBUG_PREFERRED) {
5262                                    Slog.v(TAG, "Removing match " + pa.mPref.mComponent);
5263                                }
5264                                break;
5265                            }
5266
5267                            // Okay we found a previously set preferred or last chosen app.
5268                            // If the result set is different from when this
5269                            // was created, we need to clear it and re-ask the
5270                            // user their preference, if we're looking for an "always" type entry.
5271                            if (always && !pa.mPref.sameSet(query)) {
5272                                Slog.i(TAG, "Result set changed, dropping preferred activity for "
5273                                        + intent + " type " + resolvedType);
5274                                if (DEBUG_PREFERRED) {
5275                                    Slog.v(TAG, "Removing preferred activity since set changed "
5276                                            + pa.mPref.mComponent);
5277                                }
5278                                pir.removeFilter(pa);
5279                                // Re-add the filter as a "last chosen" entry (!always)
5280                                PreferredActivity lastChosen = new PreferredActivity(
5281                                        pa, pa.mPref.mMatch, null, pa.mPref.mComponent, false);
5282                                pir.addFilter(lastChosen);
5283                                changed = true;
5284                                return null;
5285                            }
5286
5287                            // Yay! Either the set matched or we're looking for the last chosen
5288                            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Returning preferred activity: "
5289                                    + ri.activityInfo.packageName + "/" + ri.activityInfo.name);
5290                            return ri;
5291                        }
5292                    }
5293                } finally {
5294                    if (changed) {
5295                        if (DEBUG_PREFERRED) {
5296                            Slog.v(TAG, "Preferred activity bookkeeping changed; writing restrictions");
5297                        }
5298                        scheduleWritePackageRestrictionsLocked(userId);
5299                    }
5300                }
5301            }
5302        }
5303        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "No preferred activity to return");
5304        return null;
5305    }
5306
5307    /*
5308     * Returns if intent can be forwarded from the sourceUserId to the targetUserId
5309     */
5310    @Override
5311    public boolean canForwardTo(Intent intent, String resolvedType, int sourceUserId,
5312            int targetUserId) {
5313        mContext.enforceCallingOrSelfPermission(
5314                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
5315        List<CrossProfileIntentFilter> matches =
5316                getMatchingCrossProfileIntentFilters(intent, resolvedType, sourceUserId);
5317        if (matches != null) {
5318            int size = matches.size();
5319            for (int i = 0; i < size; i++) {
5320                if (matches.get(i).getTargetUserId() == targetUserId) return true;
5321            }
5322        }
5323        if (hasWebURI(intent)) {
5324            // cross-profile app linking works only towards the parent.
5325            final UserInfo parent = getProfileParent(sourceUserId);
5326            synchronized(mPackages) {
5327                int flags = updateFlagsForResolve(0, parent.id, intent);
5328                CrossProfileDomainInfo xpDomainInfo = getCrossProfileDomainPreferredLpr(
5329                        intent, resolvedType, flags, sourceUserId, parent.id);
5330                return xpDomainInfo != null;
5331            }
5332        }
5333        return false;
5334    }
5335
5336    private UserInfo getProfileParent(int userId) {
5337        final long identity = Binder.clearCallingIdentity();
5338        try {
5339            return sUserManager.getProfileParent(userId);
5340        } finally {
5341            Binder.restoreCallingIdentity(identity);
5342        }
5343    }
5344
5345    private List<CrossProfileIntentFilter> getMatchingCrossProfileIntentFilters(Intent intent,
5346            String resolvedType, int userId) {
5347        CrossProfileIntentResolver resolver = mSettings.mCrossProfileIntentResolvers.get(userId);
5348        if (resolver != null) {
5349            return resolver.queryIntent(intent, resolvedType, false, userId);
5350        }
5351        return null;
5352    }
5353
5354    @Override
5355    public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivities(Intent intent,
5356            String resolvedType, int flags, int userId) {
5357        try {
5358            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities");
5359
5360            return new ParceledListSlice<>(
5361                    queryIntentActivitiesInternal(intent, resolvedType, flags, userId));
5362        } finally {
5363            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
5364        }
5365    }
5366
5367    private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
5368            String resolvedType, int flags, int userId) {
5369        if (!sUserManager.exists(userId)) return Collections.emptyList();
5370        flags = updateFlagsForResolve(flags, userId, intent);
5371        enforceCrossUserPermission(Binder.getCallingUid(), userId,
5372                false /* requireFullPermission */, false /* checkShell */,
5373                "query intent activities");
5374        ComponentName comp = intent.getComponent();
5375        if (comp == null) {
5376            if (intent.getSelector() != null) {
5377                intent = intent.getSelector();
5378                comp = intent.getComponent();
5379            }
5380        }
5381
5382        if (comp != null) {
5383            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
5384            final ActivityInfo ai = getActivityInfo(comp, flags, userId);
5385            if (ai != null) {
5386                final ResolveInfo ri = new ResolveInfo();
5387                ri.activityInfo = ai;
5388                list.add(ri);
5389            }
5390            return list;
5391        }
5392
5393        // reader
5394        boolean sortResult = false;
5395        boolean addEphemeral = false;
5396        boolean matchEphemeralPackage = false;
5397        List<ResolveInfo> result;
5398        final String pkgName = intent.getPackage();
5399        synchronized (mPackages) {
5400            if (pkgName == null) {
5401                List<CrossProfileIntentFilter> matchingFilters =
5402                        getMatchingCrossProfileIntentFilters(intent, resolvedType, userId);
5403                // Check for results that need to skip the current profile.
5404                ResolveInfo xpResolveInfo  = querySkipCurrentProfileIntents(matchingFilters, intent,
5405                        resolvedType, flags, userId);
5406                if (xpResolveInfo != null) {
5407                    List<ResolveInfo> xpResult = new ArrayList<ResolveInfo>(1);
5408                    xpResult.add(xpResolveInfo);
5409                    return filterIfNotSystemUser(xpResult, userId);
5410                }
5411
5412                // Check for results in the current profile.
5413                result = filterIfNotSystemUser(mActivities.queryIntent(
5414                        intent, resolvedType, flags, userId), userId);
5415                addEphemeral =
5416                        isEphemeralAllowed(intent, result, userId, false /*skipPackageCheck*/);
5417
5418                // Check for cross profile results.
5419                boolean hasNonNegativePriorityResult = hasNonNegativePriority(result);
5420                xpResolveInfo = queryCrossProfileIntents(
5421                        matchingFilters, intent, resolvedType, flags, userId,
5422                        hasNonNegativePriorityResult);
5423                if (xpResolveInfo != null && isUserEnabled(xpResolveInfo.targetUserId)) {
5424                    boolean isVisibleToUser = filterIfNotSystemUser(
5425                            Collections.singletonList(xpResolveInfo), userId).size() > 0;
5426                    if (isVisibleToUser) {
5427                        result.add(xpResolveInfo);
5428                        sortResult = true;
5429                    }
5430                }
5431                if (hasWebURI(intent)) {
5432                    CrossProfileDomainInfo xpDomainInfo = null;
5433                    final UserInfo parent = getProfileParent(userId);
5434                    if (parent != null) {
5435                        xpDomainInfo = getCrossProfileDomainPreferredLpr(intent, resolvedType,
5436                                flags, userId, parent.id);
5437                    }
5438                    if (xpDomainInfo != null) {
5439                        if (xpResolveInfo != null) {
5440                            // If we didn't remove it, the cross-profile ResolveInfo would be twice
5441                            // in the result.
5442                            result.remove(xpResolveInfo);
5443                        }
5444                        if (result.size() == 0 && !addEphemeral) {
5445                            // No result in current profile, but found candidate in parent user.
5446                            // And we are not going to add emphemeral app, so we can return the
5447                            // result straight away.
5448                            result.add(xpDomainInfo.resolveInfo);
5449                            return result;
5450                        }
5451                    } else if (result.size() <= 1 && !addEphemeral) {
5452                        // No result in parent user and <= 1 result in current profile, and we
5453                        // are not going to add emphemeral app, so we can return the result without
5454                        // further processing.
5455                        return result;
5456                    }
5457                    // We have more than one candidate (combining results from current and parent
5458                    // profile), so we need filtering and sorting.
5459                    result = filterCandidatesWithDomainPreferredActivitiesLPr(
5460                            intent, flags, result, xpDomainInfo, userId);
5461                    sortResult = true;
5462                }
5463            } else {
5464                final PackageParser.Package pkg = mPackages.get(pkgName);
5465                if (pkg != null) {
5466                    result = filterIfNotSystemUser(
5467                            mActivities.queryIntentForPackage(
5468                                    intent, resolvedType, flags, pkg.activities, userId),
5469                            userId);
5470                } else {
5471                    // the caller wants to resolve for a particular package; however, there
5472                    // were no installed results, so, try to find an ephemeral result
5473                    addEphemeral = isEphemeralAllowed(
5474                            intent, null /*result*/, userId, true /*skipPackageCheck*/);
5475                    matchEphemeralPackage = true;
5476                    result = new ArrayList<ResolveInfo>();
5477                }
5478            }
5479        }
5480        if (addEphemeral) {
5481            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveEphemeral");
5482            final EphemeralResolveInfo ai = getEphemeralResolveInfo(
5483                    mContext, mEphemeralResolverConnection, intent, resolvedType, userId,
5484                    matchEphemeralPackage ? pkgName : null);
5485            if (ai != null) {
5486                if (DEBUG_EPHEMERAL) {
5487                    Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
5488                }
5489                final ResolveInfo ephemeralInstaller = new ResolveInfo(mEphemeralInstallerInfo);
5490                ephemeralInstaller.ephemeralResolveInfo = ai;
5491                // make sure this resolver is the default
5492                ephemeralInstaller.isDefault = true;
5493                ephemeralInstaller.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
5494                        | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
5495                // add a non-generic filter
5496                ephemeralInstaller.filter = new IntentFilter(intent.getAction());
5497                ephemeralInstaller.filter.addDataPath(
5498                        intent.getData().getPath(), PatternMatcher.PATTERN_LITERAL);
5499                result.add(ephemeralInstaller);
5500            }
5501            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
5502        }
5503        if (sortResult) {
5504            Collections.sort(result, mResolvePrioritySorter);
5505        }
5506        return result;
5507    }
5508
5509    private static class CrossProfileDomainInfo {
5510        /* ResolveInfo for IntentForwarderActivity to send the intent to the other profile */
5511        ResolveInfo resolveInfo;
5512        /* Best domain verification status of the activities found in the other profile */
5513        int bestDomainVerificationStatus;
5514    }
5515
5516    private CrossProfileDomainInfo getCrossProfileDomainPreferredLpr(Intent intent,
5517            String resolvedType, int flags, int sourceUserId, int parentUserId) {
5518        if (!sUserManager.hasUserRestriction(UserManager.ALLOW_PARENT_PROFILE_APP_LINKING,
5519                sourceUserId)) {
5520            return null;
5521        }
5522        List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent,
5523                resolvedType, flags, parentUserId);
5524
5525        if (resultTargetUser == null || resultTargetUser.isEmpty()) {
5526            return null;
5527        }
5528        CrossProfileDomainInfo result = null;
5529        int size = resultTargetUser.size();
5530        for (int i = 0; i < size; i++) {
5531            ResolveInfo riTargetUser = resultTargetUser.get(i);
5532            // Intent filter verification is only for filters that specify a host. So don't return
5533            // those that handle all web uris.
5534            if (riTargetUser.handleAllWebDataURI) {
5535                continue;
5536            }
5537            String packageName = riTargetUser.activityInfo.packageName;
5538            PackageSetting ps = mSettings.mPackages.get(packageName);
5539            if (ps == null) {
5540                continue;
5541            }
5542            long verificationState = getDomainVerificationStatusLPr(ps, parentUserId);
5543            int status = (int)(verificationState >> 32);
5544            if (result == null) {
5545                result = new CrossProfileDomainInfo();
5546                result.resolveInfo = createForwardingResolveInfoUnchecked(new IntentFilter(),
5547                        sourceUserId, parentUserId);
5548                result.bestDomainVerificationStatus = status;
5549            } else {
5550                result.bestDomainVerificationStatus = bestDomainVerificationStatus(status,
5551                        result.bestDomainVerificationStatus);
5552            }
5553        }
5554        // Don't consider matches with status NEVER across profiles.
5555        if (result != null && result.bestDomainVerificationStatus
5556                == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
5557            return null;
5558        }
5559        return result;
5560    }
5561
5562    /**
5563     * Verification statuses are ordered from the worse to the best, except for
5564     * INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER, which is the worse.
5565     */
5566    private int bestDomainVerificationStatus(int status1, int status2) {
5567        if (status1 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
5568            return status2;
5569        }
5570        if (status2 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
5571            return status1;
5572        }
5573        return (int) MathUtils.max(status1, status2);
5574    }
5575
5576    private boolean isUserEnabled(int userId) {
5577        long callingId = Binder.clearCallingIdentity();
5578        try {
5579            UserInfo userInfo = sUserManager.getUserInfo(userId);
5580            return userInfo != null && userInfo.isEnabled();
5581        } finally {
5582            Binder.restoreCallingIdentity(callingId);
5583        }
5584    }
5585
5586    /**
5587     * Filter out activities with systemUserOnly flag set, when current user is not System.
5588     *
5589     * @return filtered list
5590     */
5591    private List<ResolveInfo> filterIfNotSystemUser(List<ResolveInfo> resolveInfos, int userId) {
5592        if (userId == UserHandle.USER_SYSTEM) {
5593            return resolveInfos;
5594        }
5595        for (int i = resolveInfos.size() - 1; i >= 0; i--) {
5596            ResolveInfo info = resolveInfos.get(i);
5597            if ((info.activityInfo.flags & ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
5598                resolveInfos.remove(i);
5599            }
5600        }
5601        return resolveInfos;
5602    }
5603
5604    /**
5605     * @param resolveInfos list of resolve infos in descending priority order
5606     * @return if the list contains a resolve info with non-negative priority
5607     */
5608    private boolean hasNonNegativePriority(List<ResolveInfo> resolveInfos) {
5609        return resolveInfos.size() > 0 && resolveInfos.get(0).priority >= 0;
5610    }
5611
5612    private static boolean hasWebURI(Intent intent) {
5613        if (intent.getData() == null) {
5614            return false;
5615        }
5616        final String scheme = intent.getScheme();
5617        if (TextUtils.isEmpty(scheme)) {
5618            return false;
5619        }
5620        return scheme.equals(IntentFilter.SCHEME_HTTP) || scheme.equals(IntentFilter.SCHEME_HTTPS);
5621    }
5622
5623    private List<ResolveInfo> filterCandidatesWithDomainPreferredActivitiesLPr(Intent intent,
5624            int matchFlags, List<ResolveInfo> candidates, CrossProfileDomainInfo xpDomainInfo,
5625            int userId) {
5626        final boolean debug = (intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0;
5627
5628        if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) {
5629            Slog.v(TAG, "Filtering results with preferred activities. Candidates count: " +
5630                    candidates.size());
5631        }
5632
5633        ArrayList<ResolveInfo> result = new ArrayList<ResolveInfo>();
5634        ArrayList<ResolveInfo> alwaysList = new ArrayList<ResolveInfo>();
5635        ArrayList<ResolveInfo> undefinedList = new ArrayList<ResolveInfo>();
5636        ArrayList<ResolveInfo> alwaysAskList = new ArrayList<ResolveInfo>();
5637        ArrayList<ResolveInfo> neverList = new ArrayList<ResolveInfo>();
5638        ArrayList<ResolveInfo> matchAllList = new ArrayList<ResolveInfo>();
5639
5640        synchronized (mPackages) {
5641            final int count = candidates.size();
5642            // First, try to use linked apps. Partition the candidates into four lists:
5643            // one for the final results, one for the "do not use ever", one for "undefined status"
5644            // and finally one for "browser app type".
5645            for (int n=0; n<count; n++) {
5646                ResolveInfo info = candidates.get(n);
5647                String packageName = info.activityInfo.packageName;
5648                PackageSetting ps = mSettings.mPackages.get(packageName);
5649                if (ps != null) {
5650                    // Add to the special match all list (Browser use case)
5651                    if (info.handleAllWebDataURI) {
5652                        matchAllList.add(info);
5653                        continue;
5654                    }
5655                    // Try to get the status from User settings first
5656                    long packedStatus = getDomainVerificationStatusLPr(ps, userId);
5657                    int status = (int)(packedStatus >> 32);
5658                    int linkGeneration = (int)(packedStatus & 0xFFFFFFFF);
5659                    if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) {
5660                        if (DEBUG_DOMAIN_VERIFICATION) {
5661                            Slog.i(TAG, "  + always: " + info.activityInfo.packageName
5662                                    + " : linkgen=" + linkGeneration);
5663                        }
5664                        // Use link-enabled generation as preferredOrder, i.e.
5665                        // prefer newly-enabled over earlier-enabled.
5666                        info.preferredOrder = linkGeneration;
5667                        alwaysList.add(info);
5668                    } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
5669                        if (DEBUG_DOMAIN_VERIFICATION) {
5670                            Slog.i(TAG, "  + never: " + info.activityInfo.packageName);
5671                        }
5672                        neverList.add(info);
5673                    } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
5674                        if (DEBUG_DOMAIN_VERIFICATION) {
5675                            Slog.i(TAG, "  + always-ask: " + info.activityInfo.packageName);
5676                        }
5677                        alwaysAskList.add(info);
5678                    } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED ||
5679                            status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK) {
5680                        if (DEBUG_DOMAIN_VERIFICATION) {
5681                            Slog.i(TAG, "  + ask: " + info.activityInfo.packageName);
5682                        }
5683                        undefinedList.add(info);
5684                    }
5685                }
5686            }
5687
5688            // We'll want to include browser possibilities in a few cases
5689            boolean includeBrowser = false;
5690
5691            // First try to add the "always" resolution(s) for the current user, if any
5692            if (alwaysList.size() > 0) {
5693                result.addAll(alwaysList);
5694            } else {
5695                // Add all undefined apps as we want them to appear in the disambiguation dialog.
5696                result.addAll(undefinedList);
5697                // Maybe add one for the other profile.
5698                if (xpDomainInfo != null && (
5699                        xpDomainInfo.bestDomainVerificationStatus
5700                        != INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER)) {
5701                    result.add(xpDomainInfo.resolveInfo);
5702                }
5703                includeBrowser = true;
5704            }
5705
5706            // The presence of any 'always ask' alternatives means we'll also offer browsers.
5707            // If there were 'always' entries their preferred order has been set, so we also
5708            // back that off to make the alternatives equivalent
5709            if (alwaysAskList.size() > 0) {
5710                for (ResolveInfo i : result) {
5711                    i.preferredOrder = 0;
5712                }
5713                result.addAll(alwaysAskList);
5714                includeBrowser = true;
5715            }
5716
5717            if (includeBrowser) {
5718                // Also add browsers (all of them or only the default one)
5719                if (DEBUG_DOMAIN_VERIFICATION) {
5720                    Slog.v(TAG, "   ...including browsers in candidate set");
5721                }
5722                if ((matchFlags & MATCH_ALL) != 0) {
5723                    result.addAll(matchAllList);
5724                } else {
5725                    // Browser/generic handling case.  If there's a default browser, go straight
5726                    // to that (but only if there is no other higher-priority match).
5727                    final String defaultBrowserPackageName = getDefaultBrowserPackageName(userId);
5728                    int maxMatchPrio = 0;
5729                    ResolveInfo defaultBrowserMatch = null;
5730                    final int numCandidates = matchAllList.size();
5731                    for (int n = 0; n < numCandidates; n++) {
5732                        ResolveInfo info = matchAllList.get(n);
5733                        // track the highest overall match priority...
5734                        if (info.priority > maxMatchPrio) {
5735                            maxMatchPrio = info.priority;
5736                        }
5737                        // ...and the highest-priority default browser match
5738                        if (info.activityInfo.packageName.equals(defaultBrowserPackageName)) {
5739                            if (defaultBrowserMatch == null
5740                                    || (defaultBrowserMatch.priority < info.priority)) {
5741                                if (debug) {
5742                                    Slog.v(TAG, "Considering default browser match " + info);
5743                                }
5744                                defaultBrowserMatch = info;
5745                            }
5746                        }
5747                    }
5748                    if (defaultBrowserMatch != null
5749                            && defaultBrowserMatch.priority >= maxMatchPrio
5750                            && !TextUtils.isEmpty(defaultBrowserPackageName))
5751                    {
5752                        if (debug) {
5753                            Slog.v(TAG, "Default browser match " + defaultBrowserMatch);
5754                        }
5755                        result.add(defaultBrowserMatch);
5756                    } else {
5757                        result.addAll(matchAllList);
5758                    }
5759                }
5760
5761                // If there is nothing selected, add all candidates and remove the ones that the user
5762                // has explicitly put into the INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER state
5763                if (result.size() == 0) {
5764                    result.addAll(candidates);
5765                    result.removeAll(neverList);
5766                }
5767            }
5768        }
5769        if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) {
5770            Slog.v(TAG, "Filtered results with preferred activities. New candidates count: " +
5771                    result.size());
5772            for (ResolveInfo info : result) {
5773                Slog.v(TAG, "  + " + info.activityInfo);
5774            }
5775        }
5776        return result;
5777    }
5778
5779    // Returns a packed value as a long:
5780    //
5781    // high 'int'-sized word: link status: undefined/ask/never/always.
5782    // low 'int'-sized word: relative priority among 'always' results.
5783    private long getDomainVerificationStatusLPr(PackageSetting ps, int userId) {
5784        long result = ps.getDomainVerificationStatusForUser(userId);
5785        // if none available, get the master status
5786        if (result >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) {
5787            if (ps.getIntentFilterVerificationInfo() != null) {
5788                result = ((long)ps.getIntentFilterVerificationInfo().getStatus()) << 32;
5789            }
5790        }
5791        return result;
5792    }
5793
5794    private ResolveInfo querySkipCurrentProfileIntents(
5795            List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
5796            int flags, int sourceUserId) {
5797        if (matchingFilters != null) {
5798            int size = matchingFilters.size();
5799            for (int i = 0; i < size; i ++) {
5800                CrossProfileIntentFilter filter = matchingFilters.get(i);
5801                if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0) {
5802                    // Checking if there are activities in the target user that can handle the
5803                    // intent.
5804                    ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent,
5805                            resolvedType, flags, sourceUserId);
5806                    if (resolveInfo != null) {
5807                        return resolveInfo;
5808                    }
5809                }
5810            }
5811        }
5812        return null;
5813    }
5814
5815    // Return matching ResolveInfo in target user if any.
5816    private ResolveInfo queryCrossProfileIntents(
5817            List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
5818            int flags, int sourceUserId, boolean matchInCurrentProfile) {
5819        if (matchingFilters != null) {
5820            // Two {@link CrossProfileIntentFilter}s can have the same targetUserId and
5821            // match the same intent. For performance reasons, it is better not to
5822            // run queryIntent twice for the same userId
5823            SparseBooleanArray alreadyTriedUserIds = new SparseBooleanArray();
5824            int size = matchingFilters.size();
5825            for (int i = 0; i < size; i++) {
5826                CrossProfileIntentFilter filter = matchingFilters.get(i);
5827                int targetUserId = filter.getTargetUserId();
5828                boolean skipCurrentProfile =
5829                        (filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0;
5830                boolean skipCurrentProfileIfNoMatchFound =
5831                        (filter.getFlags() & PackageManager.ONLY_IF_NO_MATCH_FOUND) != 0;
5832                if (!skipCurrentProfile && !alreadyTriedUserIds.get(targetUserId)
5833                        && (!skipCurrentProfileIfNoMatchFound || !matchInCurrentProfile)) {
5834                    // Checking if there are activities in the target user that can handle the
5835                    // intent.
5836                    ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent,
5837                            resolvedType, flags, sourceUserId);
5838                    if (resolveInfo != null) return resolveInfo;
5839                    alreadyTriedUserIds.put(targetUserId, true);
5840                }
5841            }
5842        }
5843        return null;
5844    }
5845
5846    /**
5847     * If the filter's target user can handle the intent and is enabled: returns a ResolveInfo that
5848     * will forward the intent to the filter's target user.
5849     * Otherwise, returns null.
5850     */
5851    private ResolveInfo createForwardingResolveInfo(CrossProfileIntentFilter filter, Intent intent,
5852            String resolvedType, int flags, int sourceUserId) {
5853        int targetUserId = filter.getTargetUserId();
5854        List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent,
5855                resolvedType, flags, targetUserId);
5856        if (resultTargetUser != null && isUserEnabled(targetUserId)) {
5857            // If all the matches in the target profile are suspended, return null.
5858            for (int i = resultTargetUser.size() - 1; i >= 0; i--) {
5859                if ((resultTargetUser.get(i).activityInfo.applicationInfo.flags
5860                        & ApplicationInfo.FLAG_SUSPENDED) == 0) {
5861                    return createForwardingResolveInfoUnchecked(filter, sourceUserId,
5862                            targetUserId);
5863                }
5864            }
5865        }
5866        return null;
5867    }
5868
5869    private ResolveInfo createForwardingResolveInfoUnchecked(IntentFilter filter,
5870            int sourceUserId, int targetUserId) {
5871        ResolveInfo forwardingResolveInfo = new ResolveInfo();
5872        long ident = Binder.clearCallingIdentity();
5873        boolean targetIsProfile;
5874        try {
5875            targetIsProfile = sUserManager.getUserInfo(targetUserId).isManagedProfile();
5876        } finally {
5877            Binder.restoreCallingIdentity(ident);
5878        }
5879        String className;
5880        if (targetIsProfile) {
5881            className = FORWARD_INTENT_TO_MANAGED_PROFILE;
5882        } else {
5883            className = FORWARD_INTENT_TO_PARENT;
5884        }
5885        ComponentName forwardingActivityComponentName = new ComponentName(
5886                mAndroidApplication.packageName, className);
5887        ActivityInfo forwardingActivityInfo = getActivityInfo(forwardingActivityComponentName, 0,
5888                sourceUserId);
5889        if (!targetIsProfile) {
5890            forwardingActivityInfo.showUserIcon = targetUserId;
5891            forwardingResolveInfo.noResourceId = true;
5892        }
5893        forwardingResolveInfo.activityInfo = forwardingActivityInfo;
5894        forwardingResolveInfo.priority = 0;
5895        forwardingResolveInfo.preferredOrder = 0;
5896        forwardingResolveInfo.match = 0;
5897        forwardingResolveInfo.isDefault = true;
5898        forwardingResolveInfo.filter = filter;
5899        forwardingResolveInfo.targetUserId = targetUserId;
5900        return forwardingResolveInfo;
5901    }
5902
5903    @Override
5904    public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivityOptions(ComponentName caller,
5905            Intent[] specifics, String[] specificTypes, Intent intent,
5906            String resolvedType, int flags, int userId) {
5907        return new ParceledListSlice<>(queryIntentActivityOptionsInternal(caller, specifics,
5908                specificTypes, intent, resolvedType, flags, userId));
5909    }
5910
5911    private @NonNull List<ResolveInfo> queryIntentActivityOptionsInternal(ComponentName caller,
5912            Intent[] specifics, String[] specificTypes, Intent intent,
5913            String resolvedType, int flags, int userId) {
5914        if (!sUserManager.exists(userId)) return Collections.emptyList();
5915        flags = updateFlagsForResolve(flags, userId, intent);
5916        enforceCrossUserPermission(Binder.getCallingUid(), userId,
5917                false /* requireFullPermission */, false /* checkShell */,
5918                "query intent activity options");
5919        final String resultsAction = intent.getAction();
5920
5921        final List<ResolveInfo> results = queryIntentActivitiesInternal(intent, resolvedType, flags
5922                | PackageManager.GET_RESOLVED_FILTER, userId);
5923
5924        if (DEBUG_INTENT_MATCHING) {
5925            Log.v(TAG, "Query " + intent + ": " + results);
5926        }
5927
5928        int specificsPos = 0;
5929        int N;
5930
5931        // todo: note that the algorithm used here is O(N^2).  This
5932        // isn't a problem in our current environment, but if we start running
5933        // into situations where we have more than 5 or 10 matches then this
5934        // should probably be changed to something smarter...
5935
5936        // First we go through and resolve each of the specific items
5937        // that were supplied, taking care of removing any corresponding
5938        // duplicate items in the generic resolve list.
5939        if (specifics != null) {
5940            for (int i=0; i<specifics.length; i++) {
5941                final Intent sintent = specifics[i];
5942                if (sintent == null) {
5943                    continue;
5944                }
5945
5946                if (DEBUG_INTENT_MATCHING) {
5947                    Log.v(TAG, "Specific #" + i + ": " + sintent);
5948                }
5949
5950                String action = sintent.getAction();
5951                if (resultsAction != null && resultsAction.equals(action)) {
5952                    // If this action was explicitly requested, then don't
5953                    // remove things that have it.
5954                    action = null;
5955                }
5956
5957                ResolveInfo ri = null;
5958                ActivityInfo ai = null;
5959
5960                ComponentName comp = sintent.getComponent();
5961                if (comp == null) {
5962                    ri = resolveIntent(
5963                        sintent,
5964                        specificTypes != null ? specificTypes[i] : null,
5965                            flags, userId);
5966                    if (ri == null) {
5967                        continue;
5968                    }
5969                    if (ri == mResolveInfo) {
5970                        // ACK!  Must do something better with this.
5971                    }
5972                    ai = ri.activityInfo;
5973                    comp = new ComponentName(ai.applicationInfo.packageName,
5974                            ai.name);
5975                } else {
5976                    ai = getActivityInfo(comp, flags, userId);
5977                    if (ai == null) {
5978                        continue;
5979                    }
5980                }
5981
5982                // Look for any generic query activities that are duplicates
5983                // of this specific one, and remove them from the results.
5984                if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Specific #" + i + ": " + ai);
5985                N = results.size();
5986                int j;
5987                for (j=specificsPos; j<N; j++) {
5988                    ResolveInfo sri = results.get(j);
5989                    if ((sri.activityInfo.name.equals(comp.getClassName())
5990                            && sri.activityInfo.applicationInfo.packageName.equals(
5991                                    comp.getPackageName()))
5992                        || (action != null && sri.filter.matchAction(action))) {
5993                        results.remove(j);
5994                        if (DEBUG_INTENT_MATCHING) Log.v(
5995                            TAG, "Removing duplicate item from " + j
5996                            + " due to specific " + specificsPos);
5997                        if (ri == null) {
5998                            ri = sri;
5999                        }
6000                        j--;
6001                        N--;
6002                    }
6003                }
6004
6005                // Add this specific item to its proper place.
6006                if (ri == null) {
6007                    ri = new ResolveInfo();
6008                    ri.activityInfo = ai;
6009                }
6010                results.add(specificsPos, ri);
6011                ri.specificIndex = i;
6012                specificsPos++;
6013            }
6014        }
6015
6016        // Now we go through the remaining generic results and remove any
6017        // duplicate actions that are found here.
6018        N = results.size();
6019        for (int i=specificsPos; i<N-1; i++) {
6020            final ResolveInfo rii = results.get(i);
6021            if (rii.filter == null) {
6022                continue;
6023            }
6024
6025            // Iterate over all of the actions of this result's intent
6026            // filter...  typically this should be just one.
6027            final Iterator<String> it = rii.filter.actionsIterator();
6028            if (it == null) {
6029                continue;
6030            }
6031            while (it.hasNext()) {
6032                final String action = it.next();
6033                if (resultsAction != null && resultsAction.equals(action)) {
6034                    // If this action was explicitly requested, then don't
6035                    // remove things that have it.
6036                    continue;
6037                }
6038                for (int j=i+1; j<N; j++) {
6039                    final ResolveInfo rij = results.get(j);
6040                    if (rij.filter != null && rij.filter.hasAction(action)) {
6041                        results.remove(j);
6042                        if (DEBUG_INTENT_MATCHING) Log.v(
6043                            TAG, "Removing duplicate item from " + j
6044                            + " due to action " + action + " at " + i);
6045                        j--;
6046                        N--;
6047                    }
6048                }
6049            }
6050
6051            // If the caller didn't request filter information, drop it now
6052            // so we don't have to marshall/unmarshall it.
6053            if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
6054                rii.filter = null;
6055            }
6056        }
6057
6058        // Filter out the caller activity if so requested.
6059        if (caller != null) {
6060            N = results.size();
6061            for (int i=0; i<N; i++) {
6062                ActivityInfo ainfo = results.get(i).activityInfo;
6063                if (caller.getPackageName().equals(ainfo.applicationInfo.packageName)
6064                        && caller.getClassName().equals(ainfo.name)) {
6065                    results.remove(i);
6066                    break;
6067                }
6068            }
6069        }
6070
6071        // If the caller didn't request filter information,
6072        // drop them now so we don't have to
6073        // marshall/unmarshall it.
6074        if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
6075            N = results.size();
6076            for (int i=0; i<N; i++) {
6077                results.get(i).filter = null;
6078            }
6079        }
6080
6081        if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Result: " + results);
6082        return results;
6083    }
6084
6085    @Override
6086    public @NonNull ParceledListSlice<ResolveInfo> queryIntentReceivers(Intent intent,
6087            String resolvedType, int flags, int userId) {
6088        return new ParceledListSlice<>(
6089                queryIntentReceiversInternal(intent, resolvedType, flags, userId));
6090    }
6091
6092    private @NonNull List<ResolveInfo> queryIntentReceiversInternal(Intent intent,
6093            String resolvedType, int flags, int userId) {
6094        if (!sUserManager.exists(userId)) return Collections.emptyList();
6095        flags = updateFlagsForResolve(flags, userId, intent);
6096        ComponentName comp = intent.getComponent();
6097        if (comp == null) {
6098            if (intent.getSelector() != null) {
6099                intent = intent.getSelector();
6100                comp = intent.getComponent();
6101            }
6102        }
6103        if (comp != null) {
6104            List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
6105            ActivityInfo ai = getReceiverInfo(comp, flags, userId);
6106            if (ai != null) {
6107                ResolveInfo ri = new ResolveInfo();
6108                ri.activityInfo = ai;
6109                list.add(ri);
6110            }
6111            return list;
6112        }
6113
6114        // reader
6115        synchronized (mPackages) {
6116            String pkgName = intent.getPackage();
6117            if (pkgName == null) {
6118                return mReceivers.queryIntent(intent, resolvedType, flags, userId);
6119            }
6120            final PackageParser.Package pkg = mPackages.get(pkgName);
6121            if (pkg != null) {
6122                return mReceivers.queryIntentForPackage(intent, resolvedType, flags, pkg.receivers,
6123                        userId);
6124            }
6125            return Collections.emptyList();
6126        }
6127    }
6128
6129    @Override
6130    public ResolveInfo resolveService(Intent intent, String resolvedType, int flags, int userId) {
6131        if (!sUserManager.exists(userId)) return null;
6132        flags = updateFlagsForResolve(flags, userId, intent);
6133        List<ResolveInfo> query = queryIntentServicesInternal(intent, resolvedType, flags, userId);
6134        if (query != null) {
6135            if (query.size() >= 1) {
6136                // If there is more than one service with the same priority,
6137                // just arbitrarily pick the first one.
6138                return query.get(0);
6139            }
6140        }
6141        return null;
6142    }
6143
6144    @Override
6145    public @NonNull ParceledListSlice<ResolveInfo> queryIntentServices(Intent intent,
6146            String resolvedType, int flags, int userId) {
6147        return new ParceledListSlice<>(
6148                queryIntentServicesInternal(intent, resolvedType, flags, userId));
6149    }
6150
6151    private @NonNull List<ResolveInfo> queryIntentServicesInternal(Intent intent,
6152            String resolvedType, int flags, int userId) {
6153        if (!sUserManager.exists(userId)) return Collections.emptyList();
6154        flags = updateFlagsForResolve(flags, userId, intent);
6155        ComponentName comp = intent.getComponent();
6156        if (comp == null) {
6157            if (intent.getSelector() != null) {
6158                intent = intent.getSelector();
6159                comp = intent.getComponent();
6160            }
6161        }
6162        if (comp != null) {
6163            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
6164            final ServiceInfo si = getServiceInfo(comp, flags, userId);
6165            if (si != null) {
6166                final ResolveInfo ri = new ResolveInfo();
6167                ri.serviceInfo = si;
6168                list.add(ri);
6169            }
6170            return list;
6171        }
6172
6173        // reader
6174        synchronized (mPackages) {
6175            String pkgName = intent.getPackage();
6176            if (pkgName == null) {
6177                return mServices.queryIntent(intent, resolvedType, flags, userId);
6178            }
6179            final PackageParser.Package pkg = mPackages.get(pkgName);
6180            if (pkg != null) {
6181                return mServices.queryIntentForPackage(intent, resolvedType, flags, pkg.services,
6182                        userId);
6183            }
6184            return Collections.emptyList();
6185        }
6186    }
6187
6188    @Override
6189    public @NonNull ParceledListSlice<ResolveInfo> queryIntentContentProviders(Intent intent,
6190            String resolvedType, int flags, int userId) {
6191        return new ParceledListSlice<>(
6192                queryIntentContentProvidersInternal(intent, resolvedType, flags, userId));
6193    }
6194
6195    private @NonNull List<ResolveInfo> queryIntentContentProvidersInternal(
6196            Intent intent, String resolvedType, int flags, int userId) {
6197        if (!sUserManager.exists(userId)) return Collections.emptyList();
6198        flags = updateFlagsForResolve(flags, userId, intent);
6199        ComponentName comp = intent.getComponent();
6200        if (comp == null) {
6201            if (intent.getSelector() != null) {
6202                intent = intent.getSelector();
6203                comp = intent.getComponent();
6204            }
6205        }
6206        if (comp != null) {
6207            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
6208            final ProviderInfo pi = getProviderInfo(comp, flags, userId);
6209            if (pi != null) {
6210                final ResolveInfo ri = new ResolveInfo();
6211                ri.providerInfo = pi;
6212                list.add(ri);
6213            }
6214            return list;
6215        }
6216
6217        // reader
6218        synchronized (mPackages) {
6219            String pkgName = intent.getPackage();
6220            if (pkgName == null) {
6221                return mProviders.queryIntent(intent, resolvedType, flags, userId);
6222            }
6223            final PackageParser.Package pkg = mPackages.get(pkgName);
6224            if (pkg != null) {
6225                return mProviders.queryIntentForPackage(
6226                        intent, resolvedType, flags, pkg.providers, userId);
6227            }
6228            return Collections.emptyList();
6229        }
6230    }
6231
6232    @Override
6233    public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) {
6234        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
6235        flags = updateFlagsForPackage(flags, userId, null);
6236        final boolean listUninstalled = (flags & MATCH_UNINSTALLED_PACKAGES) != 0;
6237        enforceCrossUserPermission(Binder.getCallingUid(), userId,
6238                true /* requireFullPermission */, false /* checkShell */,
6239                "get installed packages");
6240
6241        // writer
6242        synchronized (mPackages) {
6243            ArrayList<PackageInfo> list;
6244            if (listUninstalled) {
6245                list = new ArrayList<PackageInfo>(mSettings.mPackages.size());
6246                for (PackageSetting ps : mSettings.mPackages.values()) {
6247                    final PackageInfo pi;
6248                    if (ps.pkg != null) {
6249                        pi = generatePackageInfo(ps, flags, userId);
6250                    } else {
6251                        pi = generatePackageInfo(ps, flags, userId);
6252                    }
6253                    if (pi != null) {
6254                        list.add(pi);
6255                    }
6256                }
6257            } else {
6258                list = new ArrayList<PackageInfo>(mPackages.size());
6259                for (PackageParser.Package p : mPackages.values()) {
6260                    final PackageInfo pi =
6261                            generatePackageInfo((PackageSetting)p.mExtras, flags, userId);
6262                    if (pi != null) {
6263                        list.add(pi);
6264                    }
6265                }
6266            }
6267
6268            return new ParceledListSlice<PackageInfo>(list);
6269        }
6270    }
6271
6272    private void addPackageHoldingPermissions(ArrayList<PackageInfo> list, PackageSetting ps,
6273            String[] permissions, boolean[] tmp, int flags, int userId) {
6274        int numMatch = 0;
6275        final PermissionsState permissionsState = ps.getPermissionsState();
6276        for (int i=0; i<permissions.length; i++) {
6277            final String permission = permissions[i];
6278            if (permissionsState.hasPermission(permission, userId)) {
6279                tmp[i] = true;
6280                numMatch++;
6281            } else {
6282                tmp[i] = false;
6283            }
6284        }
6285        if (numMatch == 0) {
6286            return;
6287        }
6288        final PackageInfo pi;
6289        if (ps.pkg != null) {
6290            pi = generatePackageInfo(ps, flags, userId);
6291        } else {
6292            pi = generatePackageInfo(ps, flags, userId);
6293        }
6294        // The above might return null in cases of uninstalled apps or install-state
6295        // skew across users/profiles.
6296        if (pi != null) {
6297            if ((flags&PackageManager.GET_PERMISSIONS) == 0) {
6298                if (numMatch == permissions.length) {
6299                    pi.requestedPermissions = permissions;
6300                } else {
6301                    pi.requestedPermissions = new String[numMatch];
6302                    numMatch = 0;
6303                    for (int i=0; i<permissions.length; i++) {
6304                        if (tmp[i]) {
6305                            pi.requestedPermissions[numMatch] = permissions[i];
6306                            numMatch++;
6307                        }
6308                    }
6309                }
6310            }
6311            list.add(pi);
6312        }
6313    }
6314
6315    @Override
6316    public ParceledListSlice<PackageInfo> getPackagesHoldingPermissions(
6317            String[] permissions, int flags, int userId) {
6318        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
6319        flags = updateFlagsForPackage(flags, userId, permissions);
6320        final boolean listUninstalled = (flags & MATCH_UNINSTALLED_PACKAGES) != 0;
6321
6322        // writer
6323        synchronized (mPackages) {
6324            ArrayList<PackageInfo> list = new ArrayList<PackageInfo>();
6325            boolean[] tmpBools = new boolean[permissions.length];
6326            if (listUninstalled) {
6327                for (PackageSetting ps : mSettings.mPackages.values()) {
6328                    addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags, userId);
6329                }
6330            } else {
6331                for (PackageParser.Package pkg : mPackages.values()) {
6332                    PackageSetting ps = (PackageSetting)pkg.mExtras;
6333                    if (ps != null) {
6334                        addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags,
6335                                userId);
6336                    }
6337                }
6338            }
6339
6340            return new ParceledListSlice<PackageInfo>(list);
6341        }
6342    }
6343
6344    @Override
6345    public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags, int userId) {
6346        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
6347        flags = updateFlagsForApplication(flags, userId, null);
6348        final boolean listUninstalled = (flags & MATCH_UNINSTALLED_PACKAGES) != 0;
6349
6350        // writer
6351        synchronized (mPackages) {
6352            ArrayList<ApplicationInfo> list;
6353            if (listUninstalled) {
6354                list = new ArrayList<ApplicationInfo>(mSettings.mPackages.size());
6355                for (PackageSetting ps : mSettings.mPackages.values()) {
6356                    ApplicationInfo ai;
6357                    if (ps.pkg != null) {
6358                        ai = PackageParser.generateApplicationInfo(ps.pkg, flags,
6359                                ps.readUserState(userId), userId);
6360                    } else {
6361                        ai = generateApplicationInfoFromSettingsLPw(ps.name, flags, userId);
6362                    }
6363                    if (ai != null) {
6364                        list.add(ai);
6365                    }
6366                }
6367            } else {
6368                list = new ArrayList<ApplicationInfo>(mPackages.size());
6369                for (PackageParser.Package p : mPackages.values()) {
6370                    if (p.mExtras != null) {
6371                        ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
6372                                ((PackageSetting)p.mExtras).readUserState(userId), userId);
6373                        if (ai != null) {
6374                            list.add(ai);
6375                        }
6376                    }
6377                }
6378            }
6379
6380            return new ParceledListSlice<ApplicationInfo>(list);
6381        }
6382    }
6383
6384    @Override
6385    public ParceledListSlice<EphemeralApplicationInfo> getEphemeralApplications(int userId) {
6386        if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
6387            return null;
6388        }
6389
6390        mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_EPHEMERAL_APPS,
6391                "getEphemeralApplications");
6392        enforceCrossUserPermission(Binder.getCallingUid(), userId,
6393                true /* requireFullPermission */, false /* checkShell */,
6394                "getEphemeralApplications");
6395        synchronized (mPackages) {
6396            List<EphemeralApplicationInfo> ephemeralApps = mEphemeralApplicationRegistry
6397                    .getEphemeralApplicationsLPw(userId);
6398            if (ephemeralApps != null) {
6399                return new ParceledListSlice<>(ephemeralApps);
6400            }
6401        }
6402        return null;
6403    }
6404
6405    @Override
6406    public boolean isEphemeralApplication(String packageName, int userId) {
6407        enforceCrossUserPermission(Binder.getCallingUid(), userId,
6408                true /* requireFullPermission */, false /* checkShell */,
6409                "isEphemeral");
6410        if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
6411            return false;
6412        }
6413
6414        if (!isCallerSameApp(packageName)) {
6415            return false;
6416        }
6417        synchronized (mPackages) {
6418            PackageParser.Package pkg = mPackages.get(packageName);
6419            if (pkg != null) {
6420                return pkg.applicationInfo.isEphemeralApp();
6421            }
6422        }
6423        return false;
6424    }
6425
6426    @Override
6427    public byte[] getEphemeralApplicationCookie(String packageName, int userId) {
6428        if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
6429            return null;
6430        }
6431
6432        enforceCrossUserPermission(Binder.getCallingUid(), userId,
6433                true /* requireFullPermission */, false /* checkShell */,
6434                "getCookie");
6435        if (!isCallerSameApp(packageName)) {
6436            return null;
6437        }
6438        synchronized (mPackages) {
6439            return mEphemeralApplicationRegistry.getEphemeralApplicationCookieLPw(
6440                    packageName, userId);
6441        }
6442    }
6443
6444    @Override
6445    public boolean setEphemeralApplicationCookie(String packageName, byte[] cookie, int userId) {
6446        if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
6447            return true;
6448        }
6449
6450        enforceCrossUserPermission(Binder.getCallingUid(), userId,
6451                true /* requireFullPermission */, true /* checkShell */,
6452                "setCookie");
6453        if (!isCallerSameApp(packageName)) {
6454            return false;
6455        }
6456        synchronized (mPackages) {
6457            return mEphemeralApplicationRegistry.setEphemeralApplicationCookieLPw(
6458                    packageName, cookie, userId);
6459        }
6460    }
6461
6462    @Override
6463    public Bitmap getEphemeralApplicationIcon(String packageName, int userId) {
6464        if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
6465            return null;
6466        }
6467
6468        mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_EPHEMERAL_APPS,
6469                "getEphemeralApplicationIcon");
6470        enforceCrossUserPermission(Binder.getCallingUid(), userId,
6471                true /* requireFullPermission */, false /* checkShell */,
6472                "getEphemeralApplicationIcon");
6473        synchronized (mPackages) {
6474            return mEphemeralApplicationRegistry.getEphemeralApplicationIconLPw(
6475                    packageName, userId);
6476        }
6477    }
6478
6479    private boolean isCallerSameApp(String packageName) {
6480        PackageParser.Package pkg = mPackages.get(packageName);
6481        return pkg != null
6482                && UserHandle.getAppId(Binder.getCallingUid()) == pkg.applicationInfo.uid;
6483    }
6484
6485    @Override
6486    public @NonNull ParceledListSlice<ApplicationInfo> getPersistentApplications(int flags) {
6487        return new ParceledListSlice<>(getPersistentApplicationsInternal(flags));
6488    }
6489
6490    private @NonNull List<ApplicationInfo> getPersistentApplicationsInternal(int flags) {
6491        final ArrayList<ApplicationInfo> finalList = new ArrayList<ApplicationInfo>();
6492
6493        // reader
6494        synchronized (mPackages) {
6495            final Iterator<PackageParser.Package> i = mPackages.values().iterator();
6496            final int userId = UserHandle.getCallingUserId();
6497            while (i.hasNext()) {
6498                final PackageParser.Package p = i.next();
6499                if (p.applicationInfo == null) continue;
6500
6501                final boolean matchesUnaware = ((flags & MATCH_DIRECT_BOOT_UNAWARE) != 0)
6502                        && !p.applicationInfo.isDirectBootAware();
6503                final boolean matchesAware = ((flags & MATCH_DIRECT_BOOT_AWARE) != 0)
6504                        && p.applicationInfo.isDirectBootAware();
6505
6506                if ((p.applicationInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0
6507                        && (!mSafeMode || isSystemApp(p))
6508                        && (matchesUnaware || matchesAware)) {
6509                    PackageSetting ps = mSettings.mPackages.get(p.packageName);
6510                    if (ps != null) {
6511                        ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
6512                                ps.readUserState(userId), userId);
6513                        if (ai != null) {
6514                            finalList.add(ai);
6515                        }
6516                    }
6517                }
6518            }
6519        }
6520
6521        return finalList;
6522    }
6523
6524    @Override
6525    public ProviderInfo resolveContentProvider(String name, int flags, int userId) {
6526        if (!sUserManager.exists(userId)) return null;
6527        flags = updateFlagsForComponent(flags, userId, name);
6528        // reader
6529        synchronized (mPackages) {
6530            final PackageParser.Provider provider = mProvidersByAuthority.get(name);
6531            PackageSetting ps = provider != null
6532                    ? mSettings.mPackages.get(provider.owner.packageName)
6533                    : null;
6534            return ps != null
6535                    && mSettings.isEnabledAndMatchLPr(provider.info, flags, userId)
6536                    ? PackageParser.generateProviderInfo(provider, flags,
6537                            ps.readUserState(userId), userId)
6538                    : null;
6539        }
6540    }
6541
6542    /**
6543     * @deprecated
6544     */
6545    @Deprecated
6546    public void querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo) {
6547        // reader
6548        synchronized (mPackages) {
6549            final Iterator<Map.Entry<String, PackageParser.Provider>> i = mProvidersByAuthority
6550                    .entrySet().iterator();
6551            final int userId = UserHandle.getCallingUserId();
6552            while (i.hasNext()) {
6553                Map.Entry<String, PackageParser.Provider> entry = i.next();
6554                PackageParser.Provider p = entry.getValue();
6555                PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
6556
6557                if (ps != null && p.syncable
6558                        && (!mSafeMode || (p.info.applicationInfo.flags
6559                                &ApplicationInfo.FLAG_SYSTEM) != 0)) {
6560                    ProviderInfo info = PackageParser.generateProviderInfo(p, 0,
6561                            ps.readUserState(userId), userId);
6562                    if (info != null) {
6563                        outNames.add(entry.getKey());
6564                        outInfo.add(info);
6565                    }
6566                }
6567            }
6568        }
6569    }
6570
6571    @Override
6572    public @NonNull ParceledListSlice<ProviderInfo> queryContentProviders(String processName,
6573            int uid, int flags) {
6574        final int userId = processName != null ? UserHandle.getUserId(uid)
6575                : UserHandle.getCallingUserId();
6576        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
6577        flags = updateFlagsForComponent(flags, userId, processName);
6578
6579        ArrayList<ProviderInfo> finalList = null;
6580        // reader
6581        synchronized (mPackages) {
6582            final Iterator<PackageParser.Provider> i = mProviders.mProviders.values().iterator();
6583            while (i.hasNext()) {
6584                final PackageParser.Provider p = i.next();
6585                PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
6586                if (ps != null && p.info.authority != null
6587                        && (processName == null
6588                                || (p.info.processName.equals(processName)
6589                                        && UserHandle.isSameApp(p.info.applicationInfo.uid, uid)))
6590                        && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) {
6591                    if (finalList == null) {
6592                        finalList = new ArrayList<ProviderInfo>(3);
6593                    }
6594                    ProviderInfo info = PackageParser.generateProviderInfo(p, flags,
6595                            ps.readUserState(userId), userId);
6596                    if (info != null) {
6597                        finalList.add(info);
6598                    }
6599                }
6600            }
6601        }
6602
6603        if (finalList != null) {
6604            Collections.sort(finalList, mProviderInitOrderSorter);
6605            return new ParceledListSlice<ProviderInfo>(finalList);
6606        }
6607
6608        return ParceledListSlice.emptyList();
6609    }
6610
6611    @Override
6612    public InstrumentationInfo getInstrumentationInfo(ComponentName name, int flags) {
6613        // reader
6614        synchronized (mPackages) {
6615            final PackageParser.Instrumentation i = mInstrumentation.get(name);
6616            return PackageParser.generateInstrumentationInfo(i, flags);
6617        }
6618    }
6619
6620    @Override
6621    public @NonNull ParceledListSlice<InstrumentationInfo> queryInstrumentation(
6622            String targetPackage, int flags) {
6623        return new ParceledListSlice<>(queryInstrumentationInternal(targetPackage, flags));
6624    }
6625
6626    private @NonNull List<InstrumentationInfo> queryInstrumentationInternal(String targetPackage,
6627            int flags) {
6628        ArrayList<InstrumentationInfo> finalList = new ArrayList<InstrumentationInfo>();
6629
6630        // reader
6631        synchronized (mPackages) {
6632            final Iterator<PackageParser.Instrumentation> i = mInstrumentation.values().iterator();
6633            while (i.hasNext()) {
6634                final PackageParser.Instrumentation p = i.next();
6635                if (targetPackage == null
6636                        || targetPackage.equals(p.info.targetPackage)) {
6637                    InstrumentationInfo ii = PackageParser.generateInstrumentationInfo(p,
6638                            flags);
6639                    if (ii != null) {
6640                        finalList.add(ii);
6641                    }
6642                }
6643            }
6644        }
6645
6646        return finalList;
6647    }
6648
6649    private void createIdmapsForPackageLI(PackageParser.Package pkg) {
6650        ArrayMap<String, PackageParser.Package> overlays = mOverlays.get(pkg.packageName);
6651        if (overlays == null) {
6652            Slog.w(TAG, "Unable to create idmap for " + pkg.packageName + ": no overlay packages");
6653            return;
6654        }
6655        for (PackageParser.Package opkg : overlays.values()) {
6656            // Not much to do if idmap fails: we already logged the error
6657            // and we certainly don't want to abort installation of pkg simply
6658            // because an overlay didn't fit properly. For these reasons,
6659            // ignore the return value of createIdmapForPackagePairLI.
6660            createIdmapForPackagePairLI(pkg, opkg);
6661        }
6662    }
6663
6664    private boolean createIdmapForPackagePairLI(PackageParser.Package pkg,
6665            PackageParser.Package opkg) {
6666        if (!opkg.mTrustedOverlay) {
6667            Slog.w(TAG, "Skipping target and overlay pair " + pkg.baseCodePath + " and " +
6668                    opkg.baseCodePath + ": overlay not trusted");
6669            return false;
6670        }
6671        ArrayMap<String, PackageParser.Package> overlaySet = mOverlays.get(pkg.packageName);
6672        if (overlaySet == null) {
6673            Slog.e(TAG, "was about to create idmap for " + pkg.baseCodePath + " and " +
6674                    opkg.baseCodePath + " but target package has no known overlays");
6675            return false;
6676        }
6677        final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
6678        // TODO: generate idmap for split APKs
6679        try {
6680            mInstaller.idmap(pkg.baseCodePath, opkg.baseCodePath, sharedGid);
6681        } catch (InstallerException e) {
6682            Slog.e(TAG, "Failed to generate idmap for " + pkg.baseCodePath + " and "
6683                    + opkg.baseCodePath);
6684            return false;
6685        }
6686        PackageParser.Package[] overlayArray =
6687            overlaySet.values().toArray(new PackageParser.Package[0]);
6688        Comparator<PackageParser.Package> cmp = new Comparator<PackageParser.Package>() {
6689            public int compare(PackageParser.Package p1, PackageParser.Package p2) {
6690                return p1.mOverlayPriority - p2.mOverlayPriority;
6691            }
6692        };
6693        Arrays.sort(overlayArray, cmp);
6694
6695        pkg.applicationInfo.resourceDirs = new String[overlayArray.length];
6696        int i = 0;
6697        for (PackageParser.Package p : overlayArray) {
6698            pkg.applicationInfo.resourceDirs[i++] = p.baseCodePath;
6699        }
6700        return true;
6701    }
6702
6703    private void scanDirTracedLI(File dir, final int parseFlags, int scanFlags, long currentTime) {
6704        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanDir");
6705        try {
6706            scanDirLI(dir, parseFlags, scanFlags, currentTime);
6707        } finally {
6708            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
6709        }
6710    }
6711
6712    private void scanDirLI(File dir, final int parseFlags, int scanFlags, long currentTime) {
6713        final File[] files = dir.listFiles();
6714        if (ArrayUtils.isEmpty(files)) {
6715            Log.d(TAG, "No files in app dir " + dir);
6716            return;
6717        }
6718
6719        if (DEBUG_PACKAGE_SCANNING) {
6720            Log.d(TAG, "Scanning app dir " + dir + " scanFlags=" + scanFlags
6721                    + " flags=0x" + Integer.toHexString(parseFlags));
6722        }
6723
6724        for (File file : files) {
6725            final boolean isPackage = (isApkFile(file) || file.isDirectory())
6726                    && !PackageInstallerService.isStageName(file.getName());
6727            if (!isPackage) {
6728                // Ignore entries which are not packages
6729                continue;
6730            }
6731            try {
6732                scanPackageTracedLI(file, parseFlags | PackageParser.PARSE_MUST_BE_APK,
6733                        scanFlags, currentTime, null);
6734            } catch (PackageManagerException e) {
6735                Slog.w(TAG, "Failed to parse " + file + ": " + e.getMessage());
6736
6737                // Delete invalid userdata apps
6738                if ((parseFlags & PackageParser.PARSE_IS_SYSTEM) == 0 &&
6739                        e.error == PackageManager.INSTALL_FAILED_INVALID_APK) {
6740                    logCriticalInfo(Log.WARN, "Deleting invalid package at " + file);
6741                    removeCodePathLI(file);
6742                }
6743            }
6744        }
6745    }
6746
6747    private static File getSettingsProblemFile() {
6748        File dataDir = Environment.getDataDirectory();
6749        File systemDir = new File(dataDir, "system");
6750        File fname = new File(systemDir, "uiderrors.txt");
6751        return fname;
6752    }
6753
6754    static void reportSettingsProblem(int priority, String msg) {
6755        logCriticalInfo(priority, msg);
6756    }
6757
6758    static void logCriticalInfo(int priority, String msg) {
6759        Slog.println(priority, TAG, msg);
6760        EventLogTags.writePmCriticalInfo(msg);
6761        try {
6762            File fname = getSettingsProblemFile();
6763            FileOutputStream out = new FileOutputStream(fname, true);
6764            PrintWriter pw = new FastPrintWriter(out);
6765            SimpleDateFormat formatter = new SimpleDateFormat();
6766            String dateString = formatter.format(new Date(System.currentTimeMillis()));
6767            pw.println(dateString + ": " + msg);
6768            pw.close();
6769            FileUtils.setPermissions(
6770                    fname.toString(),
6771                    FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IROTH,
6772                    -1, -1);
6773        } catch (java.io.IOException e) {
6774        }
6775    }
6776
6777    private long getLastModifiedTime(PackageParser.Package pkg, File srcFile) {
6778        if (srcFile.isDirectory()) {
6779            final File baseFile = new File(pkg.baseCodePath);
6780            long maxModifiedTime = baseFile.lastModified();
6781            if (pkg.splitCodePaths != null) {
6782                for (int i = pkg.splitCodePaths.length - 1; i >=0; --i) {
6783                    final File splitFile = new File(pkg.splitCodePaths[i]);
6784                    maxModifiedTime = Math.max(maxModifiedTime, splitFile.lastModified());
6785                }
6786            }
6787            return maxModifiedTime;
6788        }
6789        return srcFile.lastModified();
6790    }
6791
6792    private void collectCertificatesLI(PackageSetting ps, PackageParser.Package pkg, File srcFile,
6793            final int policyFlags) throws PackageManagerException {
6794        // When upgrading from pre-N MR1, verify the package time stamp using the package
6795        // directory and not the APK file.
6796        final long lastModifiedTime = mIsPreNMR1Upgrade
6797                ? new File(pkg.codePath).lastModified() : getLastModifiedTime(pkg, srcFile);
6798        if (ps != null
6799                && ps.codePath.equals(srcFile)
6800                && ps.timeStamp == lastModifiedTime
6801                && !isCompatSignatureUpdateNeeded(pkg)
6802                && !isRecoverSignatureUpdateNeeded(pkg)) {
6803            long mSigningKeySetId = ps.keySetData.getProperSigningKeySet();
6804            KeySetManagerService ksms = mSettings.mKeySetManagerService;
6805            ArraySet<PublicKey> signingKs;
6806            synchronized (mPackages) {
6807                signingKs = ksms.getPublicKeysFromKeySetLPr(mSigningKeySetId);
6808            }
6809            if (ps.signatures.mSignatures != null
6810                    && ps.signatures.mSignatures.length != 0
6811                    && signingKs != null) {
6812                // Optimization: reuse the existing cached certificates
6813                // if the package appears to be unchanged.
6814                pkg.mSignatures = ps.signatures.mSignatures;
6815                pkg.mSigningKeys = signingKs;
6816                return;
6817            }
6818
6819            Slog.w(TAG, "PackageSetting for " + ps.name
6820                    + " is missing signatures.  Collecting certs again to recover them.");
6821        } else {
6822            Slog.i(TAG, srcFile.toString() + " changed; collecting certs");
6823        }
6824
6825        try {
6826            PackageParser.collectCertificates(pkg, policyFlags);
6827        } catch (PackageParserException e) {
6828            throw PackageManagerException.from(e);
6829        }
6830    }
6831
6832    /**
6833     *  Traces a package scan.
6834     *  @see #scanPackageLI(File, int, int, long, UserHandle)
6835     */
6836    private PackageParser.Package scanPackageTracedLI(File scanFile, final int parseFlags,
6837            int scanFlags, long currentTime, UserHandle user) throws PackageManagerException {
6838        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage");
6839        try {
6840            return scanPackageLI(scanFile, parseFlags, scanFlags, currentTime, user);
6841        } finally {
6842            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
6843        }
6844    }
6845
6846    /**
6847     *  Scans a package and returns the newly parsed package.
6848     *  Returns {@code null} in case of errors and the error code is stored in mLastScanError
6849     */
6850    private PackageParser.Package scanPackageLI(File scanFile, int parseFlags, int scanFlags,
6851            long currentTime, UserHandle user) throws PackageManagerException {
6852        if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanFile);
6853        PackageParser pp = new PackageParser();
6854        pp.setSeparateProcesses(mSeparateProcesses);
6855        pp.setOnlyCoreApps(mOnlyCore);
6856        pp.setDisplayMetrics(mMetrics);
6857
6858        if ((scanFlags & SCAN_TRUSTED_OVERLAY) != 0) {
6859            parseFlags |= PackageParser.PARSE_TRUSTED_OVERLAY;
6860        }
6861
6862        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
6863        final PackageParser.Package pkg;
6864        try {
6865            pkg = pp.parsePackage(scanFile, parseFlags);
6866        } catch (PackageParserException e) {
6867            throw PackageManagerException.from(e);
6868        } finally {
6869            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
6870        }
6871
6872        return scanPackageLI(pkg, scanFile, parseFlags, scanFlags, currentTime, user);
6873    }
6874
6875    /**
6876     *  Scans a package and returns the newly parsed package.
6877     *  @throws PackageManagerException on a parse error.
6878     */
6879    private PackageParser.Package scanPackageLI(PackageParser.Package pkg, File scanFile,
6880            final int policyFlags, int scanFlags, long currentTime, UserHandle user)
6881            throws PackageManagerException {
6882        // If the package has children and this is the first dive in the function
6883        // we scan the package with the SCAN_CHECK_ONLY flag set to see whether all
6884        // packages (parent and children) would be successfully scanned before the
6885        // actual scan since scanning mutates internal state and we want to atomically
6886        // install the package and its children.
6887        if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
6888            if (pkg.childPackages != null && pkg.childPackages.size() > 0) {
6889                scanFlags |= SCAN_CHECK_ONLY;
6890            }
6891        } else {
6892            scanFlags &= ~SCAN_CHECK_ONLY;
6893        }
6894
6895        // Scan the parent
6896        PackageParser.Package scannedPkg = scanPackageInternalLI(pkg, scanFile, policyFlags,
6897                scanFlags, currentTime, user);
6898
6899        // Scan the children
6900        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
6901        for (int i = 0; i < childCount; i++) {
6902            PackageParser.Package childPackage = pkg.childPackages.get(i);
6903            scanPackageInternalLI(childPackage, scanFile, policyFlags, scanFlags,
6904                    currentTime, user);
6905        }
6906
6907
6908        if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
6909            return scanPackageLI(pkg, scanFile, policyFlags, scanFlags, currentTime, user);
6910        }
6911
6912        return scannedPkg;
6913    }
6914
6915    /**
6916     *  Scans a package and returns the newly parsed package.
6917     *  @throws PackageManagerException on a parse error.
6918     */
6919    private PackageParser.Package scanPackageInternalLI(PackageParser.Package pkg, File scanFile,
6920            int policyFlags, int scanFlags, long currentTime, UserHandle user)
6921            throws PackageManagerException {
6922        PackageSetting ps = null;
6923        PackageSetting updatedPkg;
6924        // reader
6925        synchronized (mPackages) {
6926            // Look to see if we already know about this package.
6927            String oldName = mSettings.mRenamedPackages.get(pkg.packageName);
6928            if (pkg.mOriginalPackages != null && pkg.mOriginalPackages.contains(oldName)) {
6929                // This package has been renamed to its original name.  Let's
6930                // use that.
6931                ps = mSettings.peekPackageLPr(oldName);
6932            }
6933            // If there was no original package, see one for the real package name.
6934            if (ps == null) {
6935                ps = mSettings.peekPackageLPr(pkg.packageName);
6936            }
6937            // Check to see if this package could be hiding/updating a system
6938            // package.  Must look for it either under the original or real
6939            // package name depending on our state.
6940            updatedPkg = mSettings.getDisabledSystemPkgLPr(ps != null ? ps.name : pkg.packageName);
6941            if (DEBUG_INSTALL && updatedPkg != null) Slog.d(TAG, "updatedPkg = " + updatedPkg);
6942
6943            // If this is a package we don't know about on the system partition, we
6944            // may need to remove disabled child packages on the system partition
6945            // or may need to not add child packages if the parent apk is updated
6946            // on the data partition and no longer defines this child package.
6947            if ((policyFlags & PackageParser.PARSE_IS_SYSTEM) != 0) {
6948                // If this is a parent package for an updated system app and this system
6949                // app got an OTA update which no longer defines some of the child packages
6950                // we have to prune them from the disabled system packages.
6951                PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(pkg.packageName);
6952                if (disabledPs != null) {
6953                    final int scannedChildCount = (pkg.childPackages != null)
6954                            ? pkg.childPackages.size() : 0;
6955                    final int disabledChildCount = disabledPs.childPackageNames != null
6956                            ? disabledPs.childPackageNames.size() : 0;
6957                    for (int i = 0; i < disabledChildCount; i++) {
6958                        String disabledChildPackageName = disabledPs.childPackageNames.get(i);
6959                        boolean disabledPackageAvailable = false;
6960                        for (int j = 0; j < scannedChildCount; j++) {
6961                            PackageParser.Package childPkg = pkg.childPackages.get(j);
6962                            if (childPkg.packageName.equals(disabledChildPackageName)) {
6963                                disabledPackageAvailable = true;
6964                                break;
6965                            }
6966                         }
6967                         if (!disabledPackageAvailable) {
6968                             mSettings.removeDisabledSystemPackageLPw(disabledChildPackageName);
6969                         }
6970                    }
6971                }
6972            }
6973        }
6974
6975        boolean updatedPkgBetter = false;
6976        // First check if this is a system package that may involve an update
6977        if (updatedPkg != null && (policyFlags & PackageParser.PARSE_IS_SYSTEM) != 0) {
6978            // If new package is not located in "/system/priv-app" (e.g. due to an OTA),
6979            // it needs to drop FLAG_PRIVILEGED.
6980            if (locationIsPrivileged(scanFile)) {
6981                updatedPkg.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
6982            } else {
6983                updatedPkg.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
6984            }
6985
6986            if (ps != null && !ps.codePath.equals(scanFile)) {
6987                // The path has changed from what was last scanned...  check the
6988                // version of the new path against what we have stored to determine
6989                // what to do.
6990                if (DEBUG_INSTALL) Slog.d(TAG, "Path changing from " + ps.codePath);
6991                if (pkg.mVersionCode <= ps.versionCode) {
6992                    // The system package has been updated and the code path does not match
6993                    // Ignore entry. Skip it.
6994                    if (DEBUG_INSTALL) Slog.i(TAG, "Package " + ps.name + " at " + scanFile
6995                            + " ignored: updated version " + ps.versionCode
6996                            + " better than this " + pkg.mVersionCode);
6997                    if (!updatedPkg.codePath.equals(scanFile)) {
6998                        Slog.w(PackageManagerService.TAG, "Code path for hidden system pkg "
6999                                + ps.name + " changing from " + updatedPkg.codePathString
7000                                + " to " + scanFile);
7001                        updatedPkg.codePath = scanFile;
7002                        updatedPkg.codePathString = scanFile.toString();
7003                        updatedPkg.resourcePath = scanFile;
7004                        updatedPkg.resourcePathString = scanFile.toString();
7005                    }
7006                    updatedPkg.pkg = pkg;
7007                    updatedPkg.versionCode = pkg.mVersionCode;
7008
7009                    // Update the disabled system child packages to point to the package too.
7010                    final int childCount = updatedPkg.childPackageNames != null
7011                            ? updatedPkg.childPackageNames.size() : 0;
7012                    for (int i = 0; i < childCount; i++) {
7013                        String childPackageName = updatedPkg.childPackageNames.get(i);
7014                        PackageSetting updatedChildPkg = mSettings.getDisabledSystemPkgLPr(
7015                                childPackageName);
7016                        if (updatedChildPkg != null) {
7017                            updatedChildPkg.pkg = pkg;
7018                            updatedChildPkg.versionCode = pkg.mVersionCode;
7019                        }
7020                    }
7021
7022                    throw new PackageManagerException(Log.WARN, "Package " + ps.name + " at "
7023                            + scanFile + " ignored: updated version " + ps.versionCode
7024                            + " better than this " + pkg.mVersionCode);
7025                } else {
7026                    // The current app on the system partition is better than
7027                    // what we have updated to on the data partition; switch
7028                    // back to the system partition version.
7029                    // At this point, its safely assumed that package installation for
7030                    // apps in system partition will go through. If not there won't be a working
7031                    // version of the app
7032                    // writer
7033                    synchronized (mPackages) {
7034                        // Just remove the loaded entries from package lists.
7035                        mPackages.remove(ps.name);
7036                    }
7037
7038                    logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile
7039                            + " reverting from " + ps.codePathString
7040                            + ": new version " + pkg.mVersionCode
7041                            + " better than installed " + ps.versionCode);
7042
7043                    InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
7044                            ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
7045                    synchronized (mInstallLock) {
7046                        args.cleanUpResourcesLI();
7047                    }
7048                    synchronized (mPackages) {
7049                        mSettings.enableSystemPackageLPw(ps.name);
7050                    }
7051                    updatedPkgBetter = true;
7052                }
7053            }
7054        }
7055
7056        if (updatedPkg != null) {
7057            // An updated system app will not have the PARSE_IS_SYSTEM flag set
7058            // initially
7059            policyFlags |= PackageParser.PARSE_IS_SYSTEM;
7060
7061            // An updated privileged app will not have the PARSE_IS_PRIVILEGED
7062            // flag set initially
7063            if ((updatedPkg.pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0) {
7064                policyFlags |= PackageParser.PARSE_IS_PRIVILEGED;
7065            }
7066        }
7067
7068        // Verify certificates against what was last scanned
7069        collectCertificatesLI(ps, pkg, scanFile, policyFlags);
7070
7071        /*
7072         * A new system app appeared, but we already had a non-system one of the
7073         * same name installed earlier.
7074         */
7075        boolean shouldHideSystemApp = false;
7076        if (updatedPkg == null && ps != null
7077                && (policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0 && !isSystemApp(ps)) {
7078            /*
7079             * Check to make sure the signatures match first. If they don't,
7080             * wipe the installed application and its data.
7081             */
7082            if (compareSignatures(ps.signatures.mSignatures, pkg.mSignatures)
7083                    != PackageManager.SIGNATURE_MATCH) {
7084                logCriticalInfo(Log.WARN, "Package " + ps.name + " appeared on system, but"
7085                        + " signatures don't match existing userdata copy; removing");
7086                try (PackageFreezer freezer = freezePackage(pkg.packageName,
7087                        "scanPackageInternalLI")) {
7088                    deletePackageLIF(pkg.packageName, null, true, null, 0, null, false, null);
7089                }
7090                ps = null;
7091            } else {
7092                /*
7093                 * If the newly-added system app is an older version than the
7094                 * already installed version, hide it. It will be scanned later
7095                 * and re-added like an update.
7096                 */
7097                if (pkg.mVersionCode <= ps.versionCode) {
7098                    shouldHideSystemApp = true;
7099                    logCriticalInfo(Log.INFO, "Package " + ps.name + " appeared at " + scanFile
7100                            + " but new version " + pkg.mVersionCode + " better than installed "
7101                            + ps.versionCode + "; hiding system");
7102                } else {
7103                    /*
7104                     * The newly found system app is a newer version that the
7105                     * one previously installed. Simply remove the
7106                     * already-installed application and replace it with our own
7107                     * while keeping the application data.
7108                     */
7109                    logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile
7110                            + " reverting from " + ps.codePathString + ": new version "
7111                            + pkg.mVersionCode + " better than installed " + ps.versionCode);
7112                    InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
7113                            ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
7114                    synchronized (mInstallLock) {
7115                        args.cleanUpResourcesLI();
7116                    }
7117                }
7118            }
7119        }
7120
7121        // The apk is forward locked (not public) if its code and resources
7122        // are kept in different files. (except for app in either system or
7123        // vendor path).
7124        // TODO grab this value from PackageSettings
7125        if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
7126            if (ps != null && !ps.codePath.equals(ps.resourcePath)) {
7127                policyFlags |= PackageParser.PARSE_FORWARD_LOCK;
7128            }
7129        }
7130
7131        // TODO: extend to support forward-locked splits
7132        String resourcePath = null;
7133        String baseResourcePath = null;
7134        if ((policyFlags & PackageParser.PARSE_FORWARD_LOCK) != 0 && !updatedPkgBetter) {
7135            if (ps != null && ps.resourcePathString != null) {
7136                resourcePath = ps.resourcePathString;
7137                baseResourcePath = ps.resourcePathString;
7138            } else {
7139                // Should not happen at all. Just log an error.
7140                Slog.e(TAG, "Resource path not set for package " + pkg.packageName);
7141            }
7142        } else {
7143            resourcePath = pkg.codePath;
7144            baseResourcePath = pkg.baseCodePath;
7145        }
7146
7147        // Set application objects path explicitly.
7148        pkg.setApplicationVolumeUuid(pkg.volumeUuid);
7149        pkg.setApplicationInfoCodePath(pkg.codePath);
7150        pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
7151        pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
7152        pkg.setApplicationInfoResourcePath(resourcePath);
7153        pkg.setApplicationInfoBaseResourcePath(baseResourcePath);
7154        pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
7155
7156        // Note that we invoke the following method only if we are about to unpack an application
7157        PackageParser.Package scannedPkg = scanPackageLI(pkg, policyFlags, scanFlags
7158                | SCAN_UPDATE_SIGNATURE, currentTime, user);
7159
7160        /*
7161         * If the system app should be overridden by a previously installed
7162         * data, hide the system app now and let the /data/app scan pick it up
7163         * again.
7164         */
7165        if (shouldHideSystemApp) {
7166            synchronized (mPackages) {
7167                mSettings.disableSystemPackageLPw(pkg.packageName, true);
7168            }
7169        }
7170
7171        return scannedPkg;
7172    }
7173
7174    private static String fixProcessName(String defProcessName,
7175            String processName, int uid) {
7176        if (processName == null) {
7177            return defProcessName;
7178        }
7179        return processName;
7180    }
7181
7182    private void verifySignaturesLP(PackageSetting pkgSetting, PackageParser.Package pkg)
7183            throws PackageManagerException {
7184        if (pkgSetting.signatures.mSignatures != null) {
7185            // Already existing package. Make sure signatures match
7186            boolean match = compareSignatures(pkgSetting.signatures.mSignatures, pkg.mSignatures)
7187                    == PackageManager.SIGNATURE_MATCH;
7188            if (!match) {
7189                match = compareSignaturesCompat(pkgSetting.signatures, pkg)
7190                        == PackageManager.SIGNATURE_MATCH;
7191            }
7192            if (!match) {
7193                match = compareSignaturesRecover(pkgSetting.signatures, pkg)
7194                        == PackageManager.SIGNATURE_MATCH;
7195            }
7196            if (!match) {
7197                throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
7198                        + pkg.packageName + " signatures do not match the "
7199                        + "previously installed version; ignoring!");
7200            }
7201        }
7202
7203        // Check for shared user signatures
7204        if (pkgSetting.sharedUser != null && pkgSetting.sharedUser.signatures.mSignatures != null) {
7205            // Already existing package. Make sure signatures match
7206            boolean match = compareSignatures(pkgSetting.sharedUser.signatures.mSignatures,
7207                    pkg.mSignatures) == PackageManager.SIGNATURE_MATCH;
7208            if (!match) {
7209                match = compareSignaturesCompat(pkgSetting.sharedUser.signatures, pkg)
7210                        == PackageManager.SIGNATURE_MATCH;
7211            }
7212            if (!match) {
7213                match = compareSignaturesRecover(pkgSetting.sharedUser.signatures, pkg)
7214                        == PackageManager.SIGNATURE_MATCH;
7215            }
7216            if (!match) {
7217                throw new PackageManagerException(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
7218                        "Package " + pkg.packageName
7219                        + " has no signatures that match those in shared user "
7220                        + pkgSetting.sharedUser.name + "; ignoring!");
7221            }
7222        }
7223    }
7224
7225    /**
7226     * Enforces that only the system UID or root's UID can call a method exposed
7227     * via Binder.
7228     *
7229     * @param message used as message if SecurityException is thrown
7230     * @throws SecurityException if the caller is not system or root
7231     */
7232    private static final void enforceSystemOrRoot(String message) {
7233        final int uid = Binder.getCallingUid();
7234        if (uid != Process.SYSTEM_UID && uid != 0) {
7235            throw new SecurityException(message);
7236        }
7237    }
7238
7239    @Override
7240    public void performFstrimIfNeeded() {
7241        enforceSystemOrRoot("Only the system can request fstrim");
7242
7243        // Before everything else, see whether we need to fstrim.
7244        try {
7245            IMountService ms = PackageHelper.getMountService();
7246            if (ms != null) {
7247                boolean doTrim = false;
7248                final long interval = android.provider.Settings.Global.getLong(
7249                        mContext.getContentResolver(),
7250                        android.provider.Settings.Global.FSTRIM_MANDATORY_INTERVAL,
7251                        DEFAULT_MANDATORY_FSTRIM_INTERVAL);
7252                if (interval > 0) {
7253                    final long timeSinceLast = System.currentTimeMillis() - ms.lastMaintenance();
7254                    if (timeSinceLast > interval) {
7255                        doTrim = true;
7256                        Slog.w(TAG, "No disk maintenance in " + timeSinceLast
7257                                + "; running immediately");
7258                    }
7259                }
7260                if (doTrim) {
7261                    final boolean dexOptDialogShown;
7262                    synchronized (mPackages) {
7263                        dexOptDialogShown = mDexOptDialogShown;
7264                    }
7265                    if (!isFirstBoot() && dexOptDialogShown) {
7266                        try {
7267                            ActivityManagerNative.getDefault().showBootMessage(
7268                                    mContext.getResources().getString(
7269                                            R.string.android_upgrading_fstrim), true);
7270                        } catch (RemoteException e) {
7271                        }
7272                    }
7273                    ms.runMaintenance();
7274                }
7275            } else {
7276                Slog.e(TAG, "Mount service unavailable!");
7277            }
7278        } catch (RemoteException e) {
7279            // Can't happen; MountService is local
7280        }
7281    }
7282
7283    @Override
7284    public void updatePackagesIfNeeded() {
7285        enforceSystemOrRoot("Only the system can request package update");
7286
7287        // We need to re-extract after an OTA.
7288        boolean causeUpgrade = isUpgrade();
7289
7290        // First boot or factory reset.
7291        // Note: we also handle devices that are upgrading to N right now as if it is their
7292        //       first boot, as they do not have profile data.
7293        boolean causeFirstBoot = isFirstBoot() || mIsPreNUpgrade;
7294
7295        // We need to re-extract after a pruned cache, as AoT-ed files will be out of date.
7296        boolean causePrunedCache = VMRuntime.didPruneDalvikCache();
7297
7298        if (!causeUpgrade && !causeFirstBoot && !causePrunedCache) {
7299            return;
7300        }
7301
7302        List<PackageParser.Package> pkgs;
7303        synchronized (mPackages) {
7304            pkgs = PackageManagerServiceUtils.getPackagesForDexopt(mPackages.values(), this);
7305        }
7306
7307        final long startTime = System.nanoTime();
7308        final int[] stats = performDexOptUpgrade(pkgs, mIsPreNUpgrade /* showDialog */,
7309                    getCompilerFilterForReason(causeFirstBoot ? REASON_FIRST_BOOT : REASON_BOOT));
7310
7311        final int elapsedTimeSeconds =
7312                (int) TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - startTime);
7313
7314        MetricsLogger.histogram(mContext, "opt_dialog_num_dexopted", stats[0]);
7315        MetricsLogger.histogram(mContext, "opt_dialog_num_skipped", stats[1]);
7316        MetricsLogger.histogram(mContext, "opt_dialog_num_failed", stats[2]);
7317        MetricsLogger.histogram(mContext, "opt_dialog_num_total", getOptimizablePackages().size());
7318        MetricsLogger.histogram(mContext, "opt_dialog_time_s", elapsedTimeSeconds);
7319    }
7320
7321    /**
7322     * Performs dexopt on the set of packages in {@code packages} and returns an int array
7323     * containing statistics about the invocation. The array consists of three elements,
7324     * which are (in order) {@code numberOfPackagesOptimized}, {@code numberOfPackagesSkipped}
7325     * and {@code numberOfPackagesFailed}.
7326     */
7327    private int[] performDexOptUpgrade(List<PackageParser.Package> pkgs, boolean showDialog,
7328            String compilerFilter) {
7329
7330        int numberOfPackagesVisited = 0;
7331        int numberOfPackagesOptimized = 0;
7332        int numberOfPackagesSkipped = 0;
7333        int numberOfPackagesFailed = 0;
7334        final int numberOfPackagesToDexopt = pkgs.size();
7335
7336        for (PackageParser.Package pkg : pkgs) {
7337            numberOfPackagesVisited++;
7338
7339            if (!PackageDexOptimizer.canOptimizePackage(pkg)) {
7340                if (DEBUG_DEXOPT) {
7341                    Log.i(TAG, "Skipping update of of non-optimizable app " + pkg.packageName);
7342                }
7343                numberOfPackagesSkipped++;
7344                continue;
7345            }
7346
7347            if (DEBUG_DEXOPT) {
7348                Log.i(TAG, "Updating app " + numberOfPackagesVisited + " of " +
7349                        numberOfPackagesToDexopt + ": " + pkg.packageName);
7350            }
7351
7352            if (showDialog) {
7353                try {
7354                    ActivityManagerNative.getDefault().showBootMessage(
7355                            mContext.getResources().getString(R.string.android_upgrading_apk,
7356                                    numberOfPackagesVisited, numberOfPackagesToDexopt), true);
7357                } catch (RemoteException e) {
7358                }
7359                synchronized (mPackages) {
7360                    mDexOptDialogShown = true;
7361                }
7362            }
7363
7364            // If the OTA updates a system app which was previously preopted to a non-preopted state
7365            // the app might end up being verified at runtime. That's because by default the apps
7366            // are verify-profile but for preopted apps there's no profile.
7367            // Do a hacky check to ensure that if we have no profiles (a reasonable indication
7368            // that before the OTA the app was preopted) the app gets compiled with a non-profile
7369            // filter (by default 'quicken').
7370            // Note that at this stage unused apps are already filtered.
7371            if (isSystemApp(pkg) &&
7372                    DexFile.isProfileGuidedCompilerFilter(compilerFilter) &&
7373                    !Environment.getReferenceProfile(pkg.packageName).exists()) {
7374                compilerFilter = getNonProfileGuidedCompilerFilter(compilerFilter);
7375            }
7376
7377            // checkProfiles is false to avoid merging profiles during boot which
7378            // might interfere with background compilation (b/28612421).
7379            // Unfortunately this will also means that "pm.dexopt.boot=speed-profile" will
7380            // behave differently than "pm.dexopt.bg-dexopt=speed-profile" but that's a
7381            // trade-off worth doing to save boot time work.
7382            int dexOptStatus = performDexOptTraced(pkg.packageName,
7383                    false /* checkProfiles */,
7384                    compilerFilter,
7385                    false /* force */);
7386            switch (dexOptStatus) {
7387                case PackageDexOptimizer.DEX_OPT_PERFORMED:
7388                    numberOfPackagesOptimized++;
7389                    break;
7390                case PackageDexOptimizer.DEX_OPT_SKIPPED:
7391                    numberOfPackagesSkipped++;
7392                    break;
7393                case PackageDexOptimizer.DEX_OPT_FAILED:
7394                    numberOfPackagesFailed++;
7395                    break;
7396                default:
7397                    Log.e(TAG, "Unexpected dexopt return code " + dexOptStatus);
7398                    break;
7399            }
7400        }
7401
7402        return new int[] { numberOfPackagesOptimized, numberOfPackagesSkipped,
7403                numberOfPackagesFailed };
7404    }
7405
7406    @Override
7407    public void notifyPackageUse(String packageName, int reason) {
7408        synchronized (mPackages) {
7409            PackageParser.Package p = mPackages.get(packageName);
7410            if (p == null) {
7411                return;
7412            }
7413            p.mLastPackageUsageTimeInMills[reason] = System.currentTimeMillis();
7414        }
7415    }
7416
7417    @Override
7418    public void notifyDexLoad(String loadingPackageName, List<String> dexPaths, String loaderIsa) {
7419        int userId = UserHandle.getCallingUserId();
7420        ApplicationInfo ai = getApplicationInfo(loadingPackageName, /*flags*/ 0, userId);
7421        if (ai == null) {
7422            Slog.w(TAG, "Loading a package that does not exist for the calling user. package="
7423                + loadingPackageName + ", user=" + userId);
7424            return;
7425        }
7426        mDexManager.notifyDexLoad(ai, dexPaths, loaderIsa, userId);
7427    }
7428
7429    // TODO: this is not used nor needed. Delete it.
7430    @Override
7431    public boolean performDexOptIfNeeded(String packageName) {
7432        int dexOptStatus = performDexOptTraced(packageName,
7433                false /* checkProfiles */, getFullCompilerFilter(), false /* force */);
7434        return dexOptStatus != PackageDexOptimizer.DEX_OPT_FAILED;
7435    }
7436
7437    @Override
7438    public boolean performDexOpt(String packageName,
7439            boolean checkProfiles, int compileReason, boolean force) {
7440        int dexOptStatus = performDexOptTraced(packageName, checkProfiles,
7441                getCompilerFilterForReason(compileReason), force);
7442        return dexOptStatus != PackageDexOptimizer.DEX_OPT_FAILED;
7443    }
7444
7445    @Override
7446    public boolean performDexOptMode(String packageName,
7447            boolean checkProfiles, String targetCompilerFilter, boolean force) {
7448        int dexOptStatus = performDexOptTraced(packageName, checkProfiles,
7449                targetCompilerFilter, force);
7450        return dexOptStatus != PackageDexOptimizer.DEX_OPT_FAILED;
7451    }
7452
7453    private int performDexOptTraced(String packageName,
7454                boolean checkProfiles, String targetCompilerFilter, boolean force) {
7455        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
7456        try {
7457            return performDexOptInternal(packageName, checkProfiles,
7458                    targetCompilerFilter, force);
7459        } finally {
7460            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
7461        }
7462    }
7463
7464    // Run dexopt on a given package. Returns true if dexopt did not fail, i.e.
7465    // if the package can now be considered up to date for the given filter.
7466    private int performDexOptInternal(String packageName,
7467                boolean checkProfiles, String targetCompilerFilter, boolean force) {
7468        PackageParser.Package p;
7469        synchronized (mPackages) {
7470            p = mPackages.get(packageName);
7471            if (p == null) {
7472                // Package could not be found. Report failure.
7473                return PackageDexOptimizer.DEX_OPT_FAILED;
7474            }
7475            mPackageUsage.maybeWriteAsync(mPackages);
7476            mCompilerStats.maybeWriteAsync();
7477        }
7478        long callingId = Binder.clearCallingIdentity();
7479        try {
7480            synchronized (mInstallLock) {
7481                return performDexOptInternalWithDependenciesLI(p, checkProfiles,
7482                        targetCompilerFilter, force);
7483            }
7484        } finally {
7485            Binder.restoreCallingIdentity(callingId);
7486        }
7487    }
7488
7489    public ArraySet<String> getOptimizablePackages() {
7490        ArraySet<String> pkgs = new ArraySet<String>();
7491        synchronized (mPackages) {
7492            for (PackageParser.Package p : mPackages.values()) {
7493                if (PackageDexOptimizer.canOptimizePackage(p)) {
7494                    pkgs.add(p.packageName);
7495                }
7496            }
7497        }
7498        return pkgs;
7499    }
7500
7501    private int performDexOptInternalWithDependenciesLI(PackageParser.Package p,
7502            boolean checkProfiles, String targetCompilerFilter,
7503            boolean force) {
7504        // Select the dex optimizer based on the force parameter.
7505        // Note: The force option is rarely used (cmdline input for testing, mostly), so it's OK to
7506        //       allocate an object here.
7507        PackageDexOptimizer pdo = force
7508                ? new PackageDexOptimizer.ForcedUpdatePackageDexOptimizer(mPackageDexOptimizer)
7509                : mPackageDexOptimizer;
7510
7511        // Optimize all dependencies first. Note: we ignore the return value and march on
7512        // on errors.
7513        Collection<PackageParser.Package> deps = findSharedNonSystemLibraries(p);
7514        final String[] instructionSets = getAppDexInstructionSets(p.applicationInfo);
7515        if (!deps.isEmpty()) {
7516            for (PackageParser.Package depPackage : deps) {
7517                // TODO: Analyze and investigate if we (should) profile libraries.
7518                // Currently this will do a full compilation of the library by default.
7519                pdo.performDexOpt(depPackage, null /* sharedLibraries */, instructionSets,
7520                        false /* checkProfiles */,
7521                        getCompilerFilterForReason(REASON_NON_SYSTEM_LIBRARY),
7522                        getOrCreateCompilerPackageStats(depPackage),
7523                        mDexManager.isUsedByOtherApps(p.packageName));
7524            }
7525        }
7526        return pdo.performDexOpt(p, p.usesLibraryFiles, instructionSets, checkProfiles,
7527                targetCompilerFilter, getOrCreateCompilerPackageStats(p),
7528                mDexManager.isUsedByOtherApps(p.packageName));
7529    }
7530
7531    // Performs dexopt on the used secondary dex files belonging to the given package.
7532    // Returns true if all dex files were process successfully (which could mean either dexopt or
7533    // skip). Returns false if any of the files caused errors.
7534    @Override
7535    public boolean performDexOptSecondary(String packageName, String compilerFilter,
7536            boolean force) {
7537        return mDexManager.dexoptSecondaryDex(packageName, compilerFilter, force);
7538    }
7539
7540    public boolean performDexOptSecondary(String packageName, int compileReason,
7541            boolean force) {
7542        return mDexManager.dexoptSecondaryDex(packageName, compileReason, force);
7543    }
7544
7545    /**
7546     * Reconcile the information we have about the secondary dex files belonging to
7547     * {@code packagName} and the actual dex files. For all dex files that were
7548     * deleted, update the internal records and delete the generated oat files.
7549     */
7550    @Override
7551    public void reconcileSecondaryDexFiles(String packageName) {
7552        mDexManager.reconcileSecondaryDexFiles(packageName);
7553    }
7554
7555    // TODO(calin): this is only needed for BackgroundDexOptService. Find a cleaner way to inject
7556    // a reference there.
7557    /*package*/ DexManager getDexManager() {
7558        return mDexManager;
7559    }
7560
7561    /**
7562     * Execute the background dexopt job immediately.
7563     */
7564    @Override
7565    public boolean runBackgroundDexoptJob() {
7566        return BackgroundDexOptService.runIdleOptimizationsNow(this, mContext);
7567    }
7568
7569    Collection<PackageParser.Package> findSharedNonSystemLibraries(PackageParser.Package p) {
7570        if (p.usesLibraries != null || p.usesOptionalLibraries != null) {
7571            ArrayList<PackageParser.Package> retValue = new ArrayList<>();
7572            Set<String> collectedNames = new HashSet<>();
7573            findSharedNonSystemLibrariesRecursive(p, retValue, collectedNames);
7574
7575            retValue.remove(p);
7576
7577            return retValue;
7578        } else {
7579            return Collections.emptyList();
7580        }
7581    }
7582
7583    private void findSharedNonSystemLibrariesRecursive(PackageParser.Package p,
7584            Collection<PackageParser.Package> collected, Set<String> collectedNames) {
7585        if (!collectedNames.contains(p.packageName)) {
7586            collectedNames.add(p.packageName);
7587            collected.add(p);
7588
7589            if (p.usesLibraries != null) {
7590                findSharedNonSystemLibrariesRecursive(p.usesLibraries, collected, collectedNames);
7591            }
7592            if (p.usesOptionalLibraries != null) {
7593                findSharedNonSystemLibrariesRecursive(p.usesOptionalLibraries, collected,
7594                        collectedNames);
7595            }
7596        }
7597    }
7598
7599    private void findSharedNonSystemLibrariesRecursive(Collection<String> libs,
7600            Collection<PackageParser.Package> collected, Set<String> collectedNames) {
7601        for (String libName : libs) {
7602            PackageParser.Package libPkg = findSharedNonSystemLibrary(libName);
7603            if (libPkg != null) {
7604                findSharedNonSystemLibrariesRecursive(libPkg, collected, collectedNames);
7605            }
7606        }
7607    }
7608
7609    private PackageParser.Package findSharedNonSystemLibrary(String libName) {
7610        synchronized (mPackages) {
7611            PackageManagerService.SharedLibraryEntry lib = mSharedLibraries.get(libName);
7612            if (lib != null && lib.apk != null) {
7613                return mPackages.get(lib.apk);
7614            }
7615        }
7616        return null;
7617    }
7618
7619    public void shutdown() {
7620        mPackageUsage.writeNow(mPackages);
7621        mCompilerStats.writeNow();
7622    }
7623
7624    @Override
7625    public void dumpProfiles(String packageName) {
7626        PackageParser.Package pkg;
7627        synchronized (mPackages) {
7628            pkg = mPackages.get(packageName);
7629            if (pkg == null) {
7630                throw new IllegalArgumentException("Unknown package: " + packageName);
7631            }
7632        }
7633        /* Only the shell, root, or the app user should be able to dump profiles. */
7634        int callingUid = Binder.getCallingUid();
7635        if (callingUid != Process.SHELL_UID &&
7636            callingUid != Process.ROOT_UID &&
7637            callingUid != pkg.applicationInfo.uid) {
7638            throw new SecurityException("dumpProfiles");
7639        }
7640
7641        synchronized (mInstallLock) {
7642            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dump profiles");
7643            final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
7644            try {
7645                List<String> allCodePaths = pkg.getAllCodePathsExcludingResourceOnly();
7646                String codePaths = TextUtils.join(";", allCodePaths);
7647                mInstaller.dumpProfiles(sharedGid, packageName, codePaths);
7648            } catch (InstallerException e) {
7649                Slog.w(TAG, "Failed to dump profiles", e);
7650            }
7651            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
7652        }
7653    }
7654
7655    @Override
7656    public void forceDexOpt(String packageName) {
7657        enforceSystemOrRoot("forceDexOpt");
7658
7659        PackageParser.Package pkg;
7660        synchronized (mPackages) {
7661            pkg = mPackages.get(packageName);
7662            if (pkg == null) {
7663                throw new IllegalArgumentException("Unknown package: " + packageName);
7664            }
7665        }
7666
7667        synchronized (mInstallLock) {
7668            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
7669
7670            // Whoever is calling forceDexOpt wants a fully compiled package.
7671            // Don't use profiles since that may cause compilation to be skipped.
7672            final int res = performDexOptInternalWithDependenciesLI(pkg,
7673                    false /* checkProfiles */, getCompilerFilterForReason(REASON_FORCED_DEXOPT),
7674                    true /* force */);
7675
7676            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
7677            if (res != PackageDexOptimizer.DEX_OPT_PERFORMED) {
7678                throw new IllegalStateException("Failed to dexopt: " + res);
7679            }
7680        }
7681    }
7682
7683    private boolean verifyPackageUpdateLPr(PackageSetting oldPkg, PackageParser.Package newPkg) {
7684        if ((oldPkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) {
7685            Slog.w(TAG, "Unable to update from " + oldPkg.name
7686                    + " to " + newPkg.packageName
7687                    + ": old package not in system partition");
7688            return false;
7689        } else if (mPackages.get(oldPkg.name) != null) {
7690            Slog.w(TAG, "Unable to update from " + oldPkg.name
7691                    + " to " + newPkg.packageName
7692                    + ": old package still exists");
7693            return false;
7694        }
7695        return true;
7696    }
7697
7698    void removeCodePathLI(File codePath) {
7699        if (codePath.isDirectory()) {
7700            try {
7701                mInstaller.rmPackageDir(codePath.getAbsolutePath());
7702            } catch (InstallerException e) {
7703                Slog.w(TAG, "Failed to remove code path", e);
7704            }
7705        } else {
7706            codePath.delete();
7707        }
7708    }
7709
7710    private int[] resolveUserIds(int userId) {
7711        return (userId == UserHandle.USER_ALL) ? sUserManager.getUserIds() : new int[] { userId };
7712    }
7713
7714    private void clearAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
7715        if (pkg == null) {
7716            Slog.wtf(TAG, "Package was null!", new Throwable());
7717            return;
7718        }
7719        clearAppDataLeafLIF(pkg, userId, flags);
7720        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
7721        for (int i = 0; i < childCount; i++) {
7722            clearAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
7723        }
7724    }
7725
7726    private void clearAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
7727        final PackageSetting ps;
7728        synchronized (mPackages) {
7729            ps = mSettings.mPackages.get(pkg.packageName);
7730        }
7731        for (int realUserId : resolveUserIds(userId)) {
7732            final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0;
7733            try {
7734                mInstaller.clearAppData(pkg.volumeUuid, pkg.packageName, realUserId, flags,
7735                        ceDataInode);
7736            } catch (InstallerException e) {
7737                Slog.w(TAG, String.valueOf(e));
7738            }
7739        }
7740    }
7741
7742    private void destroyAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
7743        if (pkg == null) {
7744            Slog.wtf(TAG, "Package was null!", new Throwable());
7745            return;
7746        }
7747        destroyAppDataLeafLIF(pkg, userId, flags);
7748        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
7749        for (int i = 0; i < childCount; i++) {
7750            destroyAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
7751        }
7752    }
7753
7754    private void destroyAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
7755        final PackageSetting ps;
7756        synchronized (mPackages) {
7757            ps = mSettings.mPackages.get(pkg.packageName);
7758        }
7759        for (int realUserId : resolveUserIds(userId)) {
7760            final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0;
7761            try {
7762                mInstaller.destroyAppData(pkg.volumeUuid, pkg.packageName, realUserId, flags,
7763                        ceDataInode);
7764            } catch (InstallerException e) {
7765                Slog.w(TAG, String.valueOf(e));
7766            }
7767            mDexManager.notifyPackageDataDestroyed(pkg.packageName, userId);
7768        }
7769    }
7770
7771    private void destroyAppProfilesLIF(PackageParser.Package pkg, int userId) {
7772        if (pkg == null) {
7773            Slog.wtf(TAG, "Package was null!", new Throwable());
7774            return;
7775        }
7776        destroyAppProfilesLeafLIF(pkg);
7777        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
7778        for (int i = 0; i < childCount; i++) {
7779            destroyAppProfilesLeafLIF(pkg.childPackages.get(i));
7780        }
7781    }
7782
7783    private void destroyAppProfilesLeafLIF(PackageParser.Package pkg) {
7784        try {
7785            mInstaller.destroyAppProfiles(pkg.packageName);
7786        } catch (InstallerException e) {
7787            Slog.w(TAG, String.valueOf(e));
7788        }
7789    }
7790
7791    private void clearAppProfilesLIF(PackageParser.Package pkg, int userId) {
7792        if (pkg == null) {
7793            Slog.wtf(TAG, "Package was null!", new Throwable());
7794            return;
7795        }
7796        clearAppProfilesLeafLIF(pkg);
7797        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
7798        for (int i = 0; i < childCount; i++) {
7799            clearAppProfilesLeafLIF(pkg.childPackages.get(i));
7800        }
7801    }
7802
7803    private void clearAppProfilesLeafLIF(PackageParser.Package pkg) {
7804        try {
7805            mInstaller.clearAppProfiles(pkg.packageName);
7806        } catch (InstallerException e) {
7807            Slog.w(TAG, String.valueOf(e));
7808        }
7809    }
7810
7811    private void setInstallAndUpdateTime(PackageParser.Package pkg, long firstInstallTime,
7812            long lastUpdateTime) {
7813        // Set parent install/update time
7814        PackageSetting ps = (PackageSetting) pkg.mExtras;
7815        if (ps != null) {
7816            ps.firstInstallTime = firstInstallTime;
7817            ps.lastUpdateTime = lastUpdateTime;
7818        }
7819        // Set children install/update time
7820        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
7821        for (int i = 0; i < childCount; i++) {
7822            PackageParser.Package childPkg = pkg.childPackages.get(i);
7823            ps = (PackageSetting) childPkg.mExtras;
7824            if (ps != null) {
7825                ps.firstInstallTime = firstInstallTime;
7826                ps.lastUpdateTime = lastUpdateTime;
7827            }
7828        }
7829    }
7830
7831    private void addSharedLibraryLPw(ArraySet<String> usesLibraryFiles, SharedLibraryEntry file,
7832            PackageParser.Package changingLib) {
7833        if (file.path != null) {
7834            usesLibraryFiles.add(file.path);
7835            return;
7836        }
7837        PackageParser.Package p = mPackages.get(file.apk);
7838        if (changingLib != null && changingLib.packageName.equals(file.apk)) {
7839            // If we are doing this while in the middle of updating a library apk,
7840            // then we need to make sure to use that new apk for determining the
7841            // dependencies here.  (We haven't yet finished committing the new apk
7842            // to the package manager state.)
7843            if (p == null || p.packageName.equals(changingLib.packageName)) {
7844                p = changingLib;
7845            }
7846        }
7847        if (p != null) {
7848            usesLibraryFiles.addAll(p.getAllCodePaths());
7849        }
7850    }
7851
7852    private void updateSharedLibrariesLPw(PackageParser.Package pkg,
7853            PackageParser.Package changingLib) throws PackageManagerException {
7854        if (pkg.usesLibraries != null || pkg.usesOptionalLibraries != null) {
7855            final ArraySet<String> usesLibraryFiles = new ArraySet<>();
7856            int N = pkg.usesLibraries != null ? pkg.usesLibraries.size() : 0;
7857            for (int i=0; i<N; i++) {
7858                final SharedLibraryEntry file = mSharedLibraries.get(pkg.usesLibraries.get(i));
7859                if (file == null) {
7860                    throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
7861                            "Package " + pkg.packageName + " requires unavailable shared library "
7862                            + pkg.usesLibraries.get(i) + "; failing!");
7863                }
7864                addSharedLibraryLPw(usesLibraryFiles, file, changingLib);
7865            }
7866            N = pkg.usesOptionalLibraries != null ? pkg.usesOptionalLibraries.size() : 0;
7867            for (int i=0; i<N; i++) {
7868                final SharedLibraryEntry file = mSharedLibraries.get(pkg.usesOptionalLibraries.get(i));
7869                if (file == null) {
7870                    Slog.w(TAG, "Package " + pkg.packageName
7871                            + " desires unavailable shared library "
7872                            + pkg.usesOptionalLibraries.get(i) + "; ignoring!");
7873                } else {
7874                    addSharedLibraryLPw(usesLibraryFiles, file, changingLib);
7875                }
7876            }
7877            N = usesLibraryFiles.size();
7878            if (N > 0) {
7879                pkg.usesLibraryFiles = usesLibraryFiles.toArray(new String[N]);
7880            } else {
7881                pkg.usesLibraryFiles = null;
7882            }
7883        }
7884    }
7885
7886    private static boolean hasString(List<String> list, List<String> which) {
7887        if (list == null) {
7888            return false;
7889        }
7890        for (int i=list.size()-1; i>=0; i--) {
7891            for (int j=which.size()-1; j>=0; j--) {
7892                if (which.get(j).equals(list.get(i))) {
7893                    return true;
7894                }
7895            }
7896        }
7897        return false;
7898    }
7899
7900    private void updateAllSharedLibrariesLPw() {
7901        for (PackageParser.Package pkg : mPackages.values()) {
7902            try {
7903                updateSharedLibrariesLPw(pkg, null);
7904            } catch (PackageManagerException e) {
7905                Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
7906            }
7907        }
7908    }
7909
7910    private ArrayList<PackageParser.Package> updateAllSharedLibrariesLPw(
7911            PackageParser.Package changingPkg) {
7912        ArrayList<PackageParser.Package> res = null;
7913        for (PackageParser.Package pkg : mPackages.values()) {
7914            if (hasString(pkg.usesLibraries, changingPkg.libraryNames)
7915                    || hasString(pkg.usesOptionalLibraries, changingPkg.libraryNames)) {
7916                if (res == null) {
7917                    res = new ArrayList<PackageParser.Package>();
7918                }
7919                res.add(pkg);
7920                try {
7921                    updateSharedLibrariesLPw(pkg, changingPkg);
7922                } catch (PackageManagerException e) {
7923                    Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
7924                }
7925            }
7926        }
7927        return res;
7928    }
7929
7930    /**
7931     * Derive the value of the {@code cpuAbiOverride} based on the provided
7932     * value and an optional stored value from the package settings.
7933     */
7934    private static String deriveAbiOverride(String abiOverride, PackageSetting settings) {
7935        String cpuAbiOverride = null;
7936
7937        if (NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(abiOverride)) {
7938            cpuAbiOverride = null;
7939        } else if (abiOverride != null) {
7940            cpuAbiOverride = abiOverride;
7941        } else if (settings != null) {
7942            cpuAbiOverride = settings.cpuAbiOverrideString;
7943        }
7944
7945        return cpuAbiOverride;
7946    }
7947
7948    private PackageParser.Package scanPackageTracedLI(PackageParser.Package pkg,
7949            final int policyFlags, int scanFlags, long currentTime, UserHandle user)
7950                    throws PackageManagerException {
7951        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage");
7952        // If the package has children and this is the first dive in the function
7953        // we recursively scan the package with the SCAN_CHECK_ONLY flag set to see
7954        // whether all packages (parent and children) would be successfully scanned
7955        // before the actual scan since scanning mutates internal state and we want
7956        // to atomically install the package and its children.
7957        if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
7958            if (pkg.childPackages != null && pkg.childPackages.size() > 0) {
7959                scanFlags |= SCAN_CHECK_ONLY;
7960            }
7961        } else {
7962            scanFlags &= ~SCAN_CHECK_ONLY;
7963        }
7964
7965        final PackageParser.Package scannedPkg;
7966        try {
7967            // Scan the parent
7968            scannedPkg = scanPackageLI(pkg, policyFlags, scanFlags, currentTime, user);
7969            // Scan the children
7970            final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
7971            for (int i = 0; i < childCount; i++) {
7972                PackageParser.Package childPkg = pkg.childPackages.get(i);
7973                scanPackageLI(childPkg, policyFlags,
7974                        scanFlags, currentTime, user);
7975            }
7976        } finally {
7977            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
7978        }
7979
7980        if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
7981            return scanPackageTracedLI(pkg, policyFlags, scanFlags, currentTime, user);
7982        }
7983
7984        return scannedPkg;
7985    }
7986
7987    private PackageParser.Package scanPackageLI(PackageParser.Package pkg, final int policyFlags,
7988            int scanFlags, long currentTime, UserHandle user) throws PackageManagerException {
7989        boolean success = false;
7990        try {
7991            final PackageParser.Package res = scanPackageDirtyLI(pkg, policyFlags, scanFlags,
7992                    currentTime, user);
7993            success = true;
7994            return res;
7995        } finally {
7996            if (!success && (scanFlags & SCAN_DELETE_DATA_ON_FAILURES) != 0) {
7997                // DELETE_DATA_ON_FAILURES is only used by frozen paths
7998                destroyAppDataLIF(pkg, UserHandle.USER_ALL,
7999                        StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
8000                destroyAppProfilesLIF(pkg, UserHandle.USER_ALL);
8001            }
8002        }
8003    }
8004
8005    /**
8006     * Returns {@code true} if the given file contains code. Otherwise {@code false}.
8007     */
8008    private static boolean apkHasCode(String fileName) {
8009        StrictJarFile jarFile = null;
8010        try {
8011            jarFile = new StrictJarFile(fileName,
8012                    false /*verify*/, false /*signatureSchemeRollbackProtectionsEnforced*/);
8013            return jarFile.findEntry("classes.dex") != null;
8014        } catch (IOException ignore) {
8015        } finally {
8016            try {
8017                if (jarFile != null) {
8018                    jarFile.close();
8019                }
8020            } catch (IOException ignore) {}
8021        }
8022        return false;
8023    }
8024
8025    /**
8026     * Enforces code policy for the package. This ensures that if an APK has
8027     * declared hasCode="true" in its manifest that the APK actually contains
8028     * code.
8029     *
8030     * @throws PackageManagerException If bytecode could not be found when it should exist
8031     */
8032    private static void enforceCodePolicy(PackageParser.Package pkg)
8033            throws PackageManagerException {
8034        final boolean shouldHaveCode =
8035                (pkg.applicationInfo.flags & ApplicationInfo.FLAG_HAS_CODE) != 0;
8036        if (shouldHaveCode && !apkHasCode(pkg.baseCodePath)) {
8037            throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
8038                    "Package " + pkg.baseCodePath + " code is missing");
8039        }
8040
8041        if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) {
8042            for (int i = 0; i < pkg.splitCodePaths.length; i++) {
8043                final boolean splitShouldHaveCode =
8044                        (pkg.splitFlags[i] & ApplicationInfo.FLAG_HAS_CODE) != 0;
8045                if (splitShouldHaveCode && !apkHasCode(pkg.splitCodePaths[i])) {
8046                    throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
8047                            "Package " + pkg.splitCodePaths[i] + " code is missing");
8048                }
8049            }
8050        }
8051    }
8052
8053    private PackageParser.Package scanPackageDirtyLI(PackageParser.Package pkg,
8054            final int policyFlags, final int scanFlags, long currentTime, UserHandle user)
8055            throws PackageManagerException {
8056        final File scanFile = new File(pkg.codePath);
8057        if (pkg.applicationInfo.getCodePath() == null ||
8058                pkg.applicationInfo.getResourcePath() == null) {
8059            // Bail out. The resource and code paths haven't been set.
8060            throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
8061                    "Code and resource paths haven't been set correctly");
8062        }
8063
8064        // Apply policy
8065        if ((policyFlags&PackageParser.PARSE_IS_SYSTEM) != 0) {
8066            pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
8067            if (pkg.applicationInfo.isDirectBootAware()) {
8068                // we're direct boot aware; set for all components
8069                for (PackageParser.Service s : pkg.services) {
8070                    s.info.encryptionAware = s.info.directBootAware = true;
8071                }
8072                for (PackageParser.Provider p : pkg.providers) {
8073                    p.info.encryptionAware = p.info.directBootAware = true;
8074                }
8075                for (PackageParser.Activity a : pkg.activities) {
8076                    a.info.encryptionAware = a.info.directBootAware = true;
8077                }
8078                for (PackageParser.Activity r : pkg.receivers) {
8079                    r.info.encryptionAware = r.info.directBootAware = true;
8080                }
8081            }
8082        } else {
8083            // Only allow system apps to be flagged as core apps.
8084            pkg.coreApp = false;
8085            // clear flags not applicable to regular apps
8086            pkg.applicationInfo.privateFlags &=
8087                    ~ApplicationInfo.PRIVATE_FLAG_DEFAULT_TO_DEVICE_PROTECTED_STORAGE;
8088            pkg.applicationInfo.privateFlags &=
8089                    ~ApplicationInfo.PRIVATE_FLAG_DIRECT_BOOT_AWARE;
8090        }
8091        pkg.mTrustedOverlay = (policyFlags&PackageParser.PARSE_TRUSTED_OVERLAY) != 0;
8092
8093        if ((policyFlags&PackageParser.PARSE_IS_PRIVILEGED) != 0) {
8094            pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
8095        }
8096
8097        if ((policyFlags & PackageParser.PARSE_ENFORCE_CODE) != 0) {
8098            enforceCodePolicy(pkg);
8099        }
8100
8101        if (mCustomResolverComponentName != null &&
8102                mCustomResolverComponentName.getPackageName().equals(pkg.packageName)) {
8103            setUpCustomResolverActivity(pkg);
8104        }
8105
8106        if (pkg.packageName.equals("android")) {
8107            synchronized (mPackages) {
8108                if (mAndroidApplication != null) {
8109                    Slog.w(TAG, "*************************************************");
8110                    Slog.w(TAG, "Core android package being redefined.  Skipping.");
8111                    Slog.w(TAG, " file=" + scanFile);
8112                    Slog.w(TAG, "*************************************************");
8113                    throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
8114                            "Core android package being redefined.  Skipping.");
8115                }
8116
8117                if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
8118                    // Set up information for our fall-back user intent resolution activity.
8119                    mPlatformPackage = pkg;
8120                    pkg.mVersionCode = mSdkVersion;
8121                    mAndroidApplication = pkg.applicationInfo;
8122
8123                    if (!mResolverReplaced) {
8124                        mResolveActivity.applicationInfo = mAndroidApplication;
8125                        mResolveActivity.name = ResolverActivity.class.getName();
8126                        mResolveActivity.packageName = mAndroidApplication.packageName;
8127                        mResolveActivity.processName = "system:ui";
8128                        mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
8129                        mResolveActivity.documentLaunchMode = ActivityInfo.DOCUMENT_LAUNCH_NEVER;
8130                        mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS;
8131                        mResolveActivity.theme = R.style.Theme_Material_Dialog_Alert;
8132                        mResolveActivity.exported = true;
8133                        mResolveActivity.enabled = true;
8134                        mResolveActivity.resizeMode = ActivityInfo.RESIZE_MODE_RESIZEABLE;
8135                        mResolveActivity.configChanges = ActivityInfo.CONFIG_SCREEN_SIZE
8136                                | ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE
8137                                | ActivityInfo.CONFIG_SCREEN_LAYOUT
8138                                | ActivityInfo.CONFIG_ORIENTATION
8139                                | ActivityInfo.CONFIG_KEYBOARD
8140                                | ActivityInfo.CONFIG_KEYBOARD_HIDDEN;
8141                        mResolveInfo.activityInfo = mResolveActivity;
8142                        mResolveInfo.priority = 0;
8143                        mResolveInfo.preferredOrder = 0;
8144                        mResolveInfo.match = 0;
8145                        mResolveComponentName = new ComponentName(
8146                                mAndroidApplication.packageName, mResolveActivity.name);
8147                    }
8148                }
8149            }
8150        }
8151
8152        if (DEBUG_PACKAGE_SCANNING) {
8153            if ((policyFlags & PackageParser.PARSE_CHATTY) != 0)
8154                Log.d(TAG, "Scanning package " + pkg.packageName);
8155        }
8156
8157        synchronized (mPackages) {
8158            if (mPackages.containsKey(pkg.packageName)
8159                    || mSharedLibraries.containsKey(pkg.packageName)) {
8160                throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
8161                        "Application package " + pkg.packageName
8162                                + " already installed.  Skipping duplicate.");
8163            }
8164
8165            // If we're only installing presumed-existing packages, require that the
8166            // scanned APK is both already known and at the path previously established
8167            // for it.  Previously unknown packages we pick up normally, but if we have an
8168            // a priori expectation about this package's install presence, enforce it.
8169            // With a singular exception for new system packages. When an OTA contains
8170            // a new system package, we allow the codepath to change from a system location
8171            // to the user-installed location. If we don't allow this change, any newer,
8172            // user-installed version of the application will be ignored.
8173            if ((scanFlags & SCAN_REQUIRE_KNOWN) != 0) {
8174                if (mExpectingBetter.containsKey(pkg.packageName)) {
8175                    logCriticalInfo(Log.WARN,
8176                            "Relax SCAN_REQUIRE_KNOWN requirement for package " + pkg.packageName);
8177                } else {
8178                    PackageSetting known = mSettings.peekPackageLPr(pkg.packageName);
8179                    if (known != null) {
8180                        if (DEBUG_PACKAGE_SCANNING) {
8181                            Log.d(TAG, "Examining " + pkg.codePath
8182                                    + " and requiring known paths " + known.codePathString
8183                                    + " & " + known.resourcePathString);
8184                        }
8185                        if (!pkg.applicationInfo.getCodePath().equals(known.codePathString)
8186                                || !pkg.applicationInfo.getResourcePath().equals(
8187                                known.resourcePathString)) {
8188                            throw new PackageManagerException(INSTALL_FAILED_PACKAGE_CHANGED,
8189                                    "Application package " + pkg.packageName
8190                                            + " found at " + pkg.applicationInfo.getCodePath()
8191                                            + " but expected at " + known.codePathString
8192                                            + "; ignoring.");
8193                        }
8194                    }
8195                }
8196            }
8197        }
8198
8199        // Initialize package source and resource directories
8200        File destCodeFile = new File(pkg.applicationInfo.getCodePath());
8201        File destResourceFile = new File(pkg.applicationInfo.getResourcePath());
8202
8203        SharedUserSetting suid = null;
8204        PackageSetting pkgSetting = null;
8205
8206        if (!isSystemApp(pkg)) {
8207            // Only system apps can use these features.
8208            pkg.mOriginalPackages = null;
8209            pkg.mRealPackage = null;
8210            pkg.mAdoptPermissions = null;
8211        }
8212
8213        // Getting the package setting may have a side-effect, so if we
8214        // are only checking if scan would succeed, stash a copy of the
8215        // old setting to restore at the end.
8216        PackageSetting nonMutatedPs = null;
8217
8218        // writer
8219        synchronized (mPackages) {
8220            if (pkg.mSharedUserId != null) {
8221                suid = mSettings.getSharedUserLPw(pkg.mSharedUserId, 0, 0, true);
8222                if (suid == null) {
8223                    throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE,
8224                            "Creating application package " + pkg.packageName
8225                            + " for shared user failed");
8226                }
8227                if (DEBUG_PACKAGE_SCANNING) {
8228                    if ((policyFlags & PackageParser.PARSE_CHATTY) != 0)
8229                        Log.d(TAG, "Shared UserID " + pkg.mSharedUserId + " (uid=" + suid.userId
8230                                + "): packages=" + suid.packages);
8231                }
8232            }
8233
8234            // Check if we are renaming from an original package name.
8235            PackageSetting origPackage = null;
8236            String realName = null;
8237            if (pkg.mOriginalPackages != null) {
8238                // This package may need to be renamed to a previously
8239                // installed name.  Let's check on that...
8240                final String renamed = mSettings.mRenamedPackages.get(pkg.mRealPackage);
8241                if (pkg.mOriginalPackages.contains(renamed)) {
8242                    // This package had originally been installed as the
8243                    // original name, and we have already taken care of
8244                    // transitioning to the new one.  Just update the new
8245                    // one to continue using the old name.
8246                    realName = pkg.mRealPackage;
8247                    if (!pkg.packageName.equals(renamed)) {
8248                        // Callers into this function may have already taken
8249                        // care of renaming the package; only do it here if
8250                        // it is not already done.
8251                        pkg.setPackageName(renamed);
8252                    }
8253
8254                } else {
8255                    for (int i=pkg.mOriginalPackages.size()-1; i>=0; i--) {
8256                        if ((origPackage = mSettings.peekPackageLPr(
8257                                pkg.mOriginalPackages.get(i))) != null) {
8258                            // We do have the package already installed under its
8259                            // original name...  should we use it?
8260                            if (!verifyPackageUpdateLPr(origPackage, pkg)) {
8261                                // New package is not compatible with original.
8262                                origPackage = null;
8263                                continue;
8264                            } else if (origPackage.sharedUser != null) {
8265                                // Make sure uid is compatible between packages.
8266                                if (!origPackage.sharedUser.name.equals(pkg.mSharedUserId)) {
8267                                    Slog.w(TAG, "Unable to migrate data from " + origPackage.name
8268                                            + " to " + pkg.packageName + ": old uid "
8269                                            + origPackage.sharedUser.name
8270                                            + " differs from " + pkg.mSharedUserId);
8271                                    origPackage = null;
8272                                    continue;
8273                                }
8274                                // TODO: Add case when shared user id is added [b/28144775]
8275                            } else {
8276                                if (DEBUG_UPGRADE) Log.v(TAG, "Renaming new package "
8277                                        + pkg.packageName + " to old name " + origPackage.name);
8278                            }
8279                            break;
8280                        }
8281                    }
8282                }
8283            }
8284
8285            if (mTransferedPackages.contains(pkg.packageName)) {
8286                Slog.w(TAG, "Package " + pkg.packageName
8287                        + " was transferred to another, but its .apk remains");
8288            }
8289
8290            // See comments in nonMutatedPs declaration
8291            if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
8292                PackageSetting foundPs = mSettings.peekPackageLPr(pkg.packageName);
8293                if (foundPs != null) {
8294                    nonMutatedPs = new PackageSetting(foundPs);
8295                }
8296            }
8297
8298            // Just create the setting, don't add it yet. For already existing packages
8299            // the PkgSetting exists already and doesn't have to be created.
8300            pkgSetting = mSettings.getPackageLPw(pkg, origPackage, realName, suid, destCodeFile,
8301                    destResourceFile, pkg.applicationInfo.nativeLibraryRootDir,
8302                    pkg.applicationInfo.primaryCpuAbi,
8303                    pkg.applicationInfo.secondaryCpuAbi,
8304                    pkg.applicationInfo.flags, pkg.applicationInfo.privateFlags,
8305                    user, false);
8306            if (pkgSetting == null) {
8307                throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE,
8308                        "Creating application package " + pkg.packageName + " failed");
8309            }
8310
8311            if (pkgSetting.origPackage != null) {
8312                // If we are first transitioning from an original package,
8313                // fix up the new package's name now.  We need to do this after
8314                // looking up the package under its new name, so getPackageLP
8315                // can take care of fiddling things correctly.
8316                pkg.setPackageName(origPackage.name);
8317
8318                // File a report about this.
8319                String msg = "New package " + pkgSetting.realName
8320                        + " renamed to replace old package " + pkgSetting.name;
8321                reportSettingsProblem(Log.WARN, msg);
8322
8323                // Make a note of it.
8324                if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
8325                    mTransferedPackages.add(origPackage.name);
8326                }
8327
8328                // No longer need to retain this.
8329                pkgSetting.origPackage = null;
8330            }
8331
8332            if ((scanFlags & SCAN_CHECK_ONLY) == 0 && realName != null) {
8333                // Make a note of it.
8334                mTransferedPackages.add(pkg.packageName);
8335            }
8336
8337            if (mSettings.isDisabledSystemPackageLPr(pkg.packageName)) {
8338                pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
8339            }
8340
8341            if ((policyFlags&PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
8342                // Check all shared libraries and map to their actual file path.
8343                // We only do this here for apps not on a system dir, because those
8344                // are the only ones that can fail an install due to this.  We
8345                // will take care of the system apps by updating all of their
8346                // library paths after the scan is done.
8347                updateSharedLibrariesLPw(pkg, null);
8348            }
8349
8350            if (mFoundPolicyFile) {
8351                SELinuxMMAC.assignSeinfoValue(pkg);
8352            }
8353
8354            pkg.applicationInfo.uid = pkgSetting.appId;
8355            pkg.mExtras = pkgSetting;
8356            if (shouldCheckUpgradeKeySetLP(pkgSetting, scanFlags)) {
8357                if (checkUpgradeKeySetLP(pkgSetting, pkg)) {
8358                    // We just determined the app is signed correctly, so bring
8359                    // over the latest parsed certs.
8360                    pkgSetting.signatures.mSignatures = pkg.mSignatures;
8361                } else {
8362                    if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
8363                        throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
8364                                "Package " + pkg.packageName + " upgrade keys do not match the "
8365                                + "previously installed version");
8366                    } else {
8367                        pkgSetting.signatures.mSignatures = pkg.mSignatures;
8368                        String msg = "System package " + pkg.packageName
8369                            + " signature changed; retaining data.";
8370                        reportSettingsProblem(Log.WARN, msg);
8371                    }
8372                }
8373            } else {
8374                try {
8375                    verifySignaturesLP(pkgSetting, pkg);
8376                    // We just determined the app is signed correctly, so bring
8377                    // over the latest parsed certs.
8378                    pkgSetting.signatures.mSignatures = pkg.mSignatures;
8379                } catch (PackageManagerException e) {
8380                    if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
8381                        throw e;
8382                    }
8383                    // The signature has changed, but this package is in the system
8384                    // image...  let's recover!
8385                    pkgSetting.signatures.mSignatures = pkg.mSignatures;
8386                    // However...  if this package is part of a shared user, but it
8387                    // doesn't match the signature of the shared user, let's fail.
8388                    // What this means is that you can't change the signatures
8389                    // associated with an overall shared user, which doesn't seem all
8390                    // that unreasonable.
8391                    if (pkgSetting.sharedUser != null) {
8392                        if (compareSignatures(pkgSetting.sharedUser.signatures.mSignatures,
8393                                              pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) {
8394                            throw new PackageManagerException(
8395                                    INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES,
8396                                            "Signature mismatch for shared user: "
8397                                            + pkgSetting.sharedUser);
8398                        }
8399                    }
8400                    // File a report about this.
8401                    String msg = "System package " + pkg.packageName
8402                        + " signature changed; retaining data.";
8403                    reportSettingsProblem(Log.WARN, msg);
8404                }
8405            }
8406            // Verify that this new package doesn't have any content providers
8407            // that conflict with existing packages.  Only do this if the
8408            // package isn't already installed, since we don't want to break
8409            // things that are installed.
8410            if ((scanFlags & SCAN_NEW_INSTALL) != 0) {
8411                final int N = pkg.providers.size();
8412                int i;
8413                for (i=0; i<N; i++) {
8414                    PackageParser.Provider p = pkg.providers.get(i);
8415                    if (p.info.authority != null) {
8416                        String names[] = p.info.authority.split(";");
8417                        for (int j = 0; j < names.length; j++) {
8418                            if (mProvidersByAuthority.containsKey(names[j])) {
8419                                PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
8420                                final String otherPackageName =
8421                                        ((other != null && other.getComponentName() != null) ?
8422                                                other.getComponentName().getPackageName() : "?");
8423                                throw new PackageManagerException(
8424                                        INSTALL_FAILED_CONFLICTING_PROVIDER,
8425                                                "Can't install because provider name " + names[j]
8426                                                + " (in package " + pkg.applicationInfo.packageName
8427                                                + ") is already used by " + otherPackageName);
8428                            }
8429                        }
8430                    }
8431                }
8432            }
8433
8434            if ((scanFlags & SCAN_CHECK_ONLY) == 0 && pkg.mAdoptPermissions != null) {
8435                // This package wants to adopt ownership of permissions from
8436                // another package.
8437                for (int i = pkg.mAdoptPermissions.size() - 1; i >= 0; i--) {
8438                    final String origName = pkg.mAdoptPermissions.get(i);
8439                    final PackageSetting orig = mSettings.peekPackageLPr(origName);
8440                    if (orig != null) {
8441                        if (verifyPackageUpdateLPr(orig, pkg)) {
8442                            Slog.i(TAG, "Adopting permissions from " + origName + " to "
8443                                    + pkg.packageName);
8444                            mSettings.transferPermissionsLPw(origName, pkg.packageName);
8445                        }
8446                    }
8447                }
8448            }
8449        }
8450
8451        final String pkgName = pkg.packageName;
8452
8453        final long scanFileTime = getLastModifiedTime(pkg, scanFile);
8454        final boolean forceDex = (scanFlags & SCAN_FORCE_DEX) != 0;
8455        pkg.applicationInfo.processName = fixProcessName(
8456                pkg.applicationInfo.packageName,
8457                pkg.applicationInfo.processName,
8458                pkg.applicationInfo.uid);
8459
8460        if (pkg != mPlatformPackage) {
8461            // Get all of our default paths setup
8462            pkg.applicationInfo.initForUser(UserHandle.USER_SYSTEM);
8463        }
8464
8465        final String path = scanFile.getPath();
8466        final String cpuAbiOverride = deriveAbiOverride(pkg.cpuAbiOverride, pkgSetting);
8467
8468        if ((scanFlags & SCAN_NEW_INSTALL) == 0) {
8469            derivePackageAbi(pkg, scanFile, cpuAbiOverride, true /* extract libs */);
8470
8471            // Some system apps still use directory structure for native libraries
8472            // in which case we might end up not detecting abi solely based on apk
8473            // structure. Try to detect abi based on directory structure.
8474            if (isSystemApp(pkg) && !pkg.isUpdatedSystemApp() &&
8475                    pkg.applicationInfo.primaryCpuAbi == null) {
8476                setBundledAppAbisAndRoots(pkg, pkgSetting);
8477                setNativeLibraryPaths(pkg);
8478            }
8479
8480        } else {
8481            if ((scanFlags & SCAN_MOVE) != 0) {
8482                // We haven't run dex-opt for this move (since we've moved the compiled output too)
8483                // but we already have this packages package info in the PackageSetting. We just
8484                // use that and derive the native library path based on the new codepath.
8485                pkg.applicationInfo.primaryCpuAbi = pkgSetting.primaryCpuAbiString;
8486                pkg.applicationInfo.secondaryCpuAbi = pkgSetting.secondaryCpuAbiString;
8487            }
8488
8489            // Set native library paths again. For moves, the path will be updated based on the
8490            // ABIs we've determined above. For non-moves, the path will be updated based on the
8491            // ABIs we determined during compilation, but the path will depend on the final
8492            // package path (after the rename away from the stage path).
8493            setNativeLibraryPaths(pkg);
8494        }
8495
8496        // This is a special case for the "system" package, where the ABI is
8497        // dictated by the zygote configuration (and init.rc). We should keep track
8498        // of this ABI so that we can deal with "normal" applications that run under
8499        // the same UID correctly.
8500        if (mPlatformPackage == pkg) {
8501            pkg.applicationInfo.primaryCpuAbi = VMRuntime.getRuntime().is64Bit() ?
8502                    Build.SUPPORTED_64_BIT_ABIS[0] : Build.SUPPORTED_32_BIT_ABIS[0];
8503        }
8504
8505        // If there's a mismatch between the abi-override in the package setting
8506        // and the abiOverride specified for the install. Warn about this because we
8507        // would've already compiled the app without taking the package setting into
8508        // account.
8509        if ((scanFlags & SCAN_NO_DEX) == 0 && (scanFlags & SCAN_NEW_INSTALL) != 0) {
8510            if (cpuAbiOverride == null && pkgSetting.cpuAbiOverrideString != null) {
8511                Slog.w(TAG, "Ignoring persisted ABI override " + cpuAbiOverride +
8512                        " for package " + pkg.packageName);
8513            }
8514        }
8515
8516        pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
8517        pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
8518        pkgSetting.cpuAbiOverrideString = cpuAbiOverride;
8519
8520        // Copy the derived override back to the parsed package, so that we can
8521        // update the package settings accordingly.
8522        pkg.cpuAbiOverride = cpuAbiOverride;
8523
8524        if (DEBUG_ABI_SELECTION) {
8525            Slog.d(TAG, "Resolved nativeLibraryRoot for " + pkg.applicationInfo.packageName
8526                    + " to root=" + pkg.applicationInfo.nativeLibraryRootDir + ", isa="
8527                    + pkg.applicationInfo.nativeLibraryRootRequiresIsa);
8528        }
8529
8530        // Push the derived path down into PackageSettings so we know what to
8531        // clean up at uninstall time.
8532        pkgSetting.legacyNativeLibraryPathString = pkg.applicationInfo.nativeLibraryRootDir;
8533
8534        if (DEBUG_ABI_SELECTION) {
8535            Log.d(TAG, "Abis for package[" + pkg.packageName + "] are" +
8536                    " primary=" + pkg.applicationInfo.primaryCpuAbi +
8537                    " secondary=" + pkg.applicationInfo.secondaryCpuAbi);
8538        }
8539
8540        if ((scanFlags & SCAN_BOOTING) == 0 && pkgSetting.sharedUser != null) {
8541            // We don't do this here during boot because we can do it all
8542            // at once after scanning all existing packages.
8543            //
8544            // We also do this *before* we perform dexopt on this package, so that
8545            // we can avoid redundant dexopts, and also to make sure we've got the
8546            // code and package path correct.
8547            adjustCpuAbisForSharedUserLPw(pkgSetting.sharedUser.packages,
8548                    pkg, true /* boot complete */);
8549        }
8550
8551        if (mFactoryTest && pkg.requestedPermissions.contains(
8552                android.Manifest.permission.FACTORY_TEST)) {
8553            pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST;
8554        }
8555
8556        if (isSystemApp(pkg)) {
8557            pkgSetting.isOrphaned = true;
8558        }
8559
8560        ArrayList<PackageParser.Package> clientLibPkgs = null;
8561
8562        if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
8563            if (nonMutatedPs != null) {
8564                synchronized (mPackages) {
8565                    mSettings.mPackages.put(nonMutatedPs.name, nonMutatedPs);
8566                }
8567            }
8568            return pkg;
8569        }
8570
8571        // Only privileged apps and updated privileged apps can add child packages.
8572        if (pkg.childPackages != null && !pkg.childPackages.isEmpty()) {
8573            if ((policyFlags & PARSE_IS_PRIVILEGED) == 0) {
8574                throw new PackageManagerException("Only privileged apps and updated "
8575                        + "privileged apps can add child packages. Ignoring package "
8576                        + pkg.packageName);
8577            }
8578            final int childCount = pkg.childPackages.size();
8579            for (int i = 0; i < childCount; i++) {
8580                PackageParser.Package childPkg = pkg.childPackages.get(i);
8581                if (mSettings.hasOtherDisabledSystemPkgWithChildLPr(pkg.packageName,
8582                        childPkg.packageName)) {
8583                    throw new PackageManagerException("Cannot override a child package of "
8584                            + "another disabled system app. Ignoring package " + pkg.packageName);
8585                }
8586            }
8587        }
8588
8589        // writer
8590        synchronized (mPackages) {
8591            if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
8592                // Only system apps can add new shared libraries.
8593                if (pkg.libraryNames != null) {
8594                    for (int i=0; i<pkg.libraryNames.size(); i++) {
8595                        String name = pkg.libraryNames.get(i);
8596                        boolean allowed = false;
8597                        if (pkg.isUpdatedSystemApp()) {
8598                            // New library entries can only be added through the
8599                            // system image.  This is important to get rid of a lot
8600                            // of nasty edge cases: for example if we allowed a non-
8601                            // system update of the app to add a library, then uninstalling
8602                            // the update would make the library go away, and assumptions
8603                            // we made such as through app install filtering would now
8604                            // have allowed apps on the device which aren't compatible
8605                            // with it.  Better to just have the restriction here, be
8606                            // conservative, and create many fewer cases that can negatively
8607                            // impact the user experience.
8608                            final PackageSetting sysPs = mSettings
8609                                    .getDisabledSystemPkgLPr(pkg.packageName);
8610                            if (sysPs.pkg != null && sysPs.pkg.libraryNames != null) {
8611                                for (int j=0; j<sysPs.pkg.libraryNames.size(); j++) {
8612                                    if (name.equals(sysPs.pkg.libraryNames.get(j))) {
8613                                        allowed = true;
8614                                        break;
8615                                    }
8616                                }
8617                            }
8618                        } else {
8619                            allowed = true;
8620                        }
8621                        if (allowed) {
8622                            if (!mSharedLibraries.containsKey(name)) {
8623                                mSharedLibraries.put(name, new SharedLibraryEntry(null, pkg.packageName));
8624                            } else if (!name.equals(pkg.packageName)) {
8625                                Slog.w(TAG, "Package " + pkg.packageName + " library "
8626                                        + name + " already exists; skipping");
8627                            }
8628                        } else {
8629                            Slog.w(TAG, "Package " + pkg.packageName + " declares lib "
8630                                    + name + " that is not declared on system image; skipping");
8631                        }
8632                    }
8633                    if ((scanFlags & SCAN_BOOTING) == 0) {
8634                        // If we are not booting, we need to update any applications
8635                        // that are clients of our shared library.  If we are booting,
8636                        // this will all be done once the scan is complete.
8637                        clientLibPkgs = updateAllSharedLibrariesLPw(pkg);
8638                    }
8639                }
8640            }
8641        }
8642
8643        if ((scanFlags & SCAN_BOOTING) != 0) {
8644            // No apps can run during boot scan, so they don't need to be frozen
8645        } else if ((scanFlags & SCAN_DONT_KILL_APP) != 0) {
8646            // Caller asked to not kill app, so it's probably not frozen
8647        } else if ((scanFlags & SCAN_IGNORE_FROZEN) != 0) {
8648            // Caller asked us to ignore frozen check for some reason; they
8649            // probably didn't know the package name
8650        } else {
8651            // We're doing major surgery on this package, so it better be frozen
8652            // right now to keep it from launching
8653            checkPackageFrozen(pkgName);
8654        }
8655
8656        // Also need to kill any apps that are dependent on the library.
8657        if (clientLibPkgs != null) {
8658            for (int i=0; i<clientLibPkgs.size(); i++) {
8659                PackageParser.Package clientPkg = clientLibPkgs.get(i);
8660                killApplication(clientPkg.applicationInfo.packageName,
8661                        clientPkg.applicationInfo.uid, "update lib");
8662            }
8663        }
8664
8665        // Make sure we're not adding any bogus keyset info
8666        KeySetManagerService ksms = mSettings.mKeySetManagerService;
8667        ksms.assertScannedPackageValid(pkg);
8668
8669        // writer
8670        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");
8671
8672        boolean createIdmapFailed = false;
8673        synchronized (mPackages) {
8674            // We don't expect installation to fail beyond this point
8675
8676            // Add the new setting to mSettings
8677            mSettings.insertPackageSettingLPw(pkgSetting, pkg);
8678            // Add the new setting to mPackages
8679            mPackages.put(pkg.applicationInfo.packageName, pkg);
8680            // Make sure we don't accidentally delete its data.
8681            final Iterator<PackageCleanItem> iter = mSettings.mPackagesToBeCleaned.iterator();
8682            while (iter.hasNext()) {
8683                PackageCleanItem item = iter.next();
8684                if (pkgName.equals(item.packageName)) {
8685                    iter.remove();
8686                }
8687            }
8688
8689            // Take care of first install / last update times.
8690            if (currentTime != 0) {
8691                if (pkgSetting.firstInstallTime == 0) {
8692                    pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = currentTime;
8693                } else if ((scanFlags&SCAN_UPDATE_TIME) != 0) {
8694                    pkgSetting.lastUpdateTime = currentTime;
8695                }
8696            } else if (pkgSetting.firstInstallTime == 0) {
8697                // We need *something*.  Take time time stamp of the file.
8698                pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = scanFileTime;
8699            } else if ((policyFlags&PackageParser.PARSE_IS_SYSTEM_DIR) != 0) {
8700                if (scanFileTime != pkgSetting.timeStamp) {
8701                    // A package on the system image has changed; consider this
8702                    // to be an update.
8703                    pkgSetting.lastUpdateTime = scanFileTime;
8704                }
8705            }
8706
8707            // Add the package's KeySets to the global KeySetManagerService
8708            ksms.addScannedPackageLPw(pkg);
8709
8710            int N = pkg.providers.size();
8711            StringBuilder r = null;
8712            int i;
8713            for (i=0; i<N; i++) {
8714                PackageParser.Provider p = pkg.providers.get(i);
8715                p.info.processName = fixProcessName(pkg.applicationInfo.processName,
8716                        p.info.processName, pkg.applicationInfo.uid);
8717                mProviders.addProvider(p);
8718                p.syncable = p.info.isSyncable;
8719                if (p.info.authority != null) {
8720                    String names[] = p.info.authority.split(";");
8721                    p.info.authority = null;
8722                    for (int j = 0; j < names.length; j++) {
8723                        if (j == 1 && p.syncable) {
8724                            // We only want the first authority for a provider to possibly be
8725                            // syncable, so if we already added this provider using a different
8726                            // authority clear the syncable flag. We copy the provider before
8727                            // changing it because the mProviders object contains a reference
8728                            // to a provider that we don't want to change.
8729                            // Only do this for the second authority since the resulting provider
8730                            // object can be the same for all future authorities for this provider.
8731                            p = new PackageParser.Provider(p);
8732                            p.syncable = false;
8733                        }
8734                        if (!mProvidersByAuthority.containsKey(names[j])) {
8735                            mProvidersByAuthority.put(names[j], p);
8736                            if (p.info.authority == null) {
8737                                p.info.authority = names[j];
8738                            } else {
8739                                p.info.authority = p.info.authority + ";" + names[j];
8740                            }
8741                            if (DEBUG_PACKAGE_SCANNING) {
8742                                if ((policyFlags & PackageParser.PARSE_CHATTY) != 0)
8743                                    Log.d(TAG, "Registered content provider: " + names[j]
8744                                            + ", className = " + p.info.name + ", isSyncable = "
8745                                            + p.info.isSyncable);
8746                            }
8747                        } else {
8748                            PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
8749                            Slog.w(TAG, "Skipping provider name " + names[j] +
8750                                    " (in package " + pkg.applicationInfo.packageName +
8751                                    "): name already used by "
8752                                    + ((other != null && other.getComponentName() != null)
8753                                            ? other.getComponentName().getPackageName() : "?"));
8754                        }
8755                    }
8756                }
8757                if ((policyFlags&PackageParser.PARSE_CHATTY) != 0) {
8758                    if (r == null) {
8759                        r = new StringBuilder(256);
8760                    } else {
8761                        r.append(' ');
8762                    }
8763                    r.append(p.info.name);
8764                }
8765            }
8766            if (r != null) {
8767                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Providers: " + r);
8768            }
8769
8770            N = pkg.services.size();
8771            r = null;
8772            for (i=0; i<N; i++) {
8773                PackageParser.Service s = pkg.services.get(i);
8774                s.info.processName = fixProcessName(pkg.applicationInfo.processName,
8775                        s.info.processName, pkg.applicationInfo.uid);
8776                mServices.addService(s);
8777                if ((policyFlags&PackageParser.PARSE_CHATTY) != 0) {
8778                    if (r == null) {
8779                        r = new StringBuilder(256);
8780                    } else {
8781                        r.append(' ');
8782                    }
8783                    r.append(s.info.name);
8784                }
8785            }
8786            if (r != null) {
8787                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Services: " + r);
8788            }
8789
8790            N = pkg.receivers.size();
8791            r = null;
8792            for (i=0; i<N; i++) {
8793                PackageParser.Activity a = pkg.receivers.get(i);
8794                a.info.processName = fixProcessName(pkg.applicationInfo.processName,
8795                        a.info.processName, pkg.applicationInfo.uid);
8796                mReceivers.addActivity(a, "receiver");
8797                if ((policyFlags&PackageParser.PARSE_CHATTY) != 0) {
8798                    if (r == null) {
8799                        r = new StringBuilder(256);
8800                    } else {
8801                        r.append(' ');
8802                    }
8803                    r.append(a.info.name);
8804                }
8805            }
8806            if (r != null) {
8807                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Receivers: " + r);
8808            }
8809
8810            N = pkg.activities.size();
8811            r = null;
8812            for (i=0; i<N; i++) {
8813                PackageParser.Activity a = pkg.activities.get(i);
8814                a.info.processName = fixProcessName(pkg.applicationInfo.processName,
8815                        a.info.processName, pkg.applicationInfo.uid);
8816                mActivities.addActivity(a, "activity");
8817                if ((policyFlags&PackageParser.PARSE_CHATTY) != 0) {
8818                    if (r == null) {
8819                        r = new StringBuilder(256);
8820                    } else {
8821                        r.append(' ');
8822                    }
8823                    r.append(a.info.name);
8824                }
8825            }
8826            if (r != null) {
8827                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Activities: " + r);
8828            }
8829
8830            N = pkg.permissionGroups.size();
8831            r = null;
8832            for (i=0; i<N; i++) {
8833                PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i);
8834                PackageParser.PermissionGroup cur = mPermissionGroups.get(pg.info.name);
8835                final String curPackageName = cur == null ? null : cur.info.packageName;
8836                final boolean isPackageUpdate = pg.info.packageName.equals(curPackageName);
8837                if (cur == null || isPackageUpdate) {
8838                    mPermissionGroups.put(pg.info.name, pg);
8839                    if ((policyFlags&PackageParser.PARSE_CHATTY) != 0) {
8840                        if (r == null) {
8841                            r = new StringBuilder(256);
8842                        } else {
8843                            r.append(' ');
8844                        }
8845                        if (isPackageUpdate) {
8846                            r.append("UPD:");
8847                        }
8848                        r.append(pg.info.name);
8849                    }
8850                } else {
8851                    Slog.w(TAG, "Permission group " + pg.info.name + " from package "
8852                            + pg.info.packageName + " ignored: original from "
8853                            + cur.info.packageName);
8854                    if ((policyFlags&PackageParser.PARSE_CHATTY) != 0) {
8855                        if (r == null) {
8856                            r = new StringBuilder(256);
8857                        } else {
8858                            r.append(' ');
8859                        }
8860                        r.append("DUP:");
8861                        r.append(pg.info.name);
8862                    }
8863                }
8864            }
8865            if (r != null) {
8866                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Permission Groups: " + r);
8867            }
8868
8869            N = pkg.permissions.size();
8870            r = null;
8871            for (i=0; i<N; i++) {
8872                PackageParser.Permission p = pkg.permissions.get(i);
8873
8874                // Assume by default that we did not install this permission into the system.
8875                p.info.flags &= ~PermissionInfo.FLAG_INSTALLED;
8876
8877                // Now that permission groups have a special meaning, we ignore permission
8878                // groups for legacy apps to prevent unexpected behavior. In particular,
8879                // permissions for one app being granted to someone just becase they happen
8880                // to be in a group defined by another app (before this had no implications).
8881                if (pkg.applicationInfo.targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1) {
8882                    p.group = mPermissionGroups.get(p.info.group);
8883                    // Warn for a permission in an unknown group.
8884                    if (p.info.group != null && p.group == null) {
8885                        Slog.w(TAG, "Permission " + p.info.name + " from package "
8886                                + p.info.packageName + " in an unknown group " + p.info.group);
8887                    }
8888                }
8889
8890                ArrayMap<String, BasePermission> permissionMap =
8891                        p.tree ? mSettings.mPermissionTrees
8892                                : mSettings.mPermissions;
8893                BasePermission bp = permissionMap.get(p.info.name);
8894
8895                // Allow system apps to redefine non-system permissions
8896                if (bp != null && !Objects.equals(bp.sourcePackage, p.info.packageName)) {
8897                    final boolean currentOwnerIsSystem = (bp.perm != null
8898                            && isSystemApp(bp.perm.owner));
8899                    if (isSystemApp(p.owner)) {
8900                        if (bp.type == BasePermission.TYPE_BUILTIN && bp.perm == null) {
8901                            // It's a built-in permission and no owner, take ownership now
8902                            bp.packageSetting = pkgSetting;
8903                            bp.perm = p;
8904                            bp.uid = pkg.applicationInfo.uid;
8905                            bp.sourcePackage = p.info.packageName;
8906                            p.info.flags |= PermissionInfo.FLAG_INSTALLED;
8907                        } else if (!currentOwnerIsSystem) {
8908                            String msg = "New decl " + p.owner + " of permission  "
8909                                    + p.info.name + " is system; overriding " + bp.sourcePackage;
8910                            reportSettingsProblem(Log.WARN, msg);
8911                            bp = null;
8912                        }
8913                    }
8914                }
8915
8916                if (bp == null) {
8917                    bp = new BasePermission(p.info.name, p.info.packageName,
8918                            BasePermission.TYPE_NORMAL);
8919                    permissionMap.put(p.info.name, bp);
8920                }
8921
8922                if (bp.perm == null) {
8923                    if (bp.sourcePackage == null
8924                            || bp.sourcePackage.equals(p.info.packageName)) {
8925                        BasePermission tree = findPermissionTreeLP(p.info.name);
8926                        if (tree == null
8927                                || tree.sourcePackage.equals(p.info.packageName)) {
8928                            bp.packageSetting = pkgSetting;
8929                            bp.perm = p;
8930                            bp.uid = pkg.applicationInfo.uid;
8931                            bp.sourcePackage = p.info.packageName;
8932                            p.info.flags |= PermissionInfo.FLAG_INSTALLED;
8933                            if ((policyFlags&PackageParser.PARSE_CHATTY) != 0) {
8934                                if (r == null) {
8935                                    r = new StringBuilder(256);
8936                                } else {
8937                                    r.append(' ');
8938                                }
8939                                r.append(p.info.name);
8940                            }
8941                        } else {
8942                            Slog.w(TAG, "Permission " + p.info.name + " from package "
8943                                    + p.info.packageName + " ignored: base tree "
8944                                    + tree.name + " is from package "
8945                                    + tree.sourcePackage);
8946                        }
8947                    } else {
8948                        Slog.w(TAG, "Permission " + p.info.name + " from package "
8949                                + p.info.packageName + " ignored: original from "
8950                                + bp.sourcePackage);
8951                    }
8952                } else if ((policyFlags&PackageParser.PARSE_CHATTY) != 0) {
8953                    if (r == null) {
8954                        r = new StringBuilder(256);
8955                    } else {
8956                        r.append(' ');
8957                    }
8958                    r.append("DUP:");
8959                    r.append(p.info.name);
8960                }
8961                if (bp.perm == p) {
8962                    bp.protectionLevel = p.info.protectionLevel;
8963                }
8964            }
8965
8966            if (r != null) {
8967                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Permissions: " + r);
8968            }
8969
8970            N = pkg.instrumentation.size();
8971            r = null;
8972            for (i=0; i<N; i++) {
8973                PackageParser.Instrumentation a = pkg.instrumentation.get(i);
8974                a.info.packageName = pkg.applicationInfo.packageName;
8975                a.info.sourceDir = pkg.applicationInfo.sourceDir;
8976                a.info.publicSourceDir = pkg.applicationInfo.publicSourceDir;
8977                a.info.splitSourceDirs = pkg.applicationInfo.splitSourceDirs;
8978                a.info.splitPublicSourceDirs = pkg.applicationInfo.splitPublicSourceDirs;
8979                a.info.dataDir = pkg.applicationInfo.dataDir;
8980                a.info.deviceProtectedDataDir = pkg.applicationInfo.deviceProtectedDataDir;
8981                a.info.credentialProtectedDataDir = pkg.applicationInfo.credentialProtectedDataDir;
8982
8983                a.info.nativeLibraryDir = pkg.applicationInfo.nativeLibraryDir;
8984                a.info.secondaryNativeLibraryDir = pkg.applicationInfo.secondaryNativeLibraryDir;
8985                mInstrumentation.put(a.getComponentName(), a);
8986                if ((policyFlags&PackageParser.PARSE_CHATTY) != 0) {
8987                    if (r == null) {
8988                        r = new StringBuilder(256);
8989                    } else {
8990                        r.append(' ');
8991                    }
8992                    r.append(a.info.name);
8993                }
8994            }
8995            if (r != null) {
8996                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Instrumentation: " + r);
8997            }
8998
8999            if (pkg.protectedBroadcasts != null) {
9000                N = pkg.protectedBroadcasts.size();
9001                for (i=0; i<N; i++) {
9002                    mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i));
9003                }
9004            }
9005
9006            pkgSetting.setTimeStamp(scanFileTime);
9007
9008            // Create idmap files for pairs of (packages, overlay packages).
9009            // Note: "android", ie framework-res.apk, is handled by native layers.
9010            if (pkg.mOverlayTarget != null) {
9011                // This is an overlay package.
9012                if (pkg.mOverlayTarget != null && !pkg.mOverlayTarget.equals("android")) {
9013                    if (!mOverlays.containsKey(pkg.mOverlayTarget)) {
9014                        mOverlays.put(pkg.mOverlayTarget,
9015                                new ArrayMap<String, PackageParser.Package>());
9016                    }
9017                    ArrayMap<String, PackageParser.Package> map = mOverlays.get(pkg.mOverlayTarget);
9018                    map.put(pkg.packageName, pkg);
9019                    PackageParser.Package orig = mPackages.get(pkg.mOverlayTarget);
9020                    if (orig != null && !createIdmapForPackagePairLI(orig, pkg)) {
9021                        createIdmapFailed = true;
9022                    }
9023                }
9024            } else if (mOverlays.containsKey(pkg.packageName) &&
9025                    !pkg.packageName.equals("android")) {
9026                // This is a regular package, with one or more known overlay packages.
9027                createIdmapsForPackageLI(pkg);
9028            }
9029        }
9030
9031        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9032
9033        if (createIdmapFailed) {
9034            throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
9035                    "scanPackageLI failed to createIdmap");
9036        }
9037        return pkg;
9038    }
9039
9040    /**
9041     * Derive the ABI of a non-system package located at {@code scanFile}. This information
9042     * is derived purely on the basis of the contents of {@code scanFile} and
9043     * {@code cpuAbiOverride}.
9044     *
9045     * If {@code extractLibs} is true, native libraries are extracted from the app if required.
9046     */
9047    private void derivePackageAbi(PackageParser.Package pkg, File scanFile,
9048                                 String cpuAbiOverride, boolean extractLibs)
9049            throws PackageManagerException {
9050        // TODO: We can probably be smarter about this stuff. For installed apps,
9051        // we can calculate this information at install time once and for all. For
9052        // system apps, we can probably assume that this information doesn't change
9053        // after the first boot scan. As things stand, we do lots of unnecessary work.
9054
9055        // Give ourselves some initial paths; we'll come back for another
9056        // pass once we've determined ABI below.
9057        setNativeLibraryPaths(pkg);
9058
9059        // We would never need to extract libs for forward-locked and external packages,
9060        // since the container service will do it for us. We shouldn't attempt to
9061        // extract libs from system app when it was not updated.
9062        if (pkg.isForwardLocked() || pkg.applicationInfo.isExternalAsec() ||
9063                (isSystemApp(pkg) && !pkg.isUpdatedSystemApp())) {
9064            extractLibs = false;
9065        }
9066
9067        final String nativeLibraryRootStr = pkg.applicationInfo.nativeLibraryRootDir;
9068        final boolean useIsaSpecificSubdirs = pkg.applicationInfo.nativeLibraryRootRequiresIsa;
9069
9070        NativeLibraryHelper.Handle handle = null;
9071        try {
9072            handle = NativeLibraryHelper.Handle.create(pkg);
9073            // TODO(multiArch): This can be null for apps that didn't go through the
9074            // usual installation process. We can calculate it again, like we
9075            // do during install time.
9076            //
9077            // TODO(multiArch): Why do we need to rescan ASEC apps again ? It seems totally
9078            // unnecessary.
9079            final File nativeLibraryRoot = new File(nativeLibraryRootStr);
9080
9081            // Null out the abis so that they can be recalculated.
9082            pkg.applicationInfo.primaryCpuAbi = null;
9083            pkg.applicationInfo.secondaryCpuAbi = null;
9084            if (isMultiArch(pkg.applicationInfo)) {
9085                // Warn if we've set an abiOverride for multi-lib packages..
9086                // By definition, we need to copy both 32 and 64 bit libraries for
9087                // such packages.
9088                if (pkg.cpuAbiOverride != null
9089                        && !NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(pkg.cpuAbiOverride)) {
9090                    Slog.w(TAG, "Ignoring abiOverride for multi arch application.");
9091                }
9092
9093                int abi32 = PackageManager.NO_NATIVE_LIBRARIES;
9094                int abi64 = PackageManager.NO_NATIVE_LIBRARIES;
9095                if (Build.SUPPORTED_32_BIT_ABIS.length > 0) {
9096                    if (extractLibs) {
9097                        abi32 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
9098                                nativeLibraryRoot, Build.SUPPORTED_32_BIT_ABIS,
9099                                useIsaSpecificSubdirs);
9100                    } else {
9101                        abi32 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_32_BIT_ABIS);
9102                    }
9103                }
9104
9105                maybeThrowExceptionForMultiArchCopy(
9106                        "Error unpackaging 32 bit native libs for multiarch app.", abi32);
9107
9108                if (Build.SUPPORTED_64_BIT_ABIS.length > 0) {
9109                    if (extractLibs) {
9110                        abi64 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
9111                                nativeLibraryRoot, Build.SUPPORTED_64_BIT_ABIS,
9112                                useIsaSpecificSubdirs);
9113                    } else {
9114                        abi64 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_64_BIT_ABIS);
9115                    }
9116                }
9117
9118                maybeThrowExceptionForMultiArchCopy(
9119                        "Error unpackaging 64 bit native libs for multiarch app.", abi64);
9120
9121                if (abi64 >= 0) {
9122                    pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[abi64];
9123                }
9124
9125                if (abi32 >= 0) {
9126                    final String abi = Build.SUPPORTED_32_BIT_ABIS[abi32];
9127                    if (abi64 >= 0) {
9128                        if (pkg.use32bitAbi) {
9129                            pkg.applicationInfo.secondaryCpuAbi = pkg.applicationInfo.primaryCpuAbi;
9130                            pkg.applicationInfo.primaryCpuAbi = abi;
9131                        } else {
9132                            pkg.applicationInfo.secondaryCpuAbi = abi;
9133                        }
9134                    } else {
9135                        pkg.applicationInfo.primaryCpuAbi = abi;
9136                    }
9137                }
9138
9139            } else {
9140                String[] abiList = (cpuAbiOverride != null) ?
9141                        new String[] { cpuAbiOverride } : Build.SUPPORTED_ABIS;
9142
9143                // Enable gross and lame hacks for apps that are built with old
9144                // SDK tools. We must scan their APKs for renderscript bitcode and
9145                // not launch them if it's present. Don't bother checking on devices
9146                // that don't have 64 bit support.
9147                boolean needsRenderScriptOverride = false;
9148                if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && cpuAbiOverride == null &&
9149                        NativeLibraryHelper.hasRenderscriptBitcode(handle)) {
9150                    abiList = Build.SUPPORTED_32_BIT_ABIS;
9151                    needsRenderScriptOverride = true;
9152                }
9153
9154                final int copyRet;
9155                if (extractLibs) {
9156                    copyRet = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
9157                            nativeLibraryRoot, abiList, useIsaSpecificSubdirs);
9158                } else {
9159                    copyRet = NativeLibraryHelper.findSupportedAbi(handle, abiList);
9160                }
9161
9162                if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) {
9163                    throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
9164                            "Error unpackaging native libs for app, errorCode=" + copyRet);
9165                }
9166
9167                if (copyRet >= 0) {
9168                    pkg.applicationInfo.primaryCpuAbi = abiList[copyRet];
9169                } else if (copyRet == PackageManager.NO_NATIVE_LIBRARIES && cpuAbiOverride != null) {
9170                    pkg.applicationInfo.primaryCpuAbi = cpuAbiOverride;
9171                } else if (needsRenderScriptOverride) {
9172                    pkg.applicationInfo.primaryCpuAbi = abiList[0];
9173                }
9174            }
9175        } catch (IOException ioe) {
9176            Slog.e(TAG, "Unable to get canonical file " + ioe.toString());
9177        } finally {
9178            IoUtils.closeQuietly(handle);
9179        }
9180
9181        // Now that we've calculated the ABIs and determined if it's an internal app,
9182        // we will go ahead and populate the nativeLibraryPath.
9183        setNativeLibraryPaths(pkg);
9184    }
9185
9186    /**
9187     * Adjusts ABIs for a set of packages belonging to a shared user so that they all match.
9188     * i.e, so that all packages can be run inside a single process if required.
9189     *
9190     * Optionally, callers can pass in a parsed package via {@code newPackage} in which case
9191     * this function will either try and make the ABI for all packages in {@code packagesForUser}
9192     * match {@code scannedPackage} or will update the ABI of {@code scannedPackage} to match
9193     * the ABI selected for {@code packagesForUser}. This variant is used when installing or
9194     * updating a package that belongs to a shared user.
9195     *
9196     * NOTE: We currently only match for the primary CPU abi string. Matching the secondary
9197     * adds unnecessary complexity.
9198     */
9199    private void adjustCpuAbisForSharedUserLPw(Set<PackageSetting> packagesForUser,
9200            PackageParser.Package scannedPackage, boolean bootComplete) {
9201        String requiredInstructionSet = null;
9202        if (scannedPackage != null && scannedPackage.applicationInfo.primaryCpuAbi != null) {
9203            requiredInstructionSet = VMRuntime.getInstructionSet(
9204                     scannedPackage.applicationInfo.primaryCpuAbi);
9205        }
9206
9207        PackageSetting requirer = null;
9208        for (PackageSetting ps : packagesForUser) {
9209            // If packagesForUser contains scannedPackage, we skip it. This will happen
9210            // when scannedPackage is an update of an existing package. Without this check,
9211            // we will never be able to change the ABI of any package belonging to a shared
9212            // user, even if it's compatible with other packages.
9213            if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
9214                if (ps.primaryCpuAbiString == null) {
9215                    continue;
9216                }
9217
9218                final String instructionSet = VMRuntime.getInstructionSet(ps.primaryCpuAbiString);
9219                if (requiredInstructionSet != null && !instructionSet.equals(requiredInstructionSet)) {
9220                    // We have a mismatch between instruction sets (say arm vs arm64) warn about
9221                    // this but there's not much we can do.
9222                    String errorMessage = "Instruction set mismatch, "
9223                            + ((requirer == null) ? "[caller]" : requirer)
9224                            + " requires " + requiredInstructionSet + " whereas " + ps
9225                            + " requires " + instructionSet;
9226                    Slog.w(TAG, errorMessage);
9227                }
9228
9229                if (requiredInstructionSet == null) {
9230                    requiredInstructionSet = instructionSet;
9231                    requirer = ps;
9232                }
9233            }
9234        }
9235
9236        if (requiredInstructionSet != null) {
9237            String adjustedAbi;
9238            if (requirer != null) {
9239                // requirer != null implies that either scannedPackage was null or that scannedPackage
9240                // did not require an ABI, in which case we have to adjust scannedPackage to match
9241                // the ABI of the set (which is the same as requirer's ABI)
9242                adjustedAbi = requirer.primaryCpuAbiString;
9243                if (scannedPackage != null) {
9244                    scannedPackage.applicationInfo.primaryCpuAbi = adjustedAbi;
9245                }
9246            } else {
9247                // requirer == null implies that we're updating all ABIs in the set to
9248                // match scannedPackage.
9249                adjustedAbi =  scannedPackage.applicationInfo.primaryCpuAbi;
9250            }
9251
9252            for (PackageSetting ps : packagesForUser) {
9253                if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
9254                    if (ps.primaryCpuAbiString != null) {
9255                        continue;
9256                    }
9257
9258                    ps.primaryCpuAbiString = adjustedAbi;
9259                    if (ps.pkg != null && ps.pkg.applicationInfo != null &&
9260                            !TextUtils.equals(adjustedAbi, ps.pkg.applicationInfo.primaryCpuAbi)) {
9261                        ps.pkg.applicationInfo.primaryCpuAbi = adjustedAbi;
9262                        Slog.i(TAG, "Adjusting ABI for " + ps.name + " to " + adjustedAbi
9263                                + " (requirer="
9264                                + (requirer != null ? requirer.pkg : "null")
9265                                + ", scannedPackage="
9266                                + (scannedPackage != null ? scannedPackage : "null")
9267                                + ")");
9268                        try {
9269                            mInstaller.rmdex(ps.codePathString,
9270                                    getDexCodeInstructionSet(getPreferredInstructionSet()));
9271                        } catch (InstallerException ignored) {
9272                        }
9273                    }
9274                }
9275            }
9276        }
9277    }
9278
9279    private void setUpCustomResolverActivity(PackageParser.Package pkg) {
9280        synchronized (mPackages) {
9281            mResolverReplaced = true;
9282            // Set up information for custom user intent resolution activity.
9283            mResolveActivity.applicationInfo = pkg.applicationInfo;
9284            mResolveActivity.name = mCustomResolverComponentName.getClassName();
9285            mResolveActivity.packageName = pkg.applicationInfo.packageName;
9286            mResolveActivity.processName = pkg.applicationInfo.packageName;
9287            mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
9288            mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS |
9289                    ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
9290            mResolveActivity.theme = 0;
9291            mResolveActivity.exported = true;
9292            mResolveActivity.enabled = true;
9293            mResolveInfo.activityInfo = mResolveActivity;
9294            mResolveInfo.priority = 0;
9295            mResolveInfo.preferredOrder = 0;
9296            mResolveInfo.match = 0;
9297            mResolveComponentName = mCustomResolverComponentName;
9298            Slog.i(TAG, "Replacing default ResolverActivity with custom activity: " +
9299                    mResolveComponentName);
9300        }
9301    }
9302
9303    private void setUpEphemeralInstallerActivityLP(ComponentName installerComponent) {
9304        final PackageParser.Package pkg = mPackages.get(installerComponent.getPackageName());
9305
9306        // Set up information for ephemeral installer activity
9307        mEphemeralInstallerActivity.applicationInfo = pkg.applicationInfo;
9308        mEphemeralInstallerActivity.name = mEphemeralInstallerComponent.getClassName();
9309        mEphemeralInstallerActivity.packageName = pkg.applicationInfo.packageName;
9310        mEphemeralInstallerActivity.processName = pkg.applicationInfo.packageName;
9311        mEphemeralInstallerActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
9312        mEphemeralInstallerActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS
9313                | ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
9314        mEphemeralInstallerActivity.theme = 0;
9315        mEphemeralInstallerActivity.exported = true;
9316        mEphemeralInstallerActivity.enabled = true;
9317        mEphemeralInstallerInfo.activityInfo = mEphemeralInstallerActivity;
9318        mEphemeralInstallerInfo.priority = 0;
9319        mEphemeralInstallerInfo.preferredOrder = 1;
9320        mEphemeralInstallerInfo.isDefault = true;
9321        mEphemeralInstallerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
9322                | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
9323
9324        if (DEBUG_EPHEMERAL) {
9325            Slog.d(TAG, "Set ephemeral installer activity: " + mEphemeralInstallerComponent);
9326        }
9327    }
9328
9329    private static String calculateBundledApkRoot(final String codePathString) {
9330        final File codePath = new File(codePathString);
9331        final File codeRoot;
9332        if (FileUtils.contains(Environment.getRootDirectory(), codePath)) {
9333            codeRoot = Environment.getRootDirectory();
9334        } else if (FileUtils.contains(Environment.getOemDirectory(), codePath)) {
9335            codeRoot = Environment.getOemDirectory();
9336        } else if (FileUtils.contains(Environment.getVendorDirectory(), codePath)) {
9337            codeRoot = Environment.getVendorDirectory();
9338        } else {
9339            // Unrecognized code path; take its top real segment as the apk root:
9340            // e.g. /something/app/blah.apk => /something
9341            try {
9342                File f = codePath.getCanonicalFile();
9343                File parent = f.getParentFile();    // non-null because codePath is a file
9344                File tmp;
9345                while ((tmp = parent.getParentFile()) != null) {
9346                    f = parent;
9347                    parent = tmp;
9348                }
9349                codeRoot = f;
9350                Slog.w(TAG, "Unrecognized code path "
9351                        + codePath + " - using " + codeRoot);
9352            } catch (IOException e) {
9353                // Can't canonicalize the code path -- shenanigans?
9354                Slog.w(TAG, "Can't canonicalize code path " + codePath);
9355                return Environment.getRootDirectory().getPath();
9356            }
9357        }
9358        return codeRoot.getPath();
9359    }
9360
9361    /**
9362     * Derive and set the location of native libraries for the given package,
9363     * which varies depending on where and how the package was installed.
9364     */
9365    private void setNativeLibraryPaths(PackageParser.Package pkg) {
9366        final ApplicationInfo info = pkg.applicationInfo;
9367        final String codePath = pkg.codePath;
9368        final File codeFile = new File(codePath);
9369        final boolean bundledApp = info.isSystemApp() && !info.isUpdatedSystemApp();
9370        final boolean asecApp = info.isForwardLocked() || info.isExternalAsec();
9371
9372        info.nativeLibraryRootDir = null;
9373        info.nativeLibraryRootRequiresIsa = false;
9374        info.nativeLibraryDir = null;
9375        info.secondaryNativeLibraryDir = null;
9376
9377        if (isApkFile(codeFile)) {
9378            // Monolithic install
9379            if (bundledApp) {
9380                // If "/system/lib64/apkname" exists, assume that is the per-package
9381                // native library directory to use; otherwise use "/system/lib/apkname".
9382                final String apkRoot = calculateBundledApkRoot(info.sourceDir);
9383                final boolean is64Bit = VMRuntime.is64BitInstructionSet(
9384                        getPrimaryInstructionSet(info));
9385
9386                // This is a bundled system app so choose the path based on the ABI.
9387                // if it's a 64 bit abi, use lib64 otherwise use lib32. Note that this
9388                // is just the default path.
9389                final String apkName = deriveCodePathName(codePath);
9390                final String libDir = is64Bit ? LIB64_DIR_NAME : LIB_DIR_NAME;
9391                info.nativeLibraryRootDir = Environment.buildPath(new File(apkRoot), libDir,
9392                        apkName).getAbsolutePath();
9393
9394                if (info.secondaryCpuAbi != null) {
9395                    final String secondaryLibDir = is64Bit ? LIB_DIR_NAME : LIB64_DIR_NAME;
9396                    info.secondaryNativeLibraryDir = Environment.buildPath(new File(apkRoot),
9397                            secondaryLibDir, apkName).getAbsolutePath();
9398                }
9399            } else if (asecApp) {
9400                info.nativeLibraryRootDir = new File(codeFile.getParentFile(), LIB_DIR_NAME)
9401                        .getAbsolutePath();
9402            } else {
9403                final String apkName = deriveCodePathName(codePath);
9404                info.nativeLibraryRootDir = new File(mAppLib32InstallDir, apkName)
9405                        .getAbsolutePath();
9406            }
9407
9408            info.nativeLibraryRootRequiresIsa = false;
9409            info.nativeLibraryDir = info.nativeLibraryRootDir;
9410        } else {
9411            // Cluster install
9412            info.nativeLibraryRootDir = new File(codeFile, LIB_DIR_NAME).getAbsolutePath();
9413            info.nativeLibraryRootRequiresIsa = true;
9414
9415            info.nativeLibraryDir = new File(info.nativeLibraryRootDir,
9416                    getPrimaryInstructionSet(info)).getAbsolutePath();
9417
9418            if (info.secondaryCpuAbi != null) {
9419                info.secondaryNativeLibraryDir = new File(info.nativeLibraryRootDir,
9420                        VMRuntime.getInstructionSet(info.secondaryCpuAbi)).getAbsolutePath();
9421            }
9422        }
9423    }
9424
9425    /**
9426     * Calculate the abis and roots for a bundled app. These can uniquely
9427     * be determined from the contents of the system partition, i.e whether
9428     * it contains 64 or 32 bit shared libraries etc. We do not validate any
9429     * of this information, and instead assume that the system was built
9430     * sensibly.
9431     */
9432    private void setBundledAppAbisAndRoots(PackageParser.Package pkg,
9433                                           PackageSetting pkgSetting) {
9434        final String apkName = deriveCodePathName(pkg.applicationInfo.getCodePath());
9435
9436        // If "/system/lib64/apkname" exists, assume that is the per-package
9437        // native library directory to use; otherwise use "/system/lib/apkname".
9438        final String apkRoot = calculateBundledApkRoot(pkg.applicationInfo.sourceDir);
9439        setBundledAppAbi(pkg, apkRoot, apkName);
9440        // pkgSetting might be null during rescan following uninstall of updates
9441        // to a bundled app, so accommodate that possibility.  The settings in
9442        // that case will be established later from the parsed package.
9443        //
9444        // If the settings aren't null, sync them up with what we've just derived.
9445        // note that apkRoot isn't stored in the package settings.
9446        if (pkgSetting != null) {
9447            pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
9448            pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
9449        }
9450    }
9451
9452    /**
9453     * Deduces the ABI of a bundled app and sets the relevant fields on the
9454     * parsed pkg object.
9455     *
9456     * @param apkRoot the root of the installed apk, something like {@code /system} or {@code /oem}
9457     *        under which system libraries are installed.
9458     * @param apkName the name of the installed package.
9459     */
9460    private static void setBundledAppAbi(PackageParser.Package pkg, String apkRoot, String apkName) {
9461        final File codeFile = new File(pkg.codePath);
9462
9463        final boolean has64BitLibs;
9464        final boolean has32BitLibs;
9465        if (isApkFile(codeFile)) {
9466            // Monolithic install
9467            has64BitLibs = (new File(apkRoot, new File(LIB64_DIR_NAME, apkName).getPath())).exists();
9468            has32BitLibs = (new File(apkRoot, new File(LIB_DIR_NAME, apkName).getPath())).exists();
9469        } else {
9470            // Cluster install
9471            final File rootDir = new File(codeFile, LIB_DIR_NAME);
9472            if (!ArrayUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS)
9473                    && !TextUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS[0])) {
9474                final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_64_BIT_ABIS[0]);
9475                has64BitLibs = (new File(rootDir, isa)).exists();
9476            } else {
9477                has64BitLibs = false;
9478            }
9479            if (!ArrayUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS)
9480                    && !TextUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS[0])) {
9481                final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_32_BIT_ABIS[0]);
9482                has32BitLibs = (new File(rootDir, isa)).exists();
9483            } else {
9484                has32BitLibs = false;
9485            }
9486        }
9487
9488        if (has64BitLibs && !has32BitLibs) {
9489            // The package has 64 bit libs, but not 32 bit libs. Its primary
9490            // ABI should be 64 bit. We can safely assume here that the bundled
9491            // native libraries correspond to the most preferred ABI in the list.
9492
9493            pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
9494            pkg.applicationInfo.secondaryCpuAbi = null;
9495        } else if (has32BitLibs && !has64BitLibs) {
9496            // The package has 32 bit libs but not 64 bit libs. Its primary
9497            // ABI should be 32 bit.
9498
9499            pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
9500            pkg.applicationInfo.secondaryCpuAbi = null;
9501        } else if (has32BitLibs && has64BitLibs) {
9502            // The application has both 64 and 32 bit bundled libraries. We check
9503            // here that the app declares multiArch support, and warn if it doesn't.
9504            //
9505            // We will be lenient here and record both ABIs. The primary will be the
9506            // ABI that's higher on the list, i.e, a device that's configured to prefer
9507            // 64 bit apps will see a 64 bit primary ABI,
9508
9509            if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) == 0) {
9510                Slog.e(TAG, "Package " + pkg + " has multiple bundled libs, but is not multiarch.");
9511            }
9512
9513            if (VMRuntime.is64BitInstructionSet(getPreferredInstructionSet())) {
9514                pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
9515                pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
9516            } else {
9517                pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
9518                pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
9519            }
9520        } else {
9521            pkg.applicationInfo.primaryCpuAbi = null;
9522            pkg.applicationInfo.secondaryCpuAbi = null;
9523        }
9524    }
9525
9526    private void killApplication(String pkgName, int appId, String reason) {
9527        killApplication(pkgName, appId, UserHandle.USER_ALL, reason);
9528    }
9529
9530    private void killApplication(String pkgName, int appId, int userId, String reason) {
9531        // Request the ActivityManager to kill the process(only for existing packages)
9532        // so that we do not end up in a confused state while the user is still using the older
9533        // version of the application while the new one gets installed.
9534        final long token = Binder.clearCallingIdentity();
9535        try {
9536            IActivityManager am = ActivityManagerNative.getDefault();
9537            if (am != null) {
9538                try {
9539                    am.killApplication(pkgName, appId, userId, reason);
9540                } catch (RemoteException e) {
9541                }
9542            }
9543        } finally {
9544            Binder.restoreCallingIdentity(token);
9545        }
9546    }
9547
9548    private void removePackageLI(PackageParser.Package pkg, boolean chatty) {
9549        // Remove the parent package setting
9550        PackageSetting ps = (PackageSetting) pkg.mExtras;
9551        if (ps != null) {
9552            removePackageLI(ps, chatty);
9553        }
9554        // Remove the child package setting
9555        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9556        for (int i = 0; i < childCount; i++) {
9557            PackageParser.Package childPkg = pkg.childPackages.get(i);
9558            ps = (PackageSetting) childPkg.mExtras;
9559            if (ps != null) {
9560                removePackageLI(ps, chatty);
9561            }
9562        }
9563    }
9564
9565    void removePackageLI(PackageSetting ps, boolean chatty) {
9566        if (DEBUG_INSTALL) {
9567            if (chatty)
9568                Log.d(TAG, "Removing package " + ps.name);
9569        }
9570
9571        // writer
9572        synchronized (mPackages) {
9573            mPackages.remove(ps.name);
9574            final PackageParser.Package pkg = ps.pkg;
9575            if (pkg != null) {
9576                cleanPackageDataStructuresLILPw(pkg, chatty);
9577            }
9578        }
9579    }
9580
9581    void removeInstalledPackageLI(PackageParser.Package pkg, boolean chatty) {
9582        if (DEBUG_INSTALL) {
9583            if (chatty)
9584                Log.d(TAG, "Removing package " + pkg.applicationInfo.packageName);
9585        }
9586
9587        // writer
9588        synchronized (mPackages) {
9589            // Remove the parent package
9590            mPackages.remove(pkg.applicationInfo.packageName);
9591            cleanPackageDataStructuresLILPw(pkg, chatty);
9592
9593            // Remove the child packages
9594            final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9595            for (int i = 0; i < childCount; i++) {
9596                PackageParser.Package childPkg = pkg.childPackages.get(i);
9597                mPackages.remove(childPkg.applicationInfo.packageName);
9598                cleanPackageDataStructuresLILPw(childPkg, chatty);
9599            }
9600        }
9601    }
9602
9603    void cleanPackageDataStructuresLILPw(PackageParser.Package pkg, boolean chatty) {
9604        int N = pkg.providers.size();
9605        StringBuilder r = null;
9606        int i;
9607        for (i=0; i<N; i++) {
9608            PackageParser.Provider p = pkg.providers.get(i);
9609            mProviders.removeProvider(p);
9610            if (p.info.authority == null) {
9611
9612                /* There was another ContentProvider with this authority when
9613                 * this app was installed so this authority is null,
9614                 * Ignore it as we don't have to unregister the provider.
9615                 */
9616                continue;
9617            }
9618            String names[] = p.info.authority.split(";");
9619            for (int j = 0; j < names.length; j++) {
9620                if (mProvidersByAuthority.get(names[j]) == p) {
9621                    mProvidersByAuthority.remove(names[j]);
9622                    if (DEBUG_REMOVE) {
9623                        if (chatty)
9624                            Log.d(TAG, "Unregistered content provider: " + names[j]
9625                                    + ", className = " + p.info.name + ", isSyncable = "
9626                                    + p.info.isSyncable);
9627                    }
9628                }
9629            }
9630            if (DEBUG_REMOVE && chatty) {
9631                if (r == null) {
9632                    r = new StringBuilder(256);
9633                } else {
9634                    r.append(' ');
9635                }
9636                r.append(p.info.name);
9637            }
9638        }
9639        if (r != null) {
9640            if (DEBUG_REMOVE) Log.d(TAG, "  Providers: " + r);
9641        }
9642
9643        N = pkg.services.size();
9644        r = null;
9645        for (i=0; i<N; i++) {
9646            PackageParser.Service s = pkg.services.get(i);
9647            mServices.removeService(s);
9648            if (chatty) {
9649                if (r == null) {
9650                    r = new StringBuilder(256);
9651                } else {
9652                    r.append(' ');
9653                }
9654                r.append(s.info.name);
9655            }
9656        }
9657        if (r != null) {
9658            if (DEBUG_REMOVE) Log.d(TAG, "  Services: " + r);
9659        }
9660
9661        N = pkg.receivers.size();
9662        r = null;
9663        for (i=0; i<N; i++) {
9664            PackageParser.Activity a = pkg.receivers.get(i);
9665            mReceivers.removeActivity(a, "receiver");
9666            if (DEBUG_REMOVE && chatty) {
9667                if (r == null) {
9668                    r = new StringBuilder(256);
9669                } else {
9670                    r.append(' ');
9671                }
9672                r.append(a.info.name);
9673            }
9674        }
9675        if (r != null) {
9676            if (DEBUG_REMOVE) Log.d(TAG, "  Receivers: " + r);
9677        }
9678
9679        N = pkg.activities.size();
9680        r = null;
9681        for (i=0; i<N; i++) {
9682            PackageParser.Activity a = pkg.activities.get(i);
9683            mActivities.removeActivity(a, "activity");
9684            if (DEBUG_REMOVE && chatty) {
9685                if (r == null) {
9686                    r = new StringBuilder(256);
9687                } else {
9688                    r.append(' ');
9689                }
9690                r.append(a.info.name);
9691            }
9692        }
9693        if (r != null) {
9694            if (DEBUG_REMOVE) Log.d(TAG, "  Activities: " + r);
9695        }
9696
9697        N = pkg.permissions.size();
9698        r = null;
9699        for (i=0; i<N; i++) {
9700            PackageParser.Permission p = pkg.permissions.get(i);
9701            BasePermission bp = mSettings.mPermissions.get(p.info.name);
9702            if (bp == null) {
9703                bp = mSettings.mPermissionTrees.get(p.info.name);
9704            }
9705            if (bp != null && bp.perm == p) {
9706                bp.perm = null;
9707                if (DEBUG_REMOVE && chatty) {
9708                    if (r == null) {
9709                        r = new StringBuilder(256);
9710                    } else {
9711                        r.append(' ');
9712                    }
9713                    r.append(p.info.name);
9714                }
9715            }
9716            if ((p.info.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
9717                ArraySet<String> appOpPkgs = mAppOpPermissionPackages.get(p.info.name);
9718                if (appOpPkgs != null) {
9719                    appOpPkgs.remove(pkg.packageName);
9720                }
9721            }
9722        }
9723        if (r != null) {
9724            if (DEBUG_REMOVE) Log.d(TAG, "  Permissions: " + r);
9725        }
9726
9727        N = pkg.requestedPermissions.size();
9728        r = null;
9729        for (i=0; i<N; i++) {
9730            String perm = pkg.requestedPermissions.get(i);
9731            BasePermission bp = mSettings.mPermissions.get(perm);
9732            if (bp != null && (bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
9733                ArraySet<String> appOpPkgs = mAppOpPermissionPackages.get(perm);
9734                if (appOpPkgs != null) {
9735                    appOpPkgs.remove(pkg.packageName);
9736                    if (appOpPkgs.isEmpty()) {
9737                        mAppOpPermissionPackages.remove(perm);
9738                    }
9739                }
9740            }
9741        }
9742        if (r != null) {
9743            if (DEBUG_REMOVE) Log.d(TAG, "  Permissions: " + r);
9744        }
9745
9746        N = pkg.instrumentation.size();
9747        r = null;
9748        for (i=0; i<N; i++) {
9749            PackageParser.Instrumentation a = pkg.instrumentation.get(i);
9750            mInstrumentation.remove(a.getComponentName());
9751            if (DEBUG_REMOVE && chatty) {
9752                if (r == null) {
9753                    r = new StringBuilder(256);
9754                } else {
9755                    r.append(' ');
9756                }
9757                r.append(a.info.name);
9758            }
9759        }
9760        if (r != null) {
9761            if (DEBUG_REMOVE) Log.d(TAG, "  Instrumentation: " + r);
9762        }
9763
9764        r = null;
9765        if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
9766            // Only system apps can hold shared libraries.
9767            if (pkg.libraryNames != null) {
9768                for (i=0; i<pkg.libraryNames.size(); i++) {
9769                    String name = pkg.libraryNames.get(i);
9770                    SharedLibraryEntry cur = mSharedLibraries.get(name);
9771                    if (cur != null && cur.apk != null && cur.apk.equals(pkg.packageName)) {
9772                        mSharedLibraries.remove(name);
9773                        if (DEBUG_REMOVE && chatty) {
9774                            if (r == null) {
9775                                r = new StringBuilder(256);
9776                            } else {
9777                                r.append(' ');
9778                            }
9779                            r.append(name);
9780                        }
9781                    }
9782                }
9783            }
9784        }
9785        if (r != null) {
9786            if (DEBUG_REMOVE) Log.d(TAG, "  Libraries: " + r);
9787        }
9788    }
9789
9790    private static boolean hasPermission(PackageParser.Package pkgInfo, String perm) {
9791        for (int i=pkgInfo.permissions.size()-1; i>=0; i--) {
9792            if (pkgInfo.permissions.get(i).info.name.equals(perm)) {
9793                return true;
9794            }
9795        }
9796        return false;
9797    }
9798
9799    static final int UPDATE_PERMISSIONS_ALL = 1<<0;
9800    static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1<<1;
9801    static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1<<2;
9802
9803    private void updatePermissionsLPw(PackageParser.Package pkg, int flags) {
9804        // Update the parent permissions
9805        updatePermissionsLPw(pkg.packageName, pkg, flags);
9806        // Update the child permissions
9807        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9808        for (int i = 0; i < childCount; i++) {
9809            PackageParser.Package childPkg = pkg.childPackages.get(i);
9810            updatePermissionsLPw(childPkg.packageName, childPkg, flags);
9811        }
9812    }
9813
9814    private void updatePermissionsLPw(String changingPkg, PackageParser.Package pkgInfo,
9815            int flags) {
9816        final String volumeUuid = (pkgInfo != null) ? getVolumeUuidForPackage(pkgInfo) : null;
9817        updatePermissionsLPw(changingPkg, pkgInfo, volumeUuid, flags);
9818    }
9819
9820    private void updatePermissionsLPw(String changingPkg,
9821            PackageParser.Package pkgInfo, String replaceVolumeUuid, int flags) {
9822        // Make sure there are no dangling permission trees.
9823        Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator();
9824        while (it.hasNext()) {
9825            final BasePermission bp = it.next();
9826            if (bp.packageSetting == null) {
9827                // We may not yet have parsed the package, so just see if
9828                // we still know about its settings.
9829                bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage);
9830            }
9831            if (bp.packageSetting == null) {
9832                Slog.w(TAG, "Removing dangling permission tree: " + bp.name
9833                        + " from package " + bp.sourcePackage);
9834                it.remove();
9835            } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) {
9836                if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
9837                    Slog.i(TAG, "Removing old permission tree: " + bp.name
9838                            + " from package " + bp.sourcePackage);
9839                    flags |= UPDATE_PERMISSIONS_ALL;
9840                    it.remove();
9841                }
9842            }
9843        }
9844
9845        // Make sure all dynamic permissions have been assigned to a package,
9846        // and make sure there are no dangling permissions.
9847        it = mSettings.mPermissions.values().iterator();
9848        while (it.hasNext()) {
9849            final BasePermission bp = it.next();
9850            if (bp.type == BasePermission.TYPE_DYNAMIC) {
9851                if (DEBUG_SETTINGS) Log.v(TAG, "Dynamic permission: name="
9852                        + bp.name + " pkg=" + bp.sourcePackage
9853                        + " info=" + bp.pendingInfo);
9854                if (bp.packageSetting == null && bp.pendingInfo != null) {
9855                    final BasePermission tree = findPermissionTreeLP(bp.name);
9856                    if (tree != null && tree.perm != null) {
9857                        bp.packageSetting = tree.packageSetting;
9858                        bp.perm = new PackageParser.Permission(tree.perm.owner,
9859                                new PermissionInfo(bp.pendingInfo));
9860                        bp.perm.info.packageName = tree.perm.info.packageName;
9861                        bp.perm.info.name = bp.name;
9862                        bp.uid = tree.uid;
9863                    }
9864                }
9865            }
9866            if (bp.packageSetting == null) {
9867                // We may not yet have parsed the package, so just see if
9868                // we still know about its settings.
9869                bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage);
9870            }
9871            if (bp.packageSetting == null) {
9872                Slog.w(TAG, "Removing dangling permission: " + bp.name
9873                        + " from package " + bp.sourcePackage);
9874                it.remove();
9875            } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) {
9876                if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
9877                    Slog.i(TAG, "Removing old permission: " + bp.name
9878                            + " from package " + bp.sourcePackage);
9879                    flags |= UPDATE_PERMISSIONS_ALL;
9880                    it.remove();
9881                }
9882            }
9883        }
9884
9885        // Now update the permissions for all packages, in particular
9886        // replace the granted permissions of the system packages.
9887        if ((flags&UPDATE_PERMISSIONS_ALL) != 0) {
9888            for (PackageParser.Package pkg : mPackages.values()) {
9889                if (pkg != pkgInfo) {
9890                    // Only replace for packages on requested volume
9891                    final String volumeUuid = getVolumeUuidForPackage(pkg);
9892                    final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_ALL) != 0)
9893                            && Objects.equals(replaceVolumeUuid, volumeUuid);
9894                    grantPermissionsLPw(pkg, replace, changingPkg);
9895                }
9896            }
9897        }
9898
9899        if (pkgInfo != null) {
9900            // Only replace for packages on requested volume
9901            final String volumeUuid = getVolumeUuidForPackage(pkgInfo);
9902            final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_PKG) != 0)
9903                    && Objects.equals(replaceVolumeUuid, volumeUuid);
9904            grantPermissionsLPw(pkgInfo, replace, changingPkg);
9905        }
9906    }
9907
9908    private void grantPermissionsLPw(PackageParser.Package pkg, boolean replace,
9909            String packageOfInterest) {
9910        // IMPORTANT: There are two types of permissions: install and runtime.
9911        // Install time permissions are granted when the app is installed to
9912        // all device users and users added in the future. Runtime permissions
9913        // are granted at runtime explicitly to specific users. Normal and signature
9914        // protected permissions are install time permissions. Dangerous permissions
9915        // are install permissions if the app's target SDK is Lollipop MR1 or older,
9916        // otherwise they are runtime permissions. This function does not manage
9917        // runtime permissions except for the case an app targeting Lollipop MR1
9918        // being upgraded to target a newer SDK, in which case dangerous permissions
9919        // are transformed from install time to runtime ones.
9920
9921        final PackageSetting ps = (PackageSetting) pkg.mExtras;
9922        if (ps == null) {
9923            return;
9924        }
9925
9926        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "grantPermissions");
9927
9928        PermissionsState permissionsState = ps.getPermissionsState();
9929        PermissionsState origPermissions = permissionsState;
9930
9931        final int[] currentUserIds = UserManagerService.getInstance().getUserIds();
9932
9933        boolean runtimePermissionsRevoked = false;
9934        int[] changedRuntimePermissionUserIds = EMPTY_INT_ARRAY;
9935
9936        boolean changedInstallPermission = false;
9937
9938        if (replace) {
9939            ps.installPermissionsFixed = false;
9940            if (!ps.isSharedUser()) {
9941                origPermissions = new PermissionsState(permissionsState);
9942                permissionsState.reset();
9943            } else {
9944                // We need to know only about runtime permission changes since the
9945                // calling code always writes the install permissions state but
9946                // the runtime ones are written only if changed. The only cases of
9947                // changed runtime permissions here are promotion of an install to
9948                // runtime and revocation of a runtime from a shared user.
9949                changedRuntimePermissionUserIds = revokeUnusedSharedUserPermissionsLPw(
9950                        ps.sharedUser, UserManagerService.getInstance().getUserIds());
9951                if (!ArrayUtils.isEmpty(changedRuntimePermissionUserIds)) {
9952                    runtimePermissionsRevoked = true;
9953                }
9954            }
9955        }
9956
9957        permissionsState.setGlobalGids(mGlobalGids);
9958
9959        final int N = pkg.requestedPermissions.size();
9960        for (int i=0; i<N; i++) {
9961            final String name = pkg.requestedPermissions.get(i);
9962            final BasePermission bp = mSettings.mPermissions.get(name);
9963
9964            if (DEBUG_INSTALL) {
9965                Log.i(TAG, "Package " + pkg.packageName + " checking " + name + ": " + bp);
9966            }
9967
9968            if (bp == null || bp.packageSetting == null) {
9969                if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) {
9970                    Slog.w(TAG, "Unknown permission " + name
9971                            + " in package " + pkg.packageName);
9972                }
9973                continue;
9974            }
9975
9976            final String perm = bp.name;
9977            boolean allowedSig = false;
9978            int grant = GRANT_DENIED;
9979
9980            // Keep track of app op permissions.
9981            if ((bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
9982                ArraySet<String> pkgs = mAppOpPermissionPackages.get(bp.name);
9983                if (pkgs == null) {
9984                    pkgs = new ArraySet<>();
9985                    mAppOpPermissionPackages.put(bp.name, pkgs);
9986                }
9987                pkgs.add(pkg.packageName);
9988            }
9989
9990            final int level = bp.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE;
9991            final boolean appSupportsRuntimePermissions = pkg.applicationInfo.targetSdkVersion
9992                    >= Build.VERSION_CODES.M;
9993            switch (level) {
9994                case PermissionInfo.PROTECTION_NORMAL: {
9995                    // For all apps normal permissions are install time ones.
9996                    grant = GRANT_INSTALL;
9997                } break;
9998
9999                case PermissionInfo.PROTECTION_DANGEROUS: {
10000                    // If a permission review is required for legacy apps we represent
10001                    // their permissions as always granted runtime ones since we need
10002                    // to keep the review required permission flag per user while an
10003                    // install permission's state is shared across all users.
10004                    if (!appSupportsRuntimePermissions && !mPermissionReviewRequired
10005                            && !Build.PERMISSIONS_REVIEW_REQUIRED) {
10006                        // For legacy apps dangerous permissions are install time ones.
10007                        grant = GRANT_INSTALL;
10008                    } else if (origPermissions.hasInstallPermission(bp.name)) {
10009                        // For legacy apps that became modern, install becomes runtime.
10010                        grant = GRANT_UPGRADE;
10011                    } else if (mPromoteSystemApps
10012                            && isSystemApp(ps)
10013                            && mExistingSystemPackages.contains(ps.name)) {
10014                        // For legacy system apps, install becomes runtime.
10015                        // We cannot check hasInstallPermission() for system apps since those
10016                        // permissions were granted implicitly and not persisted pre-M.
10017                        grant = GRANT_UPGRADE;
10018                    } else {
10019                        // For modern apps keep runtime permissions unchanged.
10020                        grant = GRANT_RUNTIME;
10021                    }
10022                } break;
10023
10024                case PermissionInfo.PROTECTION_SIGNATURE: {
10025                    // For all apps signature permissions are install time ones.
10026                    allowedSig = grantSignaturePermission(perm, pkg, bp, origPermissions);
10027                    if (allowedSig) {
10028                        grant = GRANT_INSTALL;
10029                    }
10030                } break;
10031            }
10032
10033            if (DEBUG_INSTALL) {
10034                Log.i(TAG, "Package " + pkg.packageName + " granting " + perm);
10035            }
10036
10037            if (grant != GRANT_DENIED) {
10038                if (!isSystemApp(ps) && ps.installPermissionsFixed) {
10039                    // If this is an existing, non-system package, then
10040                    // we can't add any new permissions to it.
10041                    if (!allowedSig && !origPermissions.hasInstallPermission(perm)) {
10042                        // Except...  if this is a permission that was added
10043                        // to the platform (note: need to only do this when
10044                        // updating the platform).
10045                        if (!isNewPlatformPermissionForPackage(perm, pkg)) {
10046                            grant = GRANT_DENIED;
10047                        }
10048                    }
10049                }
10050
10051                switch (grant) {
10052                    case GRANT_INSTALL: {
10053                        // Revoke this as runtime permission to handle the case of
10054                        // a runtime permission being downgraded to an install one.
10055                        // Also in permission review mode we keep dangerous permissions
10056                        // for legacy apps
10057                        for (int userId : UserManagerService.getInstance().getUserIds()) {
10058                            if (origPermissions.getRuntimePermissionState(
10059                                    bp.name, userId) != null) {
10060                                // Revoke the runtime permission and clear the flags.
10061                                origPermissions.revokeRuntimePermission(bp, userId);
10062                                origPermissions.updatePermissionFlags(bp, userId,
10063                                      PackageManager.MASK_PERMISSION_FLAGS, 0);
10064                                // If we revoked a permission permission, we have to write.
10065                                changedRuntimePermissionUserIds = ArrayUtils.appendInt(
10066                                        changedRuntimePermissionUserIds, userId);
10067                            }
10068                        }
10069                        // Grant an install permission.
10070                        if (permissionsState.grantInstallPermission(bp) !=
10071                                PermissionsState.PERMISSION_OPERATION_FAILURE) {
10072                            changedInstallPermission = true;
10073                        }
10074                    } break;
10075
10076                    case GRANT_RUNTIME: {
10077                        // Grant previously granted runtime permissions.
10078                        for (int userId : UserManagerService.getInstance().getUserIds()) {
10079                            PermissionState permissionState = origPermissions
10080                                    .getRuntimePermissionState(bp.name, userId);
10081                            int flags = permissionState != null
10082                                    ? permissionState.getFlags() : 0;
10083                            if (origPermissions.hasRuntimePermission(bp.name, userId)) {
10084                                // Don't propagate the permission in a permission review mode if
10085                                // the former was revoked, i.e. marked to not propagate on upgrade.
10086                                // Note that in a permission review mode install permissions are
10087                                // represented as constantly granted runtime ones since we need to
10088                                // keep a per user state associated with the permission. Also the
10089                                // revoke on upgrade flag is no longer applicable and is reset.
10090                                final boolean revokeOnUpgrade = (flags & PackageManager
10091                                        .FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0;
10092                                if (revokeOnUpgrade) {
10093                                    flags &= ~PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE;
10094                                    // Since we changed the flags, we have to write.
10095                                    changedRuntimePermissionUserIds = ArrayUtils.appendInt(
10096                                            changedRuntimePermissionUserIds, userId);
10097                                }
10098                                if (!mPermissionReviewRequired || !revokeOnUpgrade) {
10099                                    if (permissionsState.grantRuntimePermission(bp, userId) ==
10100                                            PermissionsState.PERMISSION_OPERATION_FAILURE) {
10101                                        // If we cannot put the permission as it was,
10102                                        // we have to write.
10103                                        changedRuntimePermissionUserIds = ArrayUtils.appendInt(
10104                                                changedRuntimePermissionUserIds, userId);
10105                                    }
10106                                }
10107
10108                                // If the app supports runtime permissions no need for a review.
10109                                if ((mPermissionReviewRequired || Build.PERMISSIONS_REVIEW_REQUIRED)
10110                                        && appSupportsRuntimePermissions
10111                                        && (flags & PackageManager
10112                                                .FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
10113                                    flags &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
10114                                    // Since we changed the flags, we have to write.
10115                                    changedRuntimePermissionUserIds = ArrayUtils.appendInt(
10116                                            changedRuntimePermissionUserIds, userId);
10117                                }
10118                            } else if ((mPermissionReviewRequired
10119                                        || Build.PERMISSIONS_REVIEW_REQUIRED)
10120                                    && !appSupportsRuntimePermissions) {
10121                                // For legacy apps that need a permission review, every new
10122                                // runtime permission is granted but it is pending a review.
10123                                // We also need to review only platform defined runtime
10124                                // permissions as these are the only ones the platform knows
10125                                // how to disable the API to simulate revocation as legacy
10126                                // apps don't expect to run with revoked permissions.
10127                                if (PLATFORM_PACKAGE_NAME.equals(bp.sourcePackage)) {
10128                                    if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) {
10129                                        flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
10130                                        // We changed the flags, hence have to write.
10131                                        changedRuntimePermissionUserIds = ArrayUtils.appendInt(
10132                                                changedRuntimePermissionUserIds, userId);
10133                                    }
10134                                }
10135                                if (permissionsState.grantRuntimePermission(bp, userId)
10136                                        != PermissionsState.PERMISSION_OPERATION_FAILURE) {
10137                                    // We changed the permission, hence have to write.
10138                                    changedRuntimePermissionUserIds = ArrayUtils.appendInt(
10139                                            changedRuntimePermissionUserIds, userId);
10140                                }
10141                            }
10142                            // Propagate the permission flags.
10143                            permissionsState.updatePermissionFlags(bp, userId, flags, flags);
10144                        }
10145                    } break;
10146
10147                    case GRANT_UPGRADE: {
10148                        // Grant runtime permissions for a previously held install permission.
10149                        PermissionState permissionState = origPermissions
10150                                .getInstallPermissionState(bp.name);
10151                        final int flags = permissionState != null ? permissionState.getFlags() : 0;
10152
10153                        if (origPermissions.revokeInstallPermission(bp)
10154                                != PermissionsState.PERMISSION_OPERATION_FAILURE) {
10155                            // We will be transferring the permission flags, so clear them.
10156                            origPermissions.updatePermissionFlags(bp, UserHandle.USER_ALL,
10157                                    PackageManager.MASK_PERMISSION_FLAGS, 0);
10158                            changedInstallPermission = true;
10159                        }
10160
10161                        // If the permission is not to be promoted to runtime we ignore it and
10162                        // also its other flags as they are not applicable to install permissions.
10163                        if ((flags & PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE) == 0) {
10164                            for (int userId : currentUserIds) {
10165                                if (permissionsState.grantRuntimePermission(bp, userId) !=
10166                                        PermissionsState.PERMISSION_OPERATION_FAILURE) {
10167                                    // Transfer the permission flags.
10168                                    permissionsState.updatePermissionFlags(bp, userId,
10169                                            flags, flags);
10170                                    // If we granted the permission, we have to write.
10171                                    changedRuntimePermissionUserIds = ArrayUtils.appendInt(
10172                                            changedRuntimePermissionUserIds, userId);
10173                                }
10174                            }
10175                        }
10176                    } break;
10177
10178                    default: {
10179                        if (packageOfInterest == null
10180                                || packageOfInterest.equals(pkg.packageName)) {
10181                            Slog.w(TAG, "Not granting permission " + perm
10182                                    + " to package " + pkg.packageName
10183                                    + " because it was previously installed without");
10184                        }
10185                    } break;
10186                }
10187            } else {
10188                if (permissionsState.revokeInstallPermission(bp) !=
10189                        PermissionsState.PERMISSION_OPERATION_FAILURE) {
10190                    // Also drop the permission flags.
10191                    permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
10192                            PackageManager.MASK_PERMISSION_FLAGS, 0);
10193                    changedInstallPermission = true;
10194                    Slog.i(TAG, "Un-granting permission " + perm
10195                            + " from package " + pkg.packageName
10196                            + " (protectionLevel=" + bp.protectionLevel
10197                            + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
10198                            + ")");
10199                } else if ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) == 0) {
10200                    // Don't print warning for app op permissions, since it is fine for them
10201                    // not to be granted, there is a UI for the user to decide.
10202                    if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) {
10203                        Slog.w(TAG, "Not granting permission " + perm
10204                                + " to package " + pkg.packageName
10205                                + " (protectionLevel=" + bp.protectionLevel
10206                                + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
10207                                + ")");
10208                    }
10209                }
10210            }
10211        }
10212
10213        if ((changedInstallPermission || replace) && !ps.installPermissionsFixed &&
10214                !isSystemApp(ps) || isUpdatedSystemApp(ps)){
10215            // This is the first that we have heard about this package, so the
10216            // permissions we have now selected are fixed until explicitly
10217            // changed.
10218            ps.installPermissionsFixed = true;
10219        }
10220
10221        // Persist the runtime permissions state for users with changes. If permissions
10222        // were revoked because no app in the shared user declares them we have to
10223        // write synchronously to avoid losing runtime permissions state.
10224        for (int userId : changedRuntimePermissionUserIds) {
10225            mSettings.writeRuntimePermissionsForUserLPr(userId, runtimePermissionsRevoked);
10226        }
10227
10228        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
10229    }
10230
10231    private boolean isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg) {
10232        boolean allowed = false;
10233        final int NP = PackageParser.NEW_PERMISSIONS.length;
10234        for (int ip=0; ip<NP; ip++) {
10235            final PackageParser.NewPermissionInfo npi
10236                    = PackageParser.NEW_PERMISSIONS[ip];
10237            if (npi.name.equals(perm)
10238                    && pkg.applicationInfo.targetSdkVersion < npi.sdkVersion) {
10239                allowed = true;
10240                Log.i(TAG, "Auto-granting " + perm + " to old pkg "
10241                        + pkg.packageName);
10242                break;
10243            }
10244        }
10245        return allowed;
10246    }
10247
10248    private boolean grantSignaturePermission(String perm, PackageParser.Package pkg,
10249            BasePermission bp, PermissionsState origPermissions) {
10250        boolean allowed;
10251        allowed = (compareSignatures(
10252                bp.packageSetting.signatures.mSignatures, pkg.mSignatures)
10253                        == PackageManager.SIGNATURE_MATCH)
10254                || (compareSignatures(mPlatformPackage.mSignatures, pkg.mSignatures)
10255                        == PackageManager.SIGNATURE_MATCH);
10256        if (!allowed && (bp.protectionLevel
10257                & PermissionInfo.PROTECTION_FLAG_PRIVILEGED) != 0) {
10258            if (isSystemApp(pkg)) {
10259                // For updated system applications, a system permission
10260                // is granted only if it had been defined by the original application.
10261                if (pkg.isUpdatedSystemApp()) {
10262                    final PackageSetting sysPs = mSettings
10263                            .getDisabledSystemPkgLPr(pkg.packageName);
10264                    if (sysPs != null && sysPs.getPermissionsState().hasInstallPermission(perm)) {
10265                        // If the original was granted this permission, we take
10266                        // that grant decision as read and propagate it to the
10267                        // update.
10268                        if (sysPs.isPrivileged()) {
10269                            allowed = true;
10270                        }
10271                    } else {
10272                        // The system apk may have been updated with an older
10273                        // version of the one on the data partition, but which
10274                        // granted a new system permission that it didn't have
10275                        // before.  In this case we do want to allow the app to
10276                        // now get the new permission if the ancestral apk is
10277                        // privileged to get it.
10278                        if (sysPs != null && sysPs.pkg != null && sysPs.isPrivileged()) {
10279                            for (int j = 0; j < sysPs.pkg.requestedPermissions.size(); j++) {
10280                                if (perm.equals(sysPs.pkg.requestedPermissions.get(j))) {
10281                                    allowed = true;
10282                                    break;
10283                                }
10284                            }
10285                        }
10286                        // Also if a privileged parent package on the system image or any of
10287                        // its children requested a privileged permission, the updated child
10288                        // packages can also get the permission.
10289                        if (pkg.parentPackage != null) {
10290                            final PackageSetting disabledSysParentPs = mSettings
10291                                    .getDisabledSystemPkgLPr(pkg.parentPackage.packageName);
10292                            if (disabledSysParentPs != null && disabledSysParentPs.pkg != null
10293                                    && disabledSysParentPs.isPrivileged()) {
10294                                if (isPackageRequestingPermission(disabledSysParentPs.pkg, perm)) {
10295                                    allowed = true;
10296                                } else if (disabledSysParentPs.pkg.childPackages != null) {
10297                                    final int count = disabledSysParentPs.pkg.childPackages.size();
10298                                    for (int i = 0; i < count; i++) {
10299                                        PackageParser.Package disabledSysChildPkg =
10300                                                disabledSysParentPs.pkg.childPackages.get(i);
10301                                        if (isPackageRequestingPermission(disabledSysChildPkg,
10302                                                perm)) {
10303                                            allowed = true;
10304                                            break;
10305                                        }
10306                                    }
10307                                }
10308                            }
10309                        }
10310                    }
10311                } else {
10312                    allowed = isPrivilegedApp(pkg);
10313                }
10314            }
10315        }
10316        if (!allowed) {
10317            if (!allowed && (bp.protectionLevel
10318                    & PermissionInfo.PROTECTION_FLAG_PRE23) != 0
10319                    && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
10320                // If this was a previously normal/dangerous permission that got moved
10321                // to a system permission as part of the runtime permission redesign, then
10322                // we still want to blindly grant it to old apps.
10323                allowed = true;
10324            }
10325            if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_INSTALLER) != 0
10326                    && pkg.packageName.equals(mRequiredInstallerPackage)) {
10327                // If this permission is to be granted to the system installer and
10328                // this app is an installer, then it gets the permission.
10329                allowed = true;
10330            }
10331            if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_VERIFIER) != 0
10332                    && pkg.packageName.equals(mRequiredVerifierPackage)) {
10333                // If this permission is to be granted to the system verifier and
10334                // this app is a verifier, then it gets the permission.
10335                allowed = true;
10336            }
10337            if (!allowed && (bp.protectionLevel
10338                    & PermissionInfo.PROTECTION_FLAG_PREINSTALLED) != 0
10339                    && isSystemApp(pkg)) {
10340                // Any pre-installed system app is allowed to get this permission.
10341                allowed = true;
10342            }
10343            if (!allowed && (bp.protectionLevel
10344                    & PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0) {
10345                // For development permissions, a development permission
10346                // is granted only if it was already granted.
10347                allowed = origPermissions.hasInstallPermission(perm);
10348            }
10349            if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_SETUP) != 0
10350                    && pkg.packageName.equals(mSetupWizardPackage)) {
10351                // If this permission is to be granted to the system setup wizard and
10352                // this app is a setup wizard, then it gets the permission.
10353                allowed = true;
10354            }
10355        }
10356        return allowed;
10357    }
10358
10359    private boolean isPackageRequestingPermission(PackageParser.Package pkg, String permission) {
10360        final int permCount = pkg.requestedPermissions.size();
10361        for (int j = 0; j < permCount; j++) {
10362            String requestedPermission = pkg.requestedPermissions.get(j);
10363            if (permission.equals(requestedPermission)) {
10364                return true;
10365            }
10366        }
10367        return false;
10368    }
10369
10370    final class ActivityIntentResolver
10371            extends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo> {
10372        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
10373                boolean defaultOnly, int userId) {
10374            if (!sUserManager.exists(userId)) return null;
10375            mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
10376            return super.queryIntent(intent, resolvedType, defaultOnly, userId);
10377        }
10378
10379        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
10380                int userId) {
10381            if (!sUserManager.exists(userId)) return null;
10382            mFlags = flags;
10383            return super.queryIntent(intent, resolvedType,
10384                    (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId);
10385        }
10386
10387        public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
10388                int flags, ArrayList<PackageParser.Activity> packageActivities, int userId) {
10389            if (!sUserManager.exists(userId)) return null;
10390            if (packageActivities == null) {
10391                return null;
10392            }
10393            mFlags = flags;
10394            final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0;
10395            final int N = packageActivities.size();
10396            ArrayList<PackageParser.ActivityIntentInfo[]> listCut =
10397                new ArrayList<PackageParser.ActivityIntentInfo[]>(N);
10398
10399            ArrayList<PackageParser.ActivityIntentInfo> intentFilters;
10400            for (int i = 0; i < N; ++i) {
10401                intentFilters = packageActivities.get(i).intents;
10402                if (intentFilters != null && intentFilters.size() > 0) {
10403                    PackageParser.ActivityIntentInfo[] array =
10404                            new PackageParser.ActivityIntentInfo[intentFilters.size()];
10405                    intentFilters.toArray(array);
10406                    listCut.add(array);
10407                }
10408            }
10409            return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
10410        }
10411
10412        /**
10413         * Finds a privileged activity that matches the specified activity names.
10414         */
10415        private PackageParser.Activity findMatchingActivity(
10416                List<PackageParser.Activity> activityList, ActivityInfo activityInfo) {
10417            for (PackageParser.Activity sysActivity : activityList) {
10418                if (sysActivity.info.name.equals(activityInfo.name)) {
10419                    return sysActivity;
10420                }
10421                if (sysActivity.info.name.equals(activityInfo.targetActivity)) {
10422                    return sysActivity;
10423                }
10424                if (sysActivity.info.targetActivity != null) {
10425                    if (sysActivity.info.targetActivity.equals(activityInfo.name)) {
10426                        return sysActivity;
10427                    }
10428                    if (sysActivity.info.targetActivity.equals(activityInfo.targetActivity)) {
10429                        return sysActivity;
10430                    }
10431                }
10432            }
10433            return null;
10434        }
10435
10436        public class IterGenerator<E> {
10437            public Iterator<E> generate(ActivityIntentInfo info) {
10438                return null;
10439            }
10440        }
10441
10442        public class ActionIterGenerator extends IterGenerator<String> {
10443            @Override
10444            public Iterator<String> generate(ActivityIntentInfo info) {
10445                return info.actionsIterator();
10446            }
10447        }
10448
10449        public class CategoriesIterGenerator extends IterGenerator<String> {
10450            @Override
10451            public Iterator<String> generate(ActivityIntentInfo info) {
10452                return info.categoriesIterator();
10453            }
10454        }
10455
10456        public class SchemesIterGenerator extends IterGenerator<String> {
10457            @Override
10458            public Iterator<String> generate(ActivityIntentInfo info) {
10459                return info.schemesIterator();
10460            }
10461        }
10462
10463        public class AuthoritiesIterGenerator extends IterGenerator<IntentFilter.AuthorityEntry> {
10464            @Override
10465            public Iterator<IntentFilter.AuthorityEntry> generate(ActivityIntentInfo info) {
10466                return info.authoritiesIterator();
10467            }
10468        }
10469
10470        /**
10471         * <em>WARNING</em> for performance reasons, the passed in intentList WILL BE
10472         * MODIFIED. Do not pass in a list that should not be changed.
10473         */
10474        private <T> void getIntentListSubset(List<ActivityIntentInfo> intentList,
10475                IterGenerator<T> generator, Iterator<T> searchIterator) {
10476            // loop through the set of actions; every one must be found in the intent filter
10477            while (searchIterator.hasNext()) {
10478                // we must have at least one filter in the list to consider a match
10479                if (intentList.size() == 0) {
10480                    break;
10481                }
10482
10483                final T searchAction = searchIterator.next();
10484
10485                // loop through the set of intent filters
10486                final Iterator<ActivityIntentInfo> intentIter = intentList.iterator();
10487                while (intentIter.hasNext()) {
10488                    final ActivityIntentInfo intentInfo = intentIter.next();
10489                    boolean selectionFound = false;
10490
10491                    // loop through the intent filter's selection criteria; at least one
10492                    // of them must match the searched criteria
10493                    final Iterator<T> intentSelectionIter = generator.generate(intentInfo);
10494                    while (intentSelectionIter != null && intentSelectionIter.hasNext()) {
10495                        final T intentSelection = intentSelectionIter.next();
10496                        if (intentSelection != null && intentSelection.equals(searchAction)) {
10497                            selectionFound = true;
10498                            break;
10499                        }
10500                    }
10501
10502                    // the selection criteria wasn't found in this filter's set; this filter
10503                    // is not a potential match
10504                    if (!selectionFound) {
10505                        intentIter.remove();
10506                    }
10507                }
10508            }
10509        }
10510
10511        private boolean isProtectedAction(ActivityIntentInfo filter) {
10512            final Iterator<String> actionsIter = filter.actionsIterator();
10513            while (actionsIter != null && actionsIter.hasNext()) {
10514                final String filterAction = actionsIter.next();
10515                if (PROTECTED_ACTIONS.contains(filterAction)) {
10516                    return true;
10517                }
10518            }
10519            return false;
10520        }
10521
10522        /**
10523         * Adjusts the priority of the given intent filter according to policy.
10524         * <p>
10525         * <ul>
10526         * <li>The priority for non privileged applications is capped to '0'</li>
10527         * <li>The priority for protected actions on privileged applications is capped to '0'</li>
10528         * <li>The priority for unbundled updates to privileged applications is capped to the
10529         *      priority defined on the system partition</li>
10530         * </ul>
10531         * <p>
10532         * <em>NOTE:</em> There is one exception. For security reasons, the setup wizard is
10533         * allowed to obtain any priority on any action.
10534         */
10535        private void adjustPriority(
10536                List<PackageParser.Activity> systemActivities, ActivityIntentInfo intent) {
10537            // nothing to do; priority is fine as-is
10538            if (intent.getPriority() <= 0) {
10539                return;
10540            }
10541
10542            final ActivityInfo activityInfo = intent.activity.info;
10543            final ApplicationInfo applicationInfo = activityInfo.applicationInfo;
10544
10545            final boolean privilegedApp =
10546                    ((applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0);
10547            if (!privilegedApp) {
10548                // non-privileged applications can never define a priority >0
10549                Slog.w(TAG, "Non-privileged app; cap priority to 0;"
10550                        + " package: " + applicationInfo.packageName
10551                        + " activity: " + intent.activity.className
10552                        + " origPrio: " + intent.getPriority());
10553                intent.setPriority(0);
10554                return;
10555            }
10556
10557            if (systemActivities == null) {
10558                // the system package is not disabled; we're parsing the system partition
10559                if (isProtectedAction(intent)) {
10560                    if (mDeferProtectedFilters) {
10561                        // We can't deal with these just yet. No component should ever obtain a
10562                        // >0 priority for a protected actions, with ONE exception -- the setup
10563                        // wizard. The setup wizard, however, cannot be known until we're able to
10564                        // query it for the category CATEGORY_SETUP_WIZARD. Which we can't do
10565                        // until all intent filters have been processed. Chicken, meet egg.
10566                        // Let the filter temporarily have a high priority and rectify the
10567                        // priorities after all system packages have been scanned.
10568                        mProtectedFilters.add(intent);
10569                        if (DEBUG_FILTERS) {
10570                            Slog.i(TAG, "Protected action; save for later;"
10571                                    + " package: " + applicationInfo.packageName
10572                                    + " activity: " + intent.activity.className
10573                                    + " origPrio: " + intent.getPriority());
10574                        }
10575                        return;
10576                    } else {
10577                        if (DEBUG_FILTERS && mSetupWizardPackage == null) {
10578                            Slog.i(TAG, "No setup wizard;"
10579                                + " All protected intents capped to priority 0");
10580                        }
10581                        if (intent.activity.info.packageName.equals(mSetupWizardPackage)) {
10582                            if (DEBUG_FILTERS) {
10583                                Slog.i(TAG, "Found setup wizard;"
10584                                    + " allow priority " + intent.getPriority() + ";"
10585                                    + " package: " + intent.activity.info.packageName
10586                                    + " activity: " + intent.activity.className
10587                                    + " priority: " + intent.getPriority());
10588                            }
10589                            // setup wizard gets whatever it wants
10590                            return;
10591                        }
10592                        Slog.w(TAG, "Protected action; cap priority to 0;"
10593                                + " package: " + intent.activity.info.packageName
10594                                + " activity: " + intent.activity.className
10595                                + " origPrio: " + intent.getPriority());
10596                        intent.setPriority(0);
10597                        return;
10598                    }
10599                }
10600                // privileged apps on the system image get whatever priority they request
10601                return;
10602            }
10603
10604            // privileged app unbundled update ... try to find the same activity
10605            final PackageParser.Activity foundActivity =
10606                    findMatchingActivity(systemActivities, activityInfo);
10607            if (foundActivity == null) {
10608                // this is a new activity; it cannot obtain >0 priority
10609                if (DEBUG_FILTERS) {
10610                    Slog.i(TAG, "New activity; cap priority to 0;"
10611                            + " package: " + applicationInfo.packageName
10612                            + " activity: " + intent.activity.className
10613                            + " origPrio: " + intent.getPriority());
10614                }
10615                intent.setPriority(0);
10616                return;
10617            }
10618
10619            // found activity, now check for filter equivalence
10620
10621            // a shallow copy is enough; we modify the list, not its contents
10622            final List<ActivityIntentInfo> intentListCopy =
10623                    new ArrayList<>(foundActivity.intents);
10624            final List<ActivityIntentInfo> foundFilters = findFilters(intent);
10625
10626            // find matching action subsets
10627            final Iterator<String> actionsIterator = intent.actionsIterator();
10628            if (actionsIterator != null) {
10629                getIntentListSubset(
10630                        intentListCopy, new ActionIterGenerator(), actionsIterator);
10631                if (intentListCopy.size() == 0) {
10632                    // no more intents to match; we're not equivalent
10633                    if (DEBUG_FILTERS) {
10634                        Slog.i(TAG, "Mismatched action; cap priority to 0;"
10635                                + " package: " + applicationInfo.packageName
10636                                + " activity: " + intent.activity.className
10637                                + " origPrio: " + intent.getPriority());
10638                    }
10639                    intent.setPriority(0);
10640                    return;
10641                }
10642            }
10643
10644            // find matching category subsets
10645            final Iterator<String> categoriesIterator = intent.categoriesIterator();
10646            if (categoriesIterator != null) {
10647                getIntentListSubset(intentListCopy, new CategoriesIterGenerator(),
10648                        categoriesIterator);
10649                if (intentListCopy.size() == 0) {
10650                    // no more intents to match; we're not equivalent
10651                    if (DEBUG_FILTERS) {
10652                        Slog.i(TAG, "Mismatched category; cap priority to 0;"
10653                                + " package: " + applicationInfo.packageName
10654                                + " activity: " + intent.activity.className
10655                                + " origPrio: " + intent.getPriority());
10656                    }
10657                    intent.setPriority(0);
10658                    return;
10659                }
10660            }
10661
10662            // find matching schemes subsets
10663            final Iterator<String> schemesIterator = intent.schemesIterator();
10664            if (schemesIterator != null) {
10665                getIntentListSubset(intentListCopy, new SchemesIterGenerator(),
10666                        schemesIterator);
10667                if (intentListCopy.size() == 0) {
10668                    // no more intents to match; we're not equivalent
10669                    if (DEBUG_FILTERS) {
10670                        Slog.i(TAG, "Mismatched scheme; cap priority to 0;"
10671                                + " package: " + applicationInfo.packageName
10672                                + " activity: " + intent.activity.className
10673                                + " origPrio: " + intent.getPriority());
10674                    }
10675                    intent.setPriority(0);
10676                    return;
10677                }
10678            }
10679
10680            // find matching authorities subsets
10681            final Iterator<IntentFilter.AuthorityEntry>
10682                    authoritiesIterator = intent.authoritiesIterator();
10683            if (authoritiesIterator != null) {
10684                getIntentListSubset(intentListCopy,
10685                        new AuthoritiesIterGenerator(),
10686                        authoritiesIterator);
10687                if (intentListCopy.size() == 0) {
10688                    // no more intents to match; we're not equivalent
10689                    if (DEBUG_FILTERS) {
10690                        Slog.i(TAG, "Mismatched authority; cap priority to 0;"
10691                                + " package: " + applicationInfo.packageName
10692                                + " activity: " + intent.activity.className
10693                                + " origPrio: " + intent.getPriority());
10694                    }
10695                    intent.setPriority(0);
10696                    return;
10697                }
10698            }
10699
10700            // we found matching filter(s); app gets the max priority of all intents
10701            int cappedPriority = 0;
10702            for (int i = intentListCopy.size() - 1; i >= 0; --i) {
10703                cappedPriority = Math.max(cappedPriority, intentListCopy.get(i).getPriority());
10704            }
10705            if (intent.getPriority() > cappedPriority) {
10706                if (DEBUG_FILTERS) {
10707                    Slog.i(TAG, "Found matching filter(s);"
10708                            + " cap priority to " + cappedPriority + ";"
10709                            + " package: " + applicationInfo.packageName
10710                            + " activity: " + intent.activity.className
10711                            + " origPrio: " + intent.getPriority());
10712                }
10713                intent.setPriority(cappedPriority);
10714                return;
10715            }
10716            // all this for nothing; the requested priority was <= what was on the system
10717        }
10718
10719        public final void addActivity(PackageParser.Activity a, String type) {
10720            mActivities.put(a.getComponentName(), a);
10721            if (DEBUG_SHOW_INFO)
10722                Log.v(
10723                TAG, "  " + type + " " +
10724                (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel : a.info.name) + ":");
10725            if (DEBUG_SHOW_INFO)
10726                Log.v(TAG, "    Class=" + a.info.name);
10727            final int NI = a.intents.size();
10728            for (int j=0; j<NI; j++) {
10729                PackageParser.ActivityIntentInfo intent = a.intents.get(j);
10730                if ("activity".equals(type)) {
10731                    final PackageSetting ps =
10732                            mSettings.getDisabledSystemPkgLPr(intent.activity.info.packageName);
10733                    final List<PackageParser.Activity> systemActivities =
10734                            ps != null && ps.pkg != null ? ps.pkg.activities : null;
10735                    adjustPriority(systemActivities, intent);
10736                }
10737                if (DEBUG_SHOW_INFO) {
10738                    Log.v(TAG, "    IntentFilter:");
10739                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
10740                }
10741                if (!intent.debugCheck()) {
10742                    Log.w(TAG, "==> For Activity " + a.info.name);
10743                }
10744                addFilter(intent);
10745            }
10746        }
10747
10748        public final void removeActivity(PackageParser.Activity a, String type) {
10749            mActivities.remove(a.getComponentName());
10750            if (DEBUG_SHOW_INFO) {
10751                Log.v(TAG, "  " + type + " "
10752                        + (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel
10753                                : a.info.name) + ":");
10754                Log.v(TAG, "    Class=" + a.info.name);
10755            }
10756            final int NI = a.intents.size();
10757            for (int j=0; j<NI; j++) {
10758                PackageParser.ActivityIntentInfo intent = a.intents.get(j);
10759                if (DEBUG_SHOW_INFO) {
10760                    Log.v(TAG, "    IntentFilter:");
10761                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
10762                }
10763                removeFilter(intent);
10764            }
10765        }
10766
10767        @Override
10768        protected boolean allowFilterResult(
10769                PackageParser.ActivityIntentInfo filter, List<ResolveInfo> dest) {
10770            ActivityInfo filterAi = filter.activity.info;
10771            for (int i=dest.size()-1; i>=0; i--) {
10772                ActivityInfo destAi = dest.get(i).activityInfo;
10773                if (destAi.name == filterAi.name
10774                        && destAi.packageName == filterAi.packageName) {
10775                    return false;
10776                }
10777            }
10778            return true;
10779        }
10780
10781        @Override
10782        protected ActivityIntentInfo[] newArray(int size) {
10783            return new ActivityIntentInfo[size];
10784        }
10785
10786        @Override
10787        protected boolean isFilterStopped(PackageParser.ActivityIntentInfo filter, int userId) {
10788            if (!sUserManager.exists(userId)) return true;
10789            PackageParser.Package p = filter.activity.owner;
10790            if (p != null) {
10791                PackageSetting ps = (PackageSetting)p.mExtras;
10792                if (ps != null) {
10793                    // System apps are never considered stopped for purposes of
10794                    // filtering, because there may be no way for the user to
10795                    // actually re-launch them.
10796                    return (ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0
10797                            && ps.getStopped(userId);
10798                }
10799            }
10800            return false;
10801        }
10802
10803        @Override
10804        protected boolean isPackageForFilter(String packageName,
10805                PackageParser.ActivityIntentInfo info) {
10806            return packageName.equals(info.activity.owner.packageName);
10807        }
10808
10809        @Override
10810        protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info,
10811                int match, int userId) {
10812            if (!sUserManager.exists(userId)) return null;
10813            if (!mSettings.isEnabledAndMatchLPr(info.activity.info, mFlags, userId)) {
10814                return null;
10815            }
10816            final PackageParser.Activity activity = info.activity;
10817            PackageSetting ps = (PackageSetting) activity.owner.mExtras;
10818            if (ps == null) {
10819                return null;
10820            }
10821            ActivityInfo ai = PackageParser.generateActivityInfo(activity, mFlags,
10822                    ps.readUserState(userId), userId);
10823            if (ai == null) {
10824                return null;
10825            }
10826            final ResolveInfo res = new ResolveInfo();
10827            res.activityInfo = ai;
10828            if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
10829                res.filter = info;
10830            }
10831            if (info != null) {
10832                res.handleAllWebDataURI = info.handleAllWebDataURI();
10833            }
10834            res.priority = info.getPriority();
10835            res.preferredOrder = activity.owner.mPreferredOrder;
10836            //System.out.println("Result: " + res.activityInfo.className +
10837            //                   " = " + res.priority);
10838            res.match = match;
10839            res.isDefault = info.hasDefault;
10840            res.labelRes = info.labelRes;
10841            res.nonLocalizedLabel = info.nonLocalizedLabel;
10842            if (userNeedsBadging(userId)) {
10843                res.noResourceId = true;
10844            } else {
10845                res.icon = info.icon;
10846            }
10847            res.iconResourceId = info.icon;
10848            res.system = res.activityInfo.applicationInfo.isSystemApp();
10849            return res;
10850        }
10851
10852        @Override
10853        protected void sortResults(List<ResolveInfo> results) {
10854            Collections.sort(results, mResolvePrioritySorter);
10855        }
10856
10857        @Override
10858        protected void dumpFilter(PrintWriter out, String prefix,
10859                PackageParser.ActivityIntentInfo filter) {
10860            out.print(prefix); out.print(
10861                    Integer.toHexString(System.identityHashCode(filter.activity)));
10862                    out.print(' ');
10863                    filter.activity.printComponentShortName(out);
10864                    out.print(" filter ");
10865                    out.println(Integer.toHexString(System.identityHashCode(filter)));
10866        }
10867
10868        @Override
10869        protected Object filterToLabel(PackageParser.ActivityIntentInfo filter) {
10870            return filter.activity;
10871        }
10872
10873        protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
10874            PackageParser.Activity activity = (PackageParser.Activity)label;
10875            out.print(prefix); out.print(
10876                    Integer.toHexString(System.identityHashCode(activity)));
10877                    out.print(' ');
10878                    activity.printComponentShortName(out);
10879            if (count > 1) {
10880                out.print(" ("); out.print(count); out.print(" filters)");
10881            }
10882            out.println();
10883        }
10884
10885        // Keys are String (activity class name), values are Activity.
10886        private final ArrayMap<ComponentName, PackageParser.Activity> mActivities
10887                = new ArrayMap<ComponentName, PackageParser.Activity>();
10888        private int mFlags;
10889    }
10890
10891    private final class ServiceIntentResolver
10892            extends IntentResolver<PackageParser.ServiceIntentInfo, ResolveInfo> {
10893        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
10894                boolean defaultOnly, int userId) {
10895            mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
10896            return super.queryIntent(intent, resolvedType, defaultOnly, userId);
10897        }
10898
10899        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
10900                int userId) {
10901            if (!sUserManager.exists(userId)) return null;
10902            mFlags = flags;
10903            return super.queryIntent(intent, resolvedType,
10904                    (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId);
10905        }
10906
10907        public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
10908                int flags, ArrayList<PackageParser.Service> packageServices, int userId) {
10909            if (!sUserManager.exists(userId)) return null;
10910            if (packageServices == null) {
10911                return null;
10912            }
10913            mFlags = flags;
10914            final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0;
10915            final int N = packageServices.size();
10916            ArrayList<PackageParser.ServiceIntentInfo[]> listCut =
10917                new ArrayList<PackageParser.ServiceIntentInfo[]>(N);
10918
10919            ArrayList<PackageParser.ServiceIntentInfo> intentFilters;
10920            for (int i = 0; i < N; ++i) {
10921                intentFilters = packageServices.get(i).intents;
10922                if (intentFilters != null && intentFilters.size() > 0) {
10923                    PackageParser.ServiceIntentInfo[] array =
10924                            new PackageParser.ServiceIntentInfo[intentFilters.size()];
10925                    intentFilters.toArray(array);
10926                    listCut.add(array);
10927                }
10928            }
10929            return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
10930        }
10931
10932        public final void addService(PackageParser.Service s) {
10933            mServices.put(s.getComponentName(), s);
10934            if (DEBUG_SHOW_INFO) {
10935                Log.v(TAG, "  "
10936                        + (s.info.nonLocalizedLabel != null
10937                        ? s.info.nonLocalizedLabel : s.info.name) + ":");
10938                Log.v(TAG, "    Class=" + s.info.name);
10939            }
10940            final int NI = s.intents.size();
10941            int j;
10942            for (j=0; j<NI; j++) {
10943                PackageParser.ServiceIntentInfo intent = s.intents.get(j);
10944                if (DEBUG_SHOW_INFO) {
10945                    Log.v(TAG, "    IntentFilter:");
10946                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
10947                }
10948                if (!intent.debugCheck()) {
10949                    Log.w(TAG, "==> For Service " + s.info.name);
10950                }
10951                addFilter(intent);
10952            }
10953        }
10954
10955        public final void removeService(PackageParser.Service s) {
10956            mServices.remove(s.getComponentName());
10957            if (DEBUG_SHOW_INFO) {
10958                Log.v(TAG, "  " + (s.info.nonLocalizedLabel != null
10959                        ? s.info.nonLocalizedLabel : s.info.name) + ":");
10960                Log.v(TAG, "    Class=" + s.info.name);
10961            }
10962            final int NI = s.intents.size();
10963            int j;
10964            for (j=0; j<NI; j++) {
10965                PackageParser.ServiceIntentInfo intent = s.intents.get(j);
10966                if (DEBUG_SHOW_INFO) {
10967                    Log.v(TAG, "    IntentFilter:");
10968                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
10969                }
10970                removeFilter(intent);
10971            }
10972        }
10973
10974        @Override
10975        protected boolean allowFilterResult(
10976                PackageParser.ServiceIntentInfo filter, List<ResolveInfo> dest) {
10977            ServiceInfo filterSi = filter.service.info;
10978            for (int i=dest.size()-1; i>=0; i--) {
10979                ServiceInfo destAi = dest.get(i).serviceInfo;
10980                if (destAi.name == filterSi.name
10981                        && destAi.packageName == filterSi.packageName) {
10982                    return false;
10983                }
10984            }
10985            return true;
10986        }
10987
10988        @Override
10989        protected PackageParser.ServiceIntentInfo[] newArray(int size) {
10990            return new PackageParser.ServiceIntentInfo[size];
10991        }
10992
10993        @Override
10994        protected boolean isFilterStopped(PackageParser.ServiceIntentInfo filter, int userId) {
10995            if (!sUserManager.exists(userId)) return true;
10996            PackageParser.Package p = filter.service.owner;
10997            if (p != null) {
10998                PackageSetting ps = (PackageSetting)p.mExtras;
10999                if (ps != null) {
11000                    // System apps are never considered stopped for purposes of
11001                    // filtering, because there may be no way for the user to
11002                    // actually re-launch them.
11003                    return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
11004                            && ps.getStopped(userId);
11005                }
11006            }
11007            return false;
11008        }
11009
11010        @Override
11011        protected boolean isPackageForFilter(String packageName,
11012                PackageParser.ServiceIntentInfo info) {
11013            return packageName.equals(info.service.owner.packageName);
11014        }
11015
11016        @Override
11017        protected ResolveInfo newResult(PackageParser.ServiceIntentInfo filter,
11018                int match, int userId) {
11019            if (!sUserManager.exists(userId)) return null;
11020            final PackageParser.ServiceIntentInfo info = (PackageParser.ServiceIntentInfo)filter;
11021            if (!mSettings.isEnabledAndMatchLPr(info.service.info, mFlags, userId)) {
11022                return null;
11023            }
11024            final PackageParser.Service service = info.service;
11025            PackageSetting ps = (PackageSetting) service.owner.mExtras;
11026            if (ps == null) {
11027                return null;
11028            }
11029            ServiceInfo si = PackageParser.generateServiceInfo(service, mFlags,
11030                    ps.readUserState(userId), userId);
11031            if (si == null) {
11032                return null;
11033            }
11034            final ResolveInfo res = new ResolveInfo();
11035            res.serviceInfo = si;
11036            if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
11037                res.filter = filter;
11038            }
11039            res.priority = info.getPriority();
11040            res.preferredOrder = service.owner.mPreferredOrder;
11041            res.match = match;
11042            res.isDefault = info.hasDefault;
11043            res.labelRes = info.labelRes;
11044            res.nonLocalizedLabel = info.nonLocalizedLabel;
11045            res.icon = info.icon;
11046            res.system = res.serviceInfo.applicationInfo.isSystemApp();
11047            return res;
11048        }
11049
11050        @Override
11051        protected void sortResults(List<ResolveInfo> results) {
11052            Collections.sort(results, mResolvePrioritySorter);
11053        }
11054
11055        @Override
11056        protected void dumpFilter(PrintWriter out, String prefix,
11057                PackageParser.ServiceIntentInfo filter) {
11058            out.print(prefix); out.print(
11059                    Integer.toHexString(System.identityHashCode(filter.service)));
11060                    out.print(' ');
11061                    filter.service.printComponentShortName(out);
11062                    out.print(" filter ");
11063                    out.println(Integer.toHexString(System.identityHashCode(filter)));
11064        }
11065
11066        @Override
11067        protected Object filterToLabel(PackageParser.ServiceIntentInfo filter) {
11068            return filter.service;
11069        }
11070
11071        protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
11072            PackageParser.Service service = (PackageParser.Service)label;
11073            out.print(prefix); out.print(
11074                    Integer.toHexString(System.identityHashCode(service)));
11075                    out.print(' ');
11076                    service.printComponentShortName(out);
11077            if (count > 1) {
11078                out.print(" ("); out.print(count); out.print(" filters)");
11079            }
11080            out.println();
11081        }
11082
11083//        List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) {
11084//            final Iterator<ResolveInfo> i = resolveInfoList.iterator();
11085//            final List<ResolveInfo> retList = Lists.newArrayList();
11086//            while (i.hasNext()) {
11087//                final ResolveInfo resolveInfo = (ResolveInfo) i;
11088//                if (isEnabledLP(resolveInfo.serviceInfo)) {
11089//                    retList.add(resolveInfo);
11090//                }
11091//            }
11092//            return retList;
11093//        }
11094
11095        // Keys are String (activity class name), values are Activity.
11096        private final ArrayMap<ComponentName, PackageParser.Service> mServices
11097                = new ArrayMap<ComponentName, PackageParser.Service>();
11098        private int mFlags;
11099    };
11100
11101    private final class ProviderIntentResolver
11102            extends IntentResolver<PackageParser.ProviderIntentInfo, ResolveInfo> {
11103        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
11104                boolean defaultOnly, int userId) {
11105            mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
11106            return super.queryIntent(intent, resolvedType, defaultOnly, userId);
11107        }
11108
11109        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
11110                int userId) {
11111            if (!sUserManager.exists(userId))
11112                return null;
11113            mFlags = flags;
11114            return super.queryIntent(intent, resolvedType,
11115                    (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId);
11116        }
11117
11118        public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
11119                int flags, ArrayList<PackageParser.Provider> packageProviders, int userId) {
11120            if (!sUserManager.exists(userId))
11121                return null;
11122            if (packageProviders == null) {
11123                return null;
11124            }
11125            mFlags = flags;
11126            final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0;
11127            final int N = packageProviders.size();
11128            ArrayList<PackageParser.ProviderIntentInfo[]> listCut =
11129                    new ArrayList<PackageParser.ProviderIntentInfo[]>(N);
11130
11131            ArrayList<PackageParser.ProviderIntentInfo> intentFilters;
11132            for (int i = 0; i < N; ++i) {
11133                intentFilters = packageProviders.get(i).intents;
11134                if (intentFilters != null && intentFilters.size() > 0) {
11135                    PackageParser.ProviderIntentInfo[] array =
11136                            new PackageParser.ProviderIntentInfo[intentFilters.size()];
11137                    intentFilters.toArray(array);
11138                    listCut.add(array);
11139                }
11140            }
11141            return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
11142        }
11143
11144        public final void addProvider(PackageParser.Provider p) {
11145            if (mProviders.containsKey(p.getComponentName())) {
11146                Slog.w(TAG, "Provider " + p.getComponentName() + " already defined; ignoring");
11147                return;
11148            }
11149
11150            mProviders.put(p.getComponentName(), p);
11151            if (DEBUG_SHOW_INFO) {
11152                Log.v(TAG, "  "
11153                        + (p.info.nonLocalizedLabel != null
11154                                ? p.info.nonLocalizedLabel : p.info.name) + ":");
11155                Log.v(TAG, "    Class=" + p.info.name);
11156            }
11157            final int NI = p.intents.size();
11158            int j;
11159            for (j = 0; j < NI; j++) {
11160                PackageParser.ProviderIntentInfo intent = p.intents.get(j);
11161                if (DEBUG_SHOW_INFO) {
11162                    Log.v(TAG, "    IntentFilter:");
11163                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
11164                }
11165                if (!intent.debugCheck()) {
11166                    Log.w(TAG, "==> For Provider " + p.info.name);
11167                }
11168                addFilter(intent);
11169            }
11170        }
11171
11172        public final void removeProvider(PackageParser.Provider p) {
11173            mProviders.remove(p.getComponentName());
11174            if (DEBUG_SHOW_INFO) {
11175                Log.v(TAG, "  " + (p.info.nonLocalizedLabel != null
11176                        ? p.info.nonLocalizedLabel : p.info.name) + ":");
11177                Log.v(TAG, "    Class=" + p.info.name);
11178            }
11179            final int NI = p.intents.size();
11180            int j;
11181            for (j = 0; j < NI; j++) {
11182                PackageParser.ProviderIntentInfo intent = p.intents.get(j);
11183                if (DEBUG_SHOW_INFO) {
11184                    Log.v(TAG, "    IntentFilter:");
11185                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
11186                }
11187                removeFilter(intent);
11188            }
11189        }
11190
11191        @Override
11192        protected boolean allowFilterResult(
11193                PackageParser.ProviderIntentInfo filter, List<ResolveInfo> dest) {
11194            ProviderInfo filterPi = filter.provider.info;
11195            for (int i = dest.size() - 1; i >= 0; i--) {
11196                ProviderInfo destPi = dest.get(i).providerInfo;
11197                if (destPi.name == filterPi.name
11198                        && destPi.packageName == filterPi.packageName) {
11199                    return false;
11200                }
11201            }
11202            return true;
11203        }
11204
11205        @Override
11206        protected PackageParser.ProviderIntentInfo[] newArray(int size) {
11207            return new PackageParser.ProviderIntentInfo[size];
11208        }
11209
11210        @Override
11211        protected boolean isFilterStopped(PackageParser.ProviderIntentInfo filter, int userId) {
11212            if (!sUserManager.exists(userId))
11213                return true;
11214            PackageParser.Package p = filter.provider.owner;
11215            if (p != null) {
11216                PackageSetting ps = (PackageSetting) p.mExtras;
11217                if (ps != null) {
11218                    // System apps are never considered stopped for purposes of
11219                    // filtering, because there may be no way for the user to
11220                    // actually re-launch them.
11221                    return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
11222                            && ps.getStopped(userId);
11223                }
11224            }
11225            return false;
11226        }
11227
11228        @Override
11229        protected boolean isPackageForFilter(String packageName,
11230                PackageParser.ProviderIntentInfo info) {
11231            return packageName.equals(info.provider.owner.packageName);
11232        }
11233
11234        @Override
11235        protected ResolveInfo newResult(PackageParser.ProviderIntentInfo filter,
11236                int match, int userId) {
11237            if (!sUserManager.exists(userId))
11238                return null;
11239            final PackageParser.ProviderIntentInfo info = filter;
11240            if (!mSettings.isEnabledAndMatchLPr(info.provider.info, mFlags, userId)) {
11241                return null;
11242            }
11243            final PackageParser.Provider provider = info.provider;
11244            PackageSetting ps = (PackageSetting) provider.owner.mExtras;
11245            if (ps == null) {
11246                return null;
11247            }
11248            ProviderInfo pi = PackageParser.generateProviderInfo(provider, mFlags,
11249                    ps.readUserState(userId), userId);
11250            if (pi == null) {
11251                return null;
11252            }
11253            final ResolveInfo res = new ResolveInfo();
11254            res.providerInfo = pi;
11255            if ((mFlags & PackageManager.GET_RESOLVED_FILTER) != 0) {
11256                res.filter = filter;
11257            }
11258            res.priority = info.getPriority();
11259            res.preferredOrder = provider.owner.mPreferredOrder;
11260            res.match = match;
11261            res.isDefault = info.hasDefault;
11262            res.labelRes = info.labelRes;
11263            res.nonLocalizedLabel = info.nonLocalizedLabel;
11264            res.icon = info.icon;
11265            res.system = res.providerInfo.applicationInfo.isSystemApp();
11266            return res;
11267        }
11268
11269        @Override
11270        protected void sortResults(List<ResolveInfo> results) {
11271            Collections.sort(results, mResolvePrioritySorter);
11272        }
11273
11274        @Override
11275        protected void dumpFilter(PrintWriter out, String prefix,
11276                PackageParser.ProviderIntentInfo filter) {
11277            out.print(prefix);
11278            out.print(
11279                    Integer.toHexString(System.identityHashCode(filter.provider)));
11280            out.print(' ');
11281            filter.provider.printComponentShortName(out);
11282            out.print(" filter ");
11283            out.println(Integer.toHexString(System.identityHashCode(filter)));
11284        }
11285
11286        @Override
11287        protected Object filterToLabel(PackageParser.ProviderIntentInfo filter) {
11288            return filter.provider;
11289        }
11290
11291        protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
11292            PackageParser.Provider provider = (PackageParser.Provider)label;
11293            out.print(prefix); out.print(
11294                    Integer.toHexString(System.identityHashCode(provider)));
11295                    out.print(' ');
11296                    provider.printComponentShortName(out);
11297            if (count > 1) {
11298                out.print(" ("); out.print(count); out.print(" filters)");
11299            }
11300            out.println();
11301        }
11302
11303        private final ArrayMap<ComponentName, PackageParser.Provider> mProviders
11304                = new ArrayMap<ComponentName, PackageParser.Provider>();
11305        private int mFlags;
11306    }
11307
11308    private static final class EphemeralIntentResolver
11309            extends IntentResolver<EphemeralResolveIntentInfo, EphemeralResolveInfo> {
11310        /**
11311         * The result that has the highest defined order. Ordering applies on a
11312         * per-package basis. Mapping is from package name to Pair of order and
11313         * EphemeralResolveInfo.
11314         * <p>
11315         * NOTE: This is implemented as a field variable for convenience and efficiency.
11316         * By having a field variable, we're able to track filter ordering as soon as
11317         * a non-zero order is defined. Otherwise, multiple loops across the result set
11318         * would be needed to apply ordering. If the intent resolver becomes re-entrant,
11319         * this needs to be contained entirely within {@link #filterResults()}.
11320         */
11321        final ArrayMap<String, Pair<Integer, EphemeralResolveInfo>> mOrderResult = new ArrayMap<>();
11322
11323        @Override
11324        protected EphemeralResolveIntentInfo[] newArray(int size) {
11325            return new EphemeralResolveIntentInfo[size];
11326        }
11327
11328        @Override
11329        protected boolean isPackageForFilter(String packageName, EphemeralResolveIntentInfo info) {
11330            return true;
11331        }
11332
11333        @Override
11334        protected EphemeralResolveInfo newResult(EphemeralResolveIntentInfo info, int match,
11335                int userId) {
11336            if (!sUserManager.exists(userId)) {
11337                return null;
11338            }
11339            final String packageName = info.getEphemeralResolveInfo().getPackageName();
11340            final Integer order = info.getOrder();
11341            final Pair<Integer, EphemeralResolveInfo> lastOrderResult =
11342                    mOrderResult.get(packageName);
11343            // ordering is enabled and this item's order isn't high enough
11344            if (lastOrderResult != null && lastOrderResult.first >= order) {
11345                return null;
11346            }
11347            final EphemeralResolveInfo res = info.getEphemeralResolveInfo();
11348            if (order > 0) {
11349                // non-zero order, enable ordering
11350                mOrderResult.put(packageName, new Pair<>(order, res));
11351            }
11352            return res;
11353        }
11354
11355        @Override
11356        protected void filterResults(List<EphemeralResolveInfo> results) {
11357            // only do work if ordering is enabled [most of the time it won't be]
11358            if (mOrderResult.size() == 0) {
11359                return;
11360            }
11361            int resultSize = results.size();
11362            for (int i = 0; i < resultSize; i++) {
11363                final EphemeralResolveInfo info = results.get(i);
11364                final String packageName = info.getPackageName();
11365                final Pair<Integer, EphemeralResolveInfo> savedInfo = mOrderResult.get(packageName);
11366                if (savedInfo == null) {
11367                    // package doesn't having ordering
11368                    continue;
11369                }
11370                if (savedInfo.second == info) {
11371                    // circled back to the highest ordered item; remove from order list
11372                    mOrderResult.remove(savedInfo);
11373                    if (mOrderResult.size() == 0) {
11374                        // no more ordered items
11375                        break;
11376                    }
11377                    continue;
11378                }
11379                // item has a worse order, remove it from the result list
11380                results.remove(i);
11381                resultSize--;
11382                i--;
11383            }
11384        }
11385    }
11386
11387    private static final Comparator<ResolveInfo> mResolvePrioritySorter =
11388            new Comparator<ResolveInfo>() {
11389        public int compare(ResolveInfo r1, ResolveInfo r2) {
11390            int v1 = r1.priority;
11391            int v2 = r2.priority;
11392            //System.out.println("Comparing: q1=" + q1 + " q2=" + q2);
11393            if (v1 != v2) {
11394                return (v1 > v2) ? -1 : 1;
11395            }
11396            v1 = r1.preferredOrder;
11397            v2 = r2.preferredOrder;
11398            if (v1 != v2) {
11399                return (v1 > v2) ? -1 : 1;
11400            }
11401            if (r1.isDefault != r2.isDefault) {
11402                return r1.isDefault ? -1 : 1;
11403            }
11404            v1 = r1.match;
11405            v2 = r2.match;
11406            //System.out.println("Comparing: m1=" + m1 + " m2=" + m2);
11407            if (v1 != v2) {
11408                return (v1 > v2) ? -1 : 1;
11409            }
11410            if (r1.system != r2.system) {
11411                return r1.system ? -1 : 1;
11412            }
11413            if (r1.activityInfo != null) {
11414                return r1.activityInfo.packageName.compareTo(r2.activityInfo.packageName);
11415            }
11416            if (r1.serviceInfo != null) {
11417                return r1.serviceInfo.packageName.compareTo(r2.serviceInfo.packageName);
11418            }
11419            if (r1.providerInfo != null) {
11420                return r1.providerInfo.packageName.compareTo(r2.providerInfo.packageName);
11421            }
11422            return 0;
11423        }
11424    };
11425
11426    private static final Comparator<ProviderInfo> mProviderInitOrderSorter =
11427            new Comparator<ProviderInfo>() {
11428        public int compare(ProviderInfo p1, ProviderInfo p2) {
11429            final int v1 = p1.initOrder;
11430            final int v2 = p2.initOrder;
11431            return (v1 > v2) ? -1 : ((v1 < v2) ? 1 : 0);
11432        }
11433    };
11434
11435    final void sendPackageBroadcast(final String action, final String pkg, final Bundle extras,
11436            final int flags, final String targetPkg, final IIntentReceiver finishedReceiver,
11437            final int[] userIds) {
11438        mHandler.post(new Runnable() {
11439            @Override
11440            public void run() {
11441                try {
11442                    final IActivityManager am = ActivityManagerNative.getDefault();
11443                    if (am == null) return;
11444                    final int[] resolvedUserIds;
11445                    if (userIds == null) {
11446                        resolvedUserIds = am.getRunningUserIds();
11447                    } else {
11448                        resolvedUserIds = userIds;
11449                    }
11450                    for (int id : resolvedUserIds) {
11451                        final Intent intent = new Intent(action,
11452                                pkg != null ? Uri.fromParts(PACKAGE_SCHEME, pkg, null) : null);
11453                        if (extras != null) {
11454                            intent.putExtras(extras);
11455                        }
11456                        if (targetPkg != null) {
11457                            intent.setPackage(targetPkg);
11458                        }
11459                        // Modify the UID when posting to other users
11460                        int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
11461                        if (uid > 0 && UserHandle.getUserId(uid) != id) {
11462                            uid = UserHandle.getUid(id, UserHandle.getAppId(uid));
11463                            intent.putExtra(Intent.EXTRA_UID, uid);
11464                        }
11465                        intent.putExtra(Intent.EXTRA_USER_HANDLE, id);
11466                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT | flags);
11467                        if (DEBUG_BROADCASTS) {
11468                            RuntimeException here = new RuntimeException("here");
11469                            here.fillInStackTrace();
11470                            Slog.d(TAG, "Sending to user " + id + ": "
11471                                    + intent.toShortString(false, true, false, false)
11472                                    + " " + intent.getExtras(), here);
11473                        }
11474                        am.broadcastIntent(null, intent, null, finishedReceiver,
11475                                0, null, null, null, android.app.AppOpsManager.OP_NONE,
11476                                null, finishedReceiver != null, false, id);
11477                    }
11478                } catch (RemoteException ex) {
11479                }
11480            }
11481        });
11482    }
11483
11484    /**
11485     * Check if the external storage media is available. This is true if there
11486     * is a mounted external storage medium or if the external storage is
11487     * emulated.
11488     */
11489    private boolean isExternalMediaAvailable() {
11490        return mMediaMounted || Environment.isExternalStorageEmulated();
11491    }
11492
11493    @Override
11494    public PackageCleanItem nextPackageToClean(PackageCleanItem lastPackage) {
11495        // writer
11496        synchronized (mPackages) {
11497            if (!isExternalMediaAvailable()) {
11498                // If the external storage is no longer mounted at this point,
11499                // the caller may not have been able to delete all of this
11500                // packages files and can not delete any more.  Bail.
11501                return null;
11502            }
11503            final ArrayList<PackageCleanItem> pkgs = mSettings.mPackagesToBeCleaned;
11504            if (lastPackage != null) {
11505                pkgs.remove(lastPackage);
11506            }
11507            if (pkgs.size() > 0) {
11508                return pkgs.get(0);
11509            }
11510        }
11511        return null;
11512    }
11513
11514    void schedulePackageCleaning(String packageName, int userId, boolean andCode) {
11515        final Message msg = mHandler.obtainMessage(START_CLEANING_PACKAGE,
11516                userId, andCode ? 1 : 0, packageName);
11517        if (mSystemReady) {
11518            msg.sendToTarget();
11519        } else {
11520            if (mPostSystemReadyMessages == null) {
11521                mPostSystemReadyMessages = new ArrayList<>();
11522            }
11523            mPostSystemReadyMessages.add(msg);
11524        }
11525    }
11526
11527    void startCleaningPackages() {
11528        // reader
11529        if (!isExternalMediaAvailable()) {
11530            return;
11531        }
11532        synchronized (mPackages) {
11533            if (mSettings.mPackagesToBeCleaned.isEmpty()) {
11534                return;
11535            }
11536        }
11537        Intent intent = new Intent(PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE);
11538        intent.setComponent(DEFAULT_CONTAINER_COMPONENT);
11539        IActivityManager am = ActivityManagerNative.getDefault();
11540        if (am != null) {
11541            try {
11542                am.startService(null, intent, null, mContext.getOpPackageName(),
11543                        UserHandle.USER_SYSTEM);
11544            } catch (RemoteException e) {
11545            }
11546        }
11547    }
11548
11549    @Override
11550    public void installPackageAsUser(String originPath, IPackageInstallObserver2 observer,
11551            int installFlags, String installerPackageName, int userId) {
11552        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null);
11553
11554        final int callingUid = Binder.getCallingUid();
11555        enforceCrossUserPermission(callingUid, userId,
11556                true /* requireFullPermission */, true /* checkShell */, "installPackageAsUser");
11557
11558        if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
11559            try {
11560                if (observer != null) {
11561                    observer.onPackageInstalled("", INSTALL_FAILED_USER_RESTRICTED, null, null);
11562                }
11563            } catch (RemoteException re) {
11564            }
11565            return;
11566        }
11567
11568        if ((callingUid == Process.SHELL_UID) || (callingUid == Process.ROOT_UID)) {
11569            installFlags |= PackageManager.INSTALL_FROM_ADB;
11570
11571        } else {
11572            // Caller holds INSTALL_PACKAGES permission, so we're less strict
11573            // about installerPackageName.
11574
11575            installFlags &= ~PackageManager.INSTALL_FROM_ADB;
11576            installFlags &= ~PackageManager.INSTALL_ALL_USERS;
11577        }
11578
11579        UserHandle user;
11580        if ((installFlags & PackageManager.INSTALL_ALL_USERS) != 0) {
11581            user = UserHandle.ALL;
11582        } else {
11583            user = new UserHandle(userId);
11584        }
11585
11586        // Only system components can circumvent runtime permissions when installing.
11587        if ((installFlags & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0
11588                && mContext.checkCallingOrSelfPermission(Manifest.permission
11589                .INSTALL_GRANT_RUNTIME_PERMISSIONS) == PackageManager.PERMISSION_DENIED) {
11590            throw new SecurityException("You need the "
11591                    + "android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS permission "
11592                    + "to use the PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS flag");
11593        }
11594
11595        final File originFile = new File(originPath);
11596        final OriginInfo origin = OriginInfo.fromUntrustedFile(originFile);
11597
11598        final Message msg = mHandler.obtainMessage(INIT_COPY);
11599        final VerificationInfo verificationInfo = new VerificationInfo(
11600                null /*originatingUri*/, null /*referrer*/, -1 /*originatingUid*/, callingUid);
11601        final InstallParams params = new InstallParams(origin, null /*moveInfo*/, observer,
11602                installFlags, installerPackageName, null /*volumeUuid*/, verificationInfo, user,
11603                null /*packageAbiOverride*/, null /*grantedPermissions*/,
11604                null /*certificates*/);
11605        params.setTraceMethod("installAsUser").setTraceCookie(System.identityHashCode(params));
11606        msg.obj = params;
11607
11608        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installAsUser",
11609                System.identityHashCode(msg.obj));
11610        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
11611                System.identityHashCode(msg.obj));
11612
11613        mHandler.sendMessage(msg);
11614    }
11615
11616    void installStage(String packageName, File stagedDir, String stagedCid,
11617            IPackageInstallObserver2 observer, PackageInstaller.SessionParams sessionParams,
11618            String installerPackageName, int installerUid, UserHandle user,
11619            Certificate[][] certificates) {
11620        if (DEBUG_EPHEMERAL) {
11621            if ((sessionParams.installFlags & PackageManager.INSTALL_EPHEMERAL) != 0) {
11622                Slog.d(TAG, "Ephemeral install of " + packageName);
11623            }
11624        }
11625        final VerificationInfo verificationInfo = new VerificationInfo(
11626                sessionParams.originatingUri, sessionParams.referrerUri,
11627                sessionParams.originatingUid, installerUid);
11628
11629        final OriginInfo origin;
11630        if (stagedDir != null) {
11631            origin = OriginInfo.fromStagedFile(stagedDir);
11632        } else {
11633            origin = OriginInfo.fromStagedContainer(stagedCid);
11634        }
11635
11636        final Message msg = mHandler.obtainMessage(INIT_COPY);
11637        final InstallParams params = new InstallParams(origin, null, observer,
11638                sessionParams.installFlags, installerPackageName, sessionParams.volumeUuid,
11639                verificationInfo, user, sessionParams.abiOverride,
11640                sessionParams.grantedRuntimePermissions, certificates);
11641        params.setTraceMethod("installStage").setTraceCookie(System.identityHashCode(params));
11642        msg.obj = params;
11643
11644        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installStage",
11645                System.identityHashCode(msg.obj));
11646        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
11647                System.identityHashCode(msg.obj));
11648
11649        mHandler.sendMessage(msg);
11650    }
11651
11652    private void sendPackageAddedForUser(String packageName, PackageSetting pkgSetting,
11653            int userId) {
11654        final boolean isSystem = isSystemApp(pkgSetting) || isUpdatedSystemApp(pkgSetting);
11655        sendPackageAddedForUser(packageName, isSystem, pkgSetting.appId, userId);
11656    }
11657
11658    private void sendPackageAddedForUser(String packageName, boolean isSystem,
11659            int appId, int userId) {
11660        Bundle extras = new Bundle(1);
11661        extras.putInt(Intent.EXTRA_UID, UserHandle.getUid(userId, appId));
11662
11663        sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
11664                packageName, extras, 0, null, null, new int[] {userId});
11665        try {
11666            IActivityManager am = ActivityManagerNative.getDefault();
11667            if (isSystem && am.isUserRunning(userId, 0)) {
11668                // The just-installed/enabled app is bundled on the system, so presumed
11669                // to be able to run automatically without needing an explicit launch.
11670                // Send it a BOOT_COMPLETED if it would ordinarily have gotten one.
11671                Intent bcIntent = new Intent(Intent.ACTION_BOOT_COMPLETED)
11672                        .addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES)
11673                        .setPackage(packageName);
11674                am.broadcastIntent(null, bcIntent, null, null, 0, null, null, null,
11675                        android.app.AppOpsManager.OP_NONE, null, false, false, userId);
11676            }
11677        } catch (RemoteException e) {
11678            // shouldn't happen
11679            Slog.w(TAG, "Unable to bootstrap installed package", e);
11680        }
11681    }
11682
11683    @Override
11684    public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden,
11685            int userId) {
11686        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
11687        PackageSetting pkgSetting;
11688        final int uid = Binder.getCallingUid();
11689        enforceCrossUserPermission(uid, userId,
11690                true /* requireFullPermission */, true /* checkShell */,
11691                "setApplicationHiddenSetting for user " + userId);
11692
11693        if (hidden && isPackageDeviceAdmin(packageName, userId)) {
11694            Slog.w(TAG, "Not hiding package " + packageName + ": has active device admin");
11695            return false;
11696        }
11697
11698        long callingId = Binder.clearCallingIdentity();
11699        try {
11700            boolean sendAdded = false;
11701            boolean sendRemoved = false;
11702            // writer
11703            synchronized (mPackages) {
11704                pkgSetting = mSettings.mPackages.get(packageName);
11705                if (pkgSetting == null) {
11706                    return false;
11707                }
11708                // Do not allow "android" is being disabled
11709                if ("android".equals(packageName)) {
11710                    Slog.w(TAG, "Cannot hide package: android");
11711                    return false;
11712                }
11713                // Only allow protected packages to hide themselves.
11714                if (hidden && !UserHandle.isSameApp(uid, pkgSetting.appId)
11715                        && mProtectedPackages.isPackageStateProtected(userId, packageName)) {
11716                    Slog.w(TAG, "Not hiding protected package: " + packageName);
11717                    return false;
11718                }
11719
11720                if (pkgSetting.getHidden(userId) != hidden) {
11721                    pkgSetting.setHidden(hidden, userId);
11722                    mSettings.writePackageRestrictionsLPr(userId);
11723                    if (hidden) {
11724                        sendRemoved = true;
11725                    } else {
11726                        sendAdded = true;
11727                    }
11728                }
11729            }
11730            if (sendAdded) {
11731                sendPackageAddedForUser(packageName, pkgSetting, userId);
11732                return true;
11733            }
11734            if (sendRemoved) {
11735                killApplication(packageName, UserHandle.getUid(userId, pkgSetting.appId),
11736                        "hiding pkg");
11737                sendApplicationHiddenForUser(packageName, pkgSetting, userId);
11738                return true;
11739            }
11740        } finally {
11741            Binder.restoreCallingIdentity(callingId);
11742        }
11743        return false;
11744    }
11745
11746    private void sendApplicationHiddenForUser(String packageName, PackageSetting pkgSetting,
11747            int userId) {
11748        final PackageRemovedInfo info = new PackageRemovedInfo();
11749        info.removedPackage = packageName;
11750        info.removedUsers = new int[] {userId};
11751        info.uid = UserHandle.getUid(userId, pkgSetting.appId);
11752        info.sendPackageRemovedBroadcasts(true /*killApp*/);
11753    }
11754
11755    private void sendPackagesSuspendedForUser(String[] pkgList, int userId, boolean suspended) {
11756        if (pkgList.length > 0) {
11757            Bundle extras = new Bundle(1);
11758            extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
11759
11760            sendPackageBroadcast(
11761                    suspended ? Intent.ACTION_PACKAGES_SUSPENDED
11762                            : Intent.ACTION_PACKAGES_UNSUSPENDED,
11763                    null, extras, Intent.FLAG_RECEIVER_REGISTERED_ONLY, null, null,
11764                    new int[] {userId});
11765        }
11766    }
11767
11768    /**
11769     * Returns true if application is not found or there was an error. Otherwise it returns
11770     * the hidden state of the package for the given user.
11771     */
11772    @Override
11773    public boolean getApplicationHiddenSettingAsUser(String packageName, int userId) {
11774        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
11775        enforceCrossUserPermission(Binder.getCallingUid(), userId,
11776                true /* requireFullPermission */, false /* checkShell */,
11777                "getApplicationHidden for user " + userId);
11778        PackageSetting pkgSetting;
11779        long callingId = Binder.clearCallingIdentity();
11780        try {
11781            // writer
11782            synchronized (mPackages) {
11783                pkgSetting = mSettings.mPackages.get(packageName);
11784                if (pkgSetting == null) {
11785                    return true;
11786                }
11787                return pkgSetting.getHidden(userId);
11788            }
11789        } finally {
11790            Binder.restoreCallingIdentity(callingId);
11791        }
11792    }
11793
11794    /**
11795     * @hide
11796     */
11797    @Override
11798    public int installExistingPackageAsUser(String packageName, int userId) {
11799        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES,
11800                null);
11801        PackageSetting pkgSetting;
11802        final int uid = Binder.getCallingUid();
11803        enforceCrossUserPermission(uid, userId,
11804                true /* requireFullPermission */, true /* checkShell */,
11805                "installExistingPackage for user " + userId);
11806        if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
11807            return PackageManager.INSTALL_FAILED_USER_RESTRICTED;
11808        }
11809
11810        long callingId = Binder.clearCallingIdentity();
11811        try {
11812            boolean installed = false;
11813
11814            // writer
11815            synchronized (mPackages) {
11816                pkgSetting = mSettings.mPackages.get(packageName);
11817                if (pkgSetting == null) {
11818                    return PackageManager.INSTALL_FAILED_INVALID_URI;
11819                }
11820                if (!pkgSetting.getInstalled(userId)) {
11821                    pkgSetting.setInstalled(true, userId);
11822                    pkgSetting.setHidden(false, userId);
11823                    mSettings.writePackageRestrictionsLPr(userId);
11824                    installed = true;
11825                }
11826            }
11827
11828            if (installed) {
11829                if (pkgSetting.pkg != null) {
11830                    synchronized (mInstallLock) {
11831                        // We don't need to freeze for a brand new install
11832                        prepareAppDataAfterInstallLIF(pkgSetting.pkg);
11833                    }
11834                }
11835                sendPackageAddedForUser(packageName, pkgSetting, userId);
11836            }
11837        } finally {
11838            Binder.restoreCallingIdentity(callingId);
11839        }
11840
11841        return PackageManager.INSTALL_SUCCEEDED;
11842    }
11843
11844    boolean isUserRestricted(int userId, String restrictionKey) {
11845        Bundle restrictions = sUserManager.getUserRestrictions(userId);
11846        if (restrictions.getBoolean(restrictionKey, false)) {
11847            Log.w(TAG, "User is restricted: " + restrictionKey);
11848            return true;
11849        }
11850        return false;
11851    }
11852
11853    @Override
11854    public String[] setPackagesSuspendedAsUser(String[] packageNames, boolean suspended,
11855            int userId) {
11856        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
11857        enforceCrossUserPermission(Binder.getCallingUid(), userId,
11858                true /* requireFullPermission */, true /* checkShell */,
11859                "setPackagesSuspended for user " + userId);
11860
11861        if (ArrayUtils.isEmpty(packageNames)) {
11862            return packageNames;
11863        }
11864
11865        // List of package names for whom the suspended state has changed.
11866        List<String> changedPackages = new ArrayList<>(packageNames.length);
11867        // List of package names for whom the suspended state is not set as requested in this
11868        // method.
11869        List<String> unactionedPackages = new ArrayList<>(packageNames.length);
11870        long callingId = Binder.clearCallingIdentity();
11871        try {
11872            for (int i = 0; i < packageNames.length; i++) {
11873                String packageName = packageNames[i];
11874                boolean changed = false;
11875                final int appId;
11876                synchronized (mPackages) {
11877                    final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
11878                    if (pkgSetting == null) {
11879                        Slog.w(TAG, "Could not find package setting for package \"" + packageName
11880                                + "\". Skipping suspending/un-suspending.");
11881                        unactionedPackages.add(packageName);
11882                        continue;
11883                    }
11884                    appId = pkgSetting.appId;
11885                    if (pkgSetting.getSuspended(userId) != suspended) {
11886                        if (!canSuspendPackageForUserLocked(packageName, userId)) {
11887                            unactionedPackages.add(packageName);
11888                            continue;
11889                        }
11890                        pkgSetting.setSuspended(suspended, userId);
11891                        mSettings.writePackageRestrictionsLPr(userId);
11892                        changed = true;
11893                        changedPackages.add(packageName);
11894                    }
11895                }
11896
11897                if (changed && suspended) {
11898                    killApplication(packageName, UserHandle.getUid(userId, appId),
11899                            "suspending package");
11900                }
11901            }
11902        } finally {
11903            Binder.restoreCallingIdentity(callingId);
11904        }
11905
11906        if (!changedPackages.isEmpty()) {
11907            sendPackagesSuspendedForUser(changedPackages.toArray(
11908                    new String[changedPackages.size()]), userId, suspended);
11909        }
11910
11911        return unactionedPackages.toArray(new String[unactionedPackages.size()]);
11912    }
11913
11914    @Override
11915    public boolean isPackageSuspendedForUser(String packageName, int userId) {
11916        enforceCrossUserPermission(Binder.getCallingUid(), userId,
11917                true /* requireFullPermission */, false /* checkShell */,
11918                "isPackageSuspendedForUser for user " + userId);
11919        synchronized (mPackages) {
11920            final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
11921            if (pkgSetting == null) {
11922                throw new IllegalArgumentException("Unknown target package: " + packageName);
11923            }
11924            return pkgSetting.getSuspended(userId);
11925        }
11926    }
11927
11928    private boolean canSuspendPackageForUserLocked(String packageName, int userId) {
11929        if (isPackageDeviceAdmin(packageName, userId)) {
11930            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
11931                    + "\": has an active device admin");
11932            return false;
11933        }
11934
11935        String activeLauncherPackageName = getActiveLauncherPackageName(userId);
11936        if (packageName.equals(activeLauncherPackageName)) {
11937            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
11938                    + "\": contains the active launcher");
11939            return false;
11940        }
11941
11942        if (packageName.equals(mRequiredInstallerPackage)) {
11943            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
11944                    + "\": required for package installation");
11945            return false;
11946        }
11947
11948        if (packageName.equals(mRequiredUninstallerPackage)) {
11949            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
11950                    + "\": required for package uninstallation");
11951            return false;
11952        }
11953
11954        if (packageName.equals(mRequiredVerifierPackage)) {
11955            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
11956                    + "\": required for package verification");
11957            return false;
11958        }
11959
11960        if (packageName.equals(getDefaultDialerPackageName(userId))) {
11961            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
11962                    + "\": is the default dialer");
11963            return false;
11964        }
11965
11966        if (mProtectedPackages.isPackageStateProtected(userId, packageName)) {
11967            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
11968                    + "\": protected package");
11969            return false;
11970        }
11971
11972        return true;
11973    }
11974
11975    private String getActiveLauncherPackageName(int userId) {
11976        Intent intent = new Intent(Intent.ACTION_MAIN);
11977        intent.addCategory(Intent.CATEGORY_HOME);
11978        ResolveInfo resolveInfo = resolveIntent(
11979                intent,
11980                intent.resolveTypeIfNeeded(mContext.getContentResolver()),
11981                PackageManager.MATCH_DEFAULT_ONLY,
11982                userId);
11983
11984        return resolveInfo == null ? null : resolveInfo.activityInfo.packageName;
11985    }
11986
11987    private String getDefaultDialerPackageName(int userId) {
11988        synchronized (mPackages) {
11989            return mSettings.getDefaultDialerPackageNameLPw(userId);
11990        }
11991    }
11992
11993    @Override
11994    public void verifyPendingInstall(int id, int verificationCode) throws RemoteException {
11995        mContext.enforceCallingOrSelfPermission(
11996                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
11997                "Only package verification agents can verify applications");
11998
11999        final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
12000        final PackageVerificationResponse response = new PackageVerificationResponse(
12001                verificationCode, Binder.getCallingUid());
12002        msg.arg1 = id;
12003        msg.obj = response;
12004        mHandler.sendMessage(msg);
12005    }
12006
12007    @Override
12008    public void extendVerificationTimeout(int id, int verificationCodeAtTimeout,
12009            long millisecondsToDelay) {
12010        mContext.enforceCallingOrSelfPermission(
12011                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
12012                "Only package verification agents can extend verification timeouts");
12013
12014        final PackageVerificationState state = mPendingVerification.get(id);
12015        final PackageVerificationResponse response = new PackageVerificationResponse(
12016                verificationCodeAtTimeout, Binder.getCallingUid());
12017
12018        if (millisecondsToDelay > PackageManager.MAXIMUM_VERIFICATION_TIMEOUT) {
12019            millisecondsToDelay = PackageManager.MAXIMUM_VERIFICATION_TIMEOUT;
12020        }
12021        if (millisecondsToDelay < 0) {
12022            millisecondsToDelay = 0;
12023        }
12024        if ((verificationCodeAtTimeout != PackageManager.VERIFICATION_ALLOW)
12025                && (verificationCodeAtTimeout != PackageManager.VERIFICATION_REJECT)) {
12026            verificationCodeAtTimeout = PackageManager.VERIFICATION_REJECT;
12027        }
12028
12029        if ((state != null) && !state.timeoutExtended()) {
12030            state.extendTimeout();
12031
12032            final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
12033            msg.arg1 = id;
12034            msg.obj = response;
12035            mHandler.sendMessageDelayed(msg, millisecondsToDelay);
12036        }
12037    }
12038
12039    private void broadcastPackageVerified(int verificationId, Uri packageUri,
12040            int verificationCode, UserHandle user) {
12041        final Intent intent = new Intent(Intent.ACTION_PACKAGE_VERIFIED);
12042        intent.setDataAndType(packageUri, PACKAGE_MIME_TYPE);
12043        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
12044        intent.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
12045        intent.putExtra(PackageManager.EXTRA_VERIFICATION_RESULT, verificationCode);
12046
12047        mContext.sendBroadcastAsUser(intent, user,
12048                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT);
12049    }
12050
12051    private ComponentName matchComponentForVerifier(String packageName,
12052            List<ResolveInfo> receivers) {
12053        ActivityInfo targetReceiver = null;
12054
12055        final int NR = receivers.size();
12056        for (int i = 0; i < NR; i++) {
12057            final ResolveInfo info = receivers.get(i);
12058            if (info.activityInfo == null) {
12059                continue;
12060            }
12061
12062            if (packageName.equals(info.activityInfo.packageName)) {
12063                targetReceiver = info.activityInfo;
12064                break;
12065            }
12066        }
12067
12068        if (targetReceiver == null) {
12069            return null;
12070        }
12071
12072        return new ComponentName(targetReceiver.packageName, targetReceiver.name);
12073    }
12074
12075    private List<ComponentName> matchVerifiers(PackageInfoLite pkgInfo,
12076            List<ResolveInfo> receivers, final PackageVerificationState verificationState) {
12077        if (pkgInfo.verifiers.length == 0) {
12078            return null;
12079        }
12080
12081        final int N = pkgInfo.verifiers.length;
12082        final List<ComponentName> sufficientVerifiers = new ArrayList<ComponentName>(N + 1);
12083        for (int i = 0; i < N; i++) {
12084            final VerifierInfo verifierInfo = pkgInfo.verifiers[i];
12085
12086            final ComponentName comp = matchComponentForVerifier(verifierInfo.packageName,
12087                    receivers);
12088            if (comp == null) {
12089                continue;
12090            }
12091
12092            final int verifierUid = getUidForVerifier(verifierInfo);
12093            if (verifierUid == -1) {
12094                continue;
12095            }
12096
12097            if (DEBUG_VERIFY) {
12098                Slog.d(TAG, "Added sufficient verifier " + verifierInfo.packageName
12099                        + " with the correct signature");
12100            }
12101            sufficientVerifiers.add(comp);
12102            verificationState.addSufficientVerifier(verifierUid);
12103        }
12104
12105        return sufficientVerifiers;
12106    }
12107
12108    private int getUidForVerifier(VerifierInfo verifierInfo) {
12109        synchronized (mPackages) {
12110            final PackageParser.Package pkg = mPackages.get(verifierInfo.packageName);
12111            if (pkg == null) {
12112                return -1;
12113            } else if (pkg.mSignatures.length != 1) {
12114                Slog.i(TAG, "Verifier package " + verifierInfo.packageName
12115                        + " has more than one signature; ignoring");
12116                return -1;
12117            }
12118
12119            /*
12120             * If the public key of the package's signature does not match
12121             * our expected public key, then this is a different package and
12122             * we should skip.
12123             */
12124
12125            final byte[] expectedPublicKey;
12126            try {
12127                final Signature verifierSig = pkg.mSignatures[0];
12128                final PublicKey publicKey = verifierSig.getPublicKey();
12129                expectedPublicKey = publicKey.getEncoded();
12130            } catch (CertificateException e) {
12131                return -1;
12132            }
12133
12134            final byte[] actualPublicKey = verifierInfo.publicKey.getEncoded();
12135
12136            if (!Arrays.equals(actualPublicKey, expectedPublicKey)) {
12137                Slog.i(TAG, "Verifier package " + verifierInfo.packageName
12138                        + " does not have the expected public key; ignoring");
12139                return -1;
12140            }
12141
12142            return pkg.applicationInfo.uid;
12143        }
12144    }
12145
12146    @Override
12147    public void finishPackageInstall(int token, boolean didLaunch) {
12148        enforceSystemOrRoot("Only the system is allowed to finish installs");
12149
12150        if (DEBUG_INSTALL) {
12151            Slog.v(TAG, "BM finishing package install for " + token);
12152        }
12153        Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "restore", token);
12154
12155        final Message msg = mHandler.obtainMessage(POST_INSTALL, token, didLaunch ? 1 : 0);
12156        mHandler.sendMessage(msg);
12157    }
12158
12159    /**
12160     * Get the verification agent timeout.
12161     *
12162     * @return verification timeout in milliseconds
12163     */
12164    private long getVerificationTimeout() {
12165        return android.provider.Settings.Global.getLong(mContext.getContentResolver(),
12166                android.provider.Settings.Global.PACKAGE_VERIFIER_TIMEOUT,
12167                DEFAULT_VERIFICATION_TIMEOUT);
12168    }
12169
12170    /**
12171     * Get the default verification agent response code.
12172     *
12173     * @return default verification response code
12174     */
12175    private int getDefaultVerificationResponse() {
12176        return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
12177                android.provider.Settings.Global.PACKAGE_VERIFIER_DEFAULT_RESPONSE,
12178                DEFAULT_VERIFICATION_RESPONSE);
12179    }
12180
12181    /**
12182     * Check whether or not package verification has been enabled.
12183     *
12184     * @return true if verification should be performed
12185     */
12186    private boolean isVerificationEnabled(int userId, int installFlags) {
12187        if (!DEFAULT_VERIFY_ENABLE) {
12188            return false;
12189        }
12190        // Ephemeral apps don't get the full verification treatment
12191        if ((installFlags & PackageManager.INSTALL_EPHEMERAL) != 0) {
12192            if (DEBUG_EPHEMERAL) {
12193                Slog.d(TAG, "INSTALL_EPHEMERAL so skipping verification");
12194            }
12195            return false;
12196        }
12197
12198        boolean ensureVerifyAppsEnabled = isUserRestricted(userId, UserManager.ENSURE_VERIFY_APPS);
12199
12200        // Check if installing from ADB
12201        if ((installFlags & PackageManager.INSTALL_FROM_ADB) != 0) {
12202            // Do not run verification in a test harness environment
12203            if (ActivityManager.isRunningInTestHarness()) {
12204                return false;
12205            }
12206            if (ensureVerifyAppsEnabled) {
12207                return true;
12208            }
12209            // Check if the developer does not want package verification for ADB installs
12210            if (android.provider.Settings.Global.getInt(mContext.getContentResolver(),
12211                    android.provider.Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, 1) == 0) {
12212                return false;
12213            }
12214        }
12215
12216        if (ensureVerifyAppsEnabled) {
12217            return true;
12218        }
12219
12220        return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
12221                android.provider.Settings.Global.PACKAGE_VERIFIER_ENABLE, 1) == 1;
12222    }
12223
12224    @Override
12225    public void verifyIntentFilter(int id, int verificationCode, List<String> failedDomains)
12226            throws RemoteException {
12227        mContext.enforceCallingOrSelfPermission(
12228                Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT,
12229                "Only intentfilter verification agents can verify applications");
12230
12231        final Message msg = mHandler.obtainMessage(INTENT_FILTER_VERIFIED);
12232        final IntentFilterVerificationResponse response = new IntentFilterVerificationResponse(
12233                Binder.getCallingUid(), verificationCode, failedDomains);
12234        msg.arg1 = id;
12235        msg.obj = response;
12236        mHandler.sendMessage(msg);
12237    }
12238
12239    @Override
12240    public int getIntentVerificationStatus(String packageName, int userId) {
12241        synchronized (mPackages) {
12242            return mSettings.getIntentFilterVerificationStatusLPr(packageName, userId);
12243        }
12244    }
12245
12246    @Override
12247    public boolean updateIntentVerificationStatus(String packageName, int status, int userId) {
12248        mContext.enforceCallingOrSelfPermission(
12249                android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
12250
12251        boolean result = false;
12252        synchronized (mPackages) {
12253            result = mSettings.updateIntentFilterVerificationStatusLPw(packageName, status, userId);
12254        }
12255        if (result) {
12256            scheduleWritePackageRestrictionsLocked(userId);
12257        }
12258        return result;
12259    }
12260
12261    @Override
12262    public @NonNull ParceledListSlice<IntentFilterVerificationInfo> getIntentFilterVerifications(
12263            String packageName) {
12264        synchronized (mPackages) {
12265            return new ParceledListSlice<>(mSettings.getIntentFilterVerificationsLPr(packageName));
12266        }
12267    }
12268
12269    @Override
12270    public @NonNull ParceledListSlice<IntentFilter> getAllIntentFilters(String packageName) {
12271        if (TextUtils.isEmpty(packageName)) {
12272            return ParceledListSlice.emptyList();
12273        }
12274        synchronized (mPackages) {
12275            PackageParser.Package pkg = mPackages.get(packageName);
12276            if (pkg == null || pkg.activities == null) {
12277                return ParceledListSlice.emptyList();
12278            }
12279            final int count = pkg.activities.size();
12280            ArrayList<IntentFilter> result = new ArrayList<>();
12281            for (int n=0; n<count; n++) {
12282                PackageParser.Activity activity = pkg.activities.get(n);
12283                if (activity.intents != null && activity.intents.size() > 0) {
12284                    result.addAll(activity.intents);
12285                }
12286            }
12287            return new ParceledListSlice<>(result);
12288        }
12289    }
12290
12291    @Override
12292    public boolean setDefaultBrowserPackageName(String packageName, int userId) {
12293        mContext.enforceCallingOrSelfPermission(
12294                android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
12295
12296        synchronized (mPackages) {
12297            boolean result = mSettings.setDefaultBrowserPackageNameLPw(packageName, userId);
12298            if (packageName != null) {
12299                result |= updateIntentVerificationStatus(packageName,
12300                        PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS,
12301                        userId);
12302                mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultBrowserLPr(
12303                        packageName, userId);
12304            }
12305            return result;
12306        }
12307    }
12308
12309    @Override
12310    public String getDefaultBrowserPackageName(int userId) {
12311        synchronized (mPackages) {
12312            return mSettings.getDefaultBrowserPackageNameLPw(userId);
12313        }
12314    }
12315
12316    /**
12317     * Get the "allow unknown sources" setting.
12318     *
12319     * @return the current "allow unknown sources" setting
12320     */
12321    private int getUnknownSourcesSettings() {
12322        return android.provider.Settings.Secure.getInt(mContext.getContentResolver(),
12323                android.provider.Settings.Secure.INSTALL_NON_MARKET_APPS,
12324                -1);
12325    }
12326
12327    @Override
12328    public void setInstallerPackageName(String targetPackage, String installerPackageName) {
12329        final int uid = Binder.getCallingUid();
12330        // writer
12331        synchronized (mPackages) {
12332            PackageSetting targetPackageSetting = mSettings.mPackages.get(targetPackage);
12333            if (targetPackageSetting == null) {
12334                throw new IllegalArgumentException("Unknown target package: " + targetPackage);
12335            }
12336
12337            PackageSetting installerPackageSetting;
12338            if (installerPackageName != null) {
12339                installerPackageSetting = mSettings.mPackages.get(installerPackageName);
12340                if (installerPackageSetting == null) {
12341                    throw new IllegalArgumentException("Unknown installer package: "
12342                            + installerPackageName);
12343                }
12344            } else {
12345                installerPackageSetting = null;
12346            }
12347
12348            Signature[] callerSignature;
12349            Object obj = mSettings.getUserIdLPr(uid);
12350            if (obj != null) {
12351                if (obj instanceof SharedUserSetting) {
12352                    callerSignature = ((SharedUserSetting)obj).signatures.mSignatures;
12353                } else if (obj instanceof PackageSetting) {
12354                    callerSignature = ((PackageSetting)obj).signatures.mSignatures;
12355                } else {
12356                    throw new SecurityException("Bad object " + obj + " for uid " + uid);
12357                }
12358            } else {
12359                throw new SecurityException("Unknown calling UID: " + uid);
12360            }
12361
12362            // Verify: can't set installerPackageName to a package that is
12363            // not signed with the same cert as the caller.
12364            if (installerPackageSetting != null) {
12365                if (compareSignatures(callerSignature,
12366                        installerPackageSetting.signatures.mSignatures)
12367                        != PackageManager.SIGNATURE_MATCH) {
12368                    throw new SecurityException(
12369                            "Caller does not have same cert as new installer package "
12370                            + installerPackageName);
12371                }
12372            }
12373
12374            // Verify: if target already has an installer package, it must
12375            // be signed with the same cert as the caller.
12376            if (targetPackageSetting.installerPackageName != null) {
12377                PackageSetting setting = mSettings.mPackages.get(
12378                        targetPackageSetting.installerPackageName);
12379                // If the currently set package isn't valid, then it's always
12380                // okay to change it.
12381                if (setting != null) {
12382                    if (compareSignatures(callerSignature,
12383                            setting.signatures.mSignatures)
12384                            != PackageManager.SIGNATURE_MATCH) {
12385                        throw new SecurityException(
12386                                "Caller does not have same cert as old installer package "
12387                                + targetPackageSetting.installerPackageName);
12388                    }
12389                }
12390            }
12391
12392            // Okay!
12393            targetPackageSetting.installerPackageName = installerPackageName;
12394            if (installerPackageName != null) {
12395                mSettings.mInstallerPackages.add(installerPackageName);
12396            }
12397            scheduleWriteSettingsLocked();
12398        }
12399    }
12400
12401    private void processPendingInstall(final InstallArgs args, final int currentStatus) {
12402        // Queue up an async operation since the package installation may take a little while.
12403        mHandler.post(new Runnable() {
12404            public void run() {
12405                mHandler.removeCallbacks(this);
12406                 // Result object to be returned
12407                PackageInstalledInfo res = new PackageInstalledInfo();
12408                res.setReturnCode(currentStatus);
12409                res.uid = -1;
12410                res.pkg = null;
12411                res.removedInfo = null;
12412                if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
12413                    args.doPreInstall(res.returnCode);
12414                    synchronized (mInstallLock) {
12415                        installPackageTracedLI(args, res);
12416                    }
12417                    args.doPostInstall(res.returnCode, res.uid);
12418                }
12419
12420                // A restore should be performed at this point if (a) the install
12421                // succeeded, (b) the operation is not an update, and (c) the new
12422                // package has not opted out of backup participation.
12423                final boolean update = res.removedInfo != null
12424                        && res.removedInfo.removedPackage != null;
12425                final int flags = (res.pkg == null) ? 0 : res.pkg.applicationInfo.flags;
12426                boolean doRestore = !update
12427                        && ((flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0);
12428
12429                // Set up the post-install work request bookkeeping.  This will be used
12430                // and cleaned up by the post-install event handling regardless of whether
12431                // there's a restore pass performed.  Token values are >= 1.
12432                int token;
12433                if (mNextInstallToken < 0) mNextInstallToken = 1;
12434                token = mNextInstallToken++;
12435
12436                PostInstallData data = new PostInstallData(args, res);
12437                mRunningInstalls.put(token, data);
12438                if (DEBUG_INSTALL) Log.v(TAG, "+ starting restore round-trip " + token);
12439
12440                if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && doRestore) {
12441                    // Pass responsibility to the Backup Manager.  It will perform a
12442                    // restore if appropriate, then pass responsibility back to the
12443                    // Package Manager to run the post-install observer callbacks
12444                    // and broadcasts.
12445                    IBackupManager bm = IBackupManager.Stub.asInterface(
12446                            ServiceManager.getService(Context.BACKUP_SERVICE));
12447                    if (bm != null) {
12448                        if (DEBUG_INSTALL) Log.v(TAG, "token " + token
12449                                + " to BM for possible restore");
12450                        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "restore", token);
12451                        try {
12452                            // TODO: http://b/22388012
12453                            if (bm.isBackupServiceActive(UserHandle.USER_SYSTEM)) {
12454                                bm.restoreAtInstall(res.pkg.applicationInfo.packageName, token);
12455                            } else {
12456                                doRestore = false;
12457                            }
12458                        } catch (RemoteException e) {
12459                            // can't happen; the backup manager is local
12460                        } catch (Exception e) {
12461                            Slog.e(TAG, "Exception trying to enqueue restore", e);
12462                            doRestore = false;
12463                        }
12464                    } else {
12465                        Slog.e(TAG, "Backup Manager not found!");
12466                        doRestore = false;
12467                    }
12468                }
12469
12470                if (!doRestore) {
12471                    // No restore possible, or the Backup Manager was mysteriously not
12472                    // available -- just fire the post-install work request directly.
12473                    if (DEBUG_INSTALL) Log.v(TAG, "No restore - queue post-install for " + token);
12474
12475                    Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "postInstall", token);
12476
12477                    Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0);
12478                    mHandler.sendMessage(msg);
12479                }
12480            }
12481        });
12482    }
12483
12484    /**
12485     * Callback from PackageSettings whenever an app is first transitioned out of the
12486     * 'stopped' state.  Normally we just issue the broadcast, but we can't do that if
12487     * the app was "launched" for a restoreAtInstall operation.  Therefore we check
12488     * here whether the app is the target of an ongoing install, and only send the
12489     * broadcast immediately if it is not in that state.  If it *is* undergoing a restore,
12490     * the first-launch broadcast will be sent implicitly on that basis in POST_INSTALL
12491     * handling.
12492     */
12493    void notifyFirstLaunch(final String pkgName, final String installerPackage, final int userId) {
12494        // Serialize this with the rest of the install-process message chain.  In the
12495        // restore-at-install case, this Runnable will necessarily run before the
12496        // POST_INSTALL message is processed, so the contents of mRunningInstalls
12497        // are coherent.  In the non-restore case, the app has already completed install
12498        // and been launched through some other means, so it is not in a problematic
12499        // state for observers to see the FIRST_LAUNCH signal.
12500        mHandler.post(new Runnable() {
12501            @Override
12502            public void run() {
12503                for (int i = 0; i < mRunningInstalls.size(); i++) {
12504                    final PostInstallData data = mRunningInstalls.valueAt(i);
12505                    if (data.res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
12506                        continue;
12507                    }
12508                    if (pkgName.equals(data.res.pkg.applicationInfo.packageName)) {
12509                        // right package; but is it for the right user?
12510                        for (int uIndex = 0; uIndex < data.res.newUsers.length; uIndex++) {
12511                            if (userId == data.res.newUsers[uIndex]) {
12512                                if (DEBUG_BACKUP) {
12513                                    Slog.i(TAG, "Package " + pkgName
12514                                            + " being restored so deferring FIRST_LAUNCH");
12515                                }
12516                                return;
12517                            }
12518                        }
12519                    }
12520                }
12521                // didn't find it, so not being restored
12522                if (DEBUG_BACKUP) {
12523                    Slog.i(TAG, "Package " + pkgName + " sending normal FIRST_LAUNCH");
12524                }
12525                sendFirstLaunchBroadcast(pkgName, installerPackage, new int[] {userId});
12526            }
12527        });
12528    }
12529
12530    private void sendFirstLaunchBroadcast(String pkgName, String installerPkg, int[] userIds) {
12531        sendPackageBroadcast(Intent.ACTION_PACKAGE_FIRST_LAUNCH, pkgName, null, 0,
12532                installerPkg, null, userIds);
12533    }
12534
12535    private abstract class HandlerParams {
12536        private static final int MAX_RETRIES = 4;
12537
12538        /**
12539         * Number of times startCopy() has been attempted and had a non-fatal
12540         * error.
12541         */
12542        private int mRetries = 0;
12543
12544        /** User handle for the user requesting the information or installation. */
12545        private final UserHandle mUser;
12546        String traceMethod;
12547        int traceCookie;
12548
12549        HandlerParams(UserHandle user) {
12550            mUser = user;
12551        }
12552
12553        UserHandle getUser() {
12554            return mUser;
12555        }
12556
12557        HandlerParams setTraceMethod(String traceMethod) {
12558            this.traceMethod = traceMethod;
12559            return this;
12560        }
12561
12562        HandlerParams setTraceCookie(int traceCookie) {
12563            this.traceCookie = traceCookie;
12564            return this;
12565        }
12566
12567        final boolean startCopy() {
12568            boolean res;
12569            try {
12570                if (DEBUG_INSTALL) Slog.i(TAG, "startCopy " + mUser + ": " + this);
12571
12572                if (++mRetries > MAX_RETRIES) {
12573                    Slog.w(TAG, "Failed to invoke remote methods on default container service. Giving up");
12574                    mHandler.sendEmptyMessage(MCS_GIVE_UP);
12575                    handleServiceError();
12576                    return false;
12577                } else {
12578                    handleStartCopy();
12579                    res = true;
12580                }
12581            } catch (RemoteException e) {
12582                if (DEBUG_INSTALL) Slog.i(TAG, "Posting install MCS_RECONNECT");
12583                mHandler.sendEmptyMessage(MCS_RECONNECT);
12584                res = false;
12585            }
12586            handleReturnCode();
12587            return res;
12588        }
12589
12590        final void serviceError() {
12591            if (DEBUG_INSTALL) Slog.i(TAG, "serviceError");
12592            handleServiceError();
12593            handleReturnCode();
12594        }
12595
12596        abstract void handleStartCopy() throws RemoteException;
12597        abstract void handleServiceError();
12598        abstract void handleReturnCode();
12599    }
12600
12601    class MeasureParams extends HandlerParams {
12602        private final PackageStats mStats;
12603        private boolean mSuccess;
12604
12605        private final IPackageStatsObserver mObserver;
12606
12607        public MeasureParams(PackageStats stats, IPackageStatsObserver observer) {
12608            super(new UserHandle(stats.userHandle));
12609            mObserver = observer;
12610            mStats = stats;
12611        }
12612
12613        @Override
12614        public String toString() {
12615            return "MeasureParams{"
12616                + Integer.toHexString(System.identityHashCode(this))
12617                + " " + mStats.packageName + "}";
12618        }
12619
12620        @Override
12621        void handleStartCopy() throws RemoteException {
12622            synchronized (mInstallLock) {
12623                mSuccess = getPackageSizeInfoLI(mStats.packageName, mStats.userHandle, mStats);
12624            }
12625
12626            if (mSuccess) {
12627                boolean mounted = false;
12628                try {
12629                    final String status = Environment.getExternalStorageState();
12630                    mounted = (Environment.MEDIA_MOUNTED.equals(status)
12631                            || Environment.MEDIA_MOUNTED_READ_ONLY.equals(status));
12632                } catch (Exception e) {
12633                }
12634
12635                if (mounted) {
12636                    final UserEnvironment userEnv = new UserEnvironment(mStats.userHandle);
12637
12638                    mStats.externalCacheSize = calculateDirectorySize(mContainerService,
12639                            userEnv.buildExternalStorageAppCacheDirs(mStats.packageName));
12640
12641                    mStats.externalDataSize = calculateDirectorySize(mContainerService,
12642                            userEnv.buildExternalStorageAppDataDirs(mStats.packageName));
12643
12644                    // Always subtract cache size, since it's a subdirectory
12645                    mStats.externalDataSize -= mStats.externalCacheSize;
12646
12647                    mStats.externalMediaSize = calculateDirectorySize(mContainerService,
12648                            userEnv.buildExternalStorageAppMediaDirs(mStats.packageName));
12649
12650                    mStats.externalObbSize = calculateDirectorySize(mContainerService,
12651                            userEnv.buildExternalStorageAppObbDirs(mStats.packageName));
12652                }
12653            }
12654        }
12655
12656        @Override
12657        void handleReturnCode() {
12658            if (mObserver != null) {
12659                try {
12660                    mObserver.onGetStatsCompleted(mStats, mSuccess);
12661                } catch (RemoteException e) {
12662                    Slog.i(TAG, "Observer no longer exists.");
12663                }
12664            }
12665        }
12666
12667        @Override
12668        void handleServiceError() {
12669            Slog.e(TAG, "Could not measure application " + mStats.packageName
12670                            + " external storage");
12671        }
12672    }
12673
12674    private static long calculateDirectorySize(IMediaContainerService mcs, File[] paths)
12675            throws RemoteException {
12676        long result = 0;
12677        for (File path : paths) {
12678            result += mcs.calculateDirectorySize(path.getAbsolutePath());
12679        }
12680        return result;
12681    }
12682
12683    private static void clearDirectory(IMediaContainerService mcs, File[] paths) {
12684        for (File path : paths) {
12685            try {
12686                mcs.clearDirectory(path.getAbsolutePath());
12687            } catch (RemoteException e) {
12688            }
12689        }
12690    }
12691
12692    static class OriginInfo {
12693        /**
12694         * Location where install is coming from, before it has been
12695         * copied/renamed into place. This could be a single monolithic APK
12696         * file, or a cluster directory. This location may be untrusted.
12697         */
12698        final File file;
12699        final String cid;
12700
12701        /**
12702         * Flag indicating that {@link #file} or {@link #cid} has already been
12703         * staged, meaning downstream users don't need to defensively copy the
12704         * contents.
12705         */
12706        final boolean staged;
12707
12708        /**
12709         * Flag indicating that {@link #file} or {@link #cid} is an already
12710         * installed app that is being moved.
12711         */
12712        final boolean existing;
12713
12714        final String resolvedPath;
12715        final File resolvedFile;
12716
12717        static OriginInfo fromNothing() {
12718            return new OriginInfo(null, null, false, false);
12719        }
12720
12721        static OriginInfo fromUntrustedFile(File file) {
12722            return new OriginInfo(file, null, false, false);
12723        }
12724
12725        static OriginInfo fromExistingFile(File file) {
12726            return new OriginInfo(file, null, false, true);
12727        }
12728
12729        static OriginInfo fromStagedFile(File file) {
12730            return new OriginInfo(file, null, true, false);
12731        }
12732
12733        static OriginInfo fromStagedContainer(String cid) {
12734            return new OriginInfo(null, cid, true, false);
12735        }
12736
12737        private OriginInfo(File file, String cid, boolean staged, boolean existing) {
12738            this.file = file;
12739            this.cid = cid;
12740            this.staged = staged;
12741            this.existing = existing;
12742
12743            if (cid != null) {
12744                resolvedPath = PackageHelper.getSdDir(cid);
12745                resolvedFile = new File(resolvedPath);
12746            } else if (file != null) {
12747                resolvedPath = file.getAbsolutePath();
12748                resolvedFile = file;
12749            } else {
12750                resolvedPath = null;
12751                resolvedFile = null;
12752            }
12753        }
12754    }
12755
12756    static class MoveInfo {
12757        final int moveId;
12758        final String fromUuid;
12759        final String toUuid;
12760        final String packageName;
12761        final String dataAppName;
12762        final int appId;
12763        final String seinfo;
12764        final int targetSdkVersion;
12765
12766        public MoveInfo(int moveId, String fromUuid, String toUuid, String packageName,
12767                String dataAppName, int appId, String seinfo, int targetSdkVersion) {
12768            this.moveId = moveId;
12769            this.fromUuid = fromUuid;
12770            this.toUuid = toUuid;
12771            this.packageName = packageName;
12772            this.dataAppName = dataAppName;
12773            this.appId = appId;
12774            this.seinfo = seinfo;
12775            this.targetSdkVersion = targetSdkVersion;
12776        }
12777    }
12778
12779    static class VerificationInfo {
12780        /** A constant used to indicate that a uid value is not present. */
12781        public static final int NO_UID = -1;
12782
12783        /** URI referencing where the package was downloaded from. */
12784        final Uri originatingUri;
12785
12786        /** HTTP referrer URI associated with the originatingURI. */
12787        final Uri referrer;
12788
12789        /** UID of the application that the install request originated from. */
12790        final int originatingUid;
12791
12792        /** UID of application requesting the install */
12793        final int installerUid;
12794
12795        VerificationInfo(Uri originatingUri, Uri referrer, int originatingUid, int installerUid) {
12796            this.originatingUri = originatingUri;
12797            this.referrer = referrer;
12798            this.originatingUid = originatingUid;
12799            this.installerUid = installerUid;
12800        }
12801    }
12802
12803    class InstallParams extends HandlerParams {
12804        final OriginInfo origin;
12805        final MoveInfo move;
12806        final IPackageInstallObserver2 observer;
12807        int installFlags;
12808        final String installerPackageName;
12809        final String volumeUuid;
12810        private InstallArgs mArgs;
12811        private int mRet;
12812        final String packageAbiOverride;
12813        final String[] grantedRuntimePermissions;
12814        final VerificationInfo verificationInfo;
12815        final Certificate[][] certificates;
12816
12817        InstallParams(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
12818                int installFlags, String installerPackageName, String volumeUuid,
12819                VerificationInfo verificationInfo, UserHandle user, String packageAbiOverride,
12820                String[] grantedPermissions, Certificate[][] certificates) {
12821            super(user);
12822            this.origin = origin;
12823            this.move = move;
12824            this.observer = observer;
12825            this.installFlags = installFlags;
12826            this.installerPackageName = installerPackageName;
12827            this.volumeUuid = volumeUuid;
12828            this.verificationInfo = verificationInfo;
12829            this.packageAbiOverride = packageAbiOverride;
12830            this.grantedRuntimePermissions = grantedPermissions;
12831            this.certificates = certificates;
12832        }
12833
12834        @Override
12835        public String toString() {
12836            return "InstallParams{" + Integer.toHexString(System.identityHashCode(this))
12837                    + " file=" + origin.file + " cid=" + origin.cid + "}";
12838        }
12839
12840        private int installLocationPolicy(PackageInfoLite pkgLite) {
12841            String packageName = pkgLite.packageName;
12842            int installLocation = pkgLite.installLocation;
12843            boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
12844            // reader
12845            synchronized (mPackages) {
12846                // Currently installed package which the new package is attempting to replace or
12847                // null if no such package is installed.
12848                PackageParser.Package installedPkg = mPackages.get(packageName);
12849                // Package which currently owns the data which the new package will own if installed.
12850                // If an app is unstalled while keeping data (e.g., adb uninstall -k), installedPkg
12851                // will be null whereas dataOwnerPkg will contain information about the package
12852                // which was uninstalled while keeping its data.
12853                PackageParser.Package dataOwnerPkg = installedPkg;
12854                if (dataOwnerPkg  == null) {
12855                    PackageSetting ps = mSettings.mPackages.get(packageName);
12856                    if (ps != null) {
12857                        dataOwnerPkg = ps.pkg;
12858                    }
12859                }
12860
12861                if (dataOwnerPkg != null) {
12862                    // If installed, the package will get access to data left on the device by its
12863                    // predecessor. As a security measure, this is permited only if this is not a
12864                    // version downgrade or if the predecessor package is marked as debuggable and
12865                    // a downgrade is explicitly requested.
12866                    //
12867                    // On debuggable platform builds, downgrades are permitted even for
12868                    // non-debuggable packages to make testing easier. Debuggable platform builds do
12869                    // not offer security guarantees and thus it's OK to disable some security
12870                    // mechanisms to make debugging/testing easier on those builds. However, even on
12871                    // debuggable builds downgrades of packages are permitted only if requested via
12872                    // installFlags. This is because we aim to keep the behavior of debuggable
12873                    // platform builds as close as possible to the behavior of non-debuggable
12874                    // platform builds.
12875                    final boolean downgradeRequested =
12876                            (installFlags & PackageManager.INSTALL_ALLOW_DOWNGRADE) != 0;
12877                    final boolean packageDebuggable =
12878                                (dataOwnerPkg.applicationInfo.flags
12879                                        & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
12880                    final boolean downgradePermitted =
12881                            (downgradeRequested) && ((Build.IS_DEBUGGABLE) || (packageDebuggable));
12882                    if (!downgradePermitted) {
12883                        try {
12884                            checkDowngrade(dataOwnerPkg, pkgLite);
12885                        } catch (PackageManagerException e) {
12886                            Slog.w(TAG, "Downgrade detected: " + e.getMessage());
12887                            return PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE;
12888                        }
12889                    }
12890                }
12891
12892                if (installedPkg != null) {
12893                    if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
12894                        // Check for updated system application.
12895                        if ((installedPkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
12896                            if (onSd) {
12897                                Slog.w(TAG, "Cannot install update to system app on sdcard");
12898                                return PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION;
12899                            }
12900                            return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
12901                        } else {
12902                            if (onSd) {
12903                                // Install flag overrides everything.
12904                                return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
12905                            }
12906                            // If current upgrade specifies particular preference
12907                            if (installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) {
12908                                // Application explicitly specified internal.
12909                                return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
12910                            } else if (installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) {
12911                                // App explictly prefers external. Let policy decide
12912                            } else {
12913                                // Prefer previous location
12914                                if (isExternal(installedPkg)) {
12915                                    return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
12916                                }
12917                                return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
12918                            }
12919                        }
12920                    } else {
12921                        // Invalid install. Return error code
12922                        return PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS;
12923                    }
12924                }
12925            }
12926            // All the special cases have been taken care of.
12927            // Return result based on recommended install location.
12928            if (onSd) {
12929                return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
12930            }
12931            return pkgLite.recommendedInstallLocation;
12932        }
12933
12934        /*
12935         * Invoke remote method to get package information and install
12936         * location values. Override install location based on default
12937         * policy if needed and then create install arguments based
12938         * on the install location.
12939         */
12940        public void handleStartCopy() throws RemoteException {
12941            int ret = PackageManager.INSTALL_SUCCEEDED;
12942
12943            // If we're already staged, we've firmly committed to an install location
12944            if (origin.staged) {
12945                if (origin.file != null) {
12946                    installFlags |= PackageManager.INSTALL_INTERNAL;
12947                    installFlags &= ~PackageManager.INSTALL_EXTERNAL;
12948                } else if (origin.cid != null) {
12949                    installFlags |= PackageManager.INSTALL_EXTERNAL;
12950                    installFlags &= ~PackageManager.INSTALL_INTERNAL;
12951                } else {
12952                    throw new IllegalStateException("Invalid stage location");
12953                }
12954            }
12955
12956            final boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
12957            final boolean onInt = (installFlags & PackageManager.INSTALL_INTERNAL) != 0;
12958            final boolean ephemeral = (installFlags & PackageManager.INSTALL_EPHEMERAL) != 0;
12959            PackageInfoLite pkgLite = null;
12960
12961            if (onInt && onSd) {
12962                // Check if both bits are set.
12963                Slog.w(TAG, "Conflicting flags specified for installing on both internal and external");
12964                ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
12965            } else if (onSd && ephemeral) {
12966                Slog.w(TAG,  "Conflicting flags specified for installing ephemeral on external");
12967                ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
12968            } else {
12969                pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, installFlags,
12970                        packageAbiOverride);
12971
12972                if (DEBUG_EPHEMERAL && ephemeral) {
12973                    Slog.v(TAG, "pkgLite for install: " + pkgLite);
12974                }
12975
12976                /*
12977                 * If we have too little free space, try to free cache
12978                 * before giving up.
12979                 */
12980                if (!origin.staged && pkgLite.recommendedInstallLocation
12981                        == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
12982                    // TODO: focus freeing disk space on the target device
12983                    final StorageManager storage = StorageManager.from(mContext);
12984                    final long lowThreshold = storage.getStorageLowBytes(
12985                            Environment.getDataDirectory());
12986
12987                    final long sizeBytes = mContainerService.calculateInstalledSize(
12988                            origin.resolvedPath, isForwardLocked(), packageAbiOverride);
12989
12990                    try {
12991                        mInstaller.freeCache(null, sizeBytes + lowThreshold, 0);
12992                        pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath,
12993                                installFlags, packageAbiOverride);
12994                    } catch (InstallerException e) {
12995                        Slog.w(TAG, "Failed to free cache", e);
12996                    }
12997
12998                    /*
12999                     * The cache free must have deleted the file we
13000                     * downloaded to install.
13001                     *
13002                     * TODO: fix the "freeCache" call to not delete
13003                     *       the file we care about.
13004                     */
13005                    if (pkgLite.recommendedInstallLocation
13006                            == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
13007                        pkgLite.recommendedInstallLocation
13008                            = PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE;
13009                    }
13010                }
13011            }
13012
13013            if (ret == PackageManager.INSTALL_SUCCEEDED) {
13014                int loc = pkgLite.recommendedInstallLocation;
13015                if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION) {
13016                    ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
13017                } else if (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS) {
13018                    ret = PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
13019                } else if (loc == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
13020                    ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
13021                } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_APK) {
13022                    ret = PackageManager.INSTALL_FAILED_INVALID_APK;
13023                } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
13024                    ret = PackageManager.INSTALL_FAILED_INVALID_URI;
13025                } else if (loc == PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE) {
13026                    ret = PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE;
13027                } else {
13028                    // Override with defaults if needed.
13029                    loc = installLocationPolicy(pkgLite);
13030                    if (loc == PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE) {
13031                        ret = PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
13032                    } else if (!onSd && !onInt) {
13033                        // Override install location with flags
13034                        if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) {
13035                            // Set the flag to install on external media.
13036                            installFlags |= PackageManager.INSTALL_EXTERNAL;
13037                            installFlags &= ~PackageManager.INSTALL_INTERNAL;
13038                        } else if (loc == PackageHelper.RECOMMEND_INSTALL_EPHEMERAL) {
13039                            if (DEBUG_EPHEMERAL) {
13040                                Slog.v(TAG, "...setting INSTALL_EPHEMERAL install flag");
13041                            }
13042                            installFlags |= PackageManager.INSTALL_EPHEMERAL;
13043                            installFlags &= ~(PackageManager.INSTALL_EXTERNAL
13044                                    |PackageManager.INSTALL_INTERNAL);
13045                        } else {
13046                            // Make sure the flag for installing on external
13047                            // media is unset
13048                            installFlags |= PackageManager.INSTALL_INTERNAL;
13049                            installFlags &= ~PackageManager.INSTALL_EXTERNAL;
13050                        }
13051                    }
13052                }
13053            }
13054
13055            final InstallArgs args = createInstallArgs(this);
13056            mArgs = args;
13057
13058            if (ret == PackageManager.INSTALL_SUCCEEDED) {
13059                // TODO: http://b/22976637
13060                // Apps installed for "all" users use the device owner to verify the app
13061                UserHandle verifierUser = getUser();
13062                if (verifierUser == UserHandle.ALL) {
13063                    verifierUser = UserHandle.SYSTEM;
13064                }
13065
13066                /*
13067                 * Determine if we have any installed package verifiers. If we
13068                 * do, then we'll defer to them to verify the packages.
13069                 */
13070                final int requiredUid = mRequiredVerifierPackage == null ? -1
13071                        : getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
13072                                verifierUser.getIdentifier());
13073                if (!origin.existing && requiredUid != -1
13074                        && isVerificationEnabled(verifierUser.getIdentifier(), installFlags)) {
13075                    final Intent verification = new Intent(
13076                            Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
13077                    verification.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
13078                    verification.setDataAndType(Uri.fromFile(new File(origin.resolvedPath)),
13079                            PACKAGE_MIME_TYPE);
13080                    verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
13081
13082                    // Query all live verifiers based on current user state
13083                    final List<ResolveInfo> receivers = queryIntentReceiversInternal(verification,
13084                            PACKAGE_MIME_TYPE, 0, verifierUser.getIdentifier());
13085
13086                    if (DEBUG_VERIFY) {
13087                        Slog.d(TAG, "Found " + receivers.size() + " verifiers for intent "
13088                                + verification.toString() + " with " + pkgLite.verifiers.length
13089                                + " optional verifiers");
13090                    }
13091
13092                    final int verificationId = mPendingVerificationToken++;
13093
13094                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
13095
13096                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_PACKAGE,
13097                            installerPackageName);
13098
13099                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALL_FLAGS,
13100                            installFlags);
13101
13102                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_PACKAGE_NAME,
13103                            pkgLite.packageName);
13104
13105                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_VERSION_CODE,
13106                            pkgLite.versionCode);
13107
13108                    if (verificationInfo != null) {
13109                        if (verificationInfo.originatingUri != null) {
13110                            verification.putExtra(Intent.EXTRA_ORIGINATING_URI,
13111                                    verificationInfo.originatingUri);
13112                        }
13113                        if (verificationInfo.referrer != null) {
13114                            verification.putExtra(Intent.EXTRA_REFERRER,
13115                                    verificationInfo.referrer);
13116                        }
13117                        if (verificationInfo.originatingUid >= 0) {
13118                            verification.putExtra(Intent.EXTRA_ORIGINATING_UID,
13119                                    verificationInfo.originatingUid);
13120                        }
13121                        if (verificationInfo.installerUid >= 0) {
13122                            verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_UID,
13123                                    verificationInfo.installerUid);
13124                        }
13125                    }
13126
13127                    final PackageVerificationState verificationState = new PackageVerificationState(
13128                            requiredUid, args);
13129
13130                    mPendingVerification.append(verificationId, verificationState);
13131
13132                    final List<ComponentName> sufficientVerifiers = matchVerifiers(pkgLite,
13133                            receivers, verificationState);
13134
13135                    /*
13136                     * If any sufficient verifiers were listed in the package
13137                     * manifest, attempt to ask them.
13138                     */
13139                    if (sufficientVerifiers != null) {
13140                        final int N = sufficientVerifiers.size();
13141                        if (N == 0) {
13142                            Slog.i(TAG, "Additional verifiers required, but none installed.");
13143                            ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
13144                        } else {
13145                            for (int i = 0; i < N; i++) {
13146                                final ComponentName verifierComponent = sufficientVerifiers.get(i);
13147
13148                                final Intent sufficientIntent = new Intent(verification);
13149                                sufficientIntent.setComponent(verifierComponent);
13150                                mContext.sendBroadcastAsUser(sufficientIntent, verifierUser);
13151                            }
13152                        }
13153                    }
13154
13155                    final ComponentName requiredVerifierComponent = matchComponentForVerifier(
13156                            mRequiredVerifierPackage, receivers);
13157                    if (ret == PackageManager.INSTALL_SUCCEEDED
13158                            && mRequiredVerifierPackage != null) {
13159                        Trace.asyncTraceBegin(
13160                                TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
13161                        /*
13162                         * Send the intent to the required verification agent,
13163                         * but only start the verification timeout after the
13164                         * target BroadcastReceivers have run.
13165                         */
13166                        verification.setComponent(requiredVerifierComponent);
13167                        mContext.sendOrderedBroadcastAsUser(verification, verifierUser,
13168                                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
13169                                new BroadcastReceiver() {
13170                                    @Override
13171                                    public void onReceive(Context context, Intent intent) {
13172                                        final Message msg = mHandler
13173                                                .obtainMessage(CHECK_PENDING_VERIFICATION);
13174                                        msg.arg1 = verificationId;
13175                                        mHandler.sendMessageDelayed(msg, getVerificationTimeout());
13176                                    }
13177                                }, null, 0, null, null);
13178
13179                        /*
13180                         * We don't want the copy to proceed until verification
13181                         * succeeds, so null out this field.
13182                         */
13183                        mArgs = null;
13184                    }
13185                } else {
13186                    /*
13187                     * No package verification is enabled, so immediately start
13188                     * the remote call to initiate copy using temporary file.
13189                     */
13190                    ret = args.copyApk(mContainerService, true);
13191                }
13192            }
13193
13194            mRet = ret;
13195        }
13196
13197        @Override
13198        void handleReturnCode() {
13199            // If mArgs is null, then MCS couldn't be reached. When it
13200            // reconnects, it will try again to install. At that point, this
13201            // will succeed.
13202            if (mArgs != null) {
13203                processPendingInstall(mArgs, mRet);
13204            }
13205        }
13206
13207        @Override
13208        void handleServiceError() {
13209            mArgs = createInstallArgs(this);
13210            mRet = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
13211        }
13212
13213        public boolean isForwardLocked() {
13214            return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
13215        }
13216    }
13217
13218    /**
13219     * Used during creation of InstallArgs
13220     *
13221     * @param installFlags package installation flags
13222     * @return true if should be installed on external storage
13223     */
13224    private static boolean installOnExternalAsec(int installFlags) {
13225        if ((installFlags & PackageManager.INSTALL_INTERNAL) != 0) {
13226            return false;
13227        }
13228        if ((installFlags & PackageManager.INSTALL_EXTERNAL) != 0) {
13229            return true;
13230        }
13231        return false;
13232    }
13233
13234    /**
13235     * Used during creation of InstallArgs
13236     *
13237     * @param installFlags package installation flags
13238     * @return true if should be installed as forward locked
13239     */
13240    private static boolean installForwardLocked(int installFlags) {
13241        return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
13242    }
13243
13244    private InstallArgs createInstallArgs(InstallParams params) {
13245        if (params.move != null) {
13246            return new MoveInstallArgs(params);
13247        } else if (installOnExternalAsec(params.installFlags) || params.isForwardLocked()) {
13248            return new AsecInstallArgs(params);
13249        } else {
13250            return new FileInstallArgs(params);
13251        }
13252    }
13253
13254    /**
13255     * Create args that describe an existing installed package. Typically used
13256     * when cleaning up old installs, or used as a move source.
13257     */
13258    private InstallArgs createInstallArgsForExisting(int installFlags, String codePath,
13259            String resourcePath, String[] instructionSets) {
13260        final boolean isInAsec;
13261        if (installOnExternalAsec(installFlags)) {
13262            /* Apps on SD card are always in ASEC containers. */
13263            isInAsec = true;
13264        } else if (installForwardLocked(installFlags)
13265                && !codePath.startsWith(mDrmAppPrivateInstallDir.getAbsolutePath())) {
13266            /*
13267             * Forward-locked apps are only in ASEC containers if they're the
13268             * new style
13269             */
13270            isInAsec = true;
13271        } else {
13272            isInAsec = false;
13273        }
13274
13275        if (isInAsec) {
13276            return new AsecInstallArgs(codePath, instructionSets,
13277                    installOnExternalAsec(installFlags), installForwardLocked(installFlags));
13278        } else {
13279            return new FileInstallArgs(codePath, resourcePath, instructionSets);
13280        }
13281    }
13282
13283    static abstract class InstallArgs {
13284        /** @see InstallParams#origin */
13285        final OriginInfo origin;
13286        /** @see InstallParams#move */
13287        final MoveInfo move;
13288
13289        final IPackageInstallObserver2 observer;
13290        // Always refers to PackageManager flags only
13291        final int installFlags;
13292        final String installerPackageName;
13293        final String volumeUuid;
13294        final UserHandle user;
13295        final String abiOverride;
13296        final String[] installGrantPermissions;
13297        /** If non-null, drop an async trace when the install completes */
13298        final String traceMethod;
13299        final int traceCookie;
13300        final Certificate[][] certificates;
13301
13302        // The list of instruction sets supported by this app. This is currently
13303        // only used during the rmdex() phase to clean up resources. We can get rid of this
13304        // if we move dex files under the common app path.
13305        /* nullable */ String[] instructionSets;
13306
13307        InstallArgs(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
13308                int installFlags, String installerPackageName, String volumeUuid,
13309                UserHandle user, String[] instructionSets,
13310                String abiOverride, String[] installGrantPermissions,
13311                String traceMethod, int traceCookie, Certificate[][] certificates) {
13312            this.origin = origin;
13313            this.move = move;
13314            this.installFlags = installFlags;
13315            this.observer = observer;
13316            this.installerPackageName = installerPackageName;
13317            this.volumeUuid = volumeUuid;
13318            this.user = user;
13319            this.instructionSets = instructionSets;
13320            this.abiOverride = abiOverride;
13321            this.installGrantPermissions = installGrantPermissions;
13322            this.traceMethod = traceMethod;
13323            this.traceCookie = traceCookie;
13324            this.certificates = certificates;
13325        }
13326
13327        abstract int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException;
13328        abstract int doPreInstall(int status);
13329
13330        /**
13331         * Rename package into final resting place. All paths on the given
13332         * scanned package should be updated to reflect the rename.
13333         */
13334        abstract boolean doRename(int status, PackageParser.Package pkg, String oldCodePath);
13335        abstract int doPostInstall(int status, int uid);
13336
13337        /** @see PackageSettingBase#codePathString */
13338        abstract String getCodePath();
13339        /** @see PackageSettingBase#resourcePathString */
13340        abstract String getResourcePath();
13341
13342        // Need installer lock especially for dex file removal.
13343        abstract void cleanUpResourcesLI();
13344        abstract boolean doPostDeleteLI(boolean delete);
13345
13346        /**
13347         * Called before the source arguments are copied. This is used mostly
13348         * for MoveParams when it needs to read the source file to put it in the
13349         * destination.
13350         */
13351        int doPreCopy() {
13352            return PackageManager.INSTALL_SUCCEEDED;
13353        }
13354
13355        /**
13356         * Called after the source arguments are copied. This is used mostly for
13357         * MoveParams when it needs to read the source file to put it in the
13358         * destination.
13359         */
13360        int doPostCopy(int uid) {
13361            return PackageManager.INSTALL_SUCCEEDED;
13362        }
13363
13364        protected boolean isFwdLocked() {
13365            return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
13366        }
13367
13368        protected boolean isExternalAsec() {
13369            return (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
13370        }
13371
13372        protected boolean isEphemeral() {
13373            return (installFlags & PackageManager.INSTALL_EPHEMERAL) != 0;
13374        }
13375
13376        UserHandle getUser() {
13377            return user;
13378        }
13379    }
13380
13381    private void removeDexFiles(List<String> allCodePaths, String[] instructionSets) {
13382        if (!allCodePaths.isEmpty()) {
13383            if (instructionSets == null) {
13384                throw new IllegalStateException("instructionSet == null");
13385            }
13386            String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
13387            for (String codePath : allCodePaths) {
13388                for (String dexCodeInstructionSet : dexCodeInstructionSets) {
13389                    try {
13390                        mInstaller.rmdex(codePath, dexCodeInstructionSet);
13391                    } catch (InstallerException ignored) {
13392                    }
13393                }
13394            }
13395        }
13396    }
13397
13398    /**
13399     * Logic to handle installation of non-ASEC applications, including copying
13400     * and renaming logic.
13401     */
13402    class FileInstallArgs extends InstallArgs {
13403        private File codeFile;
13404        private File resourceFile;
13405
13406        // Example topology:
13407        // /data/app/com.example/base.apk
13408        // /data/app/com.example/split_foo.apk
13409        // /data/app/com.example/lib/arm/libfoo.so
13410        // /data/app/com.example/lib/arm64/libfoo.so
13411        // /data/app/com.example/dalvik/arm/base.apk@classes.dex
13412
13413        /** New install */
13414        FileInstallArgs(InstallParams params) {
13415            super(params.origin, params.move, params.observer, params.installFlags,
13416                    params.installerPackageName, params.volumeUuid,
13417                    params.getUser(), null /*instructionSets*/, params.packageAbiOverride,
13418                    params.grantedRuntimePermissions,
13419                    params.traceMethod, params.traceCookie, params.certificates);
13420            if (isFwdLocked()) {
13421                throw new IllegalArgumentException("Forward locking only supported in ASEC");
13422            }
13423        }
13424
13425        /** Existing install */
13426        FileInstallArgs(String codePath, String resourcePath, String[] instructionSets) {
13427            super(OriginInfo.fromNothing(), null, null, 0, null, null, null, instructionSets,
13428                    null, null, null, 0, null /*certificates*/);
13429            this.codeFile = (codePath != null) ? new File(codePath) : null;
13430            this.resourceFile = (resourcePath != null) ? new File(resourcePath) : null;
13431        }
13432
13433        int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
13434            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyApk");
13435            try {
13436                return doCopyApk(imcs, temp);
13437            } finally {
13438                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
13439            }
13440        }
13441
13442        private int doCopyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
13443            if (origin.staged) {
13444                if (DEBUG_INSTALL) Slog.d(TAG, origin.file + " already staged; skipping copy");
13445                codeFile = origin.file;
13446                resourceFile = origin.file;
13447                return PackageManager.INSTALL_SUCCEEDED;
13448            }
13449
13450            try {
13451                final boolean isEphemeral = (installFlags & PackageManager.INSTALL_EPHEMERAL) != 0;
13452                final File tempDir =
13453                        mInstallerService.allocateStageDirLegacy(volumeUuid, isEphemeral);
13454                codeFile = tempDir;
13455                resourceFile = tempDir;
13456            } catch (IOException e) {
13457                Slog.w(TAG, "Failed to create copy file: " + e);
13458                return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
13459            }
13460
13461            final IParcelFileDescriptorFactory target = new IParcelFileDescriptorFactory.Stub() {
13462                @Override
13463                public ParcelFileDescriptor open(String name, int mode) throws RemoteException {
13464                    if (!FileUtils.isValidExtFilename(name)) {
13465                        throw new IllegalArgumentException("Invalid filename: " + name);
13466                    }
13467                    try {
13468                        final File file = new File(codeFile, name);
13469                        final FileDescriptor fd = Os.open(file.getAbsolutePath(),
13470                                O_RDWR | O_CREAT, 0644);
13471                        Os.chmod(file.getAbsolutePath(), 0644);
13472                        return new ParcelFileDescriptor(fd);
13473                    } catch (ErrnoException e) {
13474                        throw new RemoteException("Failed to open: " + e.getMessage());
13475                    }
13476                }
13477            };
13478
13479            int ret = PackageManager.INSTALL_SUCCEEDED;
13480            ret = imcs.copyPackage(origin.file.getAbsolutePath(), target);
13481            if (ret != PackageManager.INSTALL_SUCCEEDED) {
13482                Slog.e(TAG, "Failed to copy package");
13483                return ret;
13484            }
13485
13486            final File libraryRoot = new File(codeFile, LIB_DIR_NAME);
13487            NativeLibraryHelper.Handle handle = null;
13488            try {
13489                handle = NativeLibraryHelper.Handle.create(codeFile);
13490                ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot,
13491                        abiOverride);
13492            } catch (IOException e) {
13493                Slog.e(TAG, "Copying native libraries failed", e);
13494                ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
13495            } finally {
13496                IoUtils.closeQuietly(handle);
13497            }
13498
13499            return ret;
13500        }
13501
13502        int doPreInstall(int status) {
13503            if (status != PackageManager.INSTALL_SUCCEEDED) {
13504                cleanUp();
13505            }
13506            return status;
13507        }
13508
13509        boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
13510            if (status != PackageManager.INSTALL_SUCCEEDED) {
13511                cleanUp();
13512                return false;
13513            }
13514
13515            final File targetDir = codeFile.getParentFile();
13516            final File beforeCodeFile = codeFile;
13517            final File afterCodeFile = getNextCodePath(targetDir, pkg.packageName);
13518
13519            if (DEBUG_INSTALL) Slog.d(TAG, "Renaming " + beforeCodeFile + " to " + afterCodeFile);
13520            try {
13521                Os.rename(beforeCodeFile.getAbsolutePath(), afterCodeFile.getAbsolutePath());
13522            } catch (ErrnoException e) {
13523                Slog.w(TAG, "Failed to rename", e);
13524                return false;
13525            }
13526
13527            if (!SELinux.restoreconRecursive(afterCodeFile)) {
13528                Slog.w(TAG, "Failed to restorecon");
13529                return false;
13530            }
13531
13532            // Reflect the rename internally
13533            codeFile = afterCodeFile;
13534            resourceFile = afterCodeFile;
13535
13536            // Reflect the rename in scanned details
13537            pkg.setCodePath(afterCodeFile.getAbsolutePath());
13538            pkg.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile,
13539                    afterCodeFile, pkg.baseCodePath));
13540            pkg.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile,
13541                    afterCodeFile, pkg.splitCodePaths));
13542
13543            // Reflect the rename in app info
13544            pkg.setApplicationVolumeUuid(pkg.volumeUuid);
13545            pkg.setApplicationInfoCodePath(pkg.codePath);
13546            pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
13547            pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
13548            pkg.setApplicationInfoResourcePath(pkg.codePath);
13549            pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
13550            pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
13551
13552            return true;
13553        }
13554
13555        int doPostInstall(int status, int uid) {
13556            if (status != PackageManager.INSTALL_SUCCEEDED) {
13557                cleanUp();
13558            }
13559            return status;
13560        }
13561
13562        @Override
13563        String getCodePath() {
13564            return (codeFile != null) ? codeFile.getAbsolutePath() : null;
13565        }
13566
13567        @Override
13568        String getResourcePath() {
13569            return (resourceFile != null) ? resourceFile.getAbsolutePath() : null;
13570        }
13571
13572        private boolean cleanUp() {
13573            if (codeFile == null || !codeFile.exists()) {
13574                return false;
13575            }
13576
13577            removeCodePathLI(codeFile);
13578
13579            if (resourceFile != null && !FileUtils.contains(codeFile, resourceFile)) {
13580                resourceFile.delete();
13581            }
13582
13583            return true;
13584        }
13585
13586        void cleanUpResourcesLI() {
13587            // Try enumerating all code paths before deleting
13588            List<String> allCodePaths = Collections.EMPTY_LIST;
13589            if (codeFile != null && codeFile.exists()) {
13590                try {
13591                    final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0);
13592                    allCodePaths = pkg.getAllCodePaths();
13593                } catch (PackageParserException e) {
13594                    // Ignored; we tried our best
13595                }
13596            }
13597
13598            cleanUp();
13599            removeDexFiles(allCodePaths, instructionSets);
13600        }
13601
13602        boolean doPostDeleteLI(boolean delete) {
13603            // XXX err, shouldn't we respect the delete flag?
13604            cleanUpResourcesLI();
13605            return true;
13606        }
13607    }
13608
13609    private boolean isAsecExternal(String cid) {
13610        final String asecPath = PackageHelper.getSdFilesystem(cid);
13611        return !asecPath.startsWith(mAsecInternalPath);
13612    }
13613
13614    private static void maybeThrowExceptionForMultiArchCopy(String message, int copyRet) throws
13615            PackageManagerException {
13616        if (copyRet < 0) {
13617            if (copyRet != PackageManager.NO_NATIVE_LIBRARIES &&
13618                    copyRet != PackageManager.INSTALL_FAILED_NO_MATCHING_ABIS) {
13619                throw new PackageManagerException(copyRet, message);
13620            }
13621        }
13622    }
13623
13624    /**
13625     * Extract the MountService "container ID" from the full code path of an
13626     * .apk.
13627     */
13628    static String cidFromCodePath(String fullCodePath) {
13629        int eidx = fullCodePath.lastIndexOf("/");
13630        String subStr1 = fullCodePath.substring(0, eidx);
13631        int sidx = subStr1.lastIndexOf("/");
13632        return subStr1.substring(sidx+1, eidx);
13633    }
13634
13635    /**
13636     * Logic to handle installation of ASEC applications, including copying and
13637     * renaming logic.
13638     */
13639    class AsecInstallArgs extends InstallArgs {
13640        static final String RES_FILE_NAME = "pkg.apk";
13641        static final String PUBLIC_RES_FILE_NAME = "res.zip";
13642
13643        String cid;
13644        String packagePath;
13645        String resourcePath;
13646
13647        /** New install */
13648        AsecInstallArgs(InstallParams params) {
13649            super(params.origin, params.move, params.observer, params.installFlags,
13650                    params.installerPackageName, params.volumeUuid,
13651                    params.getUser(), null /* instruction sets */, params.packageAbiOverride,
13652                    params.grantedRuntimePermissions,
13653                    params.traceMethod, params.traceCookie, params.certificates);
13654        }
13655
13656        /** Existing install */
13657        AsecInstallArgs(String fullCodePath, String[] instructionSets,
13658                        boolean isExternal, boolean isForwardLocked) {
13659            super(OriginInfo.fromNothing(), null, null, (isExternal ? INSTALL_EXTERNAL : 0)
13660              | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null,
13661                    instructionSets, null, null, null, 0, null /*certificates*/);
13662            // Hackily pretend we're still looking at a full code path
13663            if (!fullCodePath.endsWith(RES_FILE_NAME)) {
13664                fullCodePath = new File(fullCodePath, RES_FILE_NAME).getAbsolutePath();
13665            }
13666
13667            // Extract cid from fullCodePath
13668            int eidx = fullCodePath.lastIndexOf("/");
13669            String subStr1 = fullCodePath.substring(0, eidx);
13670            int sidx = subStr1.lastIndexOf("/");
13671            cid = subStr1.substring(sidx+1, eidx);
13672            setMountPath(subStr1);
13673        }
13674
13675        AsecInstallArgs(String cid, String[] instructionSets, boolean isForwardLocked) {
13676            super(OriginInfo.fromNothing(), null, null, (isAsecExternal(cid) ? INSTALL_EXTERNAL : 0)
13677              | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null,
13678                    instructionSets, null, null, null, 0, null /*certificates*/);
13679            this.cid = cid;
13680            setMountPath(PackageHelper.getSdDir(cid));
13681        }
13682
13683        void createCopyFile() {
13684            cid = mInstallerService.allocateExternalStageCidLegacy();
13685        }
13686
13687        int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
13688            if (origin.staged && origin.cid != null) {
13689                if (DEBUG_INSTALL) Slog.d(TAG, origin.cid + " already staged; skipping copy");
13690                cid = origin.cid;
13691                setMountPath(PackageHelper.getSdDir(cid));
13692                return PackageManager.INSTALL_SUCCEEDED;
13693            }
13694
13695            if (temp) {
13696                createCopyFile();
13697            } else {
13698                /*
13699                 * Pre-emptively destroy the container since it's destroyed if
13700                 * copying fails due to it existing anyway.
13701                 */
13702                PackageHelper.destroySdDir(cid);
13703            }
13704
13705            final String newMountPath = imcs.copyPackageToContainer(
13706                    origin.file.getAbsolutePath(), cid, getEncryptKey(), isExternalAsec(),
13707                    isFwdLocked(), deriveAbiOverride(abiOverride, null /* settings */));
13708
13709            if (newMountPath != null) {
13710                setMountPath(newMountPath);
13711                return PackageManager.INSTALL_SUCCEEDED;
13712            } else {
13713                return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
13714            }
13715        }
13716
13717        @Override
13718        String getCodePath() {
13719            return packagePath;
13720        }
13721
13722        @Override
13723        String getResourcePath() {
13724            return resourcePath;
13725        }
13726
13727        int doPreInstall(int status) {
13728            if (status != PackageManager.INSTALL_SUCCEEDED) {
13729                // Destroy container
13730                PackageHelper.destroySdDir(cid);
13731            } else {
13732                boolean mounted = PackageHelper.isContainerMounted(cid);
13733                if (!mounted) {
13734                    String newMountPath = PackageHelper.mountSdDir(cid, getEncryptKey(),
13735                            Process.SYSTEM_UID);
13736                    if (newMountPath != null) {
13737                        setMountPath(newMountPath);
13738                    } else {
13739                        return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
13740                    }
13741                }
13742            }
13743            return status;
13744        }
13745
13746        boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
13747            String newCacheId = getNextCodePath(oldCodePath, pkg.packageName, "/" + RES_FILE_NAME);
13748            String newMountPath = null;
13749            if (PackageHelper.isContainerMounted(cid)) {
13750                // Unmount the container
13751                if (!PackageHelper.unMountSdDir(cid)) {
13752                    Slog.i(TAG, "Failed to unmount " + cid + " before renaming");
13753                    return false;
13754                }
13755            }
13756            if (!PackageHelper.renameSdDir(cid, newCacheId)) {
13757                Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId +
13758                        " which might be stale. Will try to clean up.");
13759                // Clean up the stale container and proceed to recreate.
13760                if (!PackageHelper.destroySdDir(newCacheId)) {
13761                    Slog.e(TAG, "Very strange. Cannot clean up stale container " + newCacheId);
13762                    return false;
13763                }
13764                // Successfully cleaned up stale container. Try to rename again.
13765                if (!PackageHelper.renameSdDir(cid, newCacheId)) {
13766                    Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId
13767                            + " inspite of cleaning it up.");
13768                    return false;
13769                }
13770            }
13771            if (!PackageHelper.isContainerMounted(newCacheId)) {
13772                Slog.w(TAG, "Mounting container " + newCacheId);
13773                newMountPath = PackageHelper.mountSdDir(newCacheId,
13774                        getEncryptKey(), Process.SYSTEM_UID);
13775            } else {
13776                newMountPath = PackageHelper.getSdDir(newCacheId);
13777            }
13778            if (newMountPath == null) {
13779                Slog.w(TAG, "Failed to get cache path for  " + newCacheId);
13780                return false;
13781            }
13782            Log.i(TAG, "Succesfully renamed " + cid +
13783                    " to " + newCacheId +
13784                    " at new path: " + newMountPath);
13785            cid = newCacheId;
13786
13787            final File beforeCodeFile = new File(packagePath);
13788            setMountPath(newMountPath);
13789            final File afterCodeFile = new File(packagePath);
13790
13791            // Reflect the rename in scanned details
13792            pkg.setCodePath(afterCodeFile.getAbsolutePath());
13793            pkg.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile,
13794                    afterCodeFile, pkg.baseCodePath));
13795            pkg.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile,
13796                    afterCodeFile, pkg.splitCodePaths));
13797
13798            // Reflect the rename in app info
13799            pkg.setApplicationVolumeUuid(pkg.volumeUuid);
13800            pkg.setApplicationInfoCodePath(pkg.codePath);
13801            pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
13802            pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
13803            pkg.setApplicationInfoResourcePath(pkg.codePath);
13804            pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
13805            pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
13806
13807            return true;
13808        }
13809
13810        private void setMountPath(String mountPath) {
13811            final File mountFile = new File(mountPath);
13812
13813            final File monolithicFile = new File(mountFile, RES_FILE_NAME);
13814            if (monolithicFile.exists()) {
13815                packagePath = monolithicFile.getAbsolutePath();
13816                if (isFwdLocked()) {
13817                    resourcePath = new File(mountFile, PUBLIC_RES_FILE_NAME).getAbsolutePath();
13818                } else {
13819                    resourcePath = packagePath;
13820                }
13821            } else {
13822                packagePath = mountFile.getAbsolutePath();
13823                resourcePath = packagePath;
13824            }
13825        }
13826
13827        int doPostInstall(int status, int uid) {
13828            if (status != PackageManager.INSTALL_SUCCEEDED) {
13829                cleanUp();
13830            } else {
13831                final int groupOwner;
13832                final String protectedFile;
13833                if (isFwdLocked()) {
13834                    groupOwner = UserHandle.getSharedAppGid(uid);
13835                    protectedFile = RES_FILE_NAME;
13836                } else {
13837                    groupOwner = -1;
13838                    protectedFile = null;
13839                }
13840
13841                if (uid < Process.FIRST_APPLICATION_UID
13842                        || !PackageHelper.fixSdPermissions(cid, groupOwner, protectedFile)) {
13843                    Slog.e(TAG, "Failed to finalize " + cid);
13844                    PackageHelper.destroySdDir(cid);
13845                    return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
13846                }
13847
13848                boolean mounted = PackageHelper.isContainerMounted(cid);
13849                if (!mounted) {
13850                    PackageHelper.mountSdDir(cid, getEncryptKey(), Process.myUid());
13851                }
13852            }
13853            return status;
13854        }
13855
13856        private void cleanUp() {
13857            if (DEBUG_SD_INSTALL) Slog.i(TAG, "cleanUp");
13858
13859            // Destroy secure container
13860            PackageHelper.destroySdDir(cid);
13861        }
13862
13863        private List<String> getAllCodePaths() {
13864            final File codeFile = new File(getCodePath());
13865            if (codeFile != null && codeFile.exists()) {
13866                try {
13867                    final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0);
13868                    return pkg.getAllCodePaths();
13869                } catch (PackageParserException e) {
13870                    // Ignored; we tried our best
13871                }
13872            }
13873            return Collections.EMPTY_LIST;
13874        }
13875
13876        void cleanUpResourcesLI() {
13877            // Enumerate all code paths before deleting
13878            cleanUpResourcesLI(getAllCodePaths());
13879        }
13880
13881        private void cleanUpResourcesLI(List<String> allCodePaths) {
13882            cleanUp();
13883            removeDexFiles(allCodePaths, instructionSets);
13884        }
13885
13886        String getPackageName() {
13887            return getAsecPackageName(cid);
13888        }
13889
13890        boolean doPostDeleteLI(boolean delete) {
13891            if (DEBUG_SD_INSTALL) Slog.i(TAG, "doPostDeleteLI() del=" + delete);
13892            final List<String> allCodePaths = getAllCodePaths();
13893            boolean mounted = PackageHelper.isContainerMounted(cid);
13894            if (mounted) {
13895                // Unmount first
13896                if (PackageHelper.unMountSdDir(cid)) {
13897                    mounted = false;
13898                }
13899            }
13900            if (!mounted && delete) {
13901                cleanUpResourcesLI(allCodePaths);
13902            }
13903            return !mounted;
13904        }
13905
13906        @Override
13907        int doPreCopy() {
13908            if (isFwdLocked()) {
13909                if (!PackageHelper.fixSdPermissions(cid, getPackageUid(DEFAULT_CONTAINER_PACKAGE,
13910                        MATCH_SYSTEM_ONLY, UserHandle.USER_SYSTEM), RES_FILE_NAME)) {
13911                    return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
13912                }
13913            }
13914
13915            return PackageManager.INSTALL_SUCCEEDED;
13916        }
13917
13918        @Override
13919        int doPostCopy(int uid) {
13920            if (isFwdLocked()) {
13921                if (uid < Process.FIRST_APPLICATION_UID
13922                        || !PackageHelper.fixSdPermissions(cid, UserHandle.getSharedAppGid(uid),
13923                                RES_FILE_NAME)) {
13924                    Slog.e(TAG, "Failed to finalize " + cid);
13925                    PackageHelper.destroySdDir(cid);
13926                    return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
13927                }
13928            }
13929
13930            return PackageManager.INSTALL_SUCCEEDED;
13931        }
13932    }
13933
13934    /**
13935     * Logic to handle movement of existing installed applications.
13936     */
13937    class MoveInstallArgs extends InstallArgs {
13938        private File codeFile;
13939        private File resourceFile;
13940
13941        /** New install */
13942        MoveInstallArgs(InstallParams params) {
13943            super(params.origin, params.move, params.observer, params.installFlags,
13944                    params.installerPackageName, params.volumeUuid,
13945                    params.getUser(), null /* instruction sets */, params.packageAbiOverride,
13946                    params.grantedRuntimePermissions,
13947                    params.traceMethod, params.traceCookie, params.certificates);
13948        }
13949
13950        int copyApk(IMediaContainerService imcs, boolean temp) {
13951            if (DEBUG_INSTALL) Slog.d(TAG, "Moving " + move.packageName + " from "
13952                    + move.fromUuid + " to " + move.toUuid);
13953            synchronized (mInstaller) {
13954                try {
13955                    mInstaller.moveCompleteApp(move.fromUuid, move.toUuid, move.packageName,
13956                            move.dataAppName, move.appId, move.seinfo, move.targetSdkVersion);
13957                } catch (InstallerException e) {
13958                    Slog.w(TAG, "Failed to move app", e);
13959                    return PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
13960                }
13961            }
13962
13963            codeFile = new File(Environment.getDataAppDirectory(move.toUuid), move.dataAppName);
13964            resourceFile = codeFile;
13965            if (DEBUG_INSTALL) Slog.d(TAG, "codeFile after move is " + codeFile);
13966
13967            return PackageManager.INSTALL_SUCCEEDED;
13968        }
13969
13970        int doPreInstall(int status) {
13971            if (status != PackageManager.INSTALL_SUCCEEDED) {
13972                cleanUp(move.toUuid);
13973            }
13974            return status;
13975        }
13976
13977        boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
13978            if (status != PackageManager.INSTALL_SUCCEEDED) {
13979                cleanUp(move.toUuid);
13980                return false;
13981            }
13982
13983            // Reflect the move in app info
13984            pkg.setApplicationVolumeUuid(pkg.volumeUuid);
13985            pkg.setApplicationInfoCodePath(pkg.codePath);
13986            pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
13987            pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
13988            pkg.setApplicationInfoResourcePath(pkg.codePath);
13989            pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
13990            pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
13991
13992            return true;
13993        }
13994
13995        int doPostInstall(int status, int uid) {
13996            if (status == PackageManager.INSTALL_SUCCEEDED) {
13997                cleanUp(move.fromUuid);
13998            } else {
13999                cleanUp(move.toUuid);
14000            }
14001            return status;
14002        }
14003
14004        @Override
14005        String getCodePath() {
14006            return (codeFile != null) ? codeFile.getAbsolutePath() : null;
14007        }
14008
14009        @Override
14010        String getResourcePath() {
14011            return (resourceFile != null) ? resourceFile.getAbsolutePath() : null;
14012        }
14013
14014        private boolean cleanUp(String volumeUuid) {
14015            final File codeFile = new File(Environment.getDataAppDirectory(volumeUuid),
14016                    move.dataAppName);
14017            Slog.d(TAG, "Cleaning up " + move.packageName + " on " + volumeUuid);
14018            final int[] userIds = sUserManager.getUserIds();
14019            synchronized (mInstallLock) {
14020                // Clean up both app data and code
14021                // All package moves are frozen until finished
14022                for (int userId : userIds) {
14023                    try {
14024                        mInstaller.destroyAppData(volumeUuid, move.packageName, userId,
14025                                StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE, 0);
14026                    } catch (InstallerException e) {
14027                        Slog.w(TAG, String.valueOf(e));
14028                    }
14029                }
14030                removeCodePathLI(codeFile);
14031            }
14032            return true;
14033        }
14034
14035        void cleanUpResourcesLI() {
14036            throw new UnsupportedOperationException();
14037        }
14038
14039        boolean doPostDeleteLI(boolean delete) {
14040            throw new UnsupportedOperationException();
14041        }
14042    }
14043
14044    static String getAsecPackageName(String packageCid) {
14045        int idx = packageCid.lastIndexOf("-");
14046        if (idx == -1) {
14047            return packageCid;
14048        }
14049        return packageCid.substring(0, idx);
14050    }
14051
14052    // Utility method used to create code paths based on package name and available index.
14053    private static String getNextCodePath(String oldCodePath, String prefix, String suffix) {
14054        String idxStr = "";
14055        int idx = 1;
14056        // Fall back to default value of idx=1 if prefix is not
14057        // part of oldCodePath
14058        if (oldCodePath != null) {
14059            String subStr = oldCodePath;
14060            // Drop the suffix right away
14061            if (suffix != null && subStr.endsWith(suffix)) {
14062                subStr = subStr.substring(0, subStr.length() - suffix.length());
14063            }
14064            // If oldCodePath already contains prefix find out the
14065            // ending index to either increment or decrement.
14066            int sidx = subStr.lastIndexOf(prefix);
14067            if (sidx != -1) {
14068                subStr = subStr.substring(sidx + prefix.length());
14069                if (subStr != null) {
14070                    if (subStr.startsWith(INSTALL_PACKAGE_SUFFIX)) {
14071                        subStr = subStr.substring(INSTALL_PACKAGE_SUFFIX.length());
14072                    }
14073                    try {
14074                        idx = Integer.parseInt(subStr);
14075                        if (idx <= 1) {
14076                            idx++;
14077                        } else {
14078                            idx--;
14079                        }
14080                    } catch(NumberFormatException e) {
14081                    }
14082                }
14083            }
14084        }
14085        idxStr = INSTALL_PACKAGE_SUFFIX + Integer.toString(idx);
14086        return prefix + idxStr;
14087    }
14088
14089    private File getNextCodePath(File targetDir, String packageName) {
14090        int suffix = 1;
14091        File result;
14092        do {
14093            result = new File(targetDir, packageName + "-" + suffix);
14094            suffix++;
14095        } while (result.exists());
14096        return result;
14097    }
14098
14099    // Utility method that returns the relative package path with respect
14100    // to the installation directory. Like say for /data/data/com.test-1.apk
14101    // string com.test-1 is returned.
14102    static String deriveCodePathName(String codePath) {
14103        if (codePath == null) {
14104            return null;
14105        }
14106        final File codeFile = new File(codePath);
14107        final String name = codeFile.getName();
14108        if (codeFile.isDirectory()) {
14109            return name;
14110        } else if (name.endsWith(".apk") || name.endsWith(".tmp")) {
14111            final int lastDot = name.lastIndexOf('.');
14112            return name.substring(0, lastDot);
14113        } else {
14114            Slog.w(TAG, "Odd, " + codePath + " doesn't look like an APK");
14115            return null;
14116        }
14117    }
14118
14119    static class PackageInstalledInfo {
14120        String name;
14121        int uid;
14122        // The set of users that originally had this package installed.
14123        int[] origUsers;
14124        // The set of users that now have this package installed.
14125        int[] newUsers;
14126        PackageParser.Package pkg;
14127        int returnCode;
14128        String returnMsg;
14129        PackageRemovedInfo removedInfo;
14130        ArrayMap<String, PackageInstalledInfo> addedChildPackages;
14131
14132        public void setError(int code, String msg) {
14133            setReturnCode(code);
14134            setReturnMessage(msg);
14135            Slog.w(TAG, msg);
14136        }
14137
14138        public void setError(String msg, PackageParserException e) {
14139            setReturnCode(e.error);
14140            setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e));
14141            Slog.w(TAG, msg, e);
14142        }
14143
14144        public void setError(String msg, PackageManagerException e) {
14145            returnCode = e.error;
14146            setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e));
14147            Slog.w(TAG, msg, e);
14148        }
14149
14150        public void setReturnCode(int returnCode) {
14151            this.returnCode = returnCode;
14152            final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
14153            for (int i = 0; i < childCount; i++) {
14154                addedChildPackages.valueAt(i).returnCode = returnCode;
14155            }
14156        }
14157
14158        private void setReturnMessage(String returnMsg) {
14159            this.returnMsg = returnMsg;
14160            final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
14161            for (int i = 0; i < childCount; i++) {
14162                addedChildPackages.valueAt(i).returnMsg = returnMsg;
14163            }
14164        }
14165
14166        // In some error cases we want to convey more info back to the observer
14167        String origPackage;
14168        String origPermission;
14169    }
14170
14171    /*
14172     * Install a non-existing package.
14173     */
14174    private void installNewPackageLIF(PackageParser.Package pkg, final int policyFlags,
14175            int scanFlags, UserHandle user, String installerPackageName, String volumeUuid,
14176            PackageInstalledInfo res) {
14177        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installNewPackage");
14178
14179        // Remember this for later, in case we need to rollback this install
14180        String pkgName = pkg.packageName;
14181
14182        if (DEBUG_INSTALL) Slog.d(TAG, "installNewPackageLI: " + pkg);
14183
14184        synchronized(mPackages) {
14185            if (mSettings.mRenamedPackages.containsKey(pkgName)) {
14186                // A package with the same name is already installed, though
14187                // it has been renamed to an older name.  The package we
14188                // are trying to install should be installed as an update to
14189                // the existing one, but that has not been requested, so bail.
14190                res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName
14191                        + " without first uninstalling package running as "
14192                        + mSettings.mRenamedPackages.get(pkgName));
14193                return;
14194            }
14195            if (mPackages.containsKey(pkgName)) {
14196                // Don't allow installation over an existing package with the same name.
14197                res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName
14198                        + " without first uninstalling.");
14199                return;
14200            }
14201        }
14202
14203        try {
14204            PackageParser.Package newPackage = scanPackageTracedLI(pkg, policyFlags, scanFlags,
14205                    System.currentTimeMillis(), user);
14206
14207            updateSettingsLI(newPackage, installerPackageName, null, res, user);
14208
14209            if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
14210                prepareAppDataAfterInstallLIF(newPackage);
14211
14212            } else {
14213                // Remove package from internal structures, but keep around any
14214                // data that might have already existed
14215                deletePackageLIF(pkgName, UserHandle.ALL, false, null,
14216                        PackageManager.DELETE_KEEP_DATA, res.removedInfo, true, null);
14217            }
14218        } catch (PackageManagerException e) {
14219            res.setError("Package couldn't be installed in " + pkg.codePath, e);
14220        }
14221
14222        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
14223    }
14224
14225    private boolean shouldCheckUpgradeKeySetLP(PackageSetting oldPs, int scanFlags) {
14226        // Can't rotate keys during boot or if sharedUser.
14227        if (oldPs == null || (scanFlags&SCAN_INITIAL) != 0 || oldPs.sharedUser != null
14228                || !oldPs.keySetData.isUsingUpgradeKeySets()) {
14229            return false;
14230        }
14231        // app is using upgradeKeySets; make sure all are valid
14232        KeySetManagerService ksms = mSettings.mKeySetManagerService;
14233        long[] upgradeKeySets = oldPs.keySetData.getUpgradeKeySets();
14234        for (int i = 0; i < upgradeKeySets.length; i++) {
14235            if (!ksms.isIdValidKeySetId(upgradeKeySets[i])) {
14236                Slog.wtf(TAG, "Package "
14237                         + (oldPs.name != null ? oldPs.name : "<null>")
14238                         + " contains upgrade-key-set reference to unknown key-set: "
14239                         + upgradeKeySets[i]
14240                         + " reverting to signatures check.");
14241                return false;
14242            }
14243        }
14244        return true;
14245    }
14246
14247    private boolean checkUpgradeKeySetLP(PackageSetting oldPS, PackageParser.Package newPkg) {
14248        // Upgrade keysets are being used.  Determine if new package has a superset of the
14249        // required keys.
14250        long[] upgradeKeySets = oldPS.keySetData.getUpgradeKeySets();
14251        KeySetManagerService ksms = mSettings.mKeySetManagerService;
14252        for (int i = 0; i < upgradeKeySets.length; i++) {
14253            Set<PublicKey> upgradeSet = ksms.getPublicKeysFromKeySetLPr(upgradeKeySets[i]);
14254            if (upgradeSet != null && newPkg.mSigningKeys.containsAll(upgradeSet)) {
14255                return true;
14256            }
14257        }
14258        return false;
14259    }
14260
14261    private static void updateDigest(MessageDigest digest, File file) throws IOException {
14262        try (DigestInputStream digestStream =
14263                new DigestInputStream(new FileInputStream(file), digest)) {
14264            while (digestStream.read() != -1) {} // nothing to do; just plow through the file
14265        }
14266    }
14267
14268    private void replacePackageLIF(PackageParser.Package pkg, final int policyFlags, int scanFlags,
14269            UserHandle user, String installerPackageName, PackageInstalledInfo res) {
14270        final boolean isEphemeral = (policyFlags & PackageParser.PARSE_IS_EPHEMERAL) != 0;
14271
14272        final PackageParser.Package oldPackage;
14273        final String pkgName = pkg.packageName;
14274        final int[] allUsers;
14275        final int[] installedUsers;
14276
14277        synchronized(mPackages) {
14278            oldPackage = mPackages.get(pkgName);
14279            if (DEBUG_INSTALL) Slog.d(TAG, "replacePackageLI: new=" + pkg + ", old=" + oldPackage);
14280
14281            // don't allow upgrade to target a release SDK from a pre-release SDK
14282            final boolean oldTargetsPreRelease = oldPackage.applicationInfo.targetSdkVersion
14283                    == android.os.Build.VERSION_CODES.CUR_DEVELOPMENT;
14284            final boolean newTargetsPreRelease = pkg.applicationInfo.targetSdkVersion
14285                    == android.os.Build.VERSION_CODES.CUR_DEVELOPMENT;
14286            if (oldTargetsPreRelease
14287                    && !newTargetsPreRelease
14288                    && ((policyFlags & PackageParser.PARSE_FORCE_SDK) == 0)) {
14289                Slog.w(TAG, "Can't install package targeting released sdk");
14290                res.setReturnCode(PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE);
14291                return;
14292            }
14293
14294            // don't allow an upgrade from full to ephemeral
14295            final boolean oldIsEphemeral = oldPackage.applicationInfo.isEphemeralApp();
14296            if (isEphemeral && !oldIsEphemeral) {
14297                // can't downgrade from full to ephemeral
14298                Slog.w(TAG, "Can't replace app with ephemeral: " + pkgName);
14299                res.setReturnCode(PackageManager.INSTALL_FAILED_EPHEMERAL_INVALID);
14300                return;
14301            }
14302
14303            // verify signatures are valid
14304            final PackageSetting ps = mSettings.mPackages.get(pkgName);
14305            if (shouldCheckUpgradeKeySetLP(ps, scanFlags)) {
14306                if (!checkUpgradeKeySetLP(ps, pkg)) {
14307                    res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
14308                            "New package not signed by keys specified by upgrade-keysets: "
14309                                    + pkgName);
14310                    return;
14311                }
14312            } else {
14313                // default to original signature matching
14314                if (compareSignatures(oldPackage.mSignatures, pkg.mSignatures)
14315                        != PackageManager.SIGNATURE_MATCH) {
14316                    res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
14317                            "New package has a different signature: " + pkgName);
14318                    return;
14319                }
14320            }
14321
14322            // don't allow a system upgrade unless the upgrade hash matches
14323            if (oldPackage.restrictUpdateHash != null && oldPackage.isSystemApp()) {
14324                byte[] digestBytes = null;
14325                try {
14326                    final MessageDigest digest = MessageDigest.getInstance("SHA-512");
14327                    updateDigest(digest, new File(pkg.baseCodePath));
14328                    if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) {
14329                        for (String path : pkg.splitCodePaths) {
14330                            updateDigest(digest, new File(path));
14331                        }
14332                    }
14333                    digestBytes = digest.digest();
14334                } catch (NoSuchAlgorithmException | IOException e) {
14335                    res.setError(INSTALL_FAILED_INVALID_APK,
14336                            "Could not compute hash: " + pkgName);
14337                    return;
14338                }
14339                if (!Arrays.equals(oldPackage.restrictUpdateHash, digestBytes)) {
14340                    res.setError(INSTALL_FAILED_INVALID_APK,
14341                            "New package fails restrict-update check: " + pkgName);
14342                    return;
14343                }
14344                // retain upgrade restriction
14345                pkg.restrictUpdateHash = oldPackage.restrictUpdateHash;
14346            }
14347
14348            // Check for shared user id changes
14349            String invalidPackageName =
14350                    getParentOrChildPackageChangedSharedUser(oldPackage, pkg);
14351            if (invalidPackageName != null) {
14352                res.setError(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
14353                        "Package " + invalidPackageName + " tried to change user "
14354                                + oldPackage.mSharedUserId);
14355                return;
14356            }
14357
14358            // In case of rollback, remember per-user/profile install state
14359            allUsers = sUserManager.getUserIds();
14360            installedUsers = ps.queryInstalledUsers(allUsers, true);
14361        }
14362
14363        // Update what is removed
14364        res.removedInfo = new PackageRemovedInfo();
14365        res.removedInfo.uid = oldPackage.applicationInfo.uid;
14366        res.removedInfo.removedPackage = oldPackage.packageName;
14367        res.removedInfo.isUpdate = true;
14368        res.removedInfo.origUsers = installedUsers;
14369        final int childCount = (oldPackage.childPackages != null)
14370                ? oldPackage.childPackages.size() : 0;
14371        for (int i = 0; i < childCount; i++) {
14372            boolean childPackageUpdated = false;
14373            PackageParser.Package childPkg = oldPackage.childPackages.get(i);
14374            if (res.addedChildPackages != null) {
14375                PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName);
14376                if (childRes != null) {
14377                    childRes.removedInfo.uid = childPkg.applicationInfo.uid;
14378                    childRes.removedInfo.removedPackage = childPkg.packageName;
14379                    childRes.removedInfo.isUpdate = true;
14380                    childPackageUpdated = true;
14381                }
14382            }
14383            if (!childPackageUpdated) {
14384                PackageRemovedInfo childRemovedRes = new PackageRemovedInfo();
14385                childRemovedRes.removedPackage = childPkg.packageName;
14386                childRemovedRes.isUpdate = false;
14387                childRemovedRes.dataRemoved = true;
14388                synchronized (mPackages) {
14389                    PackageSetting childPs = mSettings.peekPackageLPr(childPkg.packageName);
14390                    if (childPs != null) {
14391                        childRemovedRes.origUsers = childPs.queryInstalledUsers(allUsers, true);
14392                    }
14393                }
14394                if (res.removedInfo.removedChildPackages == null) {
14395                    res.removedInfo.removedChildPackages = new ArrayMap<>();
14396                }
14397                res.removedInfo.removedChildPackages.put(childPkg.packageName, childRemovedRes);
14398            }
14399        }
14400
14401        boolean sysPkg = (isSystemApp(oldPackage));
14402        if (sysPkg) {
14403            // Set the system/privileged flags as needed
14404            final boolean privileged =
14405                    (oldPackage.applicationInfo.privateFlags
14406                            & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0;
14407            final int systemPolicyFlags = policyFlags
14408                    | PackageParser.PARSE_IS_SYSTEM
14409                    | (privileged ? PackageParser.PARSE_IS_PRIVILEGED : 0);
14410
14411            replaceSystemPackageLIF(oldPackage, pkg, systemPolicyFlags, scanFlags,
14412                    user, allUsers, installerPackageName, res);
14413        } else {
14414            replaceNonSystemPackageLIF(oldPackage, pkg, policyFlags, scanFlags,
14415                    user, allUsers, installerPackageName, res);
14416        }
14417    }
14418
14419    public List<String> getPreviousCodePaths(String packageName) {
14420        final PackageSetting ps = mSettings.mPackages.get(packageName);
14421        final List<String> result = new ArrayList<String>();
14422        if (ps != null && ps.oldCodePaths != null) {
14423            result.addAll(ps.oldCodePaths);
14424        }
14425        return result;
14426    }
14427
14428    private void replaceNonSystemPackageLIF(PackageParser.Package deletedPackage,
14429            PackageParser.Package pkg, final int policyFlags, int scanFlags, UserHandle user,
14430            int[] allUsers, String installerPackageName, PackageInstalledInfo res) {
14431        if (DEBUG_INSTALL) Slog.d(TAG, "replaceNonSystemPackageLI: new=" + pkg + ", old="
14432                + deletedPackage);
14433
14434        String pkgName = deletedPackage.packageName;
14435        boolean deletedPkg = true;
14436        boolean addedPkg = false;
14437        boolean updatedSettings = false;
14438        final boolean killApp = (scanFlags & SCAN_DONT_KILL_APP) == 0;
14439        final int deleteFlags = PackageManager.DELETE_KEEP_DATA
14440                | (killApp ? 0 : PackageManager.DELETE_DONT_KILL_APP);
14441
14442        final long origUpdateTime = (pkg.mExtras != null)
14443                ? ((PackageSetting)pkg.mExtras).lastUpdateTime : 0;
14444
14445        // First delete the existing package while retaining the data directory
14446        if (!deletePackageLIF(pkgName, null, true, allUsers, deleteFlags,
14447                res.removedInfo, true, pkg)) {
14448            // If the existing package wasn't successfully deleted
14449            res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE, "replaceNonSystemPackageLI");
14450            deletedPkg = false;
14451        } else {
14452            // Successfully deleted the old package; proceed with replace.
14453
14454            // If deleted package lived in a container, give users a chance to
14455            // relinquish resources before killing.
14456            if (deletedPackage.isForwardLocked() || isExternal(deletedPackage)) {
14457                if (DEBUG_INSTALL) {
14458                    Slog.i(TAG, "upgrading pkg " + deletedPackage + " is ASEC-hosted -> UNAVAILABLE");
14459                }
14460                final int[] uidArray = new int[] { deletedPackage.applicationInfo.uid };
14461                final ArrayList<String> pkgList = new ArrayList<String>(1);
14462                pkgList.add(deletedPackage.applicationInfo.packageName);
14463                sendResourcesChangedBroadcast(false, true, pkgList, uidArray, null);
14464            }
14465
14466            clearAppDataLIF(pkg, UserHandle.USER_ALL, StorageManager.FLAG_STORAGE_DE
14467                    | StorageManager.FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
14468            clearAppProfilesLIF(deletedPackage, UserHandle.USER_ALL);
14469
14470            try {
14471                final PackageParser.Package newPackage = scanPackageTracedLI(pkg, policyFlags,
14472                        scanFlags | SCAN_UPDATE_TIME, System.currentTimeMillis(), user);
14473                updateSettingsLI(newPackage, installerPackageName, allUsers, res, user);
14474
14475                // Update the in-memory copy of the previous code paths.
14476                PackageSetting ps = mSettings.mPackages.get(pkgName);
14477                if (!killApp) {
14478                    if (ps.oldCodePaths == null) {
14479                        ps.oldCodePaths = new ArraySet<>();
14480                    }
14481                    Collections.addAll(ps.oldCodePaths, deletedPackage.baseCodePath);
14482                    if (deletedPackage.splitCodePaths != null) {
14483                        Collections.addAll(ps.oldCodePaths, deletedPackage.splitCodePaths);
14484                    }
14485                } else {
14486                    ps.oldCodePaths = null;
14487                }
14488                if (ps.childPackageNames != null) {
14489                    for (int i = ps.childPackageNames.size() - 1; i >= 0; --i) {
14490                        final String childPkgName = ps.childPackageNames.get(i);
14491                        final PackageSetting childPs = mSettings.mPackages.get(childPkgName);
14492                        childPs.oldCodePaths = ps.oldCodePaths;
14493                    }
14494                }
14495                prepareAppDataAfterInstallLIF(newPackage);
14496                addedPkg = true;
14497                mDexManager.notifyPackageUpdated(newPackage.packageName,
14498                        newPackage.baseCodePath, newPackage.splitCodePaths);
14499            } catch (PackageManagerException e) {
14500                res.setError("Package couldn't be installed in " + pkg.codePath, e);
14501            }
14502        }
14503
14504        if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
14505            if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, rolling pack: " + pkgName);
14506
14507            // Revert all internal state mutations and added folders for the failed install
14508            if (addedPkg) {
14509                deletePackageLIF(pkgName, null, true, allUsers, deleteFlags,
14510                        res.removedInfo, true, null);
14511            }
14512
14513            // Restore the old package
14514            if (deletedPkg) {
14515                if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, reinstalling: " + deletedPackage);
14516                File restoreFile = new File(deletedPackage.codePath);
14517                // Parse old package
14518                boolean oldExternal = isExternal(deletedPackage);
14519                int oldParseFlags  = mDefParseFlags | PackageParser.PARSE_CHATTY |
14520                        (deletedPackage.isForwardLocked() ? PackageParser.PARSE_FORWARD_LOCK : 0) |
14521                        (oldExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0);
14522                int oldScanFlags = SCAN_UPDATE_SIGNATURE | SCAN_UPDATE_TIME;
14523                try {
14524                    scanPackageTracedLI(restoreFile, oldParseFlags, oldScanFlags, origUpdateTime,
14525                            null);
14526                } catch (PackageManagerException e) {
14527                    Slog.e(TAG, "Failed to restore package : " + pkgName + " after failed upgrade: "
14528                            + e.getMessage());
14529                    return;
14530                }
14531
14532                synchronized (mPackages) {
14533                    // Ensure the installer package name up to date
14534                    setInstallerPackageNameLPw(deletedPackage, installerPackageName);
14535
14536                    // Update permissions for restored package
14537                    updatePermissionsLPw(deletedPackage, UPDATE_PERMISSIONS_ALL);
14538
14539                    mSettings.writeLPr();
14540                }
14541
14542                Slog.i(TAG, "Successfully restored package : " + pkgName + " after failed upgrade");
14543            }
14544        } else {
14545            synchronized (mPackages) {
14546                PackageSetting ps = mSettings.peekPackageLPr(pkg.packageName);
14547                if (ps != null) {
14548                    res.removedInfo.removedForAllUsers = mPackages.get(ps.name) == null;
14549                    if (res.removedInfo.removedChildPackages != null) {
14550                        final int childCount = res.removedInfo.removedChildPackages.size();
14551                        // Iterate in reverse as we may modify the collection
14552                        for (int i = childCount - 1; i >= 0; i--) {
14553                            String childPackageName = res.removedInfo.removedChildPackages.keyAt(i);
14554                            if (res.addedChildPackages.containsKey(childPackageName)) {
14555                                res.removedInfo.removedChildPackages.removeAt(i);
14556                            } else {
14557                                PackageRemovedInfo childInfo = res.removedInfo
14558                                        .removedChildPackages.valueAt(i);
14559                                childInfo.removedForAllUsers = mPackages.get(
14560                                        childInfo.removedPackage) == null;
14561                            }
14562                        }
14563                    }
14564                }
14565            }
14566        }
14567    }
14568
14569    private void replaceSystemPackageLIF(PackageParser.Package deletedPackage,
14570            PackageParser.Package pkg, final int policyFlags, int scanFlags, UserHandle user,
14571            int[] allUsers, String installerPackageName, PackageInstalledInfo res) {
14572        if (DEBUG_INSTALL) Slog.d(TAG, "replaceSystemPackageLI: new=" + pkg
14573                + ", old=" + deletedPackage);
14574
14575        final boolean disabledSystem;
14576
14577        // Remove existing system package
14578        removePackageLI(deletedPackage, true);
14579
14580        synchronized (mPackages) {
14581            disabledSystem = disableSystemPackageLPw(deletedPackage, pkg);
14582        }
14583        if (!disabledSystem) {
14584            // We didn't need to disable the .apk as a current system package,
14585            // which means we are replacing another update that is already
14586            // installed.  We need to make sure to delete the older one's .apk.
14587            res.removedInfo.args = createInstallArgsForExisting(0,
14588                    deletedPackage.applicationInfo.getCodePath(),
14589                    deletedPackage.applicationInfo.getResourcePath(),
14590                    getAppDexInstructionSets(deletedPackage.applicationInfo));
14591        } else {
14592            res.removedInfo.args = null;
14593        }
14594
14595        // Successfully disabled the old package. Now proceed with re-installation
14596        clearAppDataLIF(pkg, UserHandle.USER_ALL, StorageManager.FLAG_STORAGE_DE
14597                | StorageManager.FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
14598        clearAppProfilesLIF(deletedPackage, UserHandle.USER_ALL);
14599
14600        res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
14601        pkg.setApplicationInfoFlags(ApplicationInfo.FLAG_UPDATED_SYSTEM_APP,
14602                ApplicationInfo.FLAG_UPDATED_SYSTEM_APP);
14603
14604        PackageParser.Package newPackage = null;
14605        try {
14606            // Add the package to the internal data structures
14607            newPackage = scanPackageTracedLI(pkg, policyFlags, scanFlags, 0, user);
14608
14609            // Set the update and install times
14610            PackageSetting deletedPkgSetting = (PackageSetting) deletedPackage.mExtras;
14611            setInstallAndUpdateTime(newPackage, deletedPkgSetting.firstInstallTime,
14612                    System.currentTimeMillis());
14613
14614            // Update the package dynamic state if succeeded
14615            if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
14616                // Now that the install succeeded make sure we remove data
14617                // directories for any child package the update removed.
14618                final int deletedChildCount = (deletedPackage.childPackages != null)
14619                        ? deletedPackage.childPackages.size() : 0;
14620                final int newChildCount = (newPackage.childPackages != null)
14621                        ? newPackage.childPackages.size() : 0;
14622                for (int i = 0; i < deletedChildCount; i++) {
14623                    PackageParser.Package deletedChildPkg = deletedPackage.childPackages.get(i);
14624                    boolean childPackageDeleted = true;
14625                    for (int j = 0; j < newChildCount; j++) {
14626                        PackageParser.Package newChildPkg = newPackage.childPackages.get(j);
14627                        if (deletedChildPkg.packageName.equals(newChildPkg.packageName)) {
14628                            childPackageDeleted = false;
14629                            break;
14630                        }
14631                    }
14632                    if (childPackageDeleted) {
14633                        PackageSetting ps = mSettings.getDisabledSystemPkgLPr(
14634                                deletedChildPkg.packageName);
14635                        if (ps != null && res.removedInfo.removedChildPackages != null) {
14636                            PackageRemovedInfo removedChildRes = res.removedInfo
14637                                    .removedChildPackages.get(deletedChildPkg.packageName);
14638                            removePackageDataLIF(ps, allUsers, removedChildRes, 0, false);
14639                            removedChildRes.removedForAllUsers = mPackages.get(ps.name) == null;
14640                        }
14641                    }
14642                }
14643
14644                updateSettingsLI(newPackage, installerPackageName, allUsers, res, user);
14645                prepareAppDataAfterInstallLIF(newPackage);
14646
14647                mDexManager.notifyPackageUpdated(newPackage.packageName,
14648                            newPackage.baseCodePath, newPackage.splitCodePaths);
14649            }
14650        } catch (PackageManagerException e) {
14651            res.setReturnCode(INSTALL_FAILED_INTERNAL_ERROR);
14652            res.setError("Package couldn't be installed in " + pkg.codePath, e);
14653        }
14654
14655        if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
14656            // Re installation failed. Restore old information
14657            // Remove new pkg information
14658            if (newPackage != null) {
14659                removeInstalledPackageLI(newPackage, true);
14660            }
14661            // Add back the old system package
14662            try {
14663                scanPackageTracedLI(deletedPackage, policyFlags, SCAN_UPDATE_SIGNATURE, 0, user);
14664            } catch (PackageManagerException e) {
14665                Slog.e(TAG, "Failed to restore original package: " + e.getMessage());
14666            }
14667
14668            synchronized (mPackages) {
14669                if (disabledSystem) {
14670                    enableSystemPackageLPw(deletedPackage);
14671                }
14672
14673                // Ensure the installer package name up to date
14674                setInstallerPackageNameLPw(deletedPackage, installerPackageName);
14675
14676                // Update permissions for restored package
14677                updatePermissionsLPw(deletedPackage, UPDATE_PERMISSIONS_ALL);
14678
14679                mSettings.writeLPr();
14680            }
14681
14682            Slog.i(TAG, "Successfully restored package : " + deletedPackage.packageName
14683                    + " after failed upgrade");
14684        }
14685    }
14686
14687    /**
14688     * Checks whether the parent or any of the child packages have a change shared
14689     * user. For a package to be a valid update the shred users of the parent and
14690     * the children should match. We may later support changing child shared users.
14691     * @param oldPkg The updated package.
14692     * @param newPkg The update package.
14693     * @return The shared user that change between the versions.
14694     */
14695    private String getParentOrChildPackageChangedSharedUser(PackageParser.Package oldPkg,
14696            PackageParser.Package newPkg) {
14697        // Check parent shared user
14698        if (!Objects.equals(oldPkg.mSharedUserId, newPkg.mSharedUserId)) {
14699            return newPkg.packageName;
14700        }
14701        // Check child shared users
14702        final int oldChildCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0;
14703        final int newChildCount = (newPkg.childPackages != null) ? newPkg.childPackages.size() : 0;
14704        for (int i = 0; i < newChildCount; i++) {
14705            PackageParser.Package newChildPkg = newPkg.childPackages.get(i);
14706            // If this child was present, did it have the same shared user?
14707            for (int j = 0; j < oldChildCount; j++) {
14708                PackageParser.Package oldChildPkg = oldPkg.childPackages.get(j);
14709                if (newChildPkg.packageName.equals(oldChildPkg.packageName)
14710                        && !Objects.equals(newChildPkg.mSharedUserId, oldChildPkg.mSharedUserId)) {
14711                    return newChildPkg.packageName;
14712                }
14713            }
14714        }
14715        return null;
14716    }
14717
14718    private void removeNativeBinariesLI(PackageSetting ps) {
14719        // Remove the lib path for the parent package
14720        if (ps != null) {
14721            NativeLibraryHelper.removeNativeBinariesLI(ps.legacyNativeLibraryPathString);
14722            // Remove the lib path for the child packages
14723            final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0;
14724            for (int i = 0; i < childCount; i++) {
14725                PackageSetting childPs = null;
14726                synchronized (mPackages) {
14727                    childPs = mSettings.peekPackageLPr(ps.childPackageNames.get(i));
14728                }
14729                if (childPs != null) {
14730                    NativeLibraryHelper.removeNativeBinariesLI(childPs
14731                            .legacyNativeLibraryPathString);
14732                }
14733            }
14734        }
14735    }
14736
14737    private void enableSystemPackageLPw(PackageParser.Package pkg) {
14738        // Enable the parent package
14739        mSettings.enableSystemPackageLPw(pkg.packageName);
14740        // Enable the child packages
14741        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
14742        for (int i = 0; i < childCount; i++) {
14743            PackageParser.Package childPkg = pkg.childPackages.get(i);
14744            mSettings.enableSystemPackageLPw(childPkg.packageName);
14745        }
14746    }
14747
14748    private boolean disableSystemPackageLPw(PackageParser.Package oldPkg,
14749            PackageParser.Package newPkg) {
14750        // Disable the parent package (parent always replaced)
14751        boolean disabled = mSettings.disableSystemPackageLPw(oldPkg.packageName, true);
14752        // Disable the child packages
14753        final int childCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0;
14754        for (int i = 0; i < childCount; i++) {
14755            PackageParser.Package childPkg = oldPkg.childPackages.get(i);
14756            final boolean replace = newPkg.hasChildPackage(childPkg.packageName);
14757            disabled |= mSettings.disableSystemPackageLPw(childPkg.packageName, replace);
14758        }
14759        return disabled;
14760    }
14761
14762    private void setInstallerPackageNameLPw(PackageParser.Package pkg,
14763            String installerPackageName) {
14764        // Enable the parent package
14765        mSettings.setInstallerPackageName(pkg.packageName, installerPackageName);
14766        // Enable the child packages
14767        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
14768        for (int i = 0; i < childCount; i++) {
14769            PackageParser.Package childPkg = pkg.childPackages.get(i);
14770            mSettings.setInstallerPackageName(childPkg.packageName, installerPackageName);
14771        }
14772    }
14773
14774    private int[] revokeUnusedSharedUserPermissionsLPw(SharedUserSetting su, int[] allUserIds) {
14775        // Collect all used permissions in the UID
14776        ArraySet<String> usedPermissions = new ArraySet<>();
14777        final int packageCount = su.packages.size();
14778        for (int i = 0; i < packageCount; i++) {
14779            PackageSetting ps = su.packages.valueAt(i);
14780            if (ps.pkg == null) {
14781                continue;
14782            }
14783            final int requestedPermCount = ps.pkg.requestedPermissions.size();
14784            for (int j = 0; j < requestedPermCount; j++) {
14785                String permission = ps.pkg.requestedPermissions.get(j);
14786                BasePermission bp = mSettings.mPermissions.get(permission);
14787                if (bp != null) {
14788                    usedPermissions.add(permission);
14789                }
14790            }
14791        }
14792
14793        PermissionsState permissionsState = su.getPermissionsState();
14794        // Prune install permissions
14795        List<PermissionState> installPermStates = permissionsState.getInstallPermissionStates();
14796        final int installPermCount = installPermStates.size();
14797        for (int i = installPermCount - 1; i >= 0;  i--) {
14798            PermissionState permissionState = installPermStates.get(i);
14799            if (!usedPermissions.contains(permissionState.getName())) {
14800                BasePermission bp = mSettings.mPermissions.get(permissionState.getName());
14801                if (bp != null) {
14802                    permissionsState.revokeInstallPermission(bp);
14803                    permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
14804                            PackageManager.MASK_PERMISSION_FLAGS, 0);
14805                }
14806            }
14807        }
14808
14809        int[] runtimePermissionChangedUserIds = EmptyArray.INT;
14810
14811        // Prune runtime permissions
14812        for (int userId : allUserIds) {
14813            List<PermissionState> runtimePermStates = permissionsState
14814                    .getRuntimePermissionStates(userId);
14815            final int runtimePermCount = runtimePermStates.size();
14816            for (int i = runtimePermCount - 1; i >= 0; i--) {
14817                PermissionState permissionState = runtimePermStates.get(i);
14818                if (!usedPermissions.contains(permissionState.getName())) {
14819                    BasePermission bp = mSettings.mPermissions.get(permissionState.getName());
14820                    if (bp != null) {
14821                        permissionsState.revokeRuntimePermission(bp, userId);
14822                        permissionsState.updatePermissionFlags(bp, userId,
14823                                PackageManager.MASK_PERMISSION_FLAGS, 0);
14824                        runtimePermissionChangedUserIds = ArrayUtils.appendInt(
14825                                runtimePermissionChangedUserIds, userId);
14826                    }
14827                }
14828            }
14829        }
14830
14831        return runtimePermissionChangedUserIds;
14832    }
14833
14834    private void updateSettingsLI(PackageParser.Package newPackage, String installerPackageName,
14835            int[] allUsers, PackageInstalledInfo res, UserHandle user) {
14836        // Update the parent package setting
14837        updateSettingsInternalLI(newPackage, installerPackageName, allUsers, res.origUsers,
14838                res, user);
14839        // Update the child packages setting
14840        final int childCount = (newPackage.childPackages != null)
14841                ? newPackage.childPackages.size() : 0;
14842        for (int i = 0; i < childCount; i++) {
14843            PackageParser.Package childPackage = newPackage.childPackages.get(i);
14844            PackageInstalledInfo childRes = res.addedChildPackages.get(childPackage.packageName);
14845            updateSettingsInternalLI(childPackage, installerPackageName, allUsers,
14846                    childRes.origUsers, childRes, user);
14847        }
14848    }
14849
14850    private void updateSettingsInternalLI(PackageParser.Package newPackage,
14851            String installerPackageName, int[] allUsers, int[] installedForUsers,
14852            PackageInstalledInfo res, UserHandle user) {
14853        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");
14854
14855        String pkgName = newPackage.packageName;
14856        synchronized (mPackages) {
14857            //write settings. the installStatus will be incomplete at this stage.
14858            //note that the new package setting would have already been
14859            //added to mPackages. It hasn't been persisted yet.
14860            mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_INCOMPLETE);
14861            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings");
14862            mSettings.writeLPr();
14863            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
14864        }
14865
14866        if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + newPackage.codePath);
14867        synchronized (mPackages) {
14868            updatePermissionsLPw(newPackage.packageName, newPackage,
14869                    UPDATE_PERMISSIONS_REPLACE_PKG | (newPackage.permissions.size() > 0
14870                            ? UPDATE_PERMISSIONS_ALL : 0));
14871            // For system-bundled packages, we assume that installing an upgraded version
14872            // of the package implies that the user actually wants to run that new code,
14873            // so we enable the package.
14874            PackageSetting ps = mSettings.mPackages.get(pkgName);
14875            final int userId = user.getIdentifier();
14876            if (ps != null) {
14877                if (isSystemApp(newPackage)) {
14878                    if (DEBUG_INSTALL) {
14879                        Slog.d(TAG, "Implicitly enabling system package on upgrade: " + pkgName);
14880                    }
14881                    // Enable system package for requested users
14882                    if (res.origUsers != null) {
14883                        for (int origUserId : res.origUsers) {
14884                            if (userId == UserHandle.USER_ALL || userId == origUserId) {
14885                                ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT,
14886                                        origUserId, installerPackageName);
14887                            }
14888                        }
14889                    }
14890                    // Also convey the prior install/uninstall state
14891                    if (allUsers != null && installedForUsers != null) {
14892                        for (int currentUserId : allUsers) {
14893                            final boolean installed = ArrayUtils.contains(
14894                                    installedForUsers, currentUserId);
14895                            if (DEBUG_INSTALL) {
14896                                Slog.d(TAG, "    user " + currentUserId + " => " + installed);
14897                            }
14898                            ps.setInstalled(installed, currentUserId);
14899                        }
14900                        // these install state changes will be persisted in the
14901                        // upcoming call to mSettings.writeLPr().
14902                    }
14903                }
14904                // It's implied that when a user requests installation, they want the app to be
14905                // installed and enabled.
14906                if (userId != UserHandle.USER_ALL) {
14907                    ps.setInstalled(true, userId);
14908                    ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, userId, installerPackageName);
14909                }
14910            }
14911            res.name = pkgName;
14912            res.uid = newPackage.applicationInfo.uid;
14913            res.pkg = newPackage;
14914            mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_COMPLETE);
14915            mSettings.setInstallerPackageName(pkgName, installerPackageName);
14916            res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
14917            //to update install status
14918            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings");
14919            mSettings.writeLPr();
14920            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
14921        }
14922
14923        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
14924    }
14925
14926    private void installPackageTracedLI(InstallArgs args, PackageInstalledInfo res) {
14927        try {
14928            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installPackage");
14929            installPackageLI(args, res);
14930        } finally {
14931            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
14932        }
14933    }
14934
14935    private void installPackageLI(InstallArgs args, PackageInstalledInfo res) {
14936        final int installFlags = args.installFlags;
14937        final String installerPackageName = args.installerPackageName;
14938        final String volumeUuid = args.volumeUuid;
14939        final File tmpPackageFile = new File(args.getCodePath());
14940        final boolean forwardLocked = ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0);
14941        final boolean onExternal = (((installFlags & PackageManager.INSTALL_EXTERNAL) != 0)
14942                || (args.volumeUuid != null));
14943        final boolean ephemeral = ((installFlags & PackageManager.INSTALL_EPHEMERAL) != 0);
14944        final boolean forceSdk = ((installFlags & PackageManager.INSTALL_FORCE_SDK) != 0);
14945        boolean replace = false;
14946        int scanFlags = SCAN_NEW_INSTALL | SCAN_UPDATE_SIGNATURE;
14947        if (args.move != null) {
14948            // moving a complete application; perform an initial scan on the new install location
14949            scanFlags |= SCAN_INITIAL;
14950        }
14951        if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) {
14952            scanFlags |= SCAN_DONT_KILL_APP;
14953        }
14954
14955        // Result object to be returned
14956        res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
14957
14958        if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile);
14959
14960        // Sanity check
14961        if (ephemeral && (forwardLocked || onExternal)) {
14962            Slog.i(TAG, "Incompatible ephemeral install; fwdLocked=" + forwardLocked
14963                    + " external=" + onExternal);
14964            res.setReturnCode(PackageManager.INSTALL_FAILED_EPHEMERAL_INVALID);
14965            return;
14966        }
14967
14968        // Retrieve PackageSettings and parse package
14969        final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY
14970                | PackageParser.PARSE_ENFORCE_CODE
14971                | (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0)
14972                | (onExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0)
14973                | (ephemeral ? PackageParser.PARSE_IS_EPHEMERAL : 0)
14974                | (forceSdk ? PackageParser.PARSE_FORCE_SDK : 0);
14975        PackageParser pp = new PackageParser();
14976        pp.setSeparateProcesses(mSeparateProcesses);
14977        pp.setDisplayMetrics(mMetrics);
14978
14979        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
14980        final PackageParser.Package pkg;
14981        try {
14982            pkg = pp.parsePackage(tmpPackageFile, parseFlags);
14983        } catch (PackageParserException e) {
14984            res.setError("Failed parse during installPackageLI", e);
14985            return;
14986        } finally {
14987            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
14988        }
14989
14990        // If we are installing a clustered package add results for the children
14991        if (pkg.childPackages != null) {
14992            synchronized (mPackages) {
14993                final int childCount = pkg.childPackages.size();
14994                for (int i = 0; i < childCount; i++) {
14995                    PackageParser.Package childPkg = pkg.childPackages.get(i);
14996                    PackageInstalledInfo childRes = new PackageInstalledInfo();
14997                    childRes.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
14998                    childRes.pkg = childPkg;
14999                    childRes.name = childPkg.packageName;
15000                    PackageSetting childPs = mSettings.peekPackageLPr(childPkg.packageName);
15001                    if (childPs != null) {
15002                        childRes.origUsers = childPs.queryInstalledUsers(
15003                                sUserManager.getUserIds(), true);
15004                    }
15005                    if ((mPackages.containsKey(childPkg.packageName))) {
15006                        childRes.removedInfo = new PackageRemovedInfo();
15007                        childRes.removedInfo.removedPackage = childPkg.packageName;
15008                    }
15009                    if (res.addedChildPackages == null) {
15010                        res.addedChildPackages = new ArrayMap<>();
15011                    }
15012                    res.addedChildPackages.put(childPkg.packageName, childRes);
15013                }
15014            }
15015        }
15016
15017        // If package doesn't declare API override, mark that we have an install
15018        // time CPU ABI override.
15019        if (TextUtils.isEmpty(pkg.cpuAbiOverride)) {
15020            pkg.cpuAbiOverride = args.abiOverride;
15021        }
15022
15023        String pkgName = res.name = pkg.packageName;
15024        if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_TEST_ONLY) != 0) {
15025            if ((installFlags & PackageManager.INSTALL_ALLOW_TEST) == 0) {
15026                res.setError(INSTALL_FAILED_TEST_ONLY, "installPackageLI");
15027                return;
15028            }
15029        }
15030
15031        try {
15032            // either use what we've been given or parse directly from the APK
15033            if (args.certificates != null) {
15034                try {
15035                    PackageParser.populateCertificates(pkg, args.certificates);
15036                } catch (PackageParserException e) {
15037                    // there was something wrong with the certificates we were given;
15038                    // try to pull them from the APK
15039                    PackageParser.collectCertificates(pkg, parseFlags);
15040                }
15041            } else {
15042                PackageParser.collectCertificates(pkg, parseFlags);
15043            }
15044        } catch (PackageParserException e) {
15045            res.setError("Failed collect during installPackageLI", e);
15046            return;
15047        }
15048
15049        // Get rid of all references to package scan path via parser.
15050        pp = null;
15051        String oldCodePath = null;
15052        boolean systemApp = false;
15053        synchronized (mPackages) {
15054            // Check if installing already existing package
15055            if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
15056                String oldName = mSettings.mRenamedPackages.get(pkgName);
15057                if (pkg.mOriginalPackages != null
15058                        && pkg.mOriginalPackages.contains(oldName)
15059                        && mPackages.containsKey(oldName)) {
15060                    // This package is derived from an original package,
15061                    // and this device has been updating from that original
15062                    // name.  We must continue using the original name, so
15063                    // rename the new package here.
15064                    pkg.setPackageName(oldName);
15065                    pkgName = pkg.packageName;
15066                    replace = true;
15067                    if (DEBUG_INSTALL) Slog.d(TAG, "Replacing existing renamed package: oldName="
15068                            + oldName + " pkgName=" + pkgName);
15069                } else if (mPackages.containsKey(pkgName)) {
15070                    // This package, under its official name, already exists
15071                    // on the device; we should replace it.
15072                    replace = true;
15073                    if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing pacakge: " + pkgName);
15074                }
15075
15076                // Child packages are installed through the parent package
15077                if (pkg.parentPackage != null) {
15078                    res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME,
15079                            "Package " + pkg.packageName + " is child of package "
15080                                    + pkg.parentPackage.parentPackage + ". Child packages "
15081                                    + "can be updated only through the parent package.");
15082                    return;
15083                }
15084
15085                if (replace) {
15086                    // Prevent apps opting out from runtime permissions
15087                    PackageParser.Package oldPackage = mPackages.get(pkgName);
15088                    final int oldTargetSdk = oldPackage.applicationInfo.targetSdkVersion;
15089                    final int newTargetSdk = pkg.applicationInfo.targetSdkVersion;
15090                    if (oldTargetSdk > Build.VERSION_CODES.LOLLIPOP_MR1
15091                            && newTargetSdk <= Build.VERSION_CODES.LOLLIPOP_MR1) {
15092                        res.setError(PackageManager.INSTALL_FAILED_PERMISSION_MODEL_DOWNGRADE,
15093                                "Package " + pkg.packageName + " new target SDK " + newTargetSdk
15094                                        + " doesn't support runtime permissions but the old"
15095                                        + " target SDK " + oldTargetSdk + " does.");
15096                        return;
15097                    }
15098
15099                    // Prevent installing of child packages
15100                    if (oldPackage.parentPackage != null) {
15101                        res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME,
15102                                "Package " + pkg.packageName + " is child of package "
15103                                        + oldPackage.parentPackage + ". Child packages "
15104                                        + "can be updated only through the parent package.");
15105                        return;
15106                    }
15107                }
15108            }
15109
15110            PackageSetting ps = mSettings.mPackages.get(pkgName);
15111            if (ps != null) {
15112                if (DEBUG_INSTALL) Slog.d(TAG, "Existing package: " + ps);
15113
15114                // Quick sanity check that we're signed correctly if updating;
15115                // we'll check this again later when scanning, but we want to
15116                // bail early here before tripping over redefined permissions.
15117                if (shouldCheckUpgradeKeySetLP(ps, scanFlags)) {
15118                    if (!checkUpgradeKeySetLP(ps, pkg)) {
15119                        res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
15120                                + pkg.packageName + " upgrade keys do not match the "
15121                                + "previously installed version");
15122                        return;
15123                    }
15124                } else {
15125                    try {
15126                        verifySignaturesLP(ps, pkg);
15127                    } catch (PackageManagerException e) {
15128                        res.setError(e.error, e.getMessage());
15129                        return;
15130                    }
15131                }
15132
15133                oldCodePath = mSettings.mPackages.get(pkgName).codePathString;
15134                if (ps.pkg != null && ps.pkg.applicationInfo != null) {
15135                    systemApp = (ps.pkg.applicationInfo.flags &
15136                            ApplicationInfo.FLAG_SYSTEM) != 0;
15137                }
15138                res.origUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
15139            }
15140
15141            // Check whether the newly-scanned package wants to define an already-defined perm
15142            int N = pkg.permissions.size();
15143            for (int i = N-1; i >= 0; i--) {
15144                PackageParser.Permission perm = pkg.permissions.get(i);
15145                BasePermission bp = mSettings.mPermissions.get(perm.info.name);
15146                if (bp != null) {
15147                    // If the defining package is signed with our cert, it's okay.  This
15148                    // also includes the "updating the same package" case, of course.
15149                    // "updating same package" could also involve key-rotation.
15150                    final boolean sigsOk;
15151                    if (bp.sourcePackage.equals(pkg.packageName)
15152                            && (bp.packageSetting instanceof PackageSetting)
15153                            && (shouldCheckUpgradeKeySetLP((PackageSetting) bp.packageSetting,
15154                                    scanFlags))) {
15155                        sigsOk = checkUpgradeKeySetLP((PackageSetting) bp.packageSetting, pkg);
15156                    } else {
15157                        sigsOk = compareSignatures(bp.packageSetting.signatures.mSignatures,
15158                                pkg.mSignatures) == PackageManager.SIGNATURE_MATCH;
15159                    }
15160                    if (!sigsOk) {
15161                        // If the owning package is the system itself, we log but allow
15162                        // install to proceed; we fail the install on all other permission
15163                        // redefinitions.
15164                        if (!bp.sourcePackage.equals("android")) {
15165                            res.setError(INSTALL_FAILED_DUPLICATE_PERMISSION, "Package "
15166                                    + pkg.packageName + " attempting to redeclare permission "
15167                                    + perm.info.name + " already owned by " + bp.sourcePackage);
15168                            res.origPermission = perm.info.name;
15169                            res.origPackage = bp.sourcePackage;
15170                            return;
15171                        } else {
15172                            Slog.w(TAG, "Package " + pkg.packageName
15173                                    + " attempting to redeclare system permission "
15174                                    + perm.info.name + "; ignoring new declaration");
15175                            pkg.permissions.remove(i);
15176                        }
15177                    }
15178                }
15179            }
15180        }
15181
15182        if (systemApp) {
15183            if (onExternal) {
15184                // Abort update; system app can't be replaced with app on sdcard
15185                res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
15186                        "Cannot install updates to system apps on sdcard");
15187                return;
15188            } else if (ephemeral) {
15189                // Abort update; system app can't be replaced with an ephemeral app
15190                res.setError(INSTALL_FAILED_EPHEMERAL_INVALID,
15191                        "Cannot update a system app with an ephemeral app");
15192                return;
15193            }
15194        }
15195
15196        if (args.move != null) {
15197            // We did an in-place move, so dex is ready to roll
15198            scanFlags |= SCAN_NO_DEX;
15199            scanFlags |= SCAN_MOVE;
15200
15201            synchronized (mPackages) {
15202                final PackageSetting ps = mSettings.mPackages.get(pkgName);
15203                if (ps == null) {
15204                    res.setError(INSTALL_FAILED_INTERNAL_ERROR,
15205                            "Missing settings for moved package " + pkgName);
15206                }
15207
15208                // We moved the entire application as-is, so bring over the
15209                // previously derived ABI information.
15210                pkg.applicationInfo.primaryCpuAbi = ps.primaryCpuAbiString;
15211                pkg.applicationInfo.secondaryCpuAbi = ps.secondaryCpuAbiString;
15212            }
15213
15214        } else if (!forwardLocked && !pkg.applicationInfo.isExternalAsec()) {
15215            // Enable SCAN_NO_DEX flag to skip dexopt at a later stage
15216            scanFlags |= SCAN_NO_DEX;
15217
15218            try {
15219                String abiOverride = (TextUtils.isEmpty(pkg.cpuAbiOverride) ?
15220                    args.abiOverride : pkg.cpuAbiOverride);
15221                derivePackageAbi(pkg, new File(pkg.codePath), abiOverride,
15222                        true /* extract libs */);
15223            } catch (PackageManagerException pme) {
15224                Slog.e(TAG, "Error deriving application ABI", pme);
15225                res.setError(INSTALL_FAILED_INTERNAL_ERROR, "Error deriving application ABI");
15226                return;
15227            }
15228
15229            // Shared libraries for the package need to be updated.
15230            synchronized (mPackages) {
15231                try {
15232                    updateSharedLibrariesLPw(pkg, null);
15233                } catch (PackageManagerException e) {
15234                    Slog.e(TAG, "updateSharedLibrariesLPw failed: " + e.getMessage());
15235                }
15236            }
15237            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
15238            // Do not run PackageDexOptimizer through the local performDexOpt
15239            // method because `pkg` may not be in `mPackages` yet.
15240            //
15241            // Also, don't fail application installs if the dexopt step fails.
15242            mPackageDexOptimizer.performDexOpt(pkg, pkg.usesLibraryFiles,
15243                    null /* instructionSets */, false /* checkProfiles */,
15244                    getCompilerFilterForReason(REASON_INSTALL),
15245                    getOrCreateCompilerPackageStats(pkg),
15246                    mDexManager.isUsedByOtherApps(pkg.packageName));
15247            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
15248
15249            // Notify BackgroundDexOptService that the package has been changed.
15250            // If this is an update of a package which used to fail to compile,
15251            // BDOS will remove it from its blacklist.
15252            BackgroundDexOptService.notifyPackageChanged(pkg.packageName);
15253        }
15254
15255        if (!args.doRename(res.returnCode, pkg, oldCodePath)) {
15256            res.setError(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename");
15257            return;
15258        }
15259
15260        startIntentFilterVerifications(args.user.getIdentifier(), replace, pkg);
15261
15262        try (PackageFreezer freezer = freezePackageForInstall(pkgName, installFlags,
15263                "installPackageLI")) {
15264            if (replace) {
15265                replacePackageLIF(pkg, parseFlags, scanFlags | SCAN_REPLACING, args.user,
15266                        installerPackageName, res);
15267            } else {
15268                installNewPackageLIF(pkg, parseFlags, scanFlags | SCAN_DELETE_DATA_ON_FAILURES,
15269                        args.user, installerPackageName, volumeUuid, res);
15270            }
15271        }
15272        synchronized (mPackages) {
15273            final PackageSetting ps = mSettings.mPackages.get(pkgName);
15274            if (ps != null) {
15275                res.newUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
15276            }
15277
15278            final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
15279            for (int i = 0; i < childCount; i++) {
15280                PackageParser.Package childPkg = pkg.childPackages.get(i);
15281                PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName);
15282                PackageSetting childPs = mSettings.peekPackageLPr(childPkg.packageName);
15283                if (childPs != null) {
15284                    childRes.newUsers = childPs.queryInstalledUsers(
15285                            sUserManager.getUserIds(), true);
15286                }
15287            }
15288        }
15289    }
15290
15291    private void startIntentFilterVerifications(int userId, boolean replacing,
15292            PackageParser.Package pkg) {
15293        if (mIntentFilterVerifierComponent == null) {
15294            Slog.w(TAG, "No IntentFilter verification will not be done as "
15295                    + "there is no IntentFilterVerifier available!");
15296            return;
15297        }
15298
15299        final int verifierUid = getPackageUid(
15300                mIntentFilterVerifierComponent.getPackageName(),
15301                MATCH_DEBUG_TRIAGED_MISSING,
15302                (userId == UserHandle.USER_ALL) ? UserHandle.USER_SYSTEM : userId);
15303
15304        Message msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS);
15305        msg.obj = new IFVerificationParams(pkg, replacing, userId, verifierUid);
15306        mHandler.sendMessage(msg);
15307
15308        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
15309        for (int i = 0; i < childCount; i++) {
15310            PackageParser.Package childPkg = pkg.childPackages.get(i);
15311            msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS);
15312            msg.obj = new IFVerificationParams(childPkg, replacing, userId, verifierUid);
15313            mHandler.sendMessage(msg);
15314        }
15315    }
15316
15317    private void verifyIntentFiltersIfNeeded(int userId, int verifierUid, boolean replacing,
15318            PackageParser.Package pkg) {
15319        int size = pkg.activities.size();
15320        if (size == 0) {
15321            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
15322                    "No activity, so no need to verify any IntentFilter!");
15323            return;
15324        }
15325
15326        final boolean hasDomainURLs = hasDomainURLs(pkg);
15327        if (!hasDomainURLs) {
15328            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
15329                    "No domain URLs, so no need to verify any IntentFilter!");
15330            return;
15331        }
15332
15333        if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Checking for userId:" + userId
15334                + " if any IntentFilter from the " + size
15335                + " Activities needs verification ...");
15336
15337        int count = 0;
15338        final String packageName = pkg.packageName;
15339
15340        synchronized (mPackages) {
15341            // If this is a new install and we see that we've already run verification for this
15342            // package, we have nothing to do: it means the state was restored from backup.
15343            if (!replacing) {
15344                IntentFilterVerificationInfo ivi =
15345                        mSettings.getIntentFilterVerificationLPr(packageName);
15346                if (ivi != null) {
15347                    if (DEBUG_DOMAIN_VERIFICATION) {
15348                        Slog.i(TAG, "Package " + packageName+ " already verified: status="
15349                                + ivi.getStatusString());
15350                    }
15351                    return;
15352                }
15353            }
15354
15355            // If any filters need to be verified, then all need to be.
15356            boolean needToVerify = false;
15357            for (PackageParser.Activity a : pkg.activities) {
15358                for (ActivityIntentInfo filter : a.intents) {
15359                    if (filter.needsVerification() && needsNetworkVerificationLPr(filter)) {
15360                        if (DEBUG_DOMAIN_VERIFICATION) {
15361                            Slog.d(TAG, "Intent filter needs verification, so processing all filters");
15362                        }
15363                        needToVerify = true;
15364                        break;
15365                    }
15366                }
15367            }
15368
15369            if (needToVerify) {
15370                final int verificationId = mIntentFilterVerificationToken++;
15371                for (PackageParser.Activity a : pkg.activities) {
15372                    for (ActivityIntentInfo filter : a.intents) {
15373                        if (filter.handlesWebUris(true) && needsNetworkVerificationLPr(filter)) {
15374                            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
15375                                    "Verification needed for IntentFilter:" + filter.toString());
15376                            mIntentFilterVerifier.addOneIntentFilterVerification(
15377                                    verifierUid, userId, verificationId, filter, packageName);
15378                            count++;
15379                        }
15380                    }
15381                }
15382            }
15383        }
15384
15385        if (count > 0) {
15386            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Starting " + count
15387                    + " IntentFilter verification" + (count > 1 ? "s" : "")
15388                    +  " for userId:" + userId);
15389            mIntentFilterVerifier.startVerifications(userId);
15390        } else {
15391            if (DEBUG_DOMAIN_VERIFICATION) {
15392                Slog.d(TAG, "No filters or not all autoVerify for " + packageName);
15393            }
15394        }
15395    }
15396
15397    private boolean needsNetworkVerificationLPr(ActivityIntentInfo filter) {
15398        final ComponentName cn  = filter.activity.getComponentName();
15399        final String packageName = cn.getPackageName();
15400
15401        IntentFilterVerificationInfo ivi = mSettings.getIntentFilterVerificationLPr(
15402                packageName);
15403        if (ivi == null) {
15404            return true;
15405        }
15406        int status = ivi.getStatus();
15407        switch (status) {
15408            case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED:
15409            case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK:
15410                return true;
15411
15412            default:
15413                // Nothing to do
15414                return false;
15415        }
15416    }
15417
15418    private static boolean isMultiArch(ApplicationInfo info) {
15419        return (info.flags & ApplicationInfo.FLAG_MULTIARCH) != 0;
15420    }
15421
15422    private static boolean isExternal(PackageParser.Package pkg) {
15423        return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
15424    }
15425
15426    private static boolean isExternal(PackageSetting ps) {
15427        return (ps.pkgFlags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
15428    }
15429
15430    private static boolean isEphemeral(PackageParser.Package pkg) {
15431        return pkg.applicationInfo.isEphemeralApp();
15432    }
15433
15434    private static boolean isEphemeral(PackageSetting ps) {
15435        return ps.pkg != null && isEphemeral(ps.pkg);
15436    }
15437
15438    private static boolean isSystemApp(PackageParser.Package pkg) {
15439        return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
15440    }
15441
15442    private static boolean isPrivilegedApp(PackageParser.Package pkg) {
15443        return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0;
15444    }
15445
15446    private static boolean hasDomainURLs(PackageParser.Package pkg) {
15447        return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) != 0;
15448    }
15449
15450    private static boolean isSystemApp(PackageSetting ps) {
15451        return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0;
15452    }
15453
15454    private static boolean isUpdatedSystemApp(PackageSetting ps) {
15455        return (ps.pkgFlags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
15456    }
15457
15458    private int packageFlagsToInstallFlags(PackageSetting ps) {
15459        int installFlags = 0;
15460        if (isEphemeral(ps)) {
15461            installFlags |= PackageManager.INSTALL_EPHEMERAL;
15462        }
15463        if (isExternal(ps) && TextUtils.isEmpty(ps.volumeUuid)) {
15464            // This existing package was an external ASEC install when we have
15465            // the external flag without a UUID
15466            installFlags |= PackageManager.INSTALL_EXTERNAL;
15467        }
15468        if (ps.isForwardLocked()) {
15469            installFlags |= PackageManager.INSTALL_FORWARD_LOCK;
15470        }
15471        return installFlags;
15472    }
15473
15474    private String getVolumeUuidForPackage(PackageParser.Package pkg) {
15475        if (isExternal(pkg)) {
15476            if (TextUtils.isEmpty(pkg.volumeUuid)) {
15477                return StorageManager.UUID_PRIMARY_PHYSICAL;
15478            } else {
15479                return pkg.volumeUuid;
15480            }
15481        } else {
15482            return StorageManager.UUID_PRIVATE_INTERNAL;
15483        }
15484    }
15485
15486    private VersionInfo getSettingsVersionForPackage(PackageParser.Package pkg) {
15487        if (isExternal(pkg)) {
15488            if (TextUtils.isEmpty(pkg.volumeUuid)) {
15489                return mSettings.getExternalVersion();
15490            } else {
15491                return mSettings.findOrCreateVersion(pkg.volumeUuid);
15492            }
15493        } else {
15494            return mSettings.getInternalVersion();
15495        }
15496    }
15497
15498    private void deleteTempPackageFiles() {
15499        final FilenameFilter filter = new FilenameFilter() {
15500            public boolean accept(File dir, String name) {
15501                return name.startsWith("vmdl") && name.endsWith(".tmp");
15502            }
15503        };
15504        for (File file : mDrmAppPrivateInstallDir.listFiles(filter)) {
15505            file.delete();
15506        }
15507    }
15508
15509    @Override
15510    public void deletePackageAsUser(String packageName, IPackageDeleteObserver observer, int userId,
15511            int flags) {
15512        deletePackage(packageName, new LegacyPackageDeleteObserver(observer).getBinder(), userId,
15513                flags);
15514    }
15515
15516    @Override
15517    public void deletePackage(final String packageName,
15518            final IPackageDeleteObserver2 observer, final int userId, final int deleteFlags) {
15519        mContext.enforceCallingOrSelfPermission(
15520                android.Manifest.permission.DELETE_PACKAGES, null);
15521        Preconditions.checkNotNull(packageName);
15522        Preconditions.checkNotNull(observer);
15523        final int uid = Binder.getCallingUid();
15524        if (!isOrphaned(packageName)
15525                && !isCallerAllowedToSilentlyUninstall(uid, packageName)) {
15526            try {
15527                final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE);
15528                intent.setData(Uri.fromParts(PACKAGE_SCHEME, packageName, null));
15529                intent.putExtra(PackageInstaller.EXTRA_CALLBACK, observer.asBinder());
15530                observer.onUserActionRequired(intent);
15531            } catch (RemoteException re) {
15532            }
15533            return;
15534        }
15535        final boolean deleteAllUsers = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0;
15536        final int[] users = deleteAllUsers ? sUserManager.getUserIds() : new int[]{ userId };
15537        if (UserHandle.getUserId(uid) != userId || (deleteAllUsers && users.length > 1)) {
15538            mContext.enforceCallingOrSelfPermission(
15539                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
15540                    "deletePackage for user " + userId);
15541        }
15542
15543        if (isUserRestricted(userId, UserManager.DISALLOW_UNINSTALL_APPS)) {
15544            try {
15545                observer.onPackageDeleted(packageName,
15546                        PackageManager.DELETE_FAILED_USER_RESTRICTED, null);
15547            } catch (RemoteException re) {
15548            }
15549            return;
15550        }
15551
15552        if (!deleteAllUsers && getBlockUninstallForUser(packageName, userId)) {
15553            try {
15554                observer.onPackageDeleted(packageName,
15555                        PackageManager.DELETE_FAILED_OWNER_BLOCKED, null);
15556            } catch (RemoteException re) {
15557            }
15558            return;
15559        }
15560
15561        if (DEBUG_REMOVE) {
15562            Slog.d(TAG, "deletePackageAsUser: pkg=" + packageName + " user=" + userId
15563                    + " deleteAllUsers: " + deleteAllUsers );
15564        }
15565        // Queue up an async operation since the package deletion may take a little while.
15566        mHandler.post(new Runnable() {
15567            public void run() {
15568                mHandler.removeCallbacks(this);
15569                int returnCode;
15570                if (!deleteAllUsers) {
15571                    returnCode = deletePackageX(packageName, userId, deleteFlags);
15572                } else {
15573                    int[] blockUninstallUserIds = getBlockUninstallForUsers(packageName, users);
15574                    // If nobody is blocking uninstall, proceed with delete for all users
15575                    if (ArrayUtils.isEmpty(blockUninstallUserIds)) {
15576                        returnCode = deletePackageX(packageName, userId, deleteFlags);
15577                    } else {
15578                        // Otherwise uninstall individually for users with blockUninstalls=false
15579                        final int userFlags = deleteFlags & ~PackageManager.DELETE_ALL_USERS;
15580                        for (int userId : users) {
15581                            if (!ArrayUtils.contains(blockUninstallUserIds, userId)) {
15582                                returnCode = deletePackageX(packageName, userId, userFlags);
15583                                if (returnCode != PackageManager.DELETE_SUCCEEDED) {
15584                                    Slog.w(TAG, "Package delete failed for user " + userId
15585                                            + ", returnCode " + returnCode);
15586                                }
15587                            }
15588                        }
15589                        // The app has only been marked uninstalled for certain users.
15590                        // We still need to report that delete was blocked
15591                        returnCode = PackageManager.DELETE_FAILED_OWNER_BLOCKED;
15592                    }
15593                }
15594                try {
15595                    observer.onPackageDeleted(packageName, returnCode, null);
15596                } catch (RemoteException e) {
15597                    Log.i(TAG, "Observer no longer exists.");
15598                } //end catch
15599            } //end run
15600        });
15601    }
15602
15603    private boolean isCallerAllowedToSilentlyUninstall(int callingUid, String pkgName) {
15604        if (callingUid == Process.SHELL_UID || callingUid == Process.ROOT_UID
15605              || callingUid == Process.SYSTEM_UID) {
15606            return true;
15607        }
15608        final int callingUserId = UserHandle.getUserId(callingUid);
15609        // If the caller installed the pkgName, then allow it to silently uninstall.
15610        if (callingUid == getPackageUid(getInstallerPackageName(pkgName), 0, callingUserId)) {
15611            return true;
15612        }
15613
15614        // Allow package verifier to silently uninstall.
15615        if (mRequiredVerifierPackage != null &&
15616                callingUid == getPackageUid(mRequiredVerifierPackage, 0, callingUserId)) {
15617            return true;
15618        }
15619
15620        // Allow package uninstaller to silently uninstall.
15621        if (mRequiredUninstallerPackage != null &&
15622                callingUid == getPackageUid(mRequiredUninstallerPackage, 0, callingUserId)) {
15623            return true;
15624        }
15625
15626        // Allow storage manager to silently uninstall.
15627        if (mStorageManagerPackage != null &&
15628                callingUid == getPackageUid(mStorageManagerPackage, 0, callingUserId)) {
15629            return true;
15630        }
15631
15632        // Allow caller having MANAGE_PROFILE_AND_DEVICE_OWNERS permission to silently
15633        // uninstall for device owner provisioning.
15634        if (checkUidPermission(MANAGE_PROFILE_AND_DEVICE_OWNERS, callingUid)
15635                == PERMISSION_GRANTED) {
15636            return true;
15637        }
15638
15639        return false;
15640    }
15641
15642    private int[] getBlockUninstallForUsers(String packageName, int[] userIds) {
15643        int[] result = EMPTY_INT_ARRAY;
15644        for (int userId : userIds) {
15645            if (getBlockUninstallForUser(packageName, userId)) {
15646                result = ArrayUtils.appendInt(result, userId);
15647            }
15648        }
15649        return result;
15650    }
15651
15652    @Override
15653    public boolean isPackageDeviceAdminOnAnyUser(String packageName) {
15654        return isPackageDeviceAdmin(packageName, UserHandle.USER_ALL);
15655    }
15656
15657    private boolean isPackageDeviceAdmin(String packageName, int userId) {
15658        IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
15659                ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
15660        try {
15661            if (dpm != null) {
15662                final ComponentName deviceOwnerComponentName = dpm.getDeviceOwnerComponent(
15663                        /* callingUserOnly =*/ false);
15664                final String deviceOwnerPackageName = deviceOwnerComponentName == null ? null
15665                        : deviceOwnerComponentName.getPackageName();
15666                // Does the package contains the device owner?
15667                // TODO Do we have to do it even if userId != UserHandle.USER_ALL?  Otherwise,
15668                // this check is probably not needed, since DO should be registered as a device
15669                // admin on some user too. (Original bug for this: b/17657954)
15670                if (packageName.equals(deviceOwnerPackageName)) {
15671                    return true;
15672                }
15673                // Does it contain a device admin for any user?
15674                int[] users;
15675                if (userId == UserHandle.USER_ALL) {
15676                    users = sUserManager.getUserIds();
15677                } else {
15678                    users = new int[]{userId};
15679                }
15680                for (int i = 0; i < users.length; ++i) {
15681                    if (dpm.packageHasActiveAdmins(packageName, users[i])) {
15682                        return true;
15683                    }
15684                }
15685            }
15686        } catch (RemoteException e) {
15687        }
15688        return false;
15689    }
15690
15691    private boolean shouldKeepUninstalledPackageLPr(String packageName) {
15692        return mKeepUninstalledPackages != null && mKeepUninstalledPackages.contains(packageName);
15693    }
15694
15695    /**
15696     *  This method is an internal method that could be get invoked either
15697     *  to delete an installed package or to clean up a failed installation.
15698     *  After deleting an installed package, a broadcast is sent to notify any
15699     *  listeners that the package has been removed. For cleaning up a failed
15700     *  installation, the broadcast is not necessary since the package's
15701     *  installation wouldn't have sent the initial broadcast either
15702     *  The key steps in deleting a package are
15703     *  deleting the package information in internal structures like mPackages,
15704     *  deleting the packages base directories through installd
15705     *  updating mSettings to reflect current status
15706     *  persisting settings for later use
15707     *  sending a broadcast if necessary
15708     */
15709    private int deletePackageX(String packageName, int userId, int deleteFlags) {
15710        final PackageRemovedInfo info = new PackageRemovedInfo();
15711        final boolean res;
15712
15713        final int removeUser = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0
15714                ? UserHandle.USER_ALL : userId;
15715
15716        if (isPackageDeviceAdmin(packageName, removeUser)) {
15717            Slog.w(TAG, "Not removing package " + packageName + ": has active device admin");
15718            return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER;
15719        }
15720
15721        PackageSetting uninstalledPs = null;
15722
15723        // for the uninstall-updates case and restricted profiles, remember the per-
15724        // user handle installed state
15725        int[] allUsers;
15726        synchronized (mPackages) {
15727            uninstalledPs = mSettings.mPackages.get(packageName);
15728            if (uninstalledPs == null) {
15729                Slog.w(TAG, "Not removing non-existent package " + packageName);
15730                return PackageManager.DELETE_FAILED_INTERNAL_ERROR;
15731            }
15732            allUsers = sUserManager.getUserIds();
15733            info.origUsers = uninstalledPs.queryInstalledUsers(allUsers, true);
15734        }
15735
15736        final int freezeUser;
15737        if (isUpdatedSystemApp(uninstalledPs)
15738                && ((deleteFlags & PackageManager.DELETE_SYSTEM_APP) == 0)) {
15739            // We're downgrading a system app, which will apply to all users, so
15740            // freeze them all during the downgrade
15741            freezeUser = UserHandle.USER_ALL;
15742        } else {
15743            freezeUser = removeUser;
15744        }
15745
15746        synchronized (mInstallLock) {
15747            if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageX: pkg=" + packageName + " user=" + userId);
15748            try (PackageFreezer freezer = freezePackageForDelete(packageName, freezeUser,
15749                    deleteFlags, "deletePackageX")) {
15750                res = deletePackageLIF(packageName, UserHandle.of(removeUser), true, allUsers,
15751                        deleteFlags | REMOVE_CHATTY, info, true, null);
15752            }
15753            synchronized (mPackages) {
15754                if (res) {
15755                    mEphemeralApplicationRegistry.onPackageUninstalledLPw(uninstalledPs.pkg);
15756                }
15757            }
15758        }
15759
15760        if (res) {
15761            final boolean killApp = (deleteFlags & PackageManager.DELETE_DONT_KILL_APP) == 0;
15762            info.sendPackageRemovedBroadcasts(killApp);
15763            info.sendSystemPackageUpdatedBroadcasts();
15764            info.sendSystemPackageAppearedBroadcasts();
15765        }
15766        // Force a gc here.
15767        Runtime.getRuntime().gc();
15768        // Delete the resources here after sending the broadcast to let
15769        // other processes clean up before deleting resources.
15770        if (info.args != null) {
15771            synchronized (mInstallLock) {
15772                info.args.doPostDeleteLI(true);
15773            }
15774        }
15775
15776        return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR;
15777    }
15778
15779    class PackageRemovedInfo {
15780        String removedPackage;
15781        int uid = -1;
15782        int removedAppId = -1;
15783        int[] origUsers;
15784        int[] removedUsers = null;
15785        boolean isRemovedPackageSystemUpdate = false;
15786        boolean isUpdate;
15787        boolean dataRemoved;
15788        boolean removedForAllUsers;
15789        // Clean up resources deleted packages.
15790        InstallArgs args = null;
15791        ArrayMap<String, PackageRemovedInfo> removedChildPackages;
15792        ArrayMap<String, PackageInstalledInfo> appearedChildPackages;
15793
15794        void sendPackageRemovedBroadcasts(boolean killApp) {
15795            sendPackageRemovedBroadcastInternal(killApp);
15796            final int childCount = removedChildPackages != null ? removedChildPackages.size() : 0;
15797            for (int i = 0; i < childCount; i++) {
15798                PackageRemovedInfo childInfo = removedChildPackages.valueAt(i);
15799                childInfo.sendPackageRemovedBroadcastInternal(killApp);
15800            }
15801        }
15802
15803        void sendSystemPackageUpdatedBroadcasts() {
15804            if (isRemovedPackageSystemUpdate) {
15805                sendSystemPackageUpdatedBroadcastsInternal();
15806                final int childCount = (removedChildPackages != null)
15807                        ? removedChildPackages.size() : 0;
15808                for (int i = 0; i < childCount; i++) {
15809                    PackageRemovedInfo childInfo = removedChildPackages.valueAt(i);
15810                    if (childInfo.isRemovedPackageSystemUpdate) {
15811                        childInfo.sendSystemPackageUpdatedBroadcastsInternal();
15812                    }
15813                }
15814            }
15815        }
15816
15817        void sendSystemPackageAppearedBroadcasts() {
15818            final int packageCount = (appearedChildPackages != null)
15819                    ? appearedChildPackages.size() : 0;
15820            for (int i = 0; i < packageCount; i++) {
15821                PackageInstalledInfo installedInfo = appearedChildPackages.valueAt(i);
15822                for (int userId : installedInfo.newUsers) {
15823                    sendPackageAddedForUser(installedInfo.name, true,
15824                            UserHandle.getAppId(installedInfo.uid), userId);
15825                }
15826            }
15827        }
15828
15829        private void sendSystemPackageUpdatedBroadcastsInternal() {
15830            Bundle extras = new Bundle(2);
15831            extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid);
15832            extras.putBoolean(Intent.EXTRA_REPLACING, true);
15833            sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, removedPackage,
15834                    extras, 0, null, null, null);
15835            sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, removedPackage,
15836                    extras, 0, null, null, null);
15837            sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, null,
15838                    null, 0, removedPackage, null, null);
15839        }
15840
15841        private void sendPackageRemovedBroadcastInternal(boolean killApp) {
15842            Bundle extras = new Bundle(2);
15843            extras.putInt(Intent.EXTRA_UID, removedAppId >= 0  ? removedAppId : uid);
15844            extras.putBoolean(Intent.EXTRA_DATA_REMOVED, dataRemoved);
15845            extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, !killApp);
15846            if (isUpdate || isRemovedPackageSystemUpdate) {
15847                extras.putBoolean(Intent.EXTRA_REPLACING, true);
15848            }
15849            extras.putBoolean(Intent.EXTRA_REMOVED_FOR_ALL_USERS, removedForAllUsers);
15850            if (removedPackage != null) {
15851                sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED, removedPackage,
15852                        extras, 0, null, null, removedUsers);
15853                if (dataRemoved && !isRemovedPackageSystemUpdate) {
15854                    sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED,
15855                            removedPackage, extras, 0, null, null, removedUsers);
15856                }
15857            }
15858            if (removedAppId >= 0) {
15859                sendPackageBroadcast(Intent.ACTION_UID_REMOVED, null, extras, 0, null, null,
15860                        removedUsers);
15861            }
15862        }
15863    }
15864
15865    /*
15866     * This method deletes the package from internal data structures. If the DONT_DELETE_DATA
15867     * flag is not set, the data directory is removed as well.
15868     * make sure this flag is set for partially installed apps. If not its meaningless to
15869     * delete a partially installed application.
15870     */
15871    private void removePackageDataLIF(PackageSetting ps, int[] allUserHandles,
15872            PackageRemovedInfo outInfo, int flags, boolean writeSettings) {
15873        String packageName = ps.name;
15874        if (DEBUG_REMOVE) Slog.d(TAG, "removePackageDataLI: " + ps);
15875        // Retrieve object to delete permissions for shared user later on
15876        final PackageParser.Package deletedPkg;
15877        final PackageSetting deletedPs;
15878        // reader
15879        synchronized (mPackages) {
15880            deletedPkg = mPackages.get(packageName);
15881            deletedPs = mSettings.mPackages.get(packageName);
15882            if (outInfo != null) {
15883                outInfo.removedPackage = packageName;
15884                outInfo.removedUsers = deletedPs != null
15885                        ? deletedPs.queryInstalledUsers(sUserManager.getUserIds(), true)
15886                        : null;
15887            }
15888        }
15889
15890        removePackageLI(ps, (flags & REMOVE_CHATTY) != 0);
15891
15892        if ((flags & PackageManager.DELETE_KEEP_DATA) == 0) {
15893            final PackageParser.Package resolvedPkg;
15894            if (deletedPkg != null) {
15895                resolvedPkg = deletedPkg;
15896            } else {
15897                // We don't have a parsed package when it lives on an ejected
15898                // adopted storage device, so fake something together
15899                resolvedPkg = new PackageParser.Package(ps.name);
15900                resolvedPkg.setVolumeUuid(ps.volumeUuid);
15901            }
15902            destroyAppDataLIF(resolvedPkg, UserHandle.USER_ALL,
15903                    StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
15904            destroyAppProfilesLIF(resolvedPkg, UserHandle.USER_ALL);
15905            if (outInfo != null) {
15906                outInfo.dataRemoved = true;
15907            }
15908            schedulePackageCleaning(packageName, UserHandle.USER_ALL, true);
15909        }
15910
15911        // writer
15912        synchronized (mPackages) {
15913            if (deletedPs != null) {
15914                if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) {
15915                    clearIntentFilterVerificationsLPw(deletedPs.name, UserHandle.USER_ALL);
15916                    clearDefaultBrowserIfNeeded(packageName);
15917                    if (outInfo != null) {
15918                        mSettings.mKeySetManagerService.removeAppKeySetDataLPw(packageName);
15919                        outInfo.removedAppId = mSettings.removePackageLPw(packageName);
15920                    }
15921                    updatePermissionsLPw(deletedPs.name, null, 0);
15922                    if (deletedPs.sharedUser != null) {
15923                        // Remove permissions associated with package. Since runtime
15924                        // permissions are per user we have to kill the removed package
15925                        // or packages running under the shared user of the removed
15926                        // package if revoking the permissions requested only by the removed
15927                        // package is successful and this causes a change in gids.
15928                        for (int userId : UserManagerService.getInstance().getUserIds()) {
15929                            final int userIdToKill = mSettings.updateSharedUserPermsLPw(deletedPs,
15930                                    userId);
15931                            if (userIdToKill == UserHandle.USER_ALL
15932                                    || userIdToKill >= UserHandle.USER_SYSTEM) {
15933                                // If gids changed for this user, kill all affected packages.
15934                                mHandler.post(new Runnable() {
15935                                    @Override
15936                                    public void run() {
15937                                        // This has to happen with no lock held.
15938                                        killApplication(deletedPs.name, deletedPs.appId,
15939                                                KILL_APP_REASON_GIDS_CHANGED);
15940                                    }
15941                                });
15942                                break;
15943                            }
15944                        }
15945                    }
15946                    clearPackagePreferredActivitiesLPw(deletedPs.name, UserHandle.USER_ALL);
15947                }
15948                // make sure to preserve per-user disabled state if this removal was just
15949                // a downgrade of a system app to the factory package
15950                if (allUserHandles != null && outInfo != null && outInfo.origUsers != null) {
15951                    if (DEBUG_REMOVE) {
15952                        Slog.d(TAG, "Propagating install state across downgrade");
15953                    }
15954                    for (int userId : allUserHandles) {
15955                        final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId);
15956                        if (DEBUG_REMOVE) {
15957                            Slog.d(TAG, "    user " + userId + " => " + installed);
15958                        }
15959                        ps.setInstalled(installed, userId);
15960                    }
15961                }
15962            }
15963            // can downgrade to reader
15964            if (writeSettings) {
15965                // Save settings now
15966                mSettings.writeLPr();
15967            }
15968        }
15969        if (outInfo != null) {
15970            // A user ID was deleted here. Go through all users and remove it
15971            // from KeyStore.
15972            removeKeystoreDataIfNeeded(UserHandle.USER_ALL, outInfo.removedAppId);
15973        }
15974    }
15975
15976    static boolean locationIsPrivileged(File path) {
15977        try {
15978            final String privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app")
15979                    .getCanonicalPath();
15980            return path.getCanonicalPath().startsWith(privilegedAppDir);
15981        } catch (IOException e) {
15982            Slog.e(TAG, "Unable to access code path " + path);
15983        }
15984        return false;
15985    }
15986
15987    /*
15988     * Tries to delete system package.
15989     */
15990    private boolean deleteSystemPackageLIF(PackageParser.Package deletedPkg,
15991            PackageSetting deletedPs, int[] allUserHandles, int flags, PackageRemovedInfo outInfo,
15992            boolean writeSettings) {
15993        if (deletedPs.parentPackageName != null) {
15994            Slog.w(TAG, "Attempt to delete child system package " + deletedPkg.packageName);
15995            return false;
15996        }
15997
15998        final boolean applyUserRestrictions
15999                = (allUserHandles != null) && (outInfo.origUsers != null);
16000        final PackageSetting disabledPs;
16001        // Confirm if the system package has been updated
16002        // An updated system app can be deleted. This will also have to restore
16003        // the system pkg from system partition
16004        // reader
16005        synchronized (mPackages) {
16006            disabledPs = mSettings.getDisabledSystemPkgLPr(deletedPs.name);
16007        }
16008
16009        if (DEBUG_REMOVE) Slog.d(TAG, "deleteSystemPackageLI: newPs=" + deletedPkg.packageName
16010                + " disabledPs=" + disabledPs);
16011
16012        if (disabledPs == null) {
16013            Slog.w(TAG, "Attempt to delete unknown system package "+ deletedPkg.packageName);
16014            return false;
16015        } else if (DEBUG_REMOVE) {
16016            Slog.d(TAG, "Deleting system pkg from data partition");
16017        }
16018
16019        if (DEBUG_REMOVE) {
16020            if (applyUserRestrictions) {
16021                Slog.d(TAG, "Remembering install states:");
16022                for (int userId : allUserHandles) {
16023                    final boolean finstalled = ArrayUtils.contains(outInfo.origUsers, userId);
16024                    Slog.d(TAG, "   u=" + userId + " inst=" + finstalled);
16025                }
16026            }
16027        }
16028
16029        // Delete the updated package
16030        outInfo.isRemovedPackageSystemUpdate = true;
16031        if (outInfo.removedChildPackages != null) {
16032            final int childCount = (deletedPs.childPackageNames != null)
16033                    ? deletedPs.childPackageNames.size() : 0;
16034            for (int i = 0; i < childCount; i++) {
16035                String childPackageName = deletedPs.childPackageNames.get(i);
16036                if (disabledPs.childPackageNames != null && disabledPs.childPackageNames
16037                        .contains(childPackageName)) {
16038                    PackageRemovedInfo childInfo = outInfo.removedChildPackages.get(
16039                            childPackageName);
16040                    if (childInfo != null) {
16041                        childInfo.isRemovedPackageSystemUpdate = true;
16042                    }
16043                }
16044            }
16045        }
16046
16047        if (disabledPs.versionCode < deletedPs.versionCode) {
16048            // Delete data for downgrades
16049            flags &= ~PackageManager.DELETE_KEEP_DATA;
16050        } else {
16051            // Preserve data by setting flag
16052            flags |= PackageManager.DELETE_KEEP_DATA;
16053        }
16054
16055        boolean ret = deleteInstalledPackageLIF(deletedPs, true, flags, allUserHandles,
16056                outInfo, writeSettings, disabledPs.pkg);
16057        if (!ret) {
16058            return false;
16059        }
16060
16061        // writer
16062        synchronized (mPackages) {
16063            // Reinstate the old system package
16064            enableSystemPackageLPw(disabledPs.pkg);
16065            // Remove any native libraries from the upgraded package.
16066            removeNativeBinariesLI(deletedPs);
16067        }
16068
16069        // Install the system package
16070        if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs);
16071        int parseFlags = mDefParseFlags
16072                | PackageParser.PARSE_MUST_BE_APK
16073                | PackageParser.PARSE_IS_SYSTEM
16074                | PackageParser.PARSE_IS_SYSTEM_DIR;
16075        if (locationIsPrivileged(disabledPs.codePath)) {
16076            parseFlags |= PackageParser.PARSE_IS_PRIVILEGED;
16077        }
16078
16079        final PackageParser.Package newPkg;
16080        try {
16081            newPkg = scanPackageTracedLI(disabledPs.codePath, parseFlags, SCAN_NO_PATHS, 0, null);
16082        } catch (PackageManagerException e) {
16083            Slog.w(TAG, "Failed to restore system package:" + deletedPkg.packageName + ": "
16084                    + e.getMessage());
16085            return false;
16086        }
16087        try {
16088            // update shared libraries for the newly re-installed system package
16089            updateSharedLibrariesLPw(newPkg, null);
16090        } catch (PackageManagerException e) {
16091            Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
16092        }
16093
16094        prepareAppDataAfterInstallLIF(newPkg);
16095
16096        // writer
16097        synchronized (mPackages) {
16098            PackageSetting ps = mSettings.mPackages.get(newPkg.packageName);
16099
16100            // Propagate the permissions state as we do not want to drop on the floor
16101            // runtime permissions. The update permissions method below will take
16102            // care of removing obsolete permissions and grant install permissions.
16103            ps.getPermissionsState().copyFrom(deletedPs.getPermissionsState());
16104            updatePermissionsLPw(newPkg.packageName, newPkg,
16105                    UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG);
16106
16107            if (applyUserRestrictions) {
16108                if (DEBUG_REMOVE) {
16109                    Slog.d(TAG, "Propagating install state across reinstall");
16110                }
16111                for (int userId : allUserHandles) {
16112                    final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId);
16113                    if (DEBUG_REMOVE) {
16114                        Slog.d(TAG, "    user " + userId + " => " + installed);
16115                    }
16116                    ps.setInstalled(installed, userId);
16117
16118                    mSettings.writeRuntimePermissionsForUserLPr(userId, false);
16119                }
16120                // Regardless of writeSettings we need to ensure that this restriction
16121                // state propagation is persisted
16122                mSettings.writeAllUsersPackageRestrictionsLPr();
16123            }
16124            // can downgrade to reader here
16125            if (writeSettings) {
16126                mSettings.writeLPr();
16127            }
16128        }
16129        return true;
16130    }
16131
16132    private boolean deleteInstalledPackageLIF(PackageSetting ps,
16133            boolean deleteCodeAndResources, int flags, int[] allUserHandles,
16134            PackageRemovedInfo outInfo, boolean writeSettings,
16135            PackageParser.Package replacingPackage) {
16136        synchronized (mPackages) {
16137            if (outInfo != null) {
16138                outInfo.uid = ps.appId;
16139            }
16140
16141            if (outInfo != null && outInfo.removedChildPackages != null) {
16142                final int childCount = (ps.childPackageNames != null)
16143                        ? ps.childPackageNames.size() : 0;
16144                for (int i = 0; i < childCount; i++) {
16145                    String childPackageName = ps.childPackageNames.get(i);
16146                    PackageSetting childPs = mSettings.mPackages.get(childPackageName);
16147                    if (childPs == null) {
16148                        return false;
16149                    }
16150                    PackageRemovedInfo childInfo = outInfo.removedChildPackages.get(
16151                            childPackageName);
16152                    if (childInfo != null) {
16153                        childInfo.uid = childPs.appId;
16154                    }
16155                }
16156            }
16157        }
16158
16159        // Delete package data from internal structures and also remove data if flag is set
16160        removePackageDataLIF(ps, allUserHandles, outInfo, flags, writeSettings);
16161
16162        // Delete the child packages data
16163        final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0;
16164        for (int i = 0; i < childCount; i++) {
16165            PackageSetting childPs;
16166            synchronized (mPackages) {
16167                childPs = mSettings.peekPackageLPr(ps.childPackageNames.get(i));
16168            }
16169            if (childPs != null) {
16170                PackageRemovedInfo childOutInfo = (outInfo != null
16171                        && outInfo.removedChildPackages != null)
16172                        ? outInfo.removedChildPackages.get(childPs.name) : null;
16173                final int deleteFlags = (flags & DELETE_KEEP_DATA) != 0
16174                        && (replacingPackage != null
16175                        && !replacingPackage.hasChildPackage(childPs.name))
16176                        ? flags & ~DELETE_KEEP_DATA : flags;
16177                removePackageDataLIF(childPs, allUserHandles, childOutInfo,
16178                        deleteFlags, writeSettings);
16179            }
16180        }
16181
16182        // Delete application code and resources only for parent packages
16183        if (ps.parentPackageName == null) {
16184            if (deleteCodeAndResources && (outInfo != null)) {
16185                outInfo.args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
16186                        ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
16187                if (DEBUG_SD_INSTALL) Slog.i(TAG, "args=" + outInfo.args);
16188            }
16189        }
16190
16191        return true;
16192    }
16193
16194    @Override
16195    public boolean setBlockUninstallForUser(String packageName, boolean blockUninstall,
16196            int userId) {
16197        mContext.enforceCallingOrSelfPermission(
16198                android.Manifest.permission.DELETE_PACKAGES, null);
16199        synchronized (mPackages) {
16200            PackageSetting ps = mSettings.mPackages.get(packageName);
16201            if (ps == null) {
16202                Log.i(TAG, "Package doesn't exist in set block uninstall " + packageName);
16203                return false;
16204            }
16205            if (!ps.getInstalled(userId)) {
16206                // Can't block uninstall for an app that is not installed or enabled.
16207                Log.i(TAG, "Package not installed in set block uninstall " + packageName);
16208                return false;
16209            }
16210            ps.setBlockUninstall(blockUninstall, userId);
16211            mSettings.writePackageRestrictionsLPr(userId);
16212        }
16213        return true;
16214    }
16215
16216    @Override
16217    public boolean getBlockUninstallForUser(String packageName, int userId) {
16218        synchronized (mPackages) {
16219            PackageSetting ps = mSettings.mPackages.get(packageName);
16220            if (ps == null) {
16221                Log.i(TAG, "Package doesn't exist in get block uninstall " + packageName);
16222                return false;
16223            }
16224            return ps.getBlockUninstall(userId);
16225        }
16226    }
16227
16228    @Override
16229    public boolean setRequiredForSystemUser(String packageName, boolean systemUserApp) {
16230        int callingUid = Binder.getCallingUid();
16231        if (callingUid != Process.SYSTEM_UID && callingUid != Process.ROOT_UID) {
16232            throw new SecurityException(
16233                    "setRequiredForSystemUser can only be run by the system or root");
16234        }
16235        synchronized (mPackages) {
16236            PackageSetting ps = mSettings.mPackages.get(packageName);
16237            if (ps == null) {
16238                Log.w(TAG, "Package doesn't exist: " + packageName);
16239                return false;
16240            }
16241            if (systemUserApp) {
16242                ps.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER;
16243            } else {
16244                ps.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER;
16245            }
16246            mSettings.writeLPr();
16247        }
16248        return true;
16249    }
16250
16251    /*
16252     * This method handles package deletion in general
16253     */
16254    private boolean deletePackageLIF(String packageName, UserHandle user,
16255            boolean deleteCodeAndResources, int[] allUserHandles, int flags,
16256            PackageRemovedInfo outInfo, boolean writeSettings,
16257            PackageParser.Package replacingPackage) {
16258        if (packageName == null) {
16259            Slog.w(TAG, "Attempt to delete null packageName.");
16260            return false;
16261        }
16262
16263        if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: " + packageName + " user " + user);
16264
16265        PackageSetting ps;
16266
16267        synchronized (mPackages) {
16268            ps = mSettings.mPackages.get(packageName);
16269            if (ps == null) {
16270                Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
16271                return false;
16272            }
16273
16274            if (ps.parentPackageName != null && (!isSystemApp(ps)
16275                    || (flags & PackageManager.DELETE_SYSTEM_APP) != 0)) {
16276                if (DEBUG_REMOVE) {
16277                    Slog.d(TAG, "Uninstalled child package:" + packageName + " for user:"
16278                            + ((user == null) ? UserHandle.USER_ALL : user));
16279                }
16280                final int removedUserId = (user != null) ? user.getIdentifier()
16281                        : UserHandle.USER_ALL;
16282                if (!clearPackageStateForUserLIF(ps, removedUserId, outInfo)) {
16283                    return false;
16284                }
16285                markPackageUninstalledForUserLPw(ps, user);
16286                scheduleWritePackageRestrictionsLocked(user);
16287                return true;
16288            }
16289        }
16290
16291        if (((!isSystemApp(ps) || (flags&PackageManager.DELETE_SYSTEM_APP) != 0) && user != null
16292                && user.getIdentifier() != UserHandle.USER_ALL)) {
16293            // The caller is asking that the package only be deleted for a single
16294            // user.  To do this, we just mark its uninstalled state and delete
16295            // its data. If this is a system app, we only allow this to happen if
16296            // they have set the special DELETE_SYSTEM_APP which requests different
16297            // semantics than normal for uninstalling system apps.
16298            markPackageUninstalledForUserLPw(ps, user);
16299
16300            if (!isSystemApp(ps)) {
16301                // Do not uninstall the APK if an app should be cached
16302                boolean keepUninstalledPackage = shouldKeepUninstalledPackageLPr(packageName);
16303                if (ps.isAnyInstalled(sUserManager.getUserIds()) || keepUninstalledPackage) {
16304                    // Other user still have this package installed, so all
16305                    // we need to do is clear this user's data and save that
16306                    // it is uninstalled.
16307                    if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users");
16308                    if (!clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo)) {
16309                        return false;
16310                    }
16311                    scheduleWritePackageRestrictionsLocked(user);
16312                    return true;
16313                } else {
16314                    // We need to set it back to 'installed' so the uninstall
16315                    // broadcasts will be sent correctly.
16316                    if (DEBUG_REMOVE) Slog.d(TAG, "Not installed by other users, full delete");
16317                    ps.setInstalled(true, user.getIdentifier());
16318                }
16319            } else {
16320                // This is a system app, so we assume that the
16321                // other users still have this package installed, so all
16322                // we need to do is clear this user's data and save that
16323                // it is uninstalled.
16324                if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app");
16325                if (!clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo)) {
16326                    return false;
16327                }
16328                scheduleWritePackageRestrictionsLocked(user);
16329                return true;
16330            }
16331        }
16332
16333        // If we are deleting a composite package for all users, keep track
16334        // of result for each child.
16335        if (ps.childPackageNames != null && outInfo != null) {
16336            synchronized (mPackages) {
16337                final int childCount = ps.childPackageNames.size();
16338                outInfo.removedChildPackages = new ArrayMap<>(childCount);
16339                for (int i = 0; i < childCount; i++) {
16340                    String childPackageName = ps.childPackageNames.get(i);
16341                    PackageRemovedInfo childInfo = new PackageRemovedInfo();
16342                    childInfo.removedPackage = childPackageName;
16343                    outInfo.removedChildPackages.put(childPackageName, childInfo);
16344                    PackageSetting childPs = mSettings.peekPackageLPr(childPackageName);
16345                    if (childPs != null) {
16346                        childInfo.origUsers = childPs.queryInstalledUsers(allUserHandles, true);
16347                    }
16348                }
16349            }
16350        }
16351
16352        boolean ret = false;
16353        if (isSystemApp(ps)) {
16354            if (DEBUG_REMOVE) Slog.d(TAG, "Removing system package: " + ps.name);
16355            // When an updated system application is deleted we delete the existing resources
16356            // as well and fall back to existing code in system partition
16357            ret = deleteSystemPackageLIF(ps.pkg, ps, allUserHandles, flags, outInfo, writeSettings);
16358        } else {
16359            if (DEBUG_REMOVE) Slog.d(TAG, "Removing non-system package: " + ps.name);
16360            ret = deleteInstalledPackageLIF(ps, deleteCodeAndResources, flags, allUserHandles,
16361                    outInfo, writeSettings, replacingPackage);
16362        }
16363
16364        // Take a note whether we deleted the package for all users
16365        if (outInfo != null) {
16366            outInfo.removedForAllUsers = mPackages.get(ps.name) == null;
16367            if (outInfo.removedChildPackages != null) {
16368                synchronized (mPackages) {
16369                    final int childCount = outInfo.removedChildPackages.size();
16370                    for (int i = 0; i < childCount; i++) {
16371                        PackageRemovedInfo childInfo = outInfo.removedChildPackages.valueAt(i);
16372                        if (childInfo != null) {
16373                            childInfo.removedForAllUsers = mPackages.get(
16374                                    childInfo.removedPackage) == null;
16375                        }
16376                    }
16377                }
16378            }
16379            // If we uninstalled an update to a system app there may be some
16380            // child packages that appeared as they are declared in the system
16381            // app but were not declared in the update.
16382            if (isSystemApp(ps)) {
16383                synchronized (mPackages) {
16384                    PackageSetting updatedPs = mSettings.peekPackageLPr(ps.name);
16385                    final int childCount = (updatedPs.childPackageNames != null)
16386                            ? updatedPs.childPackageNames.size() : 0;
16387                    for (int i = 0; i < childCount; i++) {
16388                        String childPackageName = updatedPs.childPackageNames.get(i);
16389                        if (outInfo.removedChildPackages == null
16390                                || outInfo.removedChildPackages.indexOfKey(childPackageName) < 0) {
16391                            PackageSetting childPs = mSettings.peekPackageLPr(childPackageName);
16392                            if (childPs == null) {
16393                                continue;
16394                            }
16395                            PackageInstalledInfo installRes = new PackageInstalledInfo();
16396                            installRes.name = childPackageName;
16397                            installRes.newUsers = childPs.queryInstalledUsers(allUserHandles, true);
16398                            installRes.pkg = mPackages.get(childPackageName);
16399                            installRes.uid = childPs.pkg.applicationInfo.uid;
16400                            if (outInfo.appearedChildPackages == null) {
16401                                outInfo.appearedChildPackages = new ArrayMap<>();
16402                            }
16403                            outInfo.appearedChildPackages.put(childPackageName, installRes);
16404                        }
16405                    }
16406                }
16407            }
16408        }
16409
16410        return ret;
16411    }
16412
16413    private void markPackageUninstalledForUserLPw(PackageSetting ps, UserHandle user) {
16414        final int[] userIds = (user == null || user.getIdentifier() == UserHandle.USER_ALL)
16415                ? sUserManager.getUserIds() : new int[] {user.getIdentifier()};
16416        for (int nextUserId : userIds) {
16417            if (DEBUG_REMOVE) {
16418                Slog.d(TAG, "Marking package:" + ps.name + " uninstalled for user:" + nextUserId);
16419            }
16420            ps.setUserState(nextUserId, 0, COMPONENT_ENABLED_STATE_DEFAULT,
16421                    false /*installed*/, true /*stopped*/, true /*notLaunched*/,
16422                    false /*hidden*/, false /*suspended*/, null, null, null,
16423                    false /*blockUninstall*/,
16424                    ps.readUserState(nextUserId).domainVerificationStatus, 0);
16425        }
16426    }
16427
16428    private boolean clearPackageStateForUserLIF(PackageSetting ps, int userId,
16429            PackageRemovedInfo outInfo) {
16430        final PackageParser.Package pkg;
16431        synchronized (mPackages) {
16432            pkg = mPackages.get(ps.name);
16433        }
16434
16435        final int[] userIds = (userId == UserHandle.USER_ALL) ? sUserManager.getUserIds()
16436                : new int[] {userId};
16437        for (int nextUserId : userIds) {
16438            if (DEBUG_REMOVE) {
16439                Slog.d(TAG, "Updating package:" + ps.name + " install state for user:"
16440                        + nextUserId);
16441            }
16442
16443            destroyAppDataLIF(pkg, userId,
16444                    StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
16445            destroyAppProfilesLIF(pkg, userId);
16446            removeKeystoreDataIfNeeded(nextUserId, ps.appId);
16447            schedulePackageCleaning(ps.name, nextUserId, false);
16448            synchronized (mPackages) {
16449                if (clearPackagePreferredActivitiesLPw(ps.name, nextUserId)) {
16450                    scheduleWritePackageRestrictionsLocked(nextUserId);
16451                }
16452                resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, nextUserId);
16453            }
16454        }
16455
16456        if (outInfo != null) {
16457            outInfo.removedPackage = ps.name;
16458            outInfo.removedAppId = ps.appId;
16459            outInfo.removedUsers = userIds;
16460        }
16461
16462        return true;
16463    }
16464
16465    private final class ClearStorageConnection implements ServiceConnection {
16466        IMediaContainerService mContainerService;
16467
16468        @Override
16469        public void onServiceConnected(ComponentName name, IBinder service) {
16470            synchronized (this) {
16471                mContainerService = IMediaContainerService.Stub.asInterface(service);
16472                notifyAll();
16473            }
16474        }
16475
16476        @Override
16477        public void onServiceDisconnected(ComponentName name) {
16478        }
16479    }
16480
16481    private void clearExternalStorageDataSync(String packageName, int userId, boolean allData) {
16482        if (DEFAULT_CONTAINER_PACKAGE.equals(packageName)) return;
16483
16484        final boolean mounted;
16485        if (Environment.isExternalStorageEmulated()) {
16486            mounted = true;
16487        } else {
16488            final String status = Environment.getExternalStorageState();
16489
16490            mounted = status.equals(Environment.MEDIA_MOUNTED)
16491                    || status.equals(Environment.MEDIA_MOUNTED_READ_ONLY);
16492        }
16493
16494        if (!mounted) {
16495            return;
16496        }
16497
16498        final Intent containerIntent = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
16499        int[] users;
16500        if (userId == UserHandle.USER_ALL) {
16501            users = sUserManager.getUserIds();
16502        } else {
16503            users = new int[] { userId };
16504        }
16505        final ClearStorageConnection conn = new ClearStorageConnection();
16506        if (mContext.bindServiceAsUser(
16507                containerIntent, conn, Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) {
16508            try {
16509                for (int curUser : users) {
16510                    long timeout = SystemClock.uptimeMillis() + 5000;
16511                    synchronized (conn) {
16512                        long now;
16513                        while (conn.mContainerService == null &&
16514                                (now = SystemClock.uptimeMillis()) < timeout) {
16515                            try {
16516                                conn.wait(timeout - now);
16517                            } catch (InterruptedException e) {
16518                            }
16519                        }
16520                    }
16521                    if (conn.mContainerService == null) {
16522                        return;
16523                    }
16524
16525                    final UserEnvironment userEnv = new UserEnvironment(curUser);
16526                    clearDirectory(conn.mContainerService,
16527                            userEnv.buildExternalStorageAppCacheDirs(packageName));
16528                    if (allData) {
16529                        clearDirectory(conn.mContainerService,
16530                                userEnv.buildExternalStorageAppDataDirs(packageName));
16531                        clearDirectory(conn.mContainerService,
16532                                userEnv.buildExternalStorageAppMediaDirs(packageName));
16533                    }
16534                }
16535            } finally {
16536                mContext.unbindService(conn);
16537            }
16538        }
16539    }
16540
16541    @Override
16542    public void clearApplicationProfileData(String packageName) {
16543        enforceSystemOrRoot("Only the system can clear all profile data");
16544
16545        final PackageParser.Package pkg;
16546        synchronized (mPackages) {
16547            pkg = mPackages.get(packageName);
16548        }
16549
16550        try (PackageFreezer freezer = freezePackage(packageName, "clearApplicationProfileData")) {
16551            synchronized (mInstallLock) {
16552                clearAppProfilesLIF(pkg, UserHandle.USER_ALL);
16553            }
16554        }
16555    }
16556
16557    @Override
16558    public void clearApplicationUserData(final String packageName,
16559            final IPackageDataObserver observer, final int userId) {
16560        mContext.enforceCallingOrSelfPermission(
16561                android.Manifest.permission.CLEAR_APP_USER_DATA, null);
16562
16563        enforceCrossUserPermission(Binder.getCallingUid(), userId,
16564                true /* requireFullPermission */, false /* checkShell */, "clear application data");
16565
16566        if (mProtectedPackages.isPackageDataProtected(userId, packageName)) {
16567            throw new SecurityException("Cannot clear data for a protected package: "
16568                    + packageName);
16569        }
16570        // Queue up an async operation since the package deletion may take a little while.
16571        mHandler.post(new Runnable() {
16572            public void run() {
16573                mHandler.removeCallbacks(this);
16574                final boolean succeeded;
16575                try (PackageFreezer freezer = freezePackage(packageName,
16576                        "clearApplicationUserData")) {
16577                    synchronized (mInstallLock) {
16578                        succeeded = clearApplicationUserDataLIF(packageName, userId);
16579                    }
16580                    clearExternalStorageDataSync(packageName, userId, true);
16581                }
16582                if (succeeded) {
16583                    // invoke DeviceStorageMonitor's update method to clear any notifications
16584                    DeviceStorageMonitorInternal dsm = LocalServices
16585                            .getService(DeviceStorageMonitorInternal.class);
16586                    if (dsm != null) {
16587                        dsm.checkMemory();
16588                    }
16589                }
16590                if(observer != null) {
16591                    try {
16592                        observer.onRemoveCompleted(packageName, succeeded);
16593                    } catch (RemoteException e) {
16594                        Log.i(TAG, "Observer no longer exists.");
16595                    }
16596                } //end if observer
16597            } //end run
16598        });
16599    }
16600
16601    private boolean clearApplicationUserDataLIF(String packageName, int userId) {
16602        if (packageName == null) {
16603            Slog.w(TAG, "Attempt to delete null packageName.");
16604            return false;
16605        }
16606
16607        // Try finding details about the requested package
16608        PackageParser.Package pkg;
16609        synchronized (mPackages) {
16610            pkg = mPackages.get(packageName);
16611            if (pkg == null) {
16612                final PackageSetting ps = mSettings.mPackages.get(packageName);
16613                if (ps != null) {
16614                    pkg = ps.pkg;
16615                }
16616            }
16617
16618            if (pkg == null) {
16619                Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
16620                return false;
16621            }
16622
16623            PackageSetting ps = (PackageSetting) pkg.mExtras;
16624            resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
16625        }
16626
16627        clearAppDataLIF(pkg, userId,
16628                StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
16629
16630        final int appId = UserHandle.getAppId(pkg.applicationInfo.uid);
16631        removeKeystoreDataIfNeeded(userId, appId);
16632
16633        UserManagerInternal umInternal = getUserManagerInternal();
16634        final int flags;
16635        if (umInternal.isUserUnlockingOrUnlocked(userId)) {
16636            flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
16637        } else if (umInternal.isUserRunning(userId)) {
16638            flags = StorageManager.FLAG_STORAGE_DE;
16639        } else {
16640            flags = 0;
16641        }
16642        prepareAppDataContentsLIF(pkg, userId, flags);
16643
16644        return true;
16645    }
16646
16647    /**
16648     * Reverts user permission state changes (permissions and flags) in
16649     * all packages for a given user.
16650     *
16651     * @param userId The device user for which to do a reset.
16652     */
16653    private void resetUserChangesToRuntimePermissionsAndFlagsLPw(int userId) {
16654        final int packageCount = mPackages.size();
16655        for (int i = 0; i < packageCount; i++) {
16656            PackageParser.Package pkg = mPackages.valueAt(i);
16657            PackageSetting ps = (PackageSetting) pkg.mExtras;
16658            resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
16659        }
16660    }
16661
16662    private void resetNetworkPolicies(int userId) {
16663        LocalServices.getService(NetworkPolicyManagerInternal.class).resetUserState(userId);
16664    }
16665
16666    /**
16667     * Reverts user permission state changes (permissions and flags).
16668     *
16669     * @param ps The package for which to reset.
16670     * @param userId The device user for which to do a reset.
16671     */
16672    private void resetUserChangesToRuntimePermissionsAndFlagsLPw(
16673            final PackageSetting ps, final int userId) {
16674        if (ps.pkg == null) {
16675            return;
16676        }
16677
16678        // These are flags that can change base on user actions.
16679        final int userSettableMask = FLAG_PERMISSION_USER_SET
16680                | FLAG_PERMISSION_USER_FIXED
16681                | FLAG_PERMISSION_REVOKE_ON_UPGRADE
16682                | FLAG_PERMISSION_REVIEW_REQUIRED;
16683
16684        final int policyOrSystemFlags = FLAG_PERMISSION_SYSTEM_FIXED
16685                | FLAG_PERMISSION_POLICY_FIXED;
16686
16687        boolean writeInstallPermissions = false;
16688        boolean writeRuntimePermissions = false;
16689
16690        final int permissionCount = ps.pkg.requestedPermissions.size();
16691        for (int i = 0; i < permissionCount; i++) {
16692            String permission = ps.pkg.requestedPermissions.get(i);
16693
16694            BasePermission bp = mSettings.mPermissions.get(permission);
16695            if (bp == null) {
16696                continue;
16697            }
16698
16699            // If shared user we just reset the state to which only this app contributed.
16700            if (ps.sharedUser != null) {
16701                boolean used = false;
16702                final int packageCount = ps.sharedUser.packages.size();
16703                for (int j = 0; j < packageCount; j++) {
16704                    PackageSetting pkg = ps.sharedUser.packages.valueAt(j);
16705                    if (pkg.pkg != null && !pkg.pkg.packageName.equals(ps.pkg.packageName)
16706                            && pkg.pkg.requestedPermissions.contains(permission)) {
16707                        used = true;
16708                        break;
16709                    }
16710                }
16711                if (used) {
16712                    continue;
16713                }
16714            }
16715
16716            PermissionsState permissionsState = ps.getPermissionsState();
16717
16718            final int oldFlags = permissionsState.getPermissionFlags(bp.name, userId);
16719
16720            // Always clear the user settable flags.
16721            final boolean hasInstallState = permissionsState.getInstallPermissionState(
16722                    bp.name) != null;
16723            // If permission review is enabled and this is a legacy app, mark the
16724            // permission as requiring a review as this is the initial state.
16725            int flags = 0;
16726            if ((mPermissionReviewRequired || Build.PERMISSIONS_REVIEW_REQUIRED)
16727                    && ps.pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
16728                flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
16729            }
16730            if (permissionsState.updatePermissionFlags(bp, userId, userSettableMask, flags)) {
16731                if (hasInstallState) {
16732                    writeInstallPermissions = true;
16733                } else {
16734                    writeRuntimePermissions = true;
16735                }
16736            }
16737
16738            // Below is only runtime permission handling.
16739            if (!bp.isRuntime()) {
16740                continue;
16741            }
16742
16743            // Never clobber system or policy.
16744            if ((oldFlags & policyOrSystemFlags) != 0) {
16745                continue;
16746            }
16747
16748            // If this permission was granted by default, make sure it is.
16749            if ((oldFlags & FLAG_PERMISSION_GRANTED_BY_DEFAULT) != 0) {
16750                if (permissionsState.grantRuntimePermission(bp, userId)
16751                        != PERMISSION_OPERATION_FAILURE) {
16752                    writeRuntimePermissions = true;
16753                }
16754            // If permission review is enabled the permissions for a legacy apps
16755            // are represented as constantly granted runtime ones, so don't revoke.
16756            } else if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) {
16757                // Otherwise, reset the permission.
16758                final int revokeResult = permissionsState.revokeRuntimePermission(bp, userId);
16759                switch (revokeResult) {
16760                    case PERMISSION_OPERATION_SUCCESS:
16761                    case PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
16762                        writeRuntimePermissions = true;
16763                        final int appId = ps.appId;
16764                        mHandler.post(new Runnable() {
16765                            @Override
16766                            public void run() {
16767                                killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED);
16768                            }
16769                        });
16770                    } break;
16771                }
16772            }
16773        }
16774
16775        // Synchronously write as we are taking permissions away.
16776        if (writeRuntimePermissions) {
16777            mSettings.writeRuntimePermissionsForUserLPr(userId, true);
16778        }
16779
16780        // Synchronously write as we are taking permissions away.
16781        if (writeInstallPermissions) {
16782            mSettings.writeLPr();
16783        }
16784    }
16785
16786    /**
16787     * Remove entries from the keystore daemon. Will only remove it if the
16788     * {@code appId} is valid.
16789     */
16790    private static void removeKeystoreDataIfNeeded(int userId, int appId) {
16791        if (appId < 0) {
16792            return;
16793        }
16794
16795        final KeyStore keyStore = KeyStore.getInstance();
16796        if (keyStore != null) {
16797            if (userId == UserHandle.USER_ALL) {
16798                for (final int individual : sUserManager.getUserIds()) {
16799                    keyStore.clearUid(UserHandle.getUid(individual, appId));
16800                }
16801            } else {
16802                keyStore.clearUid(UserHandle.getUid(userId, appId));
16803            }
16804        } else {
16805            Slog.w(TAG, "Could not contact keystore to clear entries for app id " + appId);
16806        }
16807    }
16808
16809    @Override
16810    public void deleteApplicationCacheFiles(final String packageName,
16811            final IPackageDataObserver observer) {
16812        final int userId = UserHandle.getCallingUserId();
16813        deleteApplicationCacheFilesAsUser(packageName, userId, observer);
16814    }
16815
16816    @Override
16817    public void deleteApplicationCacheFilesAsUser(final String packageName, final int userId,
16818            final IPackageDataObserver observer) {
16819        mContext.enforceCallingOrSelfPermission(
16820                android.Manifest.permission.DELETE_CACHE_FILES, null);
16821        enforceCrossUserPermission(Binder.getCallingUid(), userId,
16822                /* requireFullPermission= */ true, /* checkShell= */ false,
16823                "delete application cache files");
16824
16825        final PackageParser.Package pkg;
16826        synchronized (mPackages) {
16827            pkg = mPackages.get(packageName);
16828        }
16829
16830        // Queue up an async operation since the package deletion may take a little while.
16831        mHandler.post(new Runnable() {
16832            public void run() {
16833                synchronized (mInstallLock) {
16834                    final int flags = StorageManager.FLAG_STORAGE_DE
16835                            | StorageManager.FLAG_STORAGE_CE;
16836                    // We're only clearing cache files, so we don't care if the
16837                    // app is unfrozen and still able to run
16838                    clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CACHE_ONLY);
16839                    clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
16840                }
16841                clearExternalStorageDataSync(packageName, userId, false);
16842                if (observer != null) {
16843                    try {
16844                        observer.onRemoveCompleted(packageName, true);
16845                    } catch (RemoteException e) {
16846                        Log.i(TAG, "Observer no longer exists.");
16847                    }
16848                }
16849            }
16850        });
16851    }
16852
16853    @Override
16854    public void getPackageSizeInfo(final String packageName, int userHandle,
16855            final IPackageStatsObserver observer) {
16856        mContext.enforceCallingOrSelfPermission(
16857                android.Manifest.permission.GET_PACKAGE_SIZE, null);
16858        if (packageName == null) {
16859            throw new IllegalArgumentException("Attempt to get size of null packageName");
16860        }
16861
16862        PackageStats stats = new PackageStats(packageName, userHandle);
16863
16864        /*
16865         * Queue up an async operation since the package measurement may take a
16866         * little while.
16867         */
16868        Message msg = mHandler.obtainMessage(INIT_COPY);
16869        msg.obj = new MeasureParams(stats, observer);
16870        mHandler.sendMessage(msg);
16871    }
16872
16873    private boolean getPackageSizeInfoLI(String packageName, int userId, PackageStats stats) {
16874        final PackageSetting ps;
16875        synchronized (mPackages) {
16876            ps = mSettings.mPackages.get(packageName);
16877            if (ps == null) {
16878                Slog.w(TAG, "Failed to find settings for " + packageName);
16879                return false;
16880            }
16881        }
16882
16883        final String[] packageNames = { packageName };
16884        final long[] ceDataInodes = { ps.getCeDataInode(userId) };
16885        final String[] codePaths = { ps.codePathString };
16886
16887        try {
16888            mInstaller.getAppSize(ps.volumeUuid, packageNames, userId, 0,
16889                    ps.appId, ceDataInodes, codePaths, stats);
16890
16891            // For now, ignore code size of packages on system partition
16892            if (isSystemApp(ps) && !isUpdatedSystemApp(ps)) {
16893                stats.codeSize = 0;
16894            }
16895
16896            // External clients expect these to be tracked separately
16897            stats.dataSize -= stats.cacheSize;
16898
16899        } catch (InstallerException e) {
16900            Slog.w(TAG, String.valueOf(e));
16901            return false;
16902        }
16903
16904        return true;
16905    }
16906
16907    private int getUidTargetSdkVersionLockedLPr(int uid) {
16908        Object obj = mSettings.getUserIdLPr(uid);
16909        if (obj instanceof SharedUserSetting) {
16910            final SharedUserSetting sus = (SharedUserSetting) obj;
16911            int vers = Build.VERSION_CODES.CUR_DEVELOPMENT;
16912            final Iterator<PackageSetting> it = sus.packages.iterator();
16913            while (it.hasNext()) {
16914                final PackageSetting ps = it.next();
16915                if (ps.pkg != null) {
16916                    int v = ps.pkg.applicationInfo.targetSdkVersion;
16917                    if (v < vers) vers = v;
16918                }
16919            }
16920            return vers;
16921        } else if (obj instanceof PackageSetting) {
16922            final PackageSetting ps = (PackageSetting) obj;
16923            if (ps.pkg != null) {
16924                return ps.pkg.applicationInfo.targetSdkVersion;
16925            }
16926        }
16927        return Build.VERSION_CODES.CUR_DEVELOPMENT;
16928    }
16929
16930    @Override
16931    public void addPreferredActivity(IntentFilter filter, int match,
16932            ComponentName[] set, ComponentName activity, int userId) {
16933        addPreferredActivityInternal(filter, match, set, activity, true, userId,
16934                "Adding preferred");
16935    }
16936
16937    private void addPreferredActivityInternal(IntentFilter filter, int match,
16938            ComponentName[] set, ComponentName activity, boolean always, int userId,
16939            String opname) {
16940        // writer
16941        int callingUid = Binder.getCallingUid();
16942        enforceCrossUserPermission(callingUid, userId,
16943                true /* requireFullPermission */, false /* checkShell */, "add preferred activity");
16944        if (filter.countActions() == 0) {
16945            Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
16946            return;
16947        }
16948        synchronized (mPackages) {
16949            if (mContext.checkCallingOrSelfPermission(
16950                    android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
16951                    != PackageManager.PERMISSION_GRANTED) {
16952                if (getUidTargetSdkVersionLockedLPr(callingUid)
16953                        < Build.VERSION_CODES.FROYO) {
16954                    Slog.w(TAG, "Ignoring addPreferredActivity() from uid "
16955                            + callingUid);
16956                    return;
16957                }
16958                mContext.enforceCallingOrSelfPermission(
16959                        android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
16960            }
16961
16962            PreferredIntentResolver pir = mSettings.editPreferredActivitiesLPw(userId);
16963            Slog.i(TAG, opname + " activity " + activity.flattenToShortString() + " for user "
16964                    + userId + ":");
16965            filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
16966            pir.addFilter(new PreferredActivity(filter, match, set, activity, always));
16967            scheduleWritePackageRestrictionsLocked(userId);
16968            postPreferredActivityChangedBroadcast(userId);
16969        }
16970    }
16971
16972    private void postPreferredActivityChangedBroadcast(int userId) {
16973        mHandler.post(() -> {
16974            final IActivityManager am = ActivityManagerNative.getDefault();
16975            if (am == null) {
16976                return;
16977            }
16978
16979            final Intent intent = new Intent(Intent.ACTION_PREFERRED_ACTIVITY_CHANGED);
16980            intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16981            try {
16982                am.broadcastIntent(null, intent, null, null,
16983                        0, null, null, null, android.app.AppOpsManager.OP_NONE,
16984                        null, false, false, userId);
16985            } catch (RemoteException e) {
16986            }
16987        });
16988    }
16989
16990    @Override
16991    public void replacePreferredActivity(IntentFilter filter, int match,
16992            ComponentName[] set, ComponentName activity, int userId) {
16993        if (filter.countActions() != 1) {
16994            throw new IllegalArgumentException(
16995                    "replacePreferredActivity expects filter to have only 1 action.");
16996        }
16997        if (filter.countDataAuthorities() != 0
16998                || filter.countDataPaths() != 0
16999                || filter.countDataSchemes() > 1
17000                || filter.countDataTypes() != 0) {
17001            throw new IllegalArgumentException(
17002                    "replacePreferredActivity expects filter to have no data authorities, " +
17003                    "paths, or types; and at most one scheme.");
17004        }
17005
17006        final int callingUid = Binder.getCallingUid();
17007        enforceCrossUserPermission(callingUid, userId,
17008                true /* requireFullPermission */, false /* checkShell */,
17009                "replace preferred activity");
17010        synchronized (mPackages) {
17011            if (mContext.checkCallingOrSelfPermission(
17012                    android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
17013                    != PackageManager.PERMISSION_GRANTED) {
17014                if (getUidTargetSdkVersionLockedLPr(callingUid)
17015                        < Build.VERSION_CODES.FROYO) {
17016                    Slog.w(TAG, "Ignoring replacePreferredActivity() from uid "
17017                            + Binder.getCallingUid());
17018                    return;
17019                }
17020                mContext.enforceCallingOrSelfPermission(
17021                        android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
17022            }
17023
17024            PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
17025            if (pir != null) {
17026                // Get all of the existing entries that exactly match this filter.
17027                ArrayList<PreferredActivity> existing = pir.findFilters(filter);
17028                if (existing != null && existing.size() == 1) {
17029                    PreferredActivity cur = existing.get(0);
17030                    if (DEBUG_PREFERRED) {
17031                        Slog.i(TAG, "Checking replace of preferred:");
17032                        filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
17033                        if (!cur.mPref.mAlways) {
17034                            Slog.i(TAG, "  -- CUR; not mAlways!");
17035                        } else {
17036                            Slog.i(TAG, "  -- CUR: mMatch=" + cur.mPref.mMatch);
17037                            Slog.i(TAG, "  -- CUR: mSet="
17038                                    + Arrays.toString(cur.mPref.mSetComponents));
17039                            Slog.i(TAG, "  -- CUR: mComponent=" + cur.mPref.mShortComponent);
17040                            Slog.i(TAG, "  -- NEW: mMatch="
17041                                    + (match&IntentFilter.MATCH_CATEGORY_MASK));
17042                            Slog.i(TAG, "  -- CUR: mSet=" + Arrays.toString(set));
17043                            Slog.i(TAG, "  -- CUR: mComponent=" + activity.flattenToShortString());
17044                        }
17045                    }
17046                    if (cur.mPref.mAlways && cur.mPref.mComponent.equals(activity)
17047                            && cur.mPref.mMatch == (match&IntentFilter.MATCH_CATEGORY_MASK)
17048                            && cur.mPref.sameSet(set)) {
17049                        // Setting the preferred activity to what it happens to be already
17050                        if (DEBUG_PREFERRED) {
17051                            Slog.i(TAG, "Replacing with same preferred activity "
17052                                    + cur.mPref.mShortComponent + " for user "
17053                                    + userId + ":");
17054                            filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
17055                        }
17056                        return;
17057                    }
17058                }
17059
17060                if (existing != null) {
17061                    if (DEBUG_PREFERRED) {
17062                        Slog.i(TAG, existing.size() + " existing preferred matches for:");
17063                        filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
17064                    }
17065                    for (int i = 0; i < existing.size(); i++) {
17066                        PreferredActivity pa = existing.get(i);
17067                        if (DEBUG_PREFERRED) {
17068                            Slog.i(TAG, "Removing existing preferred activity "
17069                                    + pa.mPref.mComponent + ":");
17070                            pa.dump(new LogPrinter(Log.INFO, TAG), "  ");
17071                        }
17072                        pir.removeFilter(pa);
17073                    }
17074                }
17075            }
17076            addPreferredActivityInternal(filter, match, set, activity, true, userId,
17077                    "Replacing preferred");
17078        }
17079    }
17080
17081    @Override
17082    public void clearPackagePreferredActivities(String packageName) {
17083        final int uid = Binder.getCallingUid();
17084        // writer
17085        synchronized (mPackages) {
17086            PackageParser.Package pkg = mPackages.get(packageName);
17087            if (pkg == null || pkg.applicationInfo.uid != uid) {
17088                if (mContext.checkCallingOrSelfPermission(
17089                        android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
17090                        != PackageManager.PERMISSION_GRANTED) {
17091                    if (getUidTargetSdkVersionLockedLPr(Binder.getCallingUid())
17092                            < Build.VERSION_CODES.FROYO) {
17093                        Slog.w(TAG, "Ignoring clearPackagePreferredActivities() from uid "
17094                                + Binder.getCallingUid());
17095                        return;
17096                    }
17097                    mContext.enforceCallingOrSelfPermission(
17098                            android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
17099                }
17100            }
17101
17102            int user = UserHandle.getCallingUserId();
17103            if (clearPackagePreferredActivitiesLPw(packageName, user)) {
17104                scheduleWritePackageRestrictionsLocked(user);
17105            }
17106        }
17107    }
17108
17109    /** This method takes a specific user id as well as UserHandle.USER_ALL. */
17110    boolean clearPackagePreferredActivitiesLPw(String packageName, int userId) {
17111        ArrayList<PreferredActivity> removed = null;
17112        boolean changed = false;
17113        for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
17114            final int thisUserId = mSettings.mPreferredActivities.keyAt(i);
17115            PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
17116            if (userId != UserHandle.USER_ALL && userId != thisUserId) {
17117                continue;
17118            }
17119            Iterator<PreferredActivity> it = pir.filterIterator();
17120            while (it.hasNext()) {
17121                PreferredActivity pa = it.next();
17122                // Mark entry for removal only if it matches the package name
17123                // and the entry is of type "always".
17124                if (packageName == null ||
17125                        (pa.mPref.mComponent.getPackageName().equals(packageName)
17126                                && pa.mPref.mAlways)) {
17127                    if (removed == null) {
17128                        removed = new ArrayList<PreferredActivity>();
17129                    }
17130                    removed.add(pa);
17131                }
17132            }
17133            if (removed != null) {
17134                for (int j=0; j<removed.size(); j++) {
17135                    PreferredActivity pa = removed.get(j);
17136                    pir.removeFilter(pa);
17137                }
17138                changed = true;
17139            }
17140        }
17141        if (changed) {
17142            postPreferredActivityChangedBroadcast(userId);
17143        }
17144        return changed;
17145    }
17146
17147    /** This method takes a specific user id as well as UserHandle.USER_ALL. */
17148    private void clearIntentFilterVerificationsLPw(int userId) {
17149        final int packageCount = mPackages.size();
17150        for (int i = 0; i < packageCount; i++) {
17151            PackageParser.Package pkg = mPackages.valueAt(i);
17152            clearIntentFilterVerificationsLPw(pkg.packageName, userId);
17153        }
17154    }
17155
17156    /** This method takes a specific user id as well as UserHandle.USER_ALL. */
17157    void clearIntentFilterVerificationsLPw(String packageName, int userId) {
17158        if (userId == UserHandle.USER_ALL) {
17159            if (mSettings.removeIntentFilterVerificationLPw(packageName,
17160                    sUserManager.getUserIds())) {
17161                for (int oneUserId : sUserManager.getUserIds()) {
17162                    scheduleWritePackageRestrictionsLocked(oneUserId);
17163                }
17164            }
17165        } else {
17166            if (mSettings.removeIntentFilterVerificationLPw(packageName, userId)) {
17167                scheduleWritePackageRestrictionsLocked(userId);
17168            }
17169        }
17170    }
17171
17172    void clearDefaultBrowserIfNeeded(String packageName) {
17173        for (int oneUserId : sUserManager.getUserIds()) {
17174            String defaultBrowserPackageName = getDefaultBrowserPackageName(oneUserId);
17175            if (TextUtils.isEmpty(defaultBrowserPackageName)) continue;
17176            if (packageName.equals(defaultBrowserPackageName)) {
17177                setDefaultBrowserPackageName(null, oneUserId);
17178            }
17179        }
17180    }
17181
17182    @Override
17183    public void resetApplicationPreferences(int userId) {
17184        mContext.enforceCallingOrSelfPermission(
17185                android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
17186        final long identity = Binder.clearCallingIdentity();
17187        // writer
17188        try {
17189            synchronized (mPackages) {
17190                clearPackagePreferredActivitiesLPw(null, userId);
17191                mSettings.applyDefaultPreferredAppsLPw(this, userId);
17192                // TODO: We have to reset the default SMS and Phone. This requires
17193                // significant refactoring to keep all default apps in the package
17194                // manager (cleaner but more work) or have the services provide
17195                // callbacks to the package manager to request a default app reset.
17196                applyFactoryDefaultBrowserLPw(userId);
17197                clearIntentFilterVerificationsLPw(userId);
17198                primeDomainVerificationsLPw(userId);
17199                resetUserChangesToRuntimePermissionsAndFlagsLPw(userId);
17200                scheduleWritePackageRestrictionsLocked(userId);
17201            }
17202            resetNetworkPolicies(userId);
17203        } finally {
17204            Binder.restoreCallingIdentity(identity);
17205        }
17206    }
17207
17208    @Override
17209    public int getPreferredActivities(List<IntentFilter> outFilters,
17210            List<ComponentName> outActivities, String packageName) {
17211
17212        int num = 0;
17213        final int userId = UserHandle.getCallingUserId();
17214        // reader
17215        synchronized (mPackages) {
17216            PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
17217            if (pir != null) {
17218                final Iterator<PreferredActivity> it = pir.filterIterator();
17219                while (it.hasNext()) {
17220                    final PreferredActivity pa = it.next();
17221                    if (packageName == null
17222                            || (pa.mPref.mComponent.getPackageName().equals(packageName)
17223                                    && pa.mPref.mAlways)) {
17224                        if (outFilters != null) {
17225                            outFilters.add(new IntentFilter(pa));
17226                        }
17227                        if (outActivities != null) {
17228                            outActivities.add(pa.mPref.mComponent);
17229                        }
17230                    }
17231                }
17232            }
17233        }
17234
17235        return num;
17236    }
17237
17238    @Override
17239    public void addPersistentPreferredActivity(IntentFilter filter, ComponentName activity,
17240            int userId) {
17241        int callingUid = Binder.getCallingUid();
17242        if (callingUid != Process.SYSTEM_UID) {
17243            throw new SecurityException(
17244                    "addPersistentPreferredActivity can only be run by the system");
17245        }
17246        if (filter.countActions() == 0) {
17247            Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
17248            return;
17249        }
17250        synchronized (mPackages) {
17251            Slog.i(TAG, "Adding persistent preferred activity " + activity + " for user " + userId +
17252                    ":");
17253            filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
17254            mSettings.editPersistentPreferredActivitiesLPw(userId).addFilter(
17255                    new PersistentPreferredActivity(filter, activity));
17256            scheduleWritePackageRestrictionsLocked(userId);
17257            postPreferredActivityChangedBroadcast(userId);
17258        }
17259    }
17260
17261    @Override
17262    public void clearPackagePersistentPreferredActivities(String packageName, int userId) {
17263        int callingUid = Binder.getCallingUid();
17264        if (callingUid != Process.SYSTEM_UID) {
17265            throw new SecurityException(
17266                    "clearPackagePersistentPreferredActivities can only be run by the system");
17267        }
17268        ArrayList<PersistentPreferredActivity> removed = null;
17269        boolean changed = false;
17270        synchronized (mPackages) {
17271            for (int i=0; i<mSettings.mPersistentPreferredActivities.size(); i++) {
17272                final int thisUserId = mSettings.mPersistentPreferredActivities.keyAt(i);
17273                PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
17274                        .valueAt(i);
17275                if (userId != thisUserId) {
17276                    continue;
17277                }
17278                Iterator<PersistentPreferredActivity> it = ppir.filterIterator();
17279                while (it.hasNext()) {
17280                    PersistentPreferredActivity ppa = it.next();
17281                    // Mark entry for removal only if it matches the package name.
17282                    if (ppa.mComponent.getPackageName().equals(packageName)) {
17283                        if (removed == null) {
17284                            removed = new ArrayList<PersistentPreferredActivity>();
17285                        }
17286                        removed.add(ppa);
17287                    }
17288                }
17289                if (removed != null) {
17290                    for (int j=0; j<removed.size(); j++) {
17291                        PersistentPreferredActivity ppa = removed.get(j);
17292                        ppir.removeFilter(ppa);
17293                    }
17294                    changed = true;
17295                }
17296            }
17297
17298            if (changed) {
17299                scheduleWritePackageRestrictionsLocked(userId);
17300                postPreferredActivityChangedBroadcast(userId);
17301            }
17302        }
17303    }
17304
17305    /**
17306     * Common machinery for picking apart a restored XML blob and passing
17307     * it to a caller-supplied functor to be applied to the running system.
17308     */
17309    private void restoreFromXml(XmlPullParser parser, int userId,
17310            String expectedStartTag, BlobXmlRestorer functor)
17311            throws IOException, XmlPullParserException {
17312        int type;
17313        while ((type = parser.next()) != XmlPullParser.START_TAG
17314                && type != XmlPullParser.END_DOCUMENT) {
17315        }
17316        if (type != XmlPullParser.START_TAG) {
17317            // oops didn't find a start tag?!
17318            if (DEBUG_BACKUP) {
17319                Slog.e(TAG, "Didn't find start tag during restore");
17320            }
17321            return;
17322        }
17323Slog.v(TAG, ":: restoreFromXml() : got to tag " + parser.getName());
17324        // this is supposed to be TAG_PREFERRED_BACKUP
17325        if (!expectedStartTag.equals(parser.getName())) {
17326            if (DEBUG_BACKUP) {
17327                Slog.e(TAG, "Found unexpected tag " + parser.getName());
17328            }
17329            return;
17330        }
17331
17332        // skip interfering stuff, then we're aligned with the backing implementation
17333        while ((type = parser.next()) == XmlPullParser.TEXT) { }
17334Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName());
17335        functor.apply(parser, userId);
17336    }
17337
17338    private interface BlobXmlRestorer {
17339        public void apply(XmlPullParser parser, int userId) throws IOException, XmlPullParserException;
17340    }
17341
17342    /**
17343     * Non-Binder method, support for the backup/restore mechanism: write the
17344     * full set of preferred activities in its canonical XML format.  Returns the
17345     * XML output as a byte array, or null if there is none.
17346     */
17347    @Override
17348    public byte[] getPreferredActivityBackup(int userId) {
17349        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
17350            throw new SecurityException("Only the system may call getPreferredActivityBackup()");
17351        }
17352
17353        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
17354        try {
17355            final XmlSerializer serializer = new FastXmlSerializer();
17356            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
17357            serializer.startDocument(null, true);
17358            serializer.startTag(null, TAG_PREFERRED_BACKUP);
17359
17360            synchronized (mPackages) {
17361                mSettings.writePreferredActivitiesLPr(serializer, userId, true);
17362            }
17363
17364            serializer.endTag(null, TAG_PREFERRED_BACKUP);
17365            serializer.endDocument();
17366            serializer.flush();
17367        } catch (Exception e) {
17368            if (DEBUG_BACKUP) {
17369                Slog.e(TAG, "Unable to write preferred activities for backup", e);
17370            }
17371            return null;
17372        }
17373
17374        return dataStream.toByteArray();
17375    }
17376
17377    @Override
17378    public void restorePreferredActivities(byte[] backup, int userId) {
17379        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
17380            throw new SecurityException("Only the system may call restorePreferredActivities()");
17381        }
17382
17383        try {
17384            final XmlPullParser parser = Xml.newPullParser();
17385            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
17386            restoreFromXml(parser, userId, TAG_PREFERRED_BACKUP,
17387                    new BlobXmlRestorer() {
17388                        @Override
17389                        public void apply(XmlPullParser parser, int userId)
17390                                throws XmlPullParserException, IOException {
17391                            synchronized (mPackages) {
17392                                mSettings.readPreferredActivitiesLPw(parser, userId);
17393                            }
17394                        }
17395                    } );
17396        } catch (Exception e) {
17397            if (DEBUG_BACKUP) {
17398                Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
17399            }
17400        }
17401    }
17402
17403    /**
17404     * Non-Binder method, support for the backup/restore mechanism: write the
17405     * default browser (etc) settings in its canonical XML format.  Returns the default
17406     * browser XML representation as a byte array, or null if there is none.
17407     */
17408    @Override
17409    public byte[] getDefaultAppsBackup(int userId) {
17410        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
17411            throw new SecurityException("Only the system may call getDefaultAppsBackup()");
17412        }
17413
17414        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
17415        try {
17416            final XmlSerializer serializer = new FastXmlSerializer();
17417            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
17418            serializer.startDocument(null, true);
17419            serializer.startTag(null, TAG_DEFAULT_APPS);
17420
17421            synchronized (mPackages) {
17422                mSettings.writeDefaultAppsLPr(serializer, userId);
17423            }
17424
17425            serializer.endTag(null, TAG_DEFAULT_APPS);
17426            serializer.endDocument();
17427            serializer.flush();
17428        } catch (Exception e) {
17429            if (DEBUG_BACKUP) {
17430                Slog.e(TAG, "Unable to write default apps for backup", e);
17431            }
17432            return null;
17433        }
17434
17435        return dataStream.toByteArray();
17436    }
17437
17438    @Override
17439    public void restoreDefaultApps(byte[] backup, int userId) {
17440        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
17441            throw new SecurityException("Only the system may call restoreDefaultApps()");
17442        }
17443
17444        try {
17445            final XmlPullParser parser = Xml.newPullParser();
17446            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
17447            restoreFromXml(parser, userId, TAG_DEFAULT_APPS,
17448                    new BlobXmlRestorer() {
17449                        @Override
17450                        public void apply(XmlPullParser parser, int userId)
17451                                throws XmlPullParserException, IOException {
17452                            synchronized (mPackages) {
17453                                mSettings.readDefaultAppsLPw(parser, userId);
17454                            }
17455                        }
17456                    } );
17457        } catch (Exception e) {
17458            if (DEBUG_BACKUP) {
17459                Slog.e(TAG, "Exception restoring default apps: " + e.getMessage());
17460            }
17461        }
17462    }
17463
17464    @Override
17465    public byte[] getIntentFilterVerificationBackup(int userId) {
17466        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
17467            throw new SecurityException("Only the system may call getIntentFilterVerificationBackup()");
17468        }
17469
17470        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
17471        try {
17472            final XmlSerializer serializer = new FastXmlSerializer();
17473            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
17474            serializer.startDocument(null, true);
17475            serializer.startTag(null, TAG_INTENT_FILTER_VERIFICATION);
17476
17477            synchronized (mPackages) {
17478                mSettings.writeAllDomainVerificationsLPr(serializer, userId);
17479            }
17480
17481            serializer.endTag(null, TAG_INTENT_FILTER_VERIFICATION);
17482            serializer.endDocument();
17483            serializer.flush();
17484        } catch (Exception e) {
17485            if (DEBUG_BACKUP) {
17486                Slog.e(TAG, "Unable to write default apps for backup", e);
17487            }
17488            return null;
17489        }
17490
17491        return dataStream.toByteArray();
17492    }
17493
17494    @Override
17495    public void restoreIntentFilterVerification(byte[] backup, int userId) {
17496        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
17497            throw new SecurityException("Only the system may call restorePreferredActivities()");
17498        }
17499
17500        try {
17501            final XmlPullParser parser = Xml.newPullParser();
17502            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
17503            restoreFromXml(parser, userId, TAG_INTENT_FILTER_VERIFICATION,
17504                    new BlobXmlRestorer() {
17505                        @Override
17506                        public void apply(XmlPullParser parser, int userId)
17507                                throws XmlPullParserException, IOException {
17508                            synchronized (mPackages) {
17509                                mSettings.readAllDomainVerificationsLPr(parser, userId);
17510                                mSettings.writeLPr();
17511                            }
17512                        }
17513                    } );
17514        } catch (Exception e) {
17515            if (DEBUG_BACKUP) {
17516                Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
17517            }
17518        }
17519    }
17520
17521    @Override
17522    public byte[] getPermissionGrantBackup(int userId) {
17523        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
17524            throw new SecurityException("Only the system may call getPermissionGrantBackup()");
17525        }
17526
17527        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
17528        try {
17529            final XmlSerializer serializer = new FastXmlSerializer();
17530            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
17531            serializer.startDocument(null, true);
17532            serializer.startTag(null, TAG_PERMISSION_BACKUP);
17533
17534            synchronized (mPackages) {
17535                serializeRuntimePermissionGrantsLPr(serializer, userId);
17536            }
17537
17538            serializer.endTag(null, TAG_PERMISSION_BACKUP);
17539            serializer.endDocument();
17540            serializer.flush();
17541        } catch (Exception e) {
17542            if (DEBUG_BACKUP) {
17543                Slog.e(TAG, "Unable to write default apps for backup", e);
17544            }
17545            return null;
17546        }
17547
17548        return dataStream.toByteArray();
17549    }
17550
17551    @Override
17552    public void restorePermissionGrants(byte[] backup, int userId) {
17553        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
17554            throw new SecurityException("Only the system may call restorePermissionGrants()");
17555        }
17556
17557        try {
17558            final XmlPullParser parser = Xml.newPullParser();
17559            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
17560            restoreFromXml(parser, userId, TAG_PERMISSION_BACKUP,
17561                    new BlobXmlRestorer() {
17562                        @Override
17563                        public void apply(XmlPullParser parser, int userId)
17564                                throws XmlPullParserException, IOException {
17565                            synchronized (mPackages) {
17566                                processRestoredPermissionGrantsLPr(parser, userId);
17567                            }
17568                        }
17569                    } );
17570        } catch (Exception e) {
17571            if (DEBUG_BACKUP) {
17572                Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
17573            }
17574        }
17575    }
17576
17577    private void serializeRuntimePermissionGrantsLPr(XmlSerializer serializer, final int userId)
17578            throws IOException {
17579        serializer.startTag(null, TAG_ALL_GRANTS);
17580
17581        final int N = mSettings.mPackages.size();
17582        for (int i = 0; i < N; i++) {
17583            final PackageSetting ps = mSettings.mPackages.valueAt(i);
17584            boolean pkgGrantsKnown = false;
17585
17586            PermissionsState packagePerms = ps.getPermissionsState();
17587
17588            for (PermissionState state : packagePerms.getRuntimePermissionStates(userId)) {
17589                final int grantFlags = state.getFlags();
17590                // only look at grants that are not system/policy fixed
17591                if ((grantFlags & SYSTEM_RUNTIME_GRANT_MASK) == 0) {
17592                    final boolean isGranted = state.isGranted();
17593                    // And only back up the user-twiddled state bits
17594                    if (isGranted || (grantFlags & USER_RUNTIME_GRANT_MASK) != 0) {
17595                        final String packageName = mSettings.mPackages.keyAt(i);
17596                        if (!pkgGrantsKnown) {
17597                            serializer.startTag(null, TAG_GRANT);
17598                            serializer.attribute(null, ATTR_PACKAGE_NAME, packageName);
17599                            pkgGrantsKnown = true;
17600                        }
17601
17602                        final boolean userSet =
17603                                (grantFlags & FLAG_PERMISSION_USER_SET) != 0;
17604                        final boolean userFixed =
17605                                (grantFlags & FLAG_PERMISSION_USER_FIXED) != 0;
17606                        final boolean revoke =
17607                                (grantFlags & FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0;
17608
17609                        serializer.startTag(null, TAG_PERMISSION);
17610                        serializer.attribute(null, ATTR_PERMISSION_NAME, state.getName());
17611                        if (isGranted) {
17612                            serializer.attribute(null, ATTR_IS_GRANTED, "true");
17613                        }
17614                        if (userSet) {
17615                            serializer.attribute(null, ATTR_USER_SET, "true");
17616                        }
17617                        if (userFixed) {
17618                            serializer.attribute(null, ATTR_USER_FIXED, "true");
17619                        }
17620                        if (revoke) {
17621                            serializer.attribute(null, ATTR_REVOKE_ON_UPGRADE, "true");
17622                        }
17623                        serializer.endTag(null, TAG_PERMISSION);
17624                    }
17625                }
17626            }
17627
17628            if (pkgGrantsKnown) {
17629                serializer.endTag(null, TAG_GRANT);
17630            }
17631        }
17632
17633        serializer.endTag(null, TAG_ALL_GRANTS);
17634    }
17635
17636    private void processRestoredPermissionGrantsLPr(XmlPullParser parser, int userId)
17637            throws XmlPullParserException, IOException {
17638        String pkgName = null;
17639        int outerDepth = parser.getDepth();
17640        int type;
17641        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
17642                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
17643            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
17644                continue;
17645            }
17646
17647            final String tagName = parser.getName();
17648            if (tagName.equals(TAG_GRANT)) {
17649                pkgName = parser.getAttributeValue(null, ATTR_PACKAGE_NAME);
17650                if (DEBUG_BACKUP) {
17651                    Slog.v(TAG, "+++ Restoring grants for package " + pkgName);
17652                }
17653            } else if (tagName.equals(TAG_PERMISSION)) {
17654
17655                final boolean isGranted = "true".equals(parser.getAttributeValue(null, ATTR_IS_GRANTED));
17656                final String permName = parser.getAttributeValue(null, ATTR_PERMISSION_NAME);
17657
17658                int newFlagSet = 0;
17659                if ("true".equals(parser.getAttributeValue(null, ATTR_USER_SET))) {
17660                    newFlagSet |= FLAG_PERMISSION_USER_SET;
17661                }
17662                if ("true".equals(parser.getAttributeValue(null, ATTR_USER_FIXED))) {
17663                    newFlagSet |= FLAG_PERMISSION_USER_FIXED;
17664                }
17665                if ("true".equals(parser.getAttributeValue(null, ATTR_REVOKE_ON_UPGRADE))) {
17666                    newFlagSet |= FLAG_PERMISSION_REVOKE_ON_UPGRADE;
17667                }
17668                if (DEBUG_BACKUP) {
17669                    Slog.v(TAG, "  + Restoring grant: pkg=" + pkgName + " perm=" + permName
17670                            + " granted=" + isGranted + " bits=0x" + Integer.toHexString(newFlagSet));
17671                }
17672                final PackageSetting ps = mSettings.mPackages.get(pkgName);
17673                if (ps != null) {
17674                    // Already installed so we apply the grant immediately
17675                    if (DEBUG_BACKUP) {
17676                        Slog.v(TAG, "        + already installed; applying");
17677                    }
17678                    PermissionsState perms = ps.getPermissionsState();
17679                    BasePermission bp = mSettings.mPermissions.get(permName);
17680                    if (bp != null) {
17681                        if (isGranted) {
17682                            perms.grantRuntimePermission(bp, userId);
17683                        }
17684                        if (newFlagSet != 0) {
17685                            perms.updatePermissionFlags(bp, userId, USER_RUNTIME_GRANT_MASK, newFlagSet);
17686                        }
17687                    }
17688                } else {
17689                    // Need to wait for post-restore install to apply the grant
17690                    if (DEBUG_BACKUP) {
17691                        Slog.v(TAG, "        - not yet installed; saving for later");
17692                    }
17693                    mSettings.processRestoredPermissionGrantLPr(pkgName, permName,
17694                            isGranted, newFlagSet, userId);
17695                }
17696            } else {
17697                PackageManagerService.reportSettingsProblem(Log.WARN,
17698                        "Unknown element under <" + TAG_PERMISSION_BACKUP + ">: " + tagName);
17699                XmlUtils.skipCurrentTag(parser);
17700            }
17701        }
17702
17703        scheduleWriteSettingsLocked();
17704        mSettings.writeRuntimePermissionsForUserLPr(userId, false);
17705    }
17706
17707    @Override
17708    public void addCrossProfileIntentFilter(IntentFilter intentFilter, String ownerPackage,
17709            int sourceUserId, int targetUserId, int flags) {
17710        mContext.enforceCallingOrSelfPermission(
17711                        android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
17712        int callingUid = Binder.getCallingUid();
17713        enforceOwnerRights(ownerPackage, callingUid);
17714        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
17715        if (intentFilter.countActions() == 0) {
17716            Slog.w(TAG, "Cannot set a crossProfile intent filter with no filter actions");
17717            return;
17718        }
17719        synchronized (mPackages) {
17720            CrossProfileIntentFilter newFilter = new CrossProfileIntentFilter(intentFilter,
17721                    ownerPackage, targetUserId, flags);
17722            CrossProfileIntentResolver resolver =
17723                    mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
17724            ArrayList<CrossProfileIntentFilter> existing = resolver.findFilters(intentFilter);
17725            // We have all those whose filter is equal. Now checking if the rest is equal as well.
17726            if (existing != null) {
17727                int size = existing.size();
17728                for (int i = 0; i < size; i++) {
17729                    if (newFilter.equalsIgnoreFilter(existing.get(i))) {
17730                        return;
17731                    }
17732                }
17733            }
17734            resolver.addFilter(newFilter);
17735            scheduleWritePackageRestrictionsLocked(sourceUserId);
17736        }
17737    }
17738
17739    @Override
17740    public void clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage) {
17741        mContext.enforceCallingOrSelfPermission(
17742                        android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
17743        int callingUid = Binder.getCallingUid();
17744        enforceOwnerRights(ownerPackage, callingUid);
17745        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
17746        synchronized (mPackages) {
17747            CrossProfileIntentResolver resolver =
17748                    mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
17749            ArraySet<CrossProfileIntentFilter> set =
17750                    new ArraySet<CrossProfileIntentFilter>(resolver.filterSet());
17751            for (CrossProfileIntentFilter filter : set) {
17752                if (filter.getOwnerPackage().equals(ownerPackage)) {
17753                    resolver.removeFilter(filter);
17754                }
17755            }
17756            scheduleWritePackageRestrictionsLocked(sourceUserId);
17757        }
17758    }
17759
17760    // Enforcing that callingUid is owning pkg on userId
17761    private void enforceOwnerRights(String pkg, int callingUid) {
17762        // The system owns everything.
17763        if (UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) {
17764            return;
17765        }
17766        int callingUserId = UserHandle.getUserId(callingUid);
17767        PackageInfo pi = getPackageInfo(pkg, 0, callingUserId);
17768        if (pi == null) {
17769            throw new IllegalArgumentException("Unknown package " + pkg + " on user "
17770                    + callingUserId);
17771        }
17772        if (!UserHandle.isSameApp(pi.applicationInfo.uid, callingUid)) {
17773            throw new SecurityException("Calling uid " + callingUid
17774                    + " does not own package " + pkg);
17775        }
17776    }
17777
17778    @Override
17779    public ComponentName getHomeActivities(List<ResolveInfo> allHomeCandidates) {
17780        return getHomeActivitiesAsUser(allHomeCandidates, UserHandle.getCallingUserId());
17781    }
17782
17783    private Intent getHomeIntent() {
17784        Intent intent = new Intent(Intent.ACTION_MAIN);
17785        intent.addCategory(Intent.CATEGORY_HOME);
17786        intent.addCategory(Intent.CATEGORY_DEFAULT);
17787        return intent;
17788    }
17789
17790    private IntentFilter getHomeFilter() {
17791        IntentFilter filter = new IntentFilter(Intent.ACTION_MAIN);
17792        filter.addCategory(Intent.CATEGORY_HOME);
17793        filter.addCategory(Intent.CATEGORY_DEFAULT);
17794        return filter;
17795    }
17796
17797    ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates,
17798            int userId) {
17799        Intent intent  = getHomeIntent();
17800        List<ResolveInfo> list = queryIntentActivitiesInternal(intent, null,
17801                PackageManager.GET_META_DATA, userId);
17802        ResolveInfo preferred = findPreferredActivity(intent, null, 0, list, 0,
17803                true, false, false, userId);
17804
17805        allHomeCandidates.clear();
17806        if (list != null) {
17807            for (ResolveInfo ri : list) {
17808                allHomeCandidates.add(ri);
17809            }
17810        }
17811        return (preferred == null || preferred.activityInfo == null)
17812                ? null
17813                : new ComponentName(preferred.activityInfo.packageName,
17814                        preferred.activityInfo.name);
17815    }
17816
17817    @Override
17818    public void setHomeActivity(ComponentName comp, int userId) {
17819        ArrayList<ResolveInfo> homeActivities = new ArrayList<>();
17820        getHomeActivitiesAsUser(homeActivities, userId);
17821
17822        boolean found = false;
17823
17824        final int size = homeActivities.size();
17825        final ComponentName[] set = new ComponentName[size];
17826        for (int i = 0; i < size; i++) {
17827            final ResolveInfo candidate = homeActivities.get(i);
17828            final ActivityInfo info = candidate.activityInfo;
17829            final ComponentName activityName = new ComponentName(info.packageName, info.name);
17830            set[i] = activityName;
17831            if (!found && activityName.equals(comp)) {
17832                found = true;
17833            }
17834        }
17835        if (!found) {
17836            throw new IllegalArgumentException("Component " + comp + " cannot be home on user "
17837                    + userId);
17838        }
17839        replacePreferredActivity(getHomeFilter(), IntentFilter.MATCH_CATEGORY_EMPTY,
17840                set, comp, userId);
17841    }
17842
17843    private @Nullable String getSetupWizardPackageName() {
17844        final Intent intent = new Intent(Intent.ACTION_MAIN);
17845        intent.addCategory(Intent.CATEGORY_SETUP_WIZARD);
17846
17847        final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null,
17848                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE
17849                        | MATCH_DISABLED_COMPONENTS,
17850                UserHandle.myUserId());
17851        if (matches.size() == 1) {
17852            return matches.get(0).getComponentInfo().packageName;
17853        } else {
17854            Slog.e(TAG, "There should probably be exactly one setup wizard; found " + matches.size()
17855                    + ": matches=" + matches);
17856            return null;
17857        }
17858    }
17859
17860    private @Nullable String getStorageManagerPackageName() {
17861        final Intent intent = new Intent(StorageManager.ACTION_MANAGE_STORAGE);
17862
17863        final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null,
17864                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE
17865                        | MATCH_DISABLED_COMPONENTS,
17866                UserHandle.myUserId());
17867        if (matches.size() == 1) {
17868            return matches.get(0).getComponentInfo().packageName;
17869        } else {
17870            Slog.e(TAG, "There should probably be exactly one storage manager; found "
17871                    + matches.size() + ": matches=" + matches);
17872            return null;
17873        }
17874    }
17875
17876    @Override
17877    public void setApplicationEnabledSetting(String appPackageName,
17878            int newState, int flags, int userId, String callingPackage) {
17879        if (!sUserManager.exists(userId)) return;
17880        if (callingPackage == null) {
17881            callingPackage = Integer.toString(Binder.getCallingUid());
17882        }
17883        setEnabledSetting(appPackageName, null, newState, flags, userId, callingPackage);
17884    }
17885
17886    @Override
17887    public void setComponentEnabledSetting(ComponentName componentName,
17888            int newState, int flags, int userId) {
17889        if (!sUserManager.exists(userId)) return;
17890        setEnabledSetting(componentName.getPackageName(),
17891                componentName.getClassName(), newState, flags, userId, null);
17892    }
17893
17894    private void setEnabledSetting(final String packageName, String className, int newState,
17895            final int flags, int userId, String callingPackage) {
17896        if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT
17897              || newState == COMPONENT_ENABLED_STATE_ENABLED
17898              || newState == COMPONENT_ENABLED_STATE_DISABLED
17899              || newState == COMPONENT_ENABLED_STATE_DISABLED_USER
17900              || newState == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED)) {
17901            throw new IllegalArgumentException("Invalid new component state: "
17902                    + newState);
17903        }
17904        PackageSetting pkgSetting;
17905        final int uid = Binder.getCallingUid();
17906        final int permission;
17907        if (uid == Process.SYSTEM_UID) {
17908            permission = PackageManager.PERMISSION_GRANTED;
17909        } else {
17910            permission = mContext.checkCallingOrSelfPermission(
17911                    android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
17912        }
17913        enforceCrossUserPermission(uid, userId,
17914                false /* requireFullPermission */, true /* checkShell */, "set enabled");
17915        final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
17916        boolean sendNow = false;
17917        boolean isApp = (className == null);
17918        String componentName = isApp ? packageName : className;
17919        int packageUid = -1;
17920        ArrayList<String> components;
17921
17922        // writer
17923        synchronized (mPackages) {
17924            pkgSetting = mSettings.mPackages.get(packageName);
17925            if (pkgSetting == null) {
17926                if (className == null) {
17927                    throw new IllegalArgumentException("Unknown package: " + packageName);
17928                }
17929                throw new IllegalArgumentException(
17930                        "Unknown component: " + packageName + "/" + className);
17931            }
17932        }
17933
17934        // Limit who can change which apps
17935        if (!UserHandle.isSameApp(uid, pkgSetting.appId)) {
17936            // Don't allow apps that don't have permission to modify other apps
17937            if (!allowedByPermission) {
17938                throw new SecurityException(
17939                        "Permission Denial: attempt to change component state from pid="
17940                        + Binder.getCallingPid()
17941                        + ", uid=" + uid + ", package uid=" + pkgSetting.appId);
17942            }
17943            // Don't allow changing protected packages.
17944            if (mProtectedPackages.isPackageStateProtected(userId, packageName)) {
17945                throw new SecurityException("Cannot disable a protected package: " + packageName);
17946            }
17947        }
17948
17949        synchronized (mPackages) {
17950            if (uid == Process.SHELL_UID) {
17951                // Shell can only change whole packages between ENABLED and DISABLED_USER states
17952                int oldState = pkgSetting.getEnabled(userId);
17953                if (className == null
17954                    &&
17955                    (oldState == COMPONENT_ENABLED_STATE_DISABLED_USER
17956                     || oldState == COMPONENT_ENABLED_STATE_DEFAULT
17957                     || oldState == COMPONENT_ENABLED_STATE_ENABLED)
17958                    &&
17959                    (newState == COMPONENT_ENABLED_STATE_DISABLED_USER
17960                     || newState == COMPONENT_ENABLED_STATE_DEFAULT
17961                     || newState == COMPONENT_ENABLED_STATE_ENABLED)) {
17962                    // ok
17963                } else {
17964                    throw new SecurityException(
17965                            "Shell cannot change component state for " + packageName + "/"
17966                            + className + " to " + newState);
17967                }
17968            }
17969            if (className == null) {
17970                // We're dealing with an application/package level state change
17971                if (pkgSetting.getEnabled(userId) == newState) {
17972                    // Nothing to do
17973                    return;
17974                }
17975                if (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
17976                    || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {
17977                    // Don't care about who enables an app.
17978                    callingPackage = null;
17979                }
17980                pkgSetting.setEnabled(newState, userId, callingPackage);
17981                // pkgSetting.pkg.mSetEnabled = newState;
17982            } else {
17983                // We're dealing with a component level state change
17984                // First, verify that this is a valid class name.
17985                PackageParser.Package pkg = pkgSetting.pkg;
17986                if (pkg == null || !pkg.hasComponentClassName(className)) {
17987                    if (pkg != null &&
17988                            pkg.applicationInfo.targetSdkVersion >=
17989                                    Build.VERSION_CODES.JELLY_BEAN) {
17990                        throw new IllegalArgumentException("Component class " + className
17991                                + " does not exist in " + packageName);
17992                    } else {
17993                        Slog.w(TAG, "Failed setComponentEnabledSetting: component class "
17994                                + className + " does not exist in " + packageName);
17995                    }
17996                }
17997                switch (newState) {
17998                case COMPONENT_ENABLED_STATE_ENABLED:
17999                    if (!pkgSetting.enableComponentLPw(className, userId)) {
18000                        return;
18001                    }
18002                    break;
18003                case COMPONENT_ENABLED_STATE_DISABLED:
18004                    if (!pkgSetting.disableComponentLPw(className, userId)) {
18005                        return;
18006                    }
18007                    break;
18008                case COMPONENT_ENABLED_STATE_DEFAULT:
18009                    if (!pkgSetting.restoreComponentLPw(className, userId)) {
18010                        return;
18011                    }
18012                    break;
18013                default:
18014                    Slog.e(TAG, "Invalid new component state: " + newState);
18015                    return;
18016                }
18017            }
18018            scheduleWritePackageRestrictionsLocked(userId);
18019            components = mPendingBroadcasts.get(userId, packageName);
18020            final boolean newPackage = components == null;
18021            if (newPackage) {
18022                components = new ArrayList<String>();
18023            }
18024            if (!components.contains(componentName)) {
18025                components.add(componentName);
18026            }
18027            if ((flags&PackageManager.DONT_KILL_APP) == 0) {
18028                sendNow = true;
18029                // Purge entry from pending broadcast list if another one exists already
18030                // since we are sending one right away.
18031                mPendingBroadcasts.remove(userId, packageName);
18032            } else {
18033                if (newPackage) {
18034                    mPendingBroadcasts.put(userId, packageName, components);
18035                }
18036                if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) {
18037                    // Schedule a message
18038                    mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, BROADCAST_DELAY);
18039                }
18040            }
18041        }
18042
18043        long callingId = Binder.clearCallingIdentity();
18044        try {
18045            if (sendNow) {
18046                packageUid = UserHandle.getUid(userId, pkgSetting.appId);
18047                sendPackageChangedBroadcast(packageName,
18048                        (flags&PackageManager.DONT_KILL_APP) != 0, components, packageUid);
18049            }
18050        } finally {
18051            Binder.restoreCallingIdentity(callingId);
18052        }
18053    }
18054
18055    @Override
18056    public void flushPackageRestrictionsAsUser(int userId) {
18057        if (!sUserManager.exists(userId)) {
18058            return;
18059        }
18060        enforceCrossUserPermission(Binder.getCallingUid(), userId, false /* requireFullPermission*/,
18061                false /* checkShell */, "flushPackageRestrictions");
18062        synchronized (mPackages) {
18063            mSettings.writePackageRestrictionsLPr(userId);
18064            mDirtyUsers.remove(userId);
18065            if (mDirtyUsers.isEmpty()) {
18066                mHandler.removeMessages(WRITE_PACKAGE_RESTRICTIONS);
18067            }
18068        }
18069    }
18070
18071    private void sendPackageChangedBroadcast(String packageName,
18072            boolean killFlag, ArrayList<String> componentNames, int packageUid) {
18073        if (DEBUG_INSTALL)
18074            Log.v(TAG, "Sending package changed: package=" + packageName + " components="
18075                    + componentNames);
18076        Bundle extras = new Bundle(4);
18077        extras.putString(Intent.EXTRA_CHANGED_COMPONENT_NAME, componentNames.get(0));
18078        String nameList[] = new String[componentNames.size()];
18079        componentNames.toArray(nameList);
18080        extras.putStringArray(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST, nameList);
18081        extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, killFlag);
18082        extras.putInt(Intent.EXTRA_UID, packageUid);
18083        // If this is not reporting a change of the overall package, then only send it
18084        // to registered receivers.  We don't want to launch a swath of apps for every
18085        // little component state change.
18086        final int flags = !componentNames.contains(packageName)
18087                ? Intent.FLAG_RECEIVER_REGISTERED_ONLY : 0;
18088        sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED,  packageName, extras, flags, null, null,
18089                new int[] {UserHandle.getUserId(packageUid)});
18090    }
18091
18092    @Override
18093    public void setPackageStoppedState(String packageName, boolean stopped, int userId) {
18094        if (!sUserManager.exists(userId)) return;
18095        final int uid = Binder.getCallingUid();
18096        final int permission = mContext.checkCallingOrSelfPermission(
18097                android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
18098        final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
18099        enforceCrossUserPermission(uid, userId,
18100                true /* requireFullPermission */, true /* checkShell */, "stop package");
18101        // writer
18102        synchronized (mPackages) {
18103            if (mSettings.setPackageStoppedStateLPw(this, packageName, stopped,
18104                    allowedByPermission, uid, userId)) {
18105                scheduleWritePackageRestrictionsLocked(userId);
18106            }
18107        }
18108    }
18109
18110    @Override
18111    public String getInstallerPackageName(String packageName) {
18112        // reader
18113        synchronized (mPackages) {
18114            return mSettings.getInstallerPackageNameLPr(packageName);
18115        }
18116    }
18117
18118    public boolean isOrphaned(String packageName) {
18119        // reader
18120        synchronized (mPackages) {
18121            return mSettings.isOrphaned(packageName);
18122        }
18123    }
18124
18125    @Override
18126    public int getApplicationEnabledSetting(String packageName, int userId) {
18127        if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
18128        int uid = Binder.getCallingUid();
18129        enforceCrossUserPermission(uid, userId,
18130                false /* requireFullPermission */, false /* checkShell */, "get enabled");
18131        // reader
18132        synchronized (mPackages) {
18133            return mSettings.getApplicationEnabledSettingLPr(packageName, userId);
18134        }
18135    }
18136
18137    @Override
18138    public int getComponentEnabledSetting(ComponentName componentName, int userId) {
18139        if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
18140        int uid = Binder.getCallingUid();
18141        enforceCrossUserPermission(uid, userId,
18142                false /* requireFullPermission */, false /* checkShell */, "get component enabled");
18143        // reader
18144        synchronized (mPackages) {
18145            return mSettings.getComponentEnabledSettingLPr(componentName, userId);
18146        }
18147    }
18148
18149    @Override
18150    public void enterSafeMode() {
18151        enforceSystemOrRoot("Only the system can request entering safe mode");
18152
18153        if (!mSystemReady) {
18154            mSafeMode = true;
18155        }
18156    }
18157
18158    @Override
18159    public void systemReady() {
18160        mSystemReady = true;
18161
18162        // Disable any carrier apps. We do this very early in boot to prevent the apps from being
18163        // disabled after already being started.
18164        CarrierAppUtils.disableCarrierAppsUntilPrivileged(mContext.getOpPackageName(), this,
18165                mContext.getContentResolver(), UserHandle.USER_SYSTEM);
18166
18167        // Read the compatibilty setting when the system is ready.
18168        boolean compatibilityModeEnabled = android.provider.Settings.Global.getInt(
18169                mContext.getContentResolver(),
18170                android.provider.Settings.Global.COMPATIBILITY_MODE, 1) == 1;
18171        PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled);
18172        if (DEBUG_SETTINGS) {
18173            Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled);
18174        }
18175
18176        int[] grantPermissionsUserIds = EMPTY_INT_ARRAY;
18177
18178        synchronized (mPackages) {
18179            // Verify that all of the preferred activity components actually
18180            // exist.  It is possible for applications to be updated and at
18181            // that point remove a previously declared activity component that
18182            // had been set as a preferred activity.  We try to clean this up
18183            // the next time we encounter that preferred activity, but it is
18184            // possible for the user flow to never be able to return to that
18185            // situation so here we do a sanity check to make sure we haven't
18186            // left any junk around.
18187            ArrayList<PreferredActivity> removed = new ArrayList<PreferredActivity>();
18188            for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
18189                PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
18190                removed.clear();
18191                for (PreferredActivity pa : pir.filterSet()) {
18192                    if (mActivities.mActivities.get(pa.mPref.mComponent) == null) {
18193                        removed.add(pa);
18194                    }
18195                }
18196                if (removed.size() > 0) {
18197                    for (int r=0; r<removed.size(); r++) {
18198                        PreferredActivity pa = removed.get(r);
18199                        Slog.w(TAG, "Removing dangling preferred activity: "
18200                                + pa.mPref.mComponent);
18201                        pir.removeFilter(pa);
18202                    }
18203                    mSettings.writePackageRestrictionsLPr(
18204                            mSettings.mPreferredActivities.keyAt(i));
18205                }
18206            }
18207
18208            for (int userId : UserManagerService.getInstance().getUserIds()) {
18209                if (!mSettings.areDefaultRuntimePermissionsGrantedLPr(userId)) {
18210                    grantPermissionsUserIds = ArrayUtils.appendInt(
18211                            grantPermissionsUserIds, userId);
18212                }
18213            }
18214        }
18215        sUserManager.systemReady();
18216
18217        // If we upgraded grant all default permissions before kicking off.
18218        for (int userId : grantPermissionsUserIds) {
18219            mDefaultPermissionPolicy.grantDefaultPermissions(userId);
18220        }
18221
18222        // If we did not grant default permissions, we preload from this the
18223        // default permission exceptions lazily to ensure we don't hit the
18224        // disk on a new user creation.
18225        if (grantPermissionsUserIds == EMPTY_INT_ARRAY) {
18226            mDefaultPermissionPolicy.scheduleReadDefaultPermissionExceptions();
18227        }
18228
18229        // Kick off any messages waiting for system ready
18230        if (mPostSystemReadyMessages != null) {
18231            for (Message msg : mPostSystemReadyMessages) {
18232                msg.sendToTarget();
18233            }
18234            mPostSystemReadyMessages = null;
18235        }
18236
18237        // Watch for external volumes that come and go over time
18238        final StorageManager storage = mContext.getSystemService(StorageManager.class);
18239        storage.registerListener(mStorageListener);
18240
18241        mInstallerService.systemReady();
18242        mPackageDexOptimizer.systemReady();
18243
18244        MountServiceInternal mountServiceInternal = LocalServices.getService(
18245                MountServiceInternal.class);
18246        mountServiceInternal.addExternalStoragePolicy(
18247                new MountServiceInternal.ExternalStorageMountPolicy() {
18248            @Override
18249            public int getMountMode(int uid, String packageName) {
18250                if (Process.isIsolated(uid)) {
18251                    return Zygote.MOUNT_EXTERNAL_NONE;
18252                }
18253                if (checkUidPermission(WRITE_MEDIA_STORAGE, uid) == PERMISSION_GRANTED) {
18254                    return Zygote.MOUNT_EXTERNAL_DEFAULT;
18255                }
18256                if (checkUidPermission(READ_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) {
18257                    return Zygote.MOUNT_EXTERNAL_DEFAULT;
18258                }
18259                if (checkUidPermission(WRITE_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) {
18260                    return Zygote.MOUNT_EXTERNAL_READ;
18261                }
18262                return Zygote.MOUNT_EXTERNAL_WRITE;
18263            }
18264
18265            @Override
18266            public boolean hasExternalStorage(int uid, String packageName) {
18267                return true;
18268            }
18269        });
18270
18271        // Now that we're mostly running, clean up stale users and apps
18272        reconcileUsers(StorageManager.UUID_PRIVATE_INTERNAL);
18273        reconcileApps(StorageManager.UUID_PRIVATE_INTERNAL);
18274    }
18275
18276    @Override
18277    public boolean isSafeMode() {
18278        return mSafeMode;
18279    }
18280
18281    @Override
18282    public boolean hasSystemUidErrors() {
18283        return mHasSystemUidErrors;
18284    }
18285
18286    static String arrayToString(int[] array) {
18287        StringBuffer buf = new StringBuffer(128);
18288        buf.append('[');
18289        if (array != null) {
18290            for (int i=0; i<array.length; i++) {
18291                if (i > 0) buf.append(", ");
18292                buf.append(array[i]);
18293            }
18294        }
18295        buf.append(']');
18296        return buf.toString();
18297    }
18298
18299    static class DumpState {
18300        public static final int DUMP_LIBS = 1 << 0;
18301        public static final int DUMP_FEATURES = 1 << 1;
18302        public static final int DUMP_ACTIVITY_RESOLVERS = 1 << 2;
18303        public static final int DUMP_SERVICE_RESOLVERS = 1 << 3;
18304        public static final int DUMP_RECEIVER_RESOLVERS = 1 << 4;
18305        public static final int DUMP_CONTENT_RESOLVERS = 1 << 5;
18306        public static final int DUMP_PERMISSIONS = 1 << 6;
18307        public static final int DUMP_PACKAGES = 1 << 7;
18308        public static final int DUMP_SHARED_USERS = 1 << 8;
18309        public static final int DUMP_MESSAGES = 1 << 9;
18310        public static final int DUMP_PROVIDERS = 1 << 10;
18311        public static final int DUMP_VERIFIERS = 1 << 11;
18312        public static final int DUMP_PREFERRED = 1 << 12;
18313        public static final int DUMP_PREFERRED_XML = 1 << 13;
18314        public static final int DUMP_KEYSETS = 1 << 14;
18315        public static final int DUMP_VERSION = 1 << 15;
18316        public static final int DUMP_INSTALLS = 1 << 16;
18317        public static final int DUMP_INTENT_FILTER_VERIFIERS = 1 << 17;
18318        public static final int DUMP_DOMAIN_PREFERRED = 1 << 18;
18319        public static final int DUMP_FROZEN = 1 << 19;
18320        public static final int DUMP_DEXOPT = 1 << 20;
18321        public static final int DUMP_COMPILER_STATS = 1 << 21;
18322
18323        public static final int OPTION_SHOW_FILTERS = 1 << 0;
18324
18325        private int mTypes;
18326
18327        private int mOptions;
18328
18329        private boolean mTitlePrinted;
18330
18331        private SharedUserSetting mSharedUser;
18332
18333        public boolean isDumping(int type) {
18334            if (mTypes == 0 && type != DUMP_PREFERRED_XML) {
18335                return true;
18336            }
18337
18338            return (mTypes & type) != 0;
18339        }
18340
18341        public void setDump(int type) {
18342            mTypes |= type;
18343        }
18344
18345        public boolean isOptionEnabled(int option) {
18346            return (mOptions & option) != 0;
18347        }
18348
18349        public void setOptionEnabled(int option) {
18350            mOptions |= option;
18351        }
18352
18353        public boolean onTitlePrinted() {
18354            final boolean printed = mTitlePrinted;
18355            mTitlePrinted = true;
18356            return printed;
18357        }
18358
18359        public boolean getTitlePrinted() {
18360            return mTitlePrinted;
18361        }
18362
18363        public void setTitlePrinted(boolean enabled) {
18364            mTitlePrinted = enabled;
18365        }
18366
18367        public SharedUserSetting getSharedUser() {
18368            return mSharedUser;
18369        }
18370
18371        public void setSharedUser(SharedUserSetting user) {
18372            mSharedUser = user;
18373        }
18374    }
18375
18376    @Override
18377    public void onShellCommand(FileDescriptor in, FileDescriptor out,
18378            FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
18379        (new PackageManagerShellCommand(this)).exec(
18380                this, in, out, err, args, resultReceiver);
18381    }
18382
18383    @Override
18384    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
18385        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
18386                != PackageManager.PERMISSION_GRANTED) {
18387            pw.println("Permission Denial: can't dump ActivityManager from from pid="
18388                    + Binder.getCallingPid()
18389                    + ", uid=" + Binder.getCallingUid()
18390                    + " without permission "
18391                    + android.Manifest.permission.DUMP);
18392            return;
18393        }
18394
18395        DumpState dumpState = new DumpState();
18396        boolean fullPreferred = false;
18397        boolean checkin = false;
18398
18399        String packageName = null;
18400        ArraySet<String> permissionNames = null;
18401
18402        int opti = 0;
18403        while (opti < args.length) {
18404            String opt = args[opti];
18405            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
18406                break;
18407            }
18408            opti++;
18409
18410            if ("-a".equals(opt)) {
18411                // Right now we only know how to print all.
18412            } else if ("-h".equals(opt)) {
18413                pw.println("Package manager dump options:");
18414                pw.println("  [-h] [-f] [--checkin] [cmd] ...");
18415                pw.println("    --checkin: dump for a checkin");
18416                pw.println("    -f: print details of intent filters");
18417                pw.println("    -h: print this help");
18418                pw.println("  cmd may be one of:");
18419                pw.println("    l[ibraries]: list known shared libraries");
18420                pw.println("    f[eatures]: list device features");
18421                pw.println("    k[eysets]: print known keysets");
18422                pw.println("    r[esolvers] [activity|service|receiver|content]: dump intent resolvers");
18423                pw.println("    perm[issions]: dump permissions");
18424                pw.println("    permission [name ...]: dump declaration and use of given permission");
18425                pw.println("    pref[erred]: print preferred package settings");
18426                pw.println("    preferred-xml [--full]: print preferred package settings as xml");
18427                pw.println("    prov[iders]: dump content providers");
18428                pw.println("    p[ackages]: dump installed packages");
18429                pw.println("    s[hared-users]: dump shared user IDs");
18430                pw.println("    m[essages]: print collected runtime messages");
18431                pw.println("    v[erifiers]: print package verifier info");
18432                pw.println("    d[omain-preferred-apps]: print domains preferred apps");
18433                pw.println("    i[ntent-filter-verifiers]|ifv: print intent filter verifier info");
18434                pw.println("    version: print database version info");
18435                pw.println("    write: write current settings now");
18436                pw.println("    installs: details about install sessions");
18437                pw.println("    check-permission <permission> <package> [<user>]: does pkg hold perm?");
18438                pw.println("    dexopt: dump dexopt state");
18439                pw.println("    compiler-stats: dump compiler statistics");
18440                pw.println("    <package.name>: info about given package");
18441                return;
18442            } else if ("--checkin".equals(opt)) {
18443                checkin = true;
18444            } else if ("-f".equals(opt)) {
18445                dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
18446            } else {
18447                pw.println("Unknown argument: " + opt + "; use -h for help");
18448            }
18449        }
18450
18451        // Is the caller requesting to dump a particular piece of data?
18452        if (opti < args.length) {
18453            String cmd = args[opti];
18454            opti++;
18455            // Is this a package name?
18456            if ("android".equals(cmd) || cmd.contains(".")) {
18457                packageName = cmd;
18458                // When dumping a single package, we always dump all of its
18459                // filter information since the amount of data will be reasonable.
18460                dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
18461            } else if ("check-permission".equals(cmd)) {
18462                if (opti >= args.length) {
18463                    pw.println("Error: check-permission missing permission argument");
18464                    return;
18465                }
18466                String perm = args[opti];
18467                opti++;
18468                if (opti >= args.length) {
18469                    pw.println("Error: check-permission missing package argument");
18470                    return;
18471                }
18472                String pkg = args[opti];
18473                opti++;
18474                int user = UserHandle.getUserId(Binder.getCallingUid());
18475                if (opti < args.length) {
18476                    try {
18477                        user = Integer.parseInt(args[opti]);
18478                    } catch (NumberFormatException e) {
18479                        pw.println("Error: check-permission user argument is not a number: "
18480                                + args[opti]);
18481                        return;
18482                    }
18483                }
18484                pw.println(checkPermission(perm, pkg, user));
18485                return;
18486            } else if ("l".equals(cmd) || "libraries".equals(cmd)) {
18487                dumpState.setDump(DumpState.DUMP_LIBS);
18488            } else if ("f".equals(cmd) || "features".equals(cmd)) {
18489                dumpState.setDump(DumpState.DUMP_FEATURES);
18490            } else if ("r".equals(cmd) || "resolvers".equals(cmd)) {
18491                if (opti >= args.length) {
18492                    dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS
18493                            | DumpState.DUMP_SERVICE_RESOLVERS
18494                            | DumpState.DUMP_RECEIVER_RESOLVERS
18495                            | DumpState.DUMP_CONTENT_RESOLVERS);
18496                } else {
18497                    while (opti < args.length) {
18498                        String name = args[opti];
18499                        if ("a".equals(name) || "activity".equals(name)) {
18500                            dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS);
18501                        } else if ("s".equals(name) || "service".equals(name)) {
18502                            dumpState.setDump(DumpState.DUMP_SERVICE_RESOLVERS);
18503                        } else if ("r".equals(name) || "receiver".equals(name)) {
18504                            dumpState.setDump(DumpState.DUMP_RECEIVER_RESOLVERS);
18505                        } else if ("c".equals(name) || "content".equals(name)) {
18506                            dumpState.setDump(DumpState.DUMP_CONTENT_RESOLVERS);
18507                        } else {
18508                            pw.println("Error: unknown resolver table type: " + name);
18509                            return;
18510                        }
18511                        opti++;
18512                    }
18513                }
18514            } else if ("perm".equals(cmd) || "permissions".equals(cmd)) {
18515                dumpState.setDump(DumpState.DUMP_PERMISSIONS);
18516            } else if ("permission".equals(cmd)) {
18517                if (opti >= args.length) {
18518                    pw.println("Error: permission requires permission name");
18519                    return;
18520                }
18521                permissionNames = new ArraySet<>();
18522                while (opti < args.length) {
18523                    permissionNames.add(args[opti]);
18524                    opti++;
18525                }
18526                dumpState.setDump(DumpState.DUMP_PERMISSIONS
18527                        | DumpState.DUMP_PACKAGES | DumpState.DUMP_SHARED_USERS);
18528            } else if ("pref".equals(cmd) || "preferred".equals(cmd)) {
18529                dumpState.setDump(DumpState.DUMP_PREFERRED);
18530            } else if ("preferred-xml".equals(cmd)) {
18531                dumpState.setDump(DumpState.DUMP_PREFERRED_XML);
18532                if (opti < args.length && "--full".equals(args[opti])) {
18533                    fullPreferred = true;
18534                    opti++;
18535                }
18536            } else if ("d".equals(cmd) || "domain-preferred-apps".equals(cmd)) {
18537                dumpState.setDump(DumpState.DUMP_DOMAIN_PREFERRED);
18538            } else if ("p".equals(cmd) || "packages".equals(cmd)) {
18539                dumpState.setDump(DumpState.DUMP_PACKAGES);
18540            } else if ("s".equals(cmd) || "shared-users".equals(cmd)) {
18541                dumpState.setDump(DumpState.DUMP_SHARED_USERS);
18542            } else if ("prov".equals(cmd) || "providers".equals(cmd)) {
18543                dumpState.setDump(DumpState.DUMP_PROVIDERS);
18544            } else if ("m".equals(cmd) || "messages".equals(cmd)) {
18545                dumpState.setDump(DumpState.DUMP_MESSAGES);
18546            } else if ("v".equals(cmd) || "verifiers".equals(cmd)) {
18547                dumpState.setDump(DumpState.DUMP_VERIFIERS);
18548            } else if ("i".equals(cmd) || "ifv".equals(cmd)
18549                    || "intent-filter-verifiers".equals(cmd)) {
18550                dumpState.setDump(DumpState.DUMP_INTENT_FILTER_VERIFIERS);
18551            } else if ("version".equals(cmd)) {
18552                dumpState.setDump(DumpState.DUMP_VERSION);
18553            } else if ("k".equals(cmd) || "keysets".equals(cmd)) {
18554                dumpState.setDump(DumpState.DUMP_KEYSETS);
18555            } else if ("installs".equals(cmd)) {
18556                dumpState.setDump(DumpState.DUMP_INSTALLS);
18557            } else if ("frozen".equals(cmd)) {
18558                dumpState.setDump(DumpState.DUMP_FROZEN);
18559            } else if ("dexopt".equals(cmd)) {
18560                dumpState.setDump(DumpState.DUMP_DEXOPT);
18561            } else if ("compiler-stats".equals(cmd)) {
18562                dumpState.setDump(DumpState.DUMP_COMPILER_STATS);
18563            } else if ("write".equals(cmd)) {
18564                synchronized (mPackages) {
18565                    mSettings.writeLPr();
18566                    pw.println("Settings written.");
18567                    return;
18568                }
18569            }
18570        }
18571
18572        if (checkin) {
18573            pw.println("vers,1");
18574        }
18575
18576        // reader
18577        synchronized (mPackages) {
18578            if (dumpState.isDumping(DumpState.DUMP_VERSION) && packageName == null) {
18579                if (!checkin) {
18580                    if (dumpState.onTitlePrinted())
18581                        pw.println();
18582                    pw.println("Database versions:");
18583                    mSettings.dumpVersionLPr(new IndentingPrintWriter(pw, "  "));
18584                }
18585            }
18586
18587            if (dumpState.isDumping(DumpState.DUMP_VERIFIERS) && packageName == null) {
18588                if (!checkin) {
18589                    if (dumpState.onTitlePrinted())
18590                        pw.println();
18591                    pw.println("Verifiers:");
18592                    pw.print("  Required: ");
18593                    pw.print(mRequiredVerifierPackage);
18594                    pw.print(" (uid=");
18595                    pw.print(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
18596                            UserHandle.USER_SYSTEM));
18597                    pw.println(")");
18598                } else if (mRequiredVerifierPackage != null) {
18599                    pw.print("vrfy,"); pw.print(mRequiredVerifierPackage);
18600                    pw.print(",");
18601                    pw.println(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
18602                            UserHandle.USER_SYSTEM));
18603                }
18604            }
18605
18606            if (dumpState.isDumping(DumpState.DUMP_INTENT_FILTER_VERIFIERS) &&
18607                    packageName == null) {
18608                if (mIntentFilterVerifierComponent != null) {
18609                    String verifierPackageName = mIntentFilterVerifierComponent.getPackageName();
18610                    if (!checkin) {
18611                        if (dumpState.onTitlePrinted())
18612                            pw.println();
18613                        pw.println("Intent Filter Verifier:");
18614                        pw.print("  Using: ");
18615                        pw.print(verifierPackageName);
18616                        pw.print(" (uid=");
18617                        pw.print(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING,
18618                                UserHandle.USER_SYSTEM));
18619                        pw.println(")");
18620                    } else if (verifierPackageName != null) {
18621                        pw.print("ifv,"); pw.print(verifierPackageName);
18622                        pw.print(",");
18623                        pw.println(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING,
18624                                UserHandle.USER_SYSTEM));
18625                    }
18626                } else {
18627                    pw.println();
18628                    pw.println("No Intent Filter Verifier available!");
18629                }
18630            }
18631
18632            if (dumpState.isDumping(DumpState.DUMP_LIBS) && packageName == null) {
18633                boolean printedHeader = false;
18634                final Iterator<String> it = mSharedLibraries.keySet().iterator();
18635                while (it.hasNext()) {
18636                    String name = it.next();
18637                    SharedLibraryEntry ent = mSharedLibraries.get(name);
18638                    if (!checkin) {
18639                        if (!printedHeader) {
18640                            if (dumpState.onTitlePrinted())
18641                                pw.println();
18642                            pw.println("Libraries:");
18643                            printedHeader = true;
18644                        }
18645                        pw.print("  ");
18646                    } else {
18647                        pw.print("lib,");
18648                    }
18649                    pw.print(name);
18650                    if (!checkin) {
18651                        pw.print(" -> ");
18652                    }
18653                    if (ent.path != null) {
18654                        if (!checkin) {
18655                            pw.print("(jar) ");
18656                            pw.print(ent.path);
18657                        } else {
18658                            pw.print(",jar,");
18659                            pw.print(ent.path);
18660                        }
18661                    } else {
18662                        if (!checkin) {
18663                            pw.print("(apk) ");
18664                            pw.print(ent.apk);
18665                        } else {
18666                            pw.print(",apk,");
18667                            pw.print(ent.apk);
18668                        }
18669                    }
18670                    pw.println();
18671                }
18672            }
18673
18674            if (dumpState.isDumping(DumpState.DUMP_FEATURES) && packageName == null) {
18675                if (dumpState.onTitlePrinted())
18676                    pw.println();
18677                if (!checkin) {
18678                    pw.println("Features:");
18679                }
18680
18681                for (FeatureInfo feat : mAvailableFeatures.values()) {
18682                    if (checkin) {
18683                        pw.print("feat,");
18684                        pw.print(feat.name);
18685                        pw.print(",");
18686                        pw.println(feat.version);
18687                    } else {
18688                        pw.print("  ");
18689                        pw.print(feat.name);
18690                        if (feat.version > 0) {
18691                            pw.print(" version=");
18692                            pw.print(feat.version);
18693                        }
18694                        pw.println();
18695                    }
18696                }
18697            }
18698
18699            if (!checkin && dumpState.isDumping(DumpState.DUMP_ACTIVITY_RESOLVERS)) {
18700                if (mActivities.dump(pw, dumpState.getTitlePrinted() ? "\nActivity Resolver Table:"
18701                        : "Activity Resolver Table:", "  ", packageName,
18702                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
18703                    dumpState.setTitlePrinted(true);
18704                }
18705            }
18706            if (!checkin && dumpState.isDumping(DumpState.DUMP_RECEIVER_RESOLVERS)) {
18707                if (mReceivers.dump(pw, dumpState.getTitlePrinted() ? "\nReceiver Resolver Table:"
18708                        : "Receiver Resolver Table:", "  ", packageName,
18709                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
18710                    dumpState.setTitlePrinted(true);
18711                }
18712            }
18713            if (!checkin && dumpState.isDumping(DumpState.DUMP_SERVICE_RESOLVERS)) {
18714                if (mServices.dump(pw, dumpState.getTitlePrinted() ? "\nService Resolver Table:"
18715                        : "Service Resolver Table:", "  ", packageName,
18716                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
18717                    dumpState.setTitlePrinted(true);
18718                }
18719            }
18720            if (!checkin && dumpState.isDumping(DumpState.DUMP_CONTENT_RESOLVERS)) {
18721                if (mProviders.dump(pw, dumpState.getTitlePrinted() ? "\nProvider Resolver Table:"
18722                        : "Provider Resolver Table:", "  ", packageName,
18723                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
18724                    dumpState.setTitlePrinted(true);
18725                }
18726            }
18727
18728            if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED)) {
18729                for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
18730                    PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
18731                    int user = mSettings.mPreferredActivities.keyAt(i);
18732                    if (pir.dump(pw,
18733                            dumpState.getTitlePrinted()
18734                                ? "\nPreferred Activities User " + user + ":"
18735                                : "Preferred Activities User " + user + ":", "  ",
18736                            packageName, true, false)) {
18737                        dumpState.setTitlePrinted(true);
18738                    }
18739                }
18740            }
18741
18742            if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED_XML)) {
18743                pw.flush();
18744                FileOutputStream fout = new FileOutputStream(fd);
18745                BufferedOutputStream str = new BufferedOutputStream(fout);
18746                XmlSerializer serializer = new FastXmlSerializer();
18747                try {
18748                    serializer.setOutput(str, StandardCharsets.UTF_8.name());
18749                    serializer.startDocument(null, true);
18750                    serializer.setFeature(
18751                            "http://xmlpull.org/v1/doc/features.html#indent-output", true);
18752                    mSettings.writePreferredActivitiesLPr(serializer, 0, fullPreferred);
18753                    serializer.endDocument();
18754                    serializer.flush();
18755                } catch (IllegalArgumentException e) {
18756                    pw.println("Failed writing: " + e);
18757                } catch (IllegalStateException e) {
18758                    pw.println("Failed writing: " + e);
18759                } catch (IOException e) {
18760                    pw.println("Failed writing: " + e);
18761                }
18762            }
18763
18764            if (!checkin
18765                    && dumpState.isDumping(DumpState.DUMP_DOMAIN_PREFERRED)
18766                    && packageName == null) {
18767                pw.println();
18768                int count = mSettings.mPackages.size();
18769                if (count == 0) {
18770                    pw.println("No applications!");
18771                    pw.println();
18772                } else {
18773                    final String prefix = "  ";
18774                    Collection<PackageSetting> allPackageSettings = mSettings.mPackages.values();
18775                    if (allPackageSettings.size() == 0) {
18776                        pw.println("No domain preferred apps!");
18777                        pw.println();
18778                    } else {
18779                        pw.println("App verification status:");
18780                        pw.println();
18781                        count = 0;
18782                        for (PackageSetting ps : allPackageSettings) {
18783                            IntentFilterVerificationInfo ivi = ps.getIntentFilterVerificationInfo();
18784                            if (ivi == null || ivi.getPackageName() == null) continue;
18785                            pw.println(prefix + "Package: " + ivi.getPackageName());
18786                            pw.println(prefix + "Domains: " + ivi.getDomainsString());
18787                            pw.println(prefix + "Status:  " + ivi.getStatusString());
18788                            pw.println();
18789                            count++;
18790                        }
18791                        if (count == 0) {
18792                            pw.println(prefix + "No app verification established.");
18793                            pw.println();
18794                        }
18795                        for (int userId : sUserManager.getUserIds()) {
18796                            pw.println("App linkages for user " + userId + ":");
18797                            pw.println();
18798                            count = 0;
18799                            for (PackageSetting ps : allPackageSettings) {
18800                                final long status = ps.getDomainVerificationStatusForUser(userId);
18801                                if (status >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) {
18802                                    continue;
18803                                }
18804                                pw.println(prefix + "Package: " + ps.name);
18805                                pw.println(prefix + "Domains: " + dumpDomainString(ps.name));
18806                                String statusStr = IntentFilterVerificationInfo.
18807                                        getStatusStringFromValue(status);
18808                                pw.println(prefix + "Status:  " + statusStr);
18809                                pw.println();
18810                                count++;
18811                            }
18812                            if (count == 0) {
18813                                pw.println(prefix + "No configured app linkages.");
18814                                pw.println();
18815                            }
18816                        }
18817                    }
18818                }
18819            }
18820
18821            if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) {
18822                mSettings.dumpPermissionsLPr(pw, packageName, permissionNames, dumpState);
18823                if (packageName == null && permissionNames == null) {
18824                    for (int iperm=0; iperm<mAppOpPermissionPackages.size(); iperm++) {
18825                        if (iperm == 0) {
18826                            if (dumpState.onTitlePrinted())
18827                                pw.println();
18828                            pw.println("AppOp Permissions:");
18829                        }
18830                        pw.print("  AppOp Permission ");
18831                        pw.print(mAppOpPermissionPackages.keyAt(iperm));
18832                        pw.println(":");
18833                        ArraySet<String> pkgs = mAppOpPermissionPackages.valueAt(iperm);
18834                        for (int ipkg=0; ipkg<pkgs.size(); ipkg++) {
18835                            pw.print("    "); pw.println(pkgs.valueAt(ipkg));
18836                        }
18837                    }
18838                }
18839            }
18840
18841            if (!checkin && dumpState.isDumping(DumpState.DUMP_PROVIDERS)) {
18842                boolean printedSomething = false;
18843                for (PackageParser.Provider p : mProviders.mProviders.values()) {
18844                    if (packageName != null && !packageName.equals(p.info.packageName)) {
18845                        continue;
18846                    }
18847                    if (!printedSomething) {
18848                        if (dumpState.onTitlePrinted())
18849                            pw.println();
18850                        pw.println("Registered ContentProviders:");
18851                        printedSomething = true;
18852                    }
18853                    pw.print("  "); p.printComponentShortName(pw); pw.println(":");
18854                    pw.print("    "); pw.println(p.toString());
18855                }
18856                printedSomething = false;
18857                for (Map.Entry<String, PackageParser.Provider> entry :
18858                        mProvidersByAuthority.entrySet()) {
18859                    PackageParser.Provider p = entry.getValue();
18860                    if (packageName != null && !packageName.equals(p.info.packageName)) {
18861                        continue;
18862                    }
18863                    if (!printedSomething) {
18864                        if (dumpState.onTitlePrinted())
18865                            pw.println();
18866                        pw.println("ContentProvider Authorities:");
18867                        printedSomething = true;
18868                    }
18869                    pw.print("  ["); pw.print(entry.getKey()); pw.println("]:");
18870                    pw.print("    "); pw.println(p.toString());
18871                    if (p.info != null && p.info.applicationInfo != null) {
18872                        final String appInfo = p.info.applicationInfo.toString();
18873                        pw.print("      applicationInfo="); pw.println(appInfo);
18874                    }
18875                }
18876            }
18877
18878            if (!checkin && dumpState.isDumping(DumpState.DUMP_KEYSETS)) {
18879                mSettings.mKeySetManagerService.dumpLPr(pw, packageName, dumpState);
18880            }
18881
18882            if (dumpState.isDumping(DumpState.DUMP_PACKAGES)) {
18883                mSettings.dumpPackagesLPr(pw, packageName, permissionNames, dumpState, checkin);
18884            }
18885
18886            if (dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) {
18887                mSettings.dumpSharedUsersLPr(pw, packageName, permissionNames, dumpState, checkin);
18888            }
18889
18890            if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS) && packageName == null) {
18891                mSettings.dumpRestoredPermissionGrantsLPr(pw, dumpState);
18892            }
18893
18894            if (!checkin && dumpState.isDumping(DumpState.DUMP_INSTALLS) && packageName == null) {
18895                // XXX should handle packageName != null by dumping only install data that
18896                // the given package is involved with.
18897                if (dumpState.onTitlePrinted()) pw.println();
18898                mInstallerService.dump(new IndentingPrintWriter(pw, "  ", 120));
18899            }
18900
18901            if (!checkin && dumpState.isDumping(DumpState.DUMP_FROZEN) && packageName == null) {
18902                // XXX should handle packageName != null by dumping only install data that
18903                // the given package is involved with.
18904                if (dumpState.onTitlePrinted()) pw.println();
18905
18906                final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ", 120);
18907                ipw.println();
18908                ipw.println("Frozen packages:");
18909                ipw.increaseIndent();
18910                if (mFrozenPackages.size() == 0) {
18911                    ipw.println("(none)");
18912                } else {
18913                    for (int i = 0; i < mFrozenPackages.size(); i++) {
18914                        ipw.println(mFrozenPackages.valueAt(i));
18915                    }
18916                }
18917                ipw.decreaseIndent();
18918            }
18919
18920            if (!checkin && dumpState.isDumping(DumpState.DUMP_DEXOPT)) {
18921                if (dumpState.onTitlePrinted()) pw.println();
18922                dumpDexoptStateLPr(pw, packageName);
18923            }
18924
18925            if (!checkin && dumpState.isDumping(DumpState.DUMP_COMPILER_STATS)) {
18926                if (dumpState.onTitlePrinted()) pw.println();
18927                dumpCompilerStatsLPr(pw, packageName);
18928            }
18929
18930            if (!checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES) && packageName == null) {
18931                if (dumpState.onTitlePrinted()) pw.println();
18932                mSettings.dumpReadMessagesLPr(pw, dumpState);
18933
18934                pw.println();
18935                pw.println("Package warning messages:");
18936                BufferedReader in = null;
18937                String line = null;
18938                try {
18939                    in = new BufferedReader(new FileReader(getSettingsProblemFile()));
18940                    while ((line = in.readLine()) != null) {
18941                        if (line.contains("ignored: updated version")) continue;
18942                        pw.println(line);
18943                    }
18944                } catch (IOException ignored) {
18945                } finally {
18946                    IoUtils.closeQuietly(in);
18947                }
18948            }
18949
18950            if (checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES)) {
18951                BufferedReader in = null;
18952                String line = null;
18953                try {
18954                    in = new BufferedReader(new FileReader(getSettingsProblemFile()));
18955                    while ((line = in.readLine()) != null) {
18956                        if (line.contains("ignored: updated version")) continue;
18957                        pw.print("msg,");
18958                        pw.println(line);
18959                    }
18960                } catch (IOException ignored) {
18961                } finally {
18962                    IoUtils.closeQuietly(in);
18963                }
18964            }
18965        }
18966    }
18967
18968    private void dumpDexoptStateLPr(PrintWriter pw, String packageName) {
18969        final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ", 120);
18970        ipw.println();
18971        ipw.println("Dexopt state:");
18972        ipw.increaseIndent();
18973        Collection<PackageParser.Package> packages = null;
18974        if (packageName != null) {
18975            PackageParser.Package targetPackage = mPackages.get(packageName);
18976            if (targetPackage != null) {
18977                packages = Collections.singletonList(targetPackage);
18978            } else {
18979                ipw.println("Unable to find package: " + packageName);
18980                return;
18981            }
18982        } else {
18983            packages = mPackages.values();
18984        }
18985
18986        for (PackageParser.Package pkg : packages) {
18987            ipw.println("[" + pkg.packageName + "]");
18988            ipw.increaseIndent();
18989            mPackageDexOptimizer.dumpDexoptState(ipw, pkg);
18990            ipw.decreaseIndent();
18991        }
18992    }
18993
18994    private void dumpCompilerStatsLPr(PrintWriter pw, String packageName) {
18995        final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ", 120);
18996        ipw.println();
18997        ipw.println("Compiler stats:");
18998        ipw.increaseIndent();
18999        Collection<PackageParser.Package> packages = null;
19000        if (packageName != null) {
19001            PackageParser.Package targetPackage = mPackages.get(packageName);
19002            if (targetPackage != null) {
19003                packages = Collections.singletonList(targetPackage);
19004            } else {
19005                ipw.println("Unable to find package: " + packageName);
19006                return;
19007            }
19008        } else {
19009            packages = mPackages.values();
19010        }
19011
19012        for (PackageParser.Package pkg : packages) {
19013            ipw.println("[" + pkg.packageName + "]");
19014            ipw.increaseIndent();
19015
19016            CompilerStats.PackageStats stats = getCompilerPackageStats(pkg.packageName);
19017            if (stats == null) {
19018                ipw.println("(No recorded stats)");
19019            } else {
19020                stats.dump(ipw);
19021            }
19022            ipw.decreaseIndent();
19023        }
19024    }
19025
19026    private String dumpDomainString(String packageName) {
19027        List<IntentFilterVerificationInfo> iviList = getIntentFilterVerifications(packageName)
19028                .getList();
19029        List<IntentFilter> filters = getAllIntentFilters(packageName).getList();
19030
19031        ArraySet<String> result = new ArraySet<>();
19032        if (iviList.size() > 0) {
19033            for (IntentFilterVerificationInfo ivi : iviList) {
19034                for (String host : ivi.getDomains()) {
19035                    result.add(host);
19036                }
19037            }
19038        }
19039        if (filters != null && filters.size() > 0) {
19040            for (IntentFilter filter : filters) {
19041                if (filter.hasCategory(Intent.CATEGORY_BROWSABLE)
19042                        && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) ||
19043                                filter.hasDataScheme(IntentFilter.SCHEME_HTTPS))) {
19044                    result.addAll(filter.getHostsList());
19045                }
19046            }
19047        }
19048
19049        StringBuilder sb = new StringBuilder(result.size() * 16);
19050        for (String domain : result) {
19051            if (sb.length() > 0) sb.append(" ");
19052            sb.append(domain);
19053        }
19054        return sb.toString();
19055    }
19056
19057    // ------- apps on sdcard specific code -------
19058    static final boolean DEBUG_SD_INSTALL = false;
19059
19060    private static final String SD_ENCRYPTION_KEYSTORE_NAME = "AppsOnSD";
19061
19062    private static final String SD_ENCRYPTION_ALGORITHM = "AES";
19063
19064    private boolean mMediaMounted = false;
19065
19066    static String getEncryptKey() {
19067        try {
19068            String sdEncKey = SystemKeyStore.getInstance().retrieveKeyHexString(
19069                    SD_ENCRYPTION_KEYSTORE_NAME);
19070            if (sdEncKey == null) {
19071                sdEncKey = SystemKeyStore.getInstance().generateNewKeyHexString(128,
19072                        SD_ENCRYPTION_ALGORITHM, SD_ENCRYPTION_KEYSTORE_NAME);
19073                if (sdEncKey == null) {
19074                    Slog.e(TAG, "Failed to create encryption keys");
19075                    return null;
19076                }
19077            }
19078            return sdEncKey;
19079        } catch (NoSuchAlgorithmException nsae) {
19080            Slog.e(TAG, "Failed to create encryption keys with exception: " + nsae);
19081            return null;
19082        } catch (IOException ioe) {
19083            Slog.e(TAG, "Failed to retrieve encryption keys with exception: " + ioe);
19084            return null;
19085        }
19086    }
19087
19088    /*
19089     * Update media status on PackageManager.
19090     */
19091    @Override
19092    public void updateExternalMediaStatus(final boolean mediaStatus, final boolean reportStatus) {
19093        int callingUid = Binder.getCallingUid();
19094        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
19095            throw new SecurityException("Media status can only be updated by the system");
19096        }
19097        // reader; this apparently protects mMediaMounted, but should probably
19098        // be a different lock in that case.
19099        synchronized (mPackages) {
19100            Log.i(TAG, "Updating external media status from "
19101                    + (mMediaMounted ? "mounted" : "unmounted") + " to "
19102                    + (mediaStatus ? "mounted" : "unmounted"));
19103            if (DEBUG_SD_INSTALL)
19104                Log.i(TAG, "updateExternalMediaStatus:: mediaStatus=" + mediaStatus
19105                        + ", mMediaMounted=" + mMediaMounted);
19106            if (mediaStatus == mMediaMounted) {
19107                final Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1
19108                        : 0, -1);
19109                mHandler.sendMessage(msg);
19110                return;
19111            }
19112            mMediaMounted = mediaStatus;
19113        }
19114        // Queue up an async operation since the package installation may take a
19115        // little while.
19116        mHandler.post(new Runnable() {
19117            public void run() {
19118                updateExternalMediaStatusInner(mediaStatus, reportStatus, true);
19119            }
19120        });
19121    }
19122
19123    /**
19124     * Called by MountService when the initial ASECs to scan are available.
19125     * Should block until all the ASEC containers are finished being scanned.
19126     */
19127    public void scanAvailableAsecs() {
19128        updateExternalMediaStatusInner(true, false, false);
19129    }
19130
19131    /*
19132     * Collect information of applications on external media, map them against
19133     * existing containers and update information based on current mount status.
19134     * Please note that we always have to report status if reportStatus has been
19135     * set to true especially when unloading packages.
19136     */
19137    private void updateExternalMediaStatusInner(boolean isMounted, boolean reportStatus,
19138            boolean externalStorage) {
19139        ArrayMap<AsecInstallArgs, String> processCids = new ArrayMap<>();
19140        int[] uidArr = EmptyArray.INT;
19141
19142        final String[] list = PackageHelper.getSecureContainerList();
19143        if (ArrayUtils.isEmpty(list)) {
19144            Log.i(TAG, "No secure containers found");
19145        } else {
19146            // Process list of secure containers and categorize them
19147            // as active or stale based on their package internal state.
19148
19149            // reader
19150            synchronized (mPackages) {
19151                for (String cid : list) {
19152                    // Leave stages untouched for now; installer service owns them
19153                    if (PackageInstallerService.isStageName(cid)) continue;
19154
19155                    if (DEBUG_SD_INSTALL)
19156                        Log.i(TAG, "Processing container " + cid);
19157                    String pkgName = getAsecPackageName(cid);
19158                    if (pkgName == null) {
19159                        Slog.i(TAG, "Found stale container " + cid + " with no package name");
19160                        continue;
19161                    }
19162                    if (DEBUG_SD_INSTALL)
19163                        Log.i(TAG, "Looking for pkg : " + pkgName);
19164
19165                    final PackageSetting ps = mSettings.mPackages.get(pkgName);
19166                    if (ps == null) {
19167                        Slog.i(TAG, "Found stale container " + cid + " with no matching settings");
19168                        continue;
19169                    }
19170
19171                    /*
19172                     * Skip packages that are not external if we're unmounting
19173                     * external storage.
19174                     */
19175                    if (externalStorage && !isMounted && !isExternal(ps)) {
19176                        continue;
19177                    }
19178
19179                    final AsecInstallArgs args = new AsecInstallArgs(cid,
19180                            getAppDexInstructionSets(ps), ps.isForwardLocked());
19181                    // The package status is changed only if the code path
19182                    // matches between settings and the container id.
19183                    if (ps.codePathString != null
19184                            && ps.codePathString.startsWith(args.getCodePath())) {
19185                        if (DEBUG_SD_INSTALL) {
19186                            Log.i(TAG, "Container : " + cid + " corresponds to pkg : " + pkgName
19187                                    + " at code path: " + ps.codePathString);
19188                        }
19189
19190                        // We do have a valid package installed on sdcard
19191                        processCids.put(args, ps.codePathString);
19192                        final int uid = ps.appId;
19193                        if (uid != -1) {
19194                            uidArr = ArrayUtils.appendInt(uidArr, uid);
19195                        }
19196                    } else {
19197                        Slog.i(TAG, "Found stale container " + cid + ": expected codePath="
19198                                + ps.codePathString);
19199                    }
19200                }
19201            }
19202
19203            Arrays.sort(uidArr);
19204        }
19205
19206        // Process packages with valid entries.
19207        if (isMounted) {
19208            if (DEBUG_SD_INSTALL)
19209                Log.i(TAG, "Loading packages");
19210            loadMediaPackages(processCids, uidArr, externalStorage);
19211            startCleaningPackages();
19212            mInstallerService.onSecureContainersAvailable();
19213        } else {
19214            if (DEBUG_SD_INSTALL)
19215                Log.i(TAG, "Unloading packages");
19216            unloadMediaPackages(processCids, uidArr, reportStatus);
19217        }
19218    }
19219
19220    private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
19221            ArrayList<ApplicationInfo> infos, IIntentReceiver finishedReceiver) {
19222        final int size = infos.size();
19223        final String[] packageNames = new String[size];
19224        final int[] packageUids = new int[size];
19225        for (int i = 0; i < size; i++) {
19226            final ApplicationInfo info = infos.get(i);
19227            packageNames[i] = info.packageName;
19228            packageUids[i] = info.uid;
19229        }
19230        sendResourcesChangedBroadcast(mediaStatus, replacing, packageNames, packageUids,
19231                finishedReceiver);
19232    }
19233
19234    private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
19235            ArrayList<String> pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
19236        sendResourcesChangedBroadcast(mediaStatus, replacing,
19237                pkgList.toArray(new String[pkgList.size()]), uidArr, finishedReceiver);
19238    }
19239
19240    private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
19241            String[] pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
19242        int size = pkgList.length;
19243        if (size > 0) {
19244            // Send broadcasts here
19245            Bundle extras = new Bundle();
19246            extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
19247            if (uidArr != null) {
19248                extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidArr);
19249            }
19250            if (replacing) {
19251                extras.putBoolean(Intent.EXTRA_REPLACING, replacing);
19252            }
19253            String action = mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE
19254                    : Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE;
19255            sendPackageBroadcast(action, null, extras, 0, null, finishedReceiver, null);
19256        }
19257    }
19258
19259   /*
19260     * Look at potentially valid container ids from processCids If package
19261     * information doesn't match the one on record or package scanning fails,
19262     * the cid is added to list of removeCids. We currently don't delete stale
19263     * containers.
19264     */
19265    private void loadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int[] uidArr,
19266            boolean externalStorage) {
19267        ArrayList<String> pkgList = new ArrayList<String>();
19268        Set<AsecInstallArgs> keys = processCids.keySet();
19269
19270        for (AsecInstallArgs args : keys) {
19271            String codePath = processCids.get(args);
19272            if (DEBUG_SD_INSTALL)
19273                Log.i(TAG, "Loading container : " + args.cid);
19274            int retCode = PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
19275            try {
19276                // Make sure there are no container errors first.
19277                if (args.doPreInstall(PackageManager.INSTALL_SUCCEEDED) != PackageManager.INSTALL_SUCCEEDED) {
19278                    Slog.e(TAG, "Failed to mount cid : " + args.cid
19279                            + " when installing from sdcard");
19280                    continue;
19281                }
19282                // Check code path here.
19283                if (codePath == null || !codePath.startsWith(args.getCodePath())) {
19284                    Slog.e(TAG, "Container " + args.cid + " cachepath " + args.getCodePath()
19285                            + " does not match one in settings " + codePath);
19286                    continue;
19287                }
19288                // Parse package
19289                int parseFlags = mDefParseFlags;
19290                if (args.isExternalAsec()) {
19291                    parseFlags |= PackageParser.PARSE_EXTERNAL_STORAGE;
19292                }
19293                if (args.isFwdLocked()) {
19294                    parseFlags |= PackageParser.PARSE_FORWARD_LOCK;
19295                }
19296
19297                synchronized (mInstallLock) {
19298                    PackageParser.Package pkg = null;
19299                    try {
19300                        // Sadly we don't know the package name yet to freeze it
19301                        pkg = scanPackageTracedLI(new File(codePath), parseFlags,
19302                                SCAN_IGNORE_FROZEN, 0, null);
19303                    } catch (PackageManagerException e) {
19304                        Slog.w(TAG, "Failed to scan " + codePath + ": " + e.getMessage());
19305                    }
19306                    // Scan the package
19307                    if (pkg != null) {
19308                        /*
19309                         * TODO why is the lock being held? doPostInstall is
19310                         * called in other places without the lock. This needs
19311                         * to be straightened out.
19312                         */
19313                        // writer
19314                        synchronized (mPackages) {
19315                            retCode = PackageManager.INSTALL_SUCCEEDED;
19316                            pkgList.add(pkg.packageName);
19317                            // Post process args
19318                            args.doPostInstall(PackageManager.INSTALL_SUCCEEDED,
19319                                    pkg.applicationInfo.uid);
19320                        }
19321                    } else {
19322                        Slog.i(TAG, "Failed to install pkg from  " + codePath + " from sdcard");
19323                    }
19324                }
19325
19326            } finally {
19327                if (retCode != PackageManager.INSTALL_SUCCEEDED) {
19328                    Log.w(TAG, "Container " + args.cid + " is stale, retCode=" + retCode);
19329                }
19330            }
19331        }
19332        // writer
19333        synchronized (mPackages) {
19334            // If the platform SDK has changed since the last time we booted,
19335            // we need to re-grant app permission to catch any new ones that
19336            // appear. This is really a hack, and means that apps can in some
19337            // cases get permissions that the user didn't initially explicitly
19338            // allow... it would be nice to have some better way to handle
19339            // this situation.
19340            final VersionInfo ver = externalStorage ? mSettings.getExternalVersion()
19341                    : mSettings.getInternalVersion();
19342            final String volumeUuid = externalStorage ? StorageManager.UUID_PRIMARY_PHYSICAL
19343                    : StorageManager.UUID_PRIVATE_INTERNAL;
19344
19345            int updateFlags = UPDATE_PERMISSIONS_ALL;
19346            if (ver.sdkVersion != mSdkVersion) {
19347                logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to "
19348                        + mSdkVersion + "; regranting permissions for external");
19349                updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
19350            }
19351            updatePermissionsLPw(null, null, volumeUuid, updateFlags);
19352
19353            // Yay, everything is now upgraded
19354            ver.forceCurrent();
19355
19356            // can downgrade to reader
19357            // Persist settings
19358            mSettings.writeLPr();
19359        }
19360        // Send a broadcast to let everyone know we are done processing
19361        if (pkgList.size() > 0) {
19362            sendResourcesChangedBroadcast(true, false, pkgList, uidArr, null);
19363        }
19364    }
19365
19366   /*
19367     * Utility method to unload a list of specified containers
19368     */
19369    private void unloadAllContainers(Set<AsecInstallArgs> cidArgs) {
19370        // Just unmount all valid containers.
19371        for (AsecInstallArgs arg : cidArgs) {
19372            synchronized (mInstallLock) {
19373                arg.doPostDeleteLI(false);
19374           }
19375       }
19376   }
19377
19378    /*
19379     * Unload packages mounted on external media. This involves deleting package
19380     * data from internal structures, sending broadcasts about disabled packages,
19381     * gc'ing to free up references, unmounting all secure containers
19382     * corresponding to packages on external media, and posting a
19383     * UPDATED_MEDIA_STATUS message if status has been requested. Please note
19384     * that we always have to post this message if status has been requested no
19385     * matter what.
19386     */
19387    private void unloadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int uidArr[],
19388            final boolean reportStatus) {
19389        if (DEBUG_SD_INSTALL)
19390            Log.i(TAG, "unloading media packages");
19391        ArrayList<String> pkgList = new ArrayList<String>();
19392        ArrayList<AsecInstallArgs> failedList = new ArrayList<AsecInstallArgs>();
19393        final Set<AsecInstallArgs> keys = processCids.keySet();
19394        for (AsecInstallArgs args : keys) {
19395            String pkgName = args.getPackageName();
19396            if (DEBUG_SD_INSTALL)
19397                Log.i(TAG, "Trying to unload pkg : " + pkgName);
19398            // Delete package internally
19399            PackageRemovedInfo outInfo = new PackageRemovedInfo();
19400            synchronized (mInstallLock) {
19401                final int deleteFlags = PackageManager.DELETE_KEEP_DATA;
19402                final boolean res;
19403                try (PackageFreezer freezer = freezePackageForDelete(pkgName, deleteFlags,
19404                        "unloadMediaPackages")) {
19405                    res = deletePackageLIF(pkgName, null, false, null, deleteFlags, outInfo, false,
19406                            null);
19407                }
19408                if (res) {
19409                    pkgList.add(pkgName);
19410                } else {
19411                    Slog.e(TAG, "Failed to delete pkg from sdcard : " + pkgName);
19412                    failedList.add(args);
19413                }
19414            }
19415        }
19416
19417        // reader
19418        synchronized (mPackages) {
19419            // We didn't update the settings after removing each package;
19420            // write them now for all packages.
19421            mSettings.writeLPr();
19422        }
19423
19424        // We have to absolutely send UPDATED_MEDIA_STATUS only
19425        // after confirming that all the receivers processed the ordered
19426        // broadcast when packages get disabled, force a gc to clean things up.
19427        // and unload all the containers.
19428        if (pkgList.size() > 0) {
19429            sendResourcesChangedBroadcast(false, false, pkgList, uidArr,
19430                    new IIntentReceiver.Stub() {
19431                public void performReceive(Intent intent, int resultCode, String data,
19432                        Bundle extras, boolean ordered, boolean sticky,
19433                        int sendingUser) throws RemoteException {
19434                    Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS,
19435                            reportStatus ? 1 : 0, 1, keys);
19436                    mHandler.sendMessage(msg);
19437                }
19438            });
19439        } else {
19440            Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1 : 0, -1,
19441                    keys);
19442            mHandler.sendMessage(msg);
19443        }
19444    }
19445
19446    private void loadPrivatePackages(final VolumeInfo vol) {
19447        mHandler.post(new Runnable() {
19448            @Override
19449            public void run() {
19450                loadPrivatePackagesInner(vol);
19451            }
19452        });
19453    }
19454
19455    private void loadPrivatePackagesInner(VolumeInfo vol) {
19456        final String volumeUuid = vol.fsUuid;
19457        if (TextUtils.isEmpty(volumeUuid)) {
19458            Slog.e(TAG, "Loading internal storage is probably a mistake; ignoring");
19459            return;
19460        }
19461
19462        final ArrayList<PackageFreezer> freezers = new ArrayList<>();
19463        final ArrayList<ApplicationInfo> loaded = new ArrayList<>();
19464        final int parseFlags = mDefParseFlags | PackageParser.PARSE_EXTERNAL_STORAGE;
19465
19466        final VersionInfo ver;
19467        final List<PackageSetting> packages;
19468        synchronized (mPackages) {
19469            ver = mSettings.findOrCreateVersion(volumeUuid);
19470            packages = mSettings.getVolumePackagesLPr(volumeUuid);
19471        }
19472
19473        for (PackageSetting ps : packages) {
19474            freezers.add(freezePackage(ps.name, "loadPrivatePackagesInner"));
19475            synchronized (mInstallLock) {
19476                final PackageParser.Package pkg;
19477                try {
19478                    pkg = scanPackageTracedLI(ps.codePath, parseFlags, SCAN_INITIAL, 0, null);
19479                    loaded.add(pkg.applicationInfo);
19480
19481                } catch (PackageManagerException e) {
19482                    Slog.w(TAG, "Failed to scan " + ps.codePath + ": " + e.getMessage());
19483                }
19484
19485                if (!Build.FINGERPRINT.equals(ver.fingerprint)) {
19486                    clearAppDataLIF(ps.pkg, UserHandle.USER_ALL,
19487                            StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE
19488                                    | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
19489                }
19490            }
19491        }
19492
19493        // Reconcile app data for all started/unlocked users
19494        final StorageManager sm = mContext.getSystemService(StorageManager.class);
19495        final UserManager um = mContext.getSystemService(UserManager.class);
19496        UserManagerInternal umInternal = getUserManagerInternal();
19497        for (UserInfo user : um.getUsers()) {
19498            final int flags;
19499            if (umInternal.isUserUnlockingOrUnlocked(user.id)) {
19500                flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
19501            } else if (umInternal.isUserRunning(user.id)) {
19502                flags = StorageManager.FLAG_STORAGE_DE;
19503            } else {
19504                continue;
19505            }
19506
19507            try {
19508                sm.prepareUserStorage(volumeUuid, user.id, user.serialNumber, flags);
19509                synchronized (mInstallLock) {
19510                    reconcileAppsDataLI(volumeUuid, user.id, flags);
19511                }
19512            } catch (IllegalStateException e) {
19513                // Device was probably ejected, and we'll process that event momentarily
19514                Slog.w(TAG, "Failed to prepare storage: " + e);
19515            }
19516        }
19517
19518        synchronized (mPackages) {
19519            int updateFlags = UPDATE_PERMISSIONS_ALL;
19520            if (ver.sdkVersion != mSdkVersion) {
19521                logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to "
19522                        + mSdkVersion + "; regranting permissions for " + volumeUuid);
19523                updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
19524            }
19525            updatePermissionsLPw(null, null, volumeUuid, updateFlags);
19526
19527            // Yay, everything is now upgraded
19528            ver.forceCurrent();
19529
19530            mSettings.writeLPr();
19531        }
19532
19533        for (PackageFreezer freezer : freezers) {
19534            freezer.close();
19535        }
19536
19537        if (DEBUG_INSTALL) Slog.d(TAG, "Loaded packages " + loaded);
19538        sendResourcesChangedBroadcast(true, false, loaded, null);
19539    }
19540
19541    private void unloadPrivatePackages(final VolumeInfo vol) {
19542        mHandler.post(new Runnable() {
19543            @Override
19544            public void run() {
19545                unloadPrivatePackagesInner(vol);
19546            }
19547        });
19548    }
19549
19550    private void unloadPrivatePackagesInner(VolumeInfo vol) {
19551        final String volumeUuid = vol.fsUuid;
19552        if (TextUtils.isEmpty(volumeUuid)) {
19553            Slog.e(TAG, "Unloading internal storage is probably a mistake; ignoring");
19554            return;
19555        }
19556
19557        final ArrayList<ApplicationInfo> unloaded = new ArrayList<>();
19558        synchronized (mInstallLock) {
19559        synchronized (mPackages) {
19560            final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(volumeUuid);
19561            for (PackageSetting ps : packages) {
19562                if (ps.pkg == null) continue;
19563
19564                final ApplicationInfo info = ps.pkg.applicationInfo;
19565                final int deleteFlags = PackageManager.DELETE_KEEP_DATA;
19566                final PackageRemovedInfo outInfo = new PackageRemovedInfo();
19567
19568                try (PackageFreezer freezer = freezePackageForDelete(ps.name, deleteFlags,
19569                        "unloadPrivatePackagesInner")) {
19570                    if (deletePackageLIF(ps.name, null, false, null, deleteFlags, outInfo,
19571                            false, null)) {
19572                        unloaded.add(info);
19573                    } else {
19574                        Slog.w(TAG, "Failed to unload " + ps.codePath);
19575                    }
19576                }
19577
19578                // Try very hard to release any references to this package
19579                // so we don't risk the system server being killed due to
19580                // open FDs
19581                AttributeCache.instance().removePackage(ps.name);
19582            }
19583
19584            mSettings.writeLPr();
19585        }
19586        }
19587
19588        if (DEBUG_INSTALL) Slog.d(TAG, "Unloaded packages " + unloaded);
19589        sendResourcesChangedBroadcast(false, false, unloaded, null);
19590
19591        // Try very hard to release any references to this path so we don't risk
19592        // the system server being killed due to open FDs
19593        ResourcesManager.getInstance().invalidatePath(vol.getPath().getAbsolutePath());
19594
19595        for (int i = 0; i < 3; i++) {
19596            System.gc();
19597            System.runFinalization();
19598        }
19599    }
19600
19601    /**
19602     * Prepare storage areas for given user on all mounted devices.
19603     */
19604    void prepareUserData(int userId, int userSerial, int flags) {
19605        synchronized (mInstallLock) {
19606            final StorageManager storage = mContext.getSystemService(StorageManager.class);
19607            for (VolumeInfo vol : storage.getWritablePrivateVolumes()) {
19608                final String volumeUuid = vol.getFsUuid();
19609                prepareUserDataLI(volumeUuid, userId, userSerial, flags, true);
19610            }
19611        }
19612    }
19613
19614    private void prepareUserDataLI(String volumeUuid, int userId, int userSerial, int flags,
19615            boolean allowRecover) {
19616        // Prepare storage and verify that serial numbers are consistent; if
19617        // there's a mismatch we need to destroy to avoid leaking data
19618        final StorageManager storage = mContext.getSystemService(StorageManager.class);
19619        try {
19620            storage.prepareUserStorage(volumeUuid, userId, userSerial, flags);
19621
19622            if ((flags & StorageManager.FLAG_STORAGE_DE) != 0 && !mOnlyCore) {
19623                UserManagerService.enforceSerialNumber(
19624                        Environment.getDataUserDeDirectory(volumeUuid, userId), userSerial);
19625                if (Objects.equals(volumeUuid, StorageManager.UUID_PRIVATE_INTERNAL)) {
19626                    UserManagerService.enforceSerialNumber(
19627                            Environment.getDataSystemDeDirectory(userId), userSerial);
19628                }
19629            }
19630            if ((flags & StorageManager.FLAG_STORAGE_CE) != 0 && !mOnlyCore) {
19631                UserManagerService.enforceSerialNumber(
19632                        Environment.getDataUserCeDirectory(volumeUuid, userId), userSerial);
19633                if (Objects.equals(volumeUuid, StorageManager.UUID_PRIVATE_INTERNAL)) {
19634                    UserManagerService.enforceSerialNumber(
19635                            Environment.getDataSystemCeDirectory(userId), userSerial);
19636                }
19637            }
19638
19639            synchronized (mInstallLock) {
19640                mInstaller.createUserData(volumeUuid, userId, userSerial, flags);
19641            }
19642        } catch (Exception e) {
19643            logCriticalInfo(Log.WARN, "Destroying user " + userId + " on volume " + volumeUuid
19644                    + " because we failed to prepare: " + e);
19645            destroyUserDataLI(volumeUuid, userId,
19646                    StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
19647
19648            if (allowRecover) {
19649                // Try one last time; if we fail again we're really in trouble
19650                prepareUserDataLI(volumeUuid, userId, userSerial, flags, false);
19651            }
19652        }
19653    }
19654
19655    /**
19656     * Destroy storage areas for given user on all mounted devices.
19657     */
19658    void destroyUserData(int userId, int flags) {
19659        synchronized (mInstallLock) {
19660            final StorageManager storage = mContext.getSystemService(StorageManager.class);
19661            for (VolumeInfo vol : storage.getWritablePrivateVolumes()) {
19662                final String volumeUuid = vol.getFsUuid();
19663                destroyUserDataLI(volumeUuid, userId, flags);
19664            }
19665        }
19666    }
19667
19668    private void destroyUserDataLI(String volumeUuid, int userId, int flags) {
19669        final StorageManager storage = mContext.getSystemService(StorageManager.class);
19670        try {
19671            // Clean up app data, profile data, and media data
19672            mInstaller.destroyUserData(volumeUuid, userId, flags);
19673
19674            // Clean up system data
19675            if (Objects.equals(volumeUuid, StorageManager.UUID_PRIVATE_INTERNAL)) {
19676                if ((flags & StorageManager.FLAG_STORAGE_DE) != 0) {
19677                    FileUtils.deleteContentsAndDir(Environment.getUserSystemDirectory(userId));
19678                    FileUtils.deleteContentsAndDir(Environment.getDataSystemDeDirectory(userId));
19679                }
19680                if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
19681                    FileUtils.deleteContentsAndDir(Environment.getDataSystemCeDirectory(userId));
19682                }
19683            }
19684
19685            // Data with special labels is now gone, so finish the job
19686            storage.destroyUserStorage(volumeUuid, userId, flags);
19687
19688        } catch (Exception e) {
19689            logCriticalInfo(Log.WARN,
19690                    "Failed to destroy user " + userId + " on volume " + volumeUuid + ": " + e);
19691        }
19692    }
19693
19694    /**
19695     * Examine all users present on given mounted volume, and destroy data
19696     * belonging to users that are no longer valid, or whose user ID has been
19697     * recycled.
19698     */
19699    private void reconcileUsers(String volumeUuid) {
19700        final List<File> files = new ArrayList<>();
19701        Collections.addAll(files, FileUtils
19702                .listFilesOrEmpty(Environment.getDataUserDeDirectory(volumeUuid)));
19703        Collections.addAll(files, FileUtils
19704                .listFilesOrEmpty(Environment.getDataUserCeDirectory(volumeUuid)));
19705        Collections.addAll(files, FileUtils
19706                .listFilesOrEmpty(Environment.getDataSystemDeDirectory()));
19707        Collections.addAll(files, FileUtils
19708                .listFilesOrEmpty(Environment.getDataSystemCeDirectory()));
19709        for (File file : files) {
19710            if (!file.isDirectory()) continue;
19711
19712            final int userId;
19713            final UserInfo info;
19714            try {
19715                userId = Integer.parseInt(file.getName());
19716                info = sUserManager.getUserInfo(userId);
19717            } catch (NumberFormatException e) {
19718                Slog.w(TAG, "Invalid user directory " + file);
19719                continue;
19720            }
19721
19722            boolean destroyUser = false;
19723            if (info == null) {
19724                logCriticalInfo(Log.WARN, "Destroying user directory " + file
19725                        + " because no matching user was found");
19726                destroyUser = true;
19727            } else if (!mOnlyCore) {
19728                try {
19729                    UserManagerService.enforceSerialNumber(file, info.serialNumber);
19730                } catch (IOException e) {
19731                    logCriticalInfo(Log.WARN, "Destroying user directory " + file
19732                            + " because we failed to enforce serial number: " + e);
19733                    destroyUser = true;
19734                }
19735            }
19736
19737            if (destroyUser) {
19738                synchronized (mInstallLock) {
19739                    destroyUserDataLI(volumeUuid, userId,
19740                            StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
19741                }
19742            }
19743        }
19744    }
19745
19746    private void assertPackageKnown(String volumeUuid, String packageName)
19747            throws PackageManagerException {
19748        synchronized (mPackages) {
19749            // Normalize package name to handle renamed packages
19750            packageName = normalizePackageNameLPr(packageName);
19751
19752            final PackageSetting ps = mSettings.mPackages.get(packageName);
19753            if (ps == null) {
19754                throw new PackageManagerException("Package " + packageName + " is unknown");
19755            } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) {
19756                throw new PackageManagerException(
19757                        "Package " + packageName + " found on unknown volume " + volumeUuid
19758                                + "; expected volume " + ps.volumeUuid);
19759            }
19760        }
19761    }
19762
19763    private void assertPackageKnownAndInstalled(String volumeUuid, String packageName, int userId)
19764            throws PackageManagerException {
19765        synchronized (mPackages) {
19766            // Normalize package name to handle renamed packages
19767            packageName = normalizePackageNameLPr(packageName);
19768
19769            final PackageSetting ps = mSettings.mPackages.get(packageName);
19770            if (ps == null) {
19771                throw new PackageManagerException("Package " + packageName + " is unknown");
19772            } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) {
19773                throw new PackageManagerException(
19774                        "Package " + packageName + " found on unknown volume " + volumeUuid
19775                                + "; expected volume " + ps.volumeUuid);
19776            } else if (!ps.getInstalled(userId)) {
19777                throw new PackageManagerException(
19778                        "Package " + packageName + " not installed for user " + userId);
19779            }
19780        }
19781    }
19782
19783    /**
19784     * Examine all apps present on given mounted volume, and destroy apps that
19785     * aren't expected, either due to uninstallation or reinstallation on
19786     * another volume.
19787     */
19788    private void reconcileApps(String volumeUuid) {
19789        final File[] files = FileUtils
19790                .listFilesOrEmpty(Environment.getDataAppDirectory(volumeUuid));
19791        for (File file : files) {
19792            final boolean isPackage = (isApkFile(file) || file.isDirectory())
19793                    && !PackageInstallerService.isStageName(file.getName());
19794            if (!isPackage) {
19795                // Ignore entries which are not packages
19796                continue;
19797            }
19798
19799            try {
19800                final PackageLite pkg = PackageParser.parsePackageLite(file,
19801                        PackageParser.PARSE_MUST_BE_APK);
19802                assertPackageKnown(volumeUuid, pkg.packageName);
19803
19804            } catch (PackageParserException | PackageManagerException e) {
19805                logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e);
19806                synchronized (mInstallLock) {
19807                    removeCodePathLI(file);
19808                }
19809            }
19810        }
19811    }
19812
19813    /**
19814     * Reconcile all app data for the given user.
19815     * <p>
19816     * Verifies that directories exist and that ownership and labeling is
19817     * correct for all installed apps on all mounted volumes.
19818     */
19819    void reconcileAppsData(int userId, int flags) {
19820        final StorageManager storage = mContext.getSystemService(StorageManager.class);
19821        for (VolumeInfo vol : storage.getWritablePrivateVolumes()) {
19822            final String volumeUuid = vol.getFsUuid();
19823            synchronized (mInstallLock) {
19824                reconcileAppsDataLI(volumeUuid, userId, flags);
19825            }
19826        }
19827    }
19828
19829    /**
19830     * Reconcile all app data on given mounted volume.
19831     * <p>
19832     * Destroys app data that isn't expected, either due to uninstallation or
19833     * reinstallation on another volume.
19834     * <p>
19835     * Verifies that directories exist and that ownership and labeling is
19836     * correct for all installed apps.
19837     */
19838    private void reconcileAppsDataLI(String volumeUuid, int userId, int flags) {
19839        Slog.v(TAG, "reconcileAppsData for " + volumeUuid + " u" + userId + " 0x"
19840                + Integer.toHexString(flags));
19841
19842        final File ceDir = Environment.getDataUserCeDirectory(volumeUuid, userId);
19843        final File deDir = Environment.getDataUserDeDirectory(volumeUuid, userId);
19844
19845        // First look for stale data that doesn't belong, and check if things
19846        // have changed since we did our last restorecon
19847        if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
19848            if (StorageManager.isFileEncryptedNativeOrEmulated()
19849                    && !StorageManager.isUserKeyUnlocked(userId)) {
19850                throw new RuntimeException(
19851                        "Yikes, someone asked us to reconcile CE storage while " + userId
19852                                + " was still locked; this would have caused massive data loss!");
19853            }
19854
19855            final File[] files = FileUtils.listFilesOrEmpty(ceDir);
19856            for (File file : files) {
19857                final String packageName = file.getName();
19858                try {
19859                    assertPackageKnownAndInstalled(volumeUuid, packageName, userId);
19860                } catch (PackageManagerException e) {
19861                    logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e);
19862                    try {
19863                        mInstaller.destroyAppData(volumeUuid, packageName, userId,
19864                                StorageManager.FLAG_STORAGE_CE, 0);
19865                    } catch (InstallerException e2) {
19866                        logCriticalInfo(Log.WARN, "Failed to destroy: " + e2);
19867                    }
19868                }
19869            }
19870        }
19871        if ((flags & StorageManager.FLAG_STORAGE_DE) != 0) {
19872            final File[] files = FileUtils.listFilesOrEmpty(deDir);
19873            for (File file : files) {
19874                final String packageName = file.getName();
19875                try {
19876                    assertPackageKnownAndInstalled(volumeUuid, packageName, userId);
19877                } catch (PackageManagerException e) {
19878                    logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e);
19879                    try {
19880                        mInstaller.destroyAppData(volumeUuid, packageName, userId,
19881                                StorageManager.FLAG_STORAGE_DE, 0);
19882                    } catch (InstallerException e2) {
19883                        logCriticalInfo(Log.WARN, "Failed to destroy: " + e2);
19884                    }
19885                }
19886            }
19887        }
19888
19889        // Ensure that data directories are ready to roll for all packages
19890        // installed for this volume and user
19891        final List<PackageSetting> packages;
19892        synchronized (mPackages) {
19893            packages = mSettings.getVolumePackagesLPr(volumeUuid);
19894        }
19895        int preparedCount = 0;
19896        for (PackageSetting ps : packages) {
19897            final String packageName = ps.name;
19898            if (ps.pkg == null) {
19899                Slog.w(TAG, "Odd, missing scanned package " + packageName);
19900                // TODO: might be due to legacy ASEC apps; we should circle back
19901                // and reconcile again once they're scanned
19902                continue;
19903            }
19904
19905            if (ps.getInstalled(userId)) {
19906                prepareAppDataLIF(ps.pkg, userId, flags);
19907
19908                if (maybeMigrateAppDataLIF(ps.pkg, userId)) {
19909                    // We may have just shuffled around app data directories, so
19910                    // prepare them one more time
19911                    prepareAppDataLIF(ps.pkg, userId, flags);
19912                }
19913
19914                preparedCount++;
19915            }
19916        }
19917
19918        Slog.v(TAG, "reconcileAppsData finished " + preparedCount + " packages");
19919    }
19920
19921    /**
19922     * Prepare app data for the given app just after it was installed or
19923     * upgraded. This method carefully only touches users that it's installed
19924     * for, and it forces a restorecon to handle any seinfo changes.
19925     * <p>
19926     * Verifies that directories exist and that ownership and labeling is
19927     * correct for all installed apps. If there is an ownership mismatch, it
19928     * will try recovering system apps by wiping data; third-party app data is
19929     * left intact.
19930     * <p>
19931     * <em>Note: To avoid a deadlock, do not call this method with {@code mPackages} lock held</em>
19932     */
19933    private void prepareAppDataAfterInstallLIF(PackageParser.Package pkg) {
19934        final PackageSetting ps;
19935        synchronized (mPackages) {
19936            ps = mSettings.mPackages.get(pkg.packageName);
19937            mSettings.writeKernelMappingLPr(ps);
19938        }
19939
19940        final UserManager um = mContext.getSystemService(UserManager.class);
19941        UserManagerInternal umInternal = getUserManagerInternal();
19942        for (UserInfo user : um.getUsers()) {
19943            final int flags;
19944            if (umInternal.isUserUnlockingOrUnlocked(user.id)) {
19945                flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
19946            } else if (umInternal.isUserRunning(user.id)) {
19947                flags = StorageManager.FLAG_STORAGE_DE;
19948            } else {
19949                continue;
19950            }
19951
19952            if (ps.getInstalled(user.id)) {
19953                // TODO: when user data is locked, mark that we're still dirty
19954                prepareAppDataLIF(pkg, user.id, flags);
19955            }
19956        }
19957    }
19958
19959    /**
19960     * Prepare app data for the given app.
19961     * <p>
19962     * Verifies that directories exist and that ownership and labeling is
19963     * correct for all installed apps. If there is an ownership mismatch, this
19964     * will try recovering system apps by wiping data; third-party app data is
19965     * left intact.
19966     */
19967    private void prepareAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
19968        if (pkg == null) {
19969            Slog.wtf(TAG, "Package was null!", new Throwable());
19970            return;
19971        }
19972        prepareAppDataLeafLIF(pkg, userId, flags);
19973        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
19974        for (int i = 0; i < childCount; i++) {
19975            prepareAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
19976        }
19977    }
19978
19979    private void prepareAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
19980        if (DEBUG_APP_DATA) {
19981            Slog.v(TAG, "prepareAppData for " + pkg.packageName + " u" + userId + " 0x"
19982                    + Integer.toHexString(flags));
19983        }
19984
19985        final String volumeUuid = pkg.volumeUuid;
19986        final String packageName = pkg.packageName;
19987        final ApplicationInfo app = pkg.applicationInfo;
19988        final int appId = UserHandle.getAppId(app.uid);
19989
19990        Preconditions.checkNotNull(app.seinfo);
19991
19992        long ceDataInode = -1;
19993        try {
19994            ceDataInode = mInstaller.createAppData(volumeUuid, packageName, userId, flags,
19995                    appId, app.seinfo, app.targetSdkVersion);
19996        } catch (InstallerException e) {
19997            if (app.isSystemApp()) {
19998                logCriticalInfo(Log.ERROR, "Failed to create app data for " + packageName
19999                        + ", but trying to recover: " + e);
20000                destroyAppDataLeafLIF(pkg, userId, flags);
20001                try {
20002                    ceDataInode = mInstaller.createAppData(volumeUuid, packageName, userId, flags,
20003                            appId, app.seinfo, app.targetSdkVersion);
20004                    logCriticalInfo(Log.DEBUG, "Recovery succeeded!");
20005                } catch (InstallerException e2) {
20006                    logCriticalInfo(Log.DEBUG, "Recovery failed!");
20007                }
20008            } else {
20009                Slog.e(TAG, "Failed to create app data for " + packageName + ": " + e);
20010            }
20011        }
20012
20013        if ((flags & StorageManager.FLAG_STORAGE_CE) != 0 && ceDataInode != -1) {
20014            // TODO: mark this structure as dirty so we persist it!
20015            synchronized (mPackages) {
20016                final PackageSetting ps = mSettings.mPackages.get(packageName);
20017                if (ps != null) {
20018                    ps.setCeDataInode(ceDataInode, userId);
20019                }
20020            }
20021        }
20022
20023        prepareAppDataContentsLeafLIF(pkg, userId, flags);
20024    }
20025
20026    private void prepareAppDataContentsLIF(PackageParser.Package pkg, int userId, int flags) {
20027        if (pkg == null) {
20028            Slog.wtf(TAG, "Package was null!", new Throwable());
20029            return;
20030        }
20031        prepareAppDataContentsLeafLIF(pkg, userId, flags);
20032        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
20033        for (int i = 0; i < childCount; i++) {
20034            prepareAppDataContentsLeafLIF(pkg.childPackages.get(i), userId, flags);
20035        }
20036    }
20037
20038    private void prepareAppDataContentsLeafLIF(PackageParser.Package pkg, int userId, int flags) {
20039        final String volumeUuid = pkg.volumeUuid;
20040        final String packageName = pkg.packageName;
20041        final ApplicationInfo app = pkg.applicationInfo;
20042
20043        if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
20044            // Create a native library symlink only if we have native libraries
20045            // and if the native libraries are 32 bit libraries. We do not provide
20046            // this symlink for 64 bit libraries.
20047            if (app.primaryCpuAbi != null && !VMRuntime.is64BitAbi(app.primaryCpuAbi)) {
20048                final String nativeLibPath = app.nativeLibraryDir;
20049                try {
20050                    mInstaller.linkNativeLibraryDirectory(volumeUuid, packageName,
20051                            nativeLibPath, userId);
20052                } catch (InstallerException e) {
20053                    Slog.e(TAG, "Failed to link native for " + packageName + ": " + e);
20054                }
20055            }
20056        }
20057    }
20058
20059    /**
20060     * For system apps on non-FBE devices, this method migrates any existing
20061     * CE/DE data to match the {@code defaultToDeviceProtectedStorage} flag
20062     * requested by the app.
20063     */
20064    private boolean maybeMigrateAppDataLIF(PackageParser.Package pkg, int userId) {
20065        if (pkg.isSystemApp() && !StorageManager.isFileEncryptedNativeOrEmulated()
20066                && PackageManager.APPLY_DEFAULT_TO_DEVICE_PROTECTED_STORAGE) {
20067            final int storageTarget = pkg.applicationInfo.isDefaultToDeviceProtectedStorage()
20068                    ? StorageManager.FLAG_STORAGE_DE : StorageManager.FLAG_STORAGE_CE;
20069            try {
20070                mInstaller.migrateAppData(pkg.volumeUuid, pkg.packageName, userId,
20071                        storageTarget);
20072            } catch (InstallerException e) {
20073                logCriticalInfo(Log.WARN,
20074                        "Failed to migrate " + pkg.packageName + ": " + e.getMessage());
20075            }
20076            return true;
20077        } else {
20078            return false;
20079        }
20080    }
20081
20082    public PackageFreezer freezePackage(String packageName, String killReason) {
20083        return freezePackage(packageName, UserHandle.USER_ALL, killReason);
20084    }
20085
20086    public PackageFreezer freezePackage(String packageName, int userId, String killReason) {
20087        return new PackageFreezer(packageName, userId, killReason);
20088    }
20089
20090    public PackageFreezer freezePackageForInstall(String packageName, int installFlags,
20091            String killReason) {
20092        return freezePackageForInstall(packageName, UserHandle.USER_ALL, installFlags, killReason);
20093    }
20094
20095    public PackageFreezer freezePackageForInstall(String packageName, int userId, int installFlags,
20096            String killReason) {
20097        if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) {
20098            return new PackageFreezer();
20099        } else {
20100            return freezePackage(packageName, userId, killReason);
20101        }
20102    }
20103
20104    public PackageFreezer freezePackageForDelete(String packageName, int deleteFlags,
20105            String killReason) {
20106        return freezePackageForDelete(packageName, UserHandle.USER_ALL, deleteFlags, killReason);
20107    }
20108
20109    public PackageFreezer freezePackageForDelete(String packageName, int userId, int deleteFlags,
20110            String killReason) {
20111        if ((deleteFlags & PackageManager.DELETE_DONT_KILL_APP) != 0) {
20112            return new PackageFreezer();
20113        } else {
20114            return freezePackage(packageName, userId, killReason);
20115        }
20116    }
20117
20118    /**
20119     * Class that freezes and kills the given package upon creation, and
20120     * unfreezes it upon closing. This is typically used when doing surgery on
20121     * app code/data to prevent the app from running while you're working.
20122     */
20123    private class PackageFreezer implements AutoCloseable {
20124        private final String mPackageName;
20125        private final PackageFreezer[] mChildren;
20126
20127        private final boolean mWeFroze;
20128
20129        private final AtomicBoolean mClosed = new AtomicBoolean();
20130        private final CloseGuard mCloseGuard = CloseGuard.get();
20131
20132        /**
20133         * Create and return a stub freezer that doesn't actually do anything,
20134         * typically used when someone requested
20135         * {@link PackageManager#INSTALL_DONT_KILL_APP} or
20136         * {@link PackageManager#DELETE_DONT_KILL_APP}.
20137         */
20138        public PackageFreezer() {
20139            mPackageName = null;
20140            mChildren = null;
20141            mWeFroze = false;
20142            mCloseGuard.open("close");
20143        }
20144
20145        public PackageFreezer(String packageName, int userId, String killReason) {
20146            synchronized (mPackages) {
20147                mPackageName = packageName;
20148                mWeFroze = mFrozenPackages.add(mPackageName);
20149
20150                final PackageSetting ps = mSettings.mPackages.get(mPackageName);
20151                if (ps != null) {
20152                    killApplication(ps.name, ps.appId, userId, killReason);
20153                }
20154
20155                final PackageParser.Package p = mPackages.get(packageName);
20156                if (p != null && p.childPackages != null) {
20157                    final int N = p.childPackages.size();
20158                    mChildren = new PackageFreezer[N];
20159                    for (int i = 0; i < N; i++) {
20160                        mChildren[i] = new PackageFreezer(p.childPackages.get(i).packageName,
20161                                userId, killReason);
20162                    }
20163                } else {
20164                    mChildren = null;
20165                }
20166            }
20167            mCloseGuard.open("close");
20168        }
20169
20170        @Override
20171        protected void finalize() throws Throwable {
20172            try {
20173                mCloseGuard.warnIfOpen();
20174                close();
20175            } finally {
20176                super.finalize();
20177            }
20178        }
20179
20180        @Override
20181        public void close() {
20182            mCloseGuard.close();
20183            if (mClosed.compareAndSet(false, true)) {
20184                synchronized (mPackages) {
20185                    if (mWeFroze) {
20186                        mFrozenPackages.remove(mPackageName);
20187                    }
20188
20189                    if (mChildren != null) {
20190                        for (PackageFreezer freezer : mChildren) {
20191                            freezer.close();
20192                        }
20193                    }
20194                }
20195            }
20196        }
20197    }
20198
20199    /**
20200     * Verify that given package is currently frozen.
20201     */
20202    private void checkPackageFrozen(String packageName) {
20203        synchronized (mPackages) {
20204            if (!mFrozenPackages.contains(packageName)) {
20205                Slog.wtf(TAG, "Expected " + packageName + " to be frozen!", new Throwable());
20206            }
20207        }
20208    }
20209
20210    @Override
20211    public int movePackage(final String packageName, final String volumeUuid) {
20212        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
20213
20214        final UserHandle user = new UserHandle(UserHandle.getCallingUserId());
20215        final int moveId = mNextMoveId.getAndIncrement();
20216        mHandler.post(new Runnable() {
20217            @Override
20218            public void run() {
20219                try {
20220                    movePackageInternal(packageName, volumeUuid, moveId, user);
20221                } catch (PackageManagerException e) {
20222                    Slog.w(TAG, "Failed to move " + packageName, e);
20223                    mMoveCallbacks.notifyStatusChanged(moveId,
20224                            PackageManager.MOVE_FAILED_INTERNAL_ERROR);
20225                }
20226            }
20227        });
20228        return moveId;
20229    }
20230
20231    private void movePackageInternal(final String packageName, final String volumeUuid,
20232            final int moveId, UserHandle user) throws PackageManagerException {
20233        final StorageManager storage = mContext.getSystemService(StorageManager.class);
20234        final PackageManager pm = mContext.getPackageManager();
20235
20236        final boolean currentAsec;
20237        final String currentVolumeUuid;
20238        final File codeFile;
20239        final String installerPackageName;
20240        final String packageAbiOverride;
20241        final int appId;
20242        final String seinfo;
20243        final String label;
20244        final int targetSdkVersion;
20245        final PackageFreezer freezer;
20246        final int[] installedUserIds;
20247
20248        // reader
20249        synchronized (mPackages) {
20250            final PackageParser.Package pkg = mPackages.get(packageName);
20251            final PackageSetting ps = mSettings.mPackages.get(packageName);
20252            if (pkg == null || ps == null) {
20253                throw new PackageManagerException(MOVE_FAILED_DOESNT_EXIST, "Missing package");
20254            }
20255
20256            if (pkg.applicationInfo.isSystemApp()) {
20257                throw new PackageManagerException(MOVE_FAILED_SYSTEM_PACKAGE,
20258                        "Cannot move system application");
20259            }
20260
20261            if (pkg.applicationInfo.isExternalAsec()) {
20262                currentAsec = true;
20263                currentVolumeUuid = StorageManager.UUID_PRIMARY_PHYSICAL;
20264            } else if (pkg.applicationInfo.isForwardLocked()) {
20265                currentAsec = true;
20266                currentVolumeUuid = "forward_locked";
20267            } else {
20268                currentAsec = false;
20269                currentVolumeUuid = ps.volumeUuid;
20270
20271                final File probe = new File(pkg.codePath);
20272                final File probeOat = new File(probe, "oat");
20273                if (!probe.isDirectory() || !probeOat.isDirectory()) {
20274                    throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
20275                            "Move only supported for modern cluster style installs");
20276                }
20277            }
20278
20279            if (Objects.equals(currentVolumeUuid, volumeUuid)) {
20280                throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
20281                        "Package already moved to " + volumeUuid);
20282            }
20283            if (pkg.applicationInfo.isInternal() && isPackageDeviceAdminOnAnyUser(packageName)) {
20284                throw new PackageManagerException(MOVE_FAILED_DEVICE_ADMIN,
20285                        "Device admin cannot be moved");
20286            }
20287
20288            if (mFrozenPackages.contains(packageName)) {
20289                throw new PackageManagerException(MOVE_FAILED_OPERATION_PENDING,
20290                        "Failed to move already frozen package");
20291            }
20292
20293            codeFile = new File(pkg.codePath);
20294            installerPackageName = ps.installerPackageName;
20295            packageAbiOverride = ps.cpuAbiOverrideString;
20296            appId = UserHandle.getAppId(pkg.applicationInfo.uid);
20297            seinfo = pkg.applicationInfo.seinfo;
20298            label = String.valueOf(pm.getApplicationLabel(pkg.applicationInfo));
20299            targetSdkVersion = pkg.applicationInfo.targetSdkVersion;
20300            freezer = freezePackage(packageName, "movePackageInternal");
20301            installedUserIds = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
20302        }
20303
20304        final Bundle extras = new Bundle();
20305        extras.putString(Intent.EXTRA_PACKAGE_NAME, packageName);
20306        extras.putString(Intent.EXTRA_TITLE, label);
20307        mMoveCallbacks.notifyCreated(moveId, extras);
20308
20309        int installFlags;
20310        final boolean moveCompleteApp;
20311        final File measurePath;
20312
20313        if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, volumeUuid)) {
20314            installFlags = INSTALL_INTERNAL;
20315            moveCompleteApp = !currentAsec;
20316            measurePath = Environment.getDataAppDirectory(volumeUuid);
20317        } else if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, volumeUuid)) {
20318            installFlags = INSTALL_EXTERNAL;
20319            moveCompleteApp = false;
20320            measurePath = storage.getPrimaryPhysicalVolume().getPath();
20321        } else {
20322            final VolumeInfo volume = storage.findVolumeByUuid(volumeUuid);
20323            if (volume == null || volume.getType() != VolumeInfo.TYPE_PRIVATE
20324                    || !volume.isMountedWritable()) {
20325                freezer.close();
20326                throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
20327                        "Move location not mounted private volume");
20328            }
20329
20330            Preconditions.checkState(!currentAsec);
20331
20332            installFlags = INSTALL_INTERNAL;
20333            moveCompleteApp = true;
20334            measurePath = Environment.getDataAppDirectory(volumeUuid);
20335        }
20336
20337        final PackageStats stats = new PackageStats(null, -1);
20338        synchronized (mInstaller) {
20339            for (int userId : installedUserIds) {
20340                if (!getPackageSizeInfoLI(packageName, userId, stats)) {
20341                    freezer.close();
20342                    throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
20343                            "Failed to measure package size");
20344                }
20345            }
20346        }
20347
20348        if (DEBUG_INSTALL) Slog.d(TAG, "Measured code size " + stats.codeSize + ", data size "
20349                + stats.dataSize);
20350
20351        final long startFreeBytes = measurePath.getFreeSpace();
20352        final long sizeBytes;
20353        if (moveCompleteApp) {
20354            sizeBytes = stats.codeSize + stats.dataSize;
20355        } else {
20356            sizeBytes = stats.codeSize;
20357        }
20358
20359        if (sizeBytes > storage.getStorageBytesUntilLow(measurePath)) {
20360            freezer.close();
20361            throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
20362                    "Not enough free space to move");
20363        }
20364
20365        mMoveCallbacks.notifyStatusChanged(moveId, 10);
20366
20367        final CountDownLatch installedLatch = new CountDownLatch(1);
20368        final IPackageInstallObserver2 installObserver = new IPackageInstallObserver2.Stub() {
20369            @Override
20370            public void onUserActionRequired(Intent intent) throws RemoteException {
20371                throw new IllegalStateException();
20372            }
20373
20374            @Override
20375            public void onPackageInstalled(String basePackageName, int returnCode, String msg,
20376                    Bundle extras) throws RemoteException {
20377                if (DEBUG_INSTALL) Slog.d(TAG, "Install result for move: "
20378                        + PackageManager.installStatusToString(returnCode, msg));
20379
20380                installedLatch.countDown();
20381                freezer.close();
20382
20383                final int status = PackageManager.installStatusToPublicStatus(returnCode);
20384                switch (status) {
20385                    case PackageInstaller.STATUS_SUCCESS:
20386                        mMoveCallbacks.notifyStatusChanged(moveId,
20387                                PackageManager.MOVE_SUCCEEDED);
20388                        break;
20389                    case PackageInstaller.STATUS_FAILURE_STORAGE:
20390                        mMoveCallbacks.notifyStatusChanged(moveId,
20391                                PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE);
20392                        break;
20393                    default:
20394                        mMoveCallbacks.notifyStatusChanged(moveId,
20395                                PackageManager.MOVE_FAILED_INTERNAL_ERROR);
20396                        break;
20397                }
20398            }
20399        };
20400
20401        final MoveInfo move;
20402        if (moveCompleteApp) {
20403            // Kick off a thread to report progress estimates
20404            new Thread() {
20405                @Override
20406                public void run() {
20407                    while (true) {
20408                        try {
20409                            if (installedLatch.await(1, TimeUnit.SECONDS)) {
20410                                break;
20411                            }
20412                        } catch (InterruptedException ignored) {
20413                        }
20414
20415                        final long deltaFreeBytes = startFreeBytes - measurePath.getFreeSpace();
20416                        final int progress = 10 + (int) MathUtils.constrain(
20417                                ((deltaFreeBytes * 80) / sizeBytes), 0, 80);
20418                        mMoveCallbacks.notifyStatusChanged(moveId, progress);
20419                    }
20420                }
20421            }.start();
20422
20423            final String dataAppName = codeFile.getName();
20424            move = new MoveInfo(moveId, currentVolumeUuid, volumeUuid, packageName,
20425                    dataAppName, appId, seinfo, targetSdkVersion);
20426        } else {
20427            move = null;
20428        }
20429
20430        installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
20431
20432        final Message msg = mHandler.obtainMessage(INIT_COPY);
20433        final OriginInfo origin = OriginInfo.fromExistingFile(codeFile);
20434        final InstallParams params = new InstallParams(origin, move, installObserver, installFlags,
20435                installerPackageName, volumeUuid, null /*verificationInfo*/, user,
20436                packageAbiOverride, null /*grantedPermissions*/, null /*certificates*/);
20437        params.setTraceMethod("movePackage").setTraceCookie(System.identityHashCode(params));
20438        msg.obj = params;
20439
20440        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "movePackage",
20441                System.identityHashCode(msg.obj));
20442        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
20443                System.identityHashCode(msg.obj));
20444
20445        mHandler.sendMessage(msg);
20446    }
20447
20448    @Override
20449    public int movePrimaryStorage(String volumeUuid) throws RemoteException {
20450        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
20451
20452        final int realMoveId = mNextMoveId.getAndIncrement();
20453        final Bundle extras = new Bundle();
20454        extras.putString(VolumeRecord.EXTRA_FS_UUID, volumeUuid);
20455        mMoveCallbacks.notifyCreated(realMoveId, extras);
20456
20457        final IPackageMoveObserver callback = new IPackageMoveObserver.Stub() {
20458            @Override
20459            public void onCreated(int moveId, Bundle extras) {
20460                // Ignored
20461            }
20462
20463            @Override
20464            public void onStatusChanged(int moveId, int status, long estMillis) {
20465                mMoveCallbacks.notifyStatusChanged(realMoveId, status, estMillis);
20466            }
20467        };
20468
20469        final StorageManager storage = mContext.getSystemService(StorageManager.class);
20470        storage.setPrimaryStorageUuid(volumeUuid, callback);
20471        return realMoveId;
20472    }
20473
20474    @Override
20475    public int getMoveStatus(int moveId) {
20476        mContext.enforceCallingOrSelfPermission(
20477                android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
20478        return mMoveCallbacks.mLastStatus.get(moveId);
20479    }
20480
20481    @Override
20482    public void registerMoveCallback(IPackageMoveObserver callback) {
20483        mContext.enforceCallingOrSelfPermission(
20484                android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
20485        mMoveCallbacks.register(callback);
20486    }
20487
20488    @Override
20489    public void unregisterMoveCallback(IPackageMoveObserver callback) {
20490        mContext.enforceCallingOrSelfPermission(
20491                android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
20492        mMoveCallbacks.unregister(callback);
20493    }
20494
20495    @Override
20496    public boolean setInstallLocation(int loc) {
20497        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS,
20498                null);
20499        if (getInstallLocation() == loc) {
20500            return true;
20501        }
20502        if (loc == PackageHelper.APP_INSTALL_AUTO || loc == PackageHelper.APP_INSTALL_INTERNAL
20503                || loc == PackageHelper.APP_INSTALL_EXTERNAL) {
20504            android.provider.Settings.Global.putInt(mContext.getContentResolver(),
20505                    android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, loc);
20506            return true;
20507        }
20508        return false;
20509   }
20510
20511    @Override
20512    public int getInstallLocation() {
20513        return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
20514                android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION,
20515                PackageHelper.APP_INSTALL_AUTO);
20516    }
20517
20518    /** Called by UserManagerService */
20519    void cleanUpUser(UserManagerService userManager, int userHandle) {
20520        synchronized (mPackages) {
20521            mDirtyUsers.remove(userHandle);
20522            mUserNeedsBadging.delete(userHandle);
20523            mSettings.removeUserLPw(userHandle);
20524            mPendingBroadcasts.remove(userHandle);
20525            mEphemeralApplicationRegistry.onUserRemovedLPw(userHandle);
20526            removeUnusedPackagesLPw(userManager, userHandle);
20527        }
20528    }
20529
20530    /**
20531     * We're removing userHandle and would like to remove any downloaded packages
20532     * that are no longer in use by any other user.
20533     * @param userHandle the user being removed
20534     */
20535    private void removeUnusedPackagesLPw(UserManagerService userManager, final int userHandle) {
20536        final boolean DEBUG_CLEAN_APKS = false;
20537        int [] users = userManager.getUserIds();
20538        Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
20539        while (psit.hasNext()) {
20540            PackageSetting ps = psit.next();
20541            if (ps.pkg == null) {
20542                continue;
20543            }
20544            final String packageName = ps.pkg.packageName;
20545            // Skip over if system app
20546            if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) {
20547                continue;
20548            }
20549            if (DEBUG_CLEAN_APKS) {
20550                Slog.i(TAG, "Checking package " + packageName);
20551            }
20552            boolean keep = shouldKeepUninstalledPackageLPr(packageName);
20553            if (keep) {
20554                if (DEBUG_CLEAN_APKS) {
20555                    Slog.i(TAG, "  Keeping package " + packageName + " - requested by DO");
20556                }
20557            } else {
20558                for (int i = 0; i < users.length; i++) {
20559                    if (users[i] != userHandle && ps.getInstalled(users[i])) {
20560                        keep = true;
20561                        if (DEBUG_CLEAN_APKS) {
20562                            Slog.i(TAG, "  Keeping package " + packageName + " for user "
20563                                    + users[i]);
20564                        }
20565                        break;
20566                    }
20567                }
20568            }
20569            if (!keep) {
20570                if (DEBUG_CLEAN_APKS) {
20571                    Slog.i(TAG, "  Removing package " + packageName);
20572                }
20573                mHandler.post(new Runnable() {
20574                    public void run() {
20575                        deletePackageX(packageName, userHandle, 0);
20576                    } //end run
20577                });
20578            }
20579        }
20580    }
20581
20582    /** Called by UserManagerService */
20583    void createNewUser(int userId) {
20584        synchronized (mInstallLock) {
20585            mSettings.createNewUserLI(this, mInstaller, userId);
20586        }
20587        synchronized (mPackages) {
20588            scheduleWritePackageRestrictionsLocked(userId);
20589            scheduleWritePackageListLocked(userId);
20590            applyFactoryDefaultBrowserLPw(userId);
20591            primeDomainVerificationsLPw(userId);
20592        }
20593    }
20594
20595    void onNewUserCreated(final int userId) {
20596        mDefaultPermissionPolicy.grantDefaultPermissions(userId);
20597        // If permission review for legacy apps is required, we represent
20598        // dagerous permissions for such apps as always granted runtime
20599        // permissions to keep per user flag state whether review is needed.
20600        // Hence, if a new user is added we have to propagate dangerous
20601        // permission grants for these legacy apps.
20602        if (mPermissionReviewRequired || Build.PERMISSIONS_REVIEW_REQUIRED) {
20603            updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL
20604                    | UPDATE_PERMISSIONS_REPLACE_ALL);
20605        }
20606    }
20607
20608    @Override
20609    public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException {
20610        mContext.enforceCallingOrSelfPermission(
20611                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
20612                "Only package verification agents can read the verifier device identity");
20613
20614        synchronized (mPackages) {
20615            return mSettings.getVerifierDeviceIdentityLPw();
20616        }
20617    }
20618
20619    @Override
20620    public void setPermissionEnforced(String permission, boolean enforced) {
20621        // TODO: Now that we no longer change GID for storage, this should to away.
20622        mContext.enforceCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
20623                "setPermissionEnforced");
20624        if (READ_EXTERNAL_STORAGE.equals(permission)) {
20625            synchronized (mPackages) {
20626                if (mSettings.mReadExternalStorageEnforced == null
20627                        || mSettings.mReadExternalStorageEnforced != enforced) {
20628                    mSettings.mReadExternalStorageEnforced = enforced;
20629                    mSettings.writeLPr();
20630                }
20631            }
20632            // kill any non-foreground processes so we restart them and
20633            // grant/revoke the GID.
20634            final IActivityManager am = ActivityManagerNative.getDefault();
20635            if (am != null) {
20636                final long token = Binder.clearCallingIdentity();
20637                try {
20638                    am.killProcessesBelowForeground("setPermissionEnforcement");
20639                } catch (RemoteException e) {
20640                } finally {
20641                    Binder.restoreCallingIdentity(token);
20642                }
20643            }
20644        } else {
20645            throw new IllegalArgumentException("No selective enforcement for " + permission);
20646        }
20647    }
20648
20649    @Override
20650    @Deprecated
20651    public boolean isPermissionEnforced(String permission) {
20652        return true;
20653    }
20654
20655    @Override
20656    public boolean isStorageLow() {
20657        final long token = Binder.clearCallingIdentity();
20658        try {
20659            final DeviceStorageMonitorInternal
20660                    dsm = LocalServices.getService(DeviceStorageMonitorInternal.class);
20661            if (dsm != null) {
20662                return dsm.isMemoryLow();
20663            } else {
20664                return false;
20665            }
20666        } finally {
20667            Binder.restoreCallingIdentity(token);
20668        }
20669    }
20670
20671    @Override
20672    public IPackageInstaller getPackageInstaller() {
20673        return mInstallerService;
20674    }
20675
20676    private boolean userNeedsBadging(int userId) {
20677        int index = mUserNeedsBadging.indexOfKey(userId);
20678        if (index < 0) {
20679            final UserInfo userInfo;
20680            final long token = Binder.clearCallingIdentity();
20681            try {
20682                userInfo = sUserManager.getUserInfo(userId);
20683            } finally {
20684                Binder.restoreCallingIdentity(token);
20685            }
20686            final boolean b;
20687            if (userInfo != null && userInfo.isManagedProfile()) {
20688                b = true;
20689            } else {
20690                b = false;
20691            }
20692            mUserNeedsBadging.put(userId, b);
20693            return b;
20694        }
20695        return mUserNeedsBadging.valueAt(index);
20696    }
20697
20698    @Override
20699    public KeySet getKeySetByAlias(String packageName, String alias) {
20700        if (packageName == null || alias == null) {
20701            return null;
20702        }
20703        synchronized(mPackages) {
20704            final PackageParser.Package pkg = mPackages.get(packageName);
20705            if (pkg == null) {
20706                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
20707                throw new IllegalArgumentException("Unknown package: " + packageName);
20708            }
20709            KeySetManagerService ksms = mSettings.mKeySetManagerService;
20710            return new KeySet(ksms.getKeySetByAliasAndPackageNameLPr(packageName, alias));
20711        }
20712    }
20713
20714    @Override
20715    public KeySet getSigningKeySet(String packageName) {
20716        if (packageName == null) {
20717            return null;
20718        }
20719        synchronized(mPackages) {
20720            final PackageParser.Package pkg = mPackages.get(packageName);
20721            if (pkg == null) {
20722                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
20723                throw new IllegalArgumentException("Unknown package: " + packageName);
20724            }
20725            if (pkg.applicationInfo.uid != Binder.getCallingUid()
20726                    && Process.SYSTEM_UID != Binder.getCallingUid()) {
20727                throw new SecurityException("May not access signing KeySet of other apps.");
20728            }
20729            KeySetManagerService ksms = mSettings.mKeySetManagerService;
20730            return new KeySet(ksms.getSigningKeySetByPackageNameLPr(packageName));
20731        }
20732    }
20733
20734    @Override
20735    public boolean isPackageSignedByKeySet(String packageName, KeySet ks) {
20736        if (packageName == null || ks == null) {
20737            return false;
20738        }
20739        synchronized(mPackages) {
20740            final PackageParser.Package pkg = mPackages.get(packageName);
20741            if (pkg == null) {
20742                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
20743                throw new IllegalArgumentException("Unknown package: " + packageName);
20744            }
20745            IBinder ksh = ks.getToken();
20746            if (ksh instanceof KeySetHandle) {
20747                KeySetManagerService ksms = mSettings.mKeySetManagerService;
20748                return ksms.packageIsSignedByLPr(packageName, (KeySetHandle) ksh);
20749            }
20750            return false;
20751        }
20752    }
20753
20754    @Override
20755    public boolean isPackageSignedByKeySetExactly(String packageName, KeySet ks) {
20756        if (packageName == null || ks == null) {
20757            return false;
20758        }
20759        synchronized(mPackages) {
20760            final PackageParser.Package pkg = mPackages.get(packageName);
20761            if (pkg == null) {
20762                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
20763                throw new IllegalArgumentException("Unknown package: " + packageName);
20764            }
20765            IBinder ksh = ks.getToken();
20766            if (ksh instanceof KeySetHandle) {
20767                KeySetManagerService ksms = mSettings.mKeySetManagerService;
20768                return ksms.packageIsSignedByExactlyLPr(packageName, (KeySetHandle) ksh);
20769            }
20770            return false;
20771        }
20772    }
20773
20774    private void deletePackageIfUnusedLPr(final String packageName) {
20775        PackageSetting ps = mSettings.mPackages.get(packageName);
20776        if (ps == null) {
20777            return;
20778        }
20779        if (!ps.isAnyInstalled(sUserManager.getUserIds())) {
20780            // TODO Implement atomic delete if package is unused
20781            // It is currently possible that the package will be deleted even if it is installed
20782            // after this method returns.
20783            mHandler.post(new Runnable() {
20784                public void run() {
20785                    deletePackageX(packageName, 0, PackageManager.DELETE_ALL_USERS);
20786                }
20787            });
20788        }
20789    }
20790
20791    /**
20792     * Check and throw if the given before/after packages would be considered a
20793     * downgrade.
20794     */
20795    private static void checkDowngrade(PackageParser.Package before, PackageInfoLite after)
20796            throws PackageManagerException {
20797        if (after.versionCode < before.mVersionCode) {
20798            throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
20799                    "Update version code " + after.versionCode + " is older than current "
20800                    + before.mVersionCode);
20801        } else if (after.versionCode == before.mVersionCode) {
20802            if (after.baseRevisionCode < before.baseRevisionCode) {
20803                throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
20804                        "Update base revision code " + after.baseRevisionCode
20805                        + " is older than current " + before.baseRevisionCode);
20806            }
20807
20808            if (!ArrayUtils.isEmpty(after.splitNames)) {
20809                for (int i = 0; i < after.splitNames.length; i++) {
20810                    final String splitName = after.splitNames[i];
20811                    final int j = ArrayUtils.indexOf(before.splitNames, splitName);
20812                    if (j != -1) {
20813                        if (after.splitRevisionCodes[i] < before.splitRevisionCodes[j]) {
20814                            throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
20815                                    "Update split " + splitName + " revision code "
20816                                    + after.splitRevisionCodes[i] + " is older than current "
20817                                    + before.splitRevisionCodes[j]);
20818                        }
20819                    }
20820                }
20821            }
20822        }
20823    }
20824
20825    private static class MoveCallbacks extends Handler {
20826        private static final int MSG_CREATED = 1;
20827        private static final int MSG_STATUS_CHANGED = 2;
20828
20829        private final RemoteCallbackList<IPackageMoveObserver>
20830                mCallbacks = new RemoteCallbackList<>();
20831
20832        private final SparseIntArray mLastStatus = new SparseIntArray();
20833
20834        public MoveCallbacks(Looper looper) {
20835            super(looper);
20836        }
20837
20838        public void register(IPackageMoveObserver callback) {
20839            mCallbacks.register(callback);
20840        }
20841
20842        public void unregister(IPackageMoveObserver callback) {
20843            mCallbacks.unregister(callback);
20844        }
20845
20846        @Override
20847        public void handleMessage(Message msg) {
20848            final SomeArgs args = (SomeArgs) msg.obj;
20849            final int n = mCallbacks.beginBroadcast();
20850            for (int i = 0; i < n; i++) {
20851                final IPackageMoveObserver callback = mCallbacks.getBroadcastItem(i);
20852                try {
20853                    invokeCallback(callback, msg.what, args);
20854                } catch (RemoteException ignored) {
20855                }
20856            }
20857            mCallbacks.finishBroadcast();
20858            args.recycle();
20859        }
20860
20861        private void invokeCallback(IPackageMoveObserver callback, int what, SomeArgs args)
20862                throws RemoteException {
20863            switch (what) {
20864                case MSG_CREATED: {
20865                    callback.onCreated(args.argi1, (Bundle) args.arg2);
20866                    break;
20867                }
20868                case MSG_STATUS_CHANGED: {
20869                    callback.onStatusChanged(args.argi1, args.argi2, (long) args.arg3);
20870                    break;
20871                }
20872            }
20873        }
20874
20875        private void notifyCreated(int moveId, Bundle extras) {
20876            Slog.v(TAG, "Move " + moveId + " created " + extras.toString());
20877
20878            final SomeArgs args = SomeArgs.obtain();
20879            args.argi1 = moveId;
20880            args.arg2 = extras;
20881            obtainMessage(MSG_CREATED, args).sendToTarget();
20882        }
20883
20884        private void notifyStatusChanged(int moveId, int status) {
20885            notifyStatusChanged(moveId, status, -1);
20886        }
20887
20888        private void notifyStatusChanged(int moveId, int status, long estMillis) {
20889            Slog.v(TAG, "Move " + moveId + " status " + status);
20890
20891            final SomeArgs args = SomeArgs.obtain();
20892            args.argi1 = moveId;
20893            args.argi2 = status;
20894            args.arg3 = estMillis;
20895            obtainMessage(MSG_STATUS_CHANGED, args).sendToTarget();
20896
20897            synchronized (mLastStatus) {
20898                mLastStatus.put(moveId, status);
20899            }
20900        }
20901    }
20902
20903    private final static class OnPermissionChangeListeners extends Handler {
20904        private static final int MSG_ON_PERMISSIONS_CHANGED = 1;
20905
20906        private final RemoteCallbackList<IOnPermissionsChangeListener> mPermissionListeners =
20907                new RemoteCallbackList<>();
20908
20909        public OnPermissionChangeListeners(Looper looper) {
20910            super(looper);
20911        }
20912
20913        @Override
20914        public void handleMessage(Message msg) {
20915            switch (msg.what) {
20916                case MSG_ON_PERMISSIONS_CHANGED: {
20917                    final int uid = msg.arg1;
20918                    handleOnPermissionsChanged(uid);
20919                } break;
20920            }
20921        }
20922
20923        public void addListenerLocked(IOnPermissionsChangeListener listener) {
20924            mPermissionListeners.register(listener);
20925
20926        }
20927
20928        public void removeListenerLocked(IOnPermissionsChangeListener listener) {
20929            mPermissionListeners.unregister(listener);
20930        }
20931
20932        public void onPermissionsChanged(int uid) {
20933            if (mPermissionListeners.getRegisteredCallbackCount() > 0) {
20934                obtainMessage(MSG_ON_PERMISSIONS_CHANGED, uid, 0).sendToTarget();
20935            }
20936        }
20937
20938        private void handleOnPermissionsChanged(int uid) {
20939            final int count = mPermissionListeners.beginBroadcast();
20940            try {
20941                for (int i = 0; i < count; i++) {
20942                    IOnPermissionsChangeListener callback = mPermissionListeners
20943                            .getBroadcastItem(i);
20944                    try {
20945                        callback.onPermissionsChanged(uid);
20946                    } catch (RemoteException e) {
20947                        Log.e(TAG, "Permission listener is dead", e);
20948                    }
20949                }
20950            } finally {
20951                mPermissionListeners.finishBroadcast();
20952            }
20953        }
20954    }
20955
20956    private class PackageManagerInternalImpl extends PackageManagerInternal {
20957        @Override
20958        public void setLocationPackagesProvider(PackagesProvider provider) {
20959            synchronized (mPackages) {
20960                mDefaultPermissionPolicy.setLocationPackagesProviderLPw(provider);
20961            }
20962        }
20963
20964        @Override
20965        public void setVoiceInteractionPackagesProvider(PackagesProvider provider) {
20966            synchronized (mPackages) {
20967                mDefaultPermissionPolicy.setVoiceInteractionPackagesProviderLPw(provider);
20968            }
20969        }
20970
20971        @Override
20972        public void setSmsAppPackagesProvider(PackagesProvider provider) {
20973            synchronized (mPackages) {
20974                mDefaultPermissionPolicy.setSmsAppPackagesProviderLPw(provider);
20975            }
20976        }
20977
20978        @Override
20979        public void setDialerAppPackagesProvider(PackagesProvider provider) {
20980            synchronized (mPackages) {
20981                mDefaultPermissionPolicy.setDialerAppPackagesProviderLPw(provider);
20982            }
20983        }
20984
20985        @Override
20986        public void setSimCallManagerPackagesProvider(PackagesProvider provider) {
20987            synchronized (mPackages) {
20988                mDefaultPermissionPolicy.setSimCallManagerPackagesProviderLPw(provider);
20989            }
20990        }
20991
20992        @Override
20993        public void setSyncAdapterPackagesprovider(SyncAdapterPackagesProvider provider) {
20994            synchronized (mPackages) {
20995                mDefaultPermissionPolicy.setSyncAdapterPackagesProviderLPw(provider);
20996            }
20997        }
20998
20999        @Override
21000        public void grantDefaultPermissionsToDefaultSmsApp(String packageName, int userId) {
21001            synchronized (mPackages) {
21002                mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSmsAppLPr(
21003                        packageName, userId);
21004            }
21005        }
21006
21007        @Override
21008        public void grantDefaultPermissionsToDefaultDialerApp(String packageName, int userId) {
21009            synchronized (mPackages) {
21010                mSettings.setDefaultDialerPackageNameLPw(packageName, userId);
21011                mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultDialerAppLPr(
21012                        packageName, userId);
21013            }
21014        }
21015
21016        @Override
21017        public void grantDefaultPermissionsToDefaultSimCallManager(String packageName, int userId) {
21018            synchronized (mPackages) {
21019                mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSimCallManagerLPr(
21020                        packageName, userId);
21021            }
21022        }
21023
21024        @Override
21025        public void setKeepUninstalledPackages(final List<String> packageList) {
21026            Preconditions.checkNotNull(packageList);
21027            List<String> removedFromList = null;
21028            synchronized (mPackages) {
21029                if (mKeepUninstalledPackages != null) {
21030                    final int packagesCount = mKeepUninstalledPackages.size();
21031                    for (int i = 0; i < packagesCount; i++) {
21032                        String oldPackage = mKeepUninstalledPackages.get(i);
21033                        if (packageList != null && packageList.contains(oldPackage)) {
21034                            continue;
21035                        }
21036                        if (removedFromList == null) {
21037                            removedFromList = new ArrayList<>();
21038                        }
21039                        removedFromList.add(oldPackage);
21040                    }
21041                }
21042                mKeepUninstalledPackages = new ArrayList<>(packageList);
21043                if (removedFromList != null) {
21044                    final int removedCount = removedFromList.size();
21045                    for (int i = 0; i < removedCount; i++) {
21046                        deletePackageIfUnusedLPr(removedFromList.get(i));
21047                    }
21048                }
21049            }
21050        }
21051
21052        @Override
21053        public boolean isPermissionsReviewRequired(String packageName, int userId) {
21054            synchronized (mPackages) {
21055                // If we do not support permission review, done.
21056                if (!mPermissionReviewRequired && !Build.PERMISSIONS_REVIEW_REQUIRED) {
21057                    return false;
21058                }
21059
21060                PackageSetting packageSetting = mSettings.mPackages.get(packageName);
21061                if (packageSetting == null) {
21062                    return false;
21063                }
21064
21065                // Permission review applies only to apps not supporting the new permission model.
21066                if (packageSetting.pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.M) {
21067                    return false;
21068                }
21069
21070                // Legacy apps have the permission and get user consent on launch.
21071                PermissionsState permissionsState = packageSetting.getPermissionsState();
21072                return permissionsState.isPermissionReviewRequired(userId);
21073            }
21074        }
21075
21076        @Override
21077        public ApplicationInfo getApplicationInfo(String packageName, int userId) {
21078            return PackageManagerService.this.getApplicationInfo(packageName, 0 /*flags*/, userId);
21079        }
21080
21081        @Override
21082        public ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates,
21083                int userId) {
21084            return PackageManagerService.this.getHomeActivitiesAsUser(allHomeCandidates, userId);
21085        }
21086
21087        @Override
21088        public void setDeviceAndProfileOwnerPackages(
21089                int deviceOwnerUserId, String deviceOwnerPackage,
21090                SparseArray<String> profileOwnerPackages) {
21091            mProtectedPackages.setDeviceAndProfileOwnerPackages(
21092                    deviceOwnerUserId, deviceOwnerPackage, profileOwnerPackages);
21093        }
21094
21095        @Override
21096        public boolean isPackageDataProtected(int userId, String packageName) {
21097            return mProtectedPackages.isPackageDataProtected(userId, packageName);
21098        }
21099
21100        @Override
21101        public boolean wasPackageEverLaunched(String packageName, int userId) {
21102            synchronized (mPackages) {
21103                return mSettings.wasPackageEverLaunchedLPr(packageName, userId);
21104            }
21105        }
21106
21107        @Override
21108        public String getNameForUid(int uid) {
21109            return PackageManagerService.this.getNameForUid(uid);
21110        }
21111    }
21112
21113    @Override
21114    public void grantDefaultPermissionsToEnabledCarrierApps(String[] packageNames, int userId) {
21115        enforceSystemOrPhoneCaller("grantPermissionsToEnabledCarrierApps");
21116        synchronized (mPackages) {
21117            final long identity = Binder.clearCallingIdentity();
21118            try {
21119                mDefaultPermissionPolicy.grantDefaultPermissionsToEnabledCarrierAppsLPr(
21120                        packageNames, userId);
21121            } finally {
21122                Binder.restoreCallingIdentity(identity);
21123            }
21124        }
21125    }
21126
21127    @Override
21128    public void grantDefaultPermissionsToEnabledImsServices(String[] packageNames, int userId) {
21129        enforceSystemOrPhoneCaller("grantDefaultPermissionsToEnabledImsServices");
21130        synchronized (mPackages) {
21131            final long identity = Binder.clearCallingIdentity();
21132            try {
21133                mDefaultPermissionPolicy.grantDefaultPermissionsToEnabledImsServicesLPr(
21134                        packageNames, userId);
21135            } finally {
21136                Binder.restoreCallingIdentity(identity);
21137            }
21138        }
21139    }
21140
21141    private static void enforceSystemOrPhoneCaller(String tag) {
21142        int callingUid = Binder.getCallingUid();
21143        if (callingUid != Process.PHONE_UID && callingUid != Process.SYSTEM_UID) {
21144            throw new SecurityException(
21145                    "Cannot call " + tag + " from UID " + callingUid);
21146        }
21147    }
21148
21149    boolean isHistoricalPackageUsageAvailable() {
21150        return mPackageUsage.isHistoricalPackageUsageAvailable();
21151    }
21152
21153    /**
21154     * Return a <b>copy</b> of the collection of packages known to the package manager.
21155     * @return A copy of the values of mPackages.
21156     */
21157    Collection<PackageParser.Package> getPackages() {
21158        synchronized (mPackages) {
21159            return new ArrayList<>(mPackages.values());
21160        }
21161    }
21162
21163    /**
21164     * Logs process start information (including base APK hash) to the security log.
21165     * @hide
21166     */
21167    public void logAppProcessStartIfNeeded(String processName, int uid, String seinfo,
21168            String apkFile, int pid) {
21169        if (!SecurityLog.isLoggingEnabled()) {
21170            return;
21171        }
21172        Bundle data = new Bundle();
21173        data.putLong("startTimestamp", System.currentTimeMillis());
21174        data.putString("processName", processName);
21175        data.putInt("uid", uid);
21176        data.putString("seinfo", seinfo);
21177        data.putString("apkFile", apkFile);
21178        data.putInt("pid", pid);
21179        Message msg = mProcessLoggingHandler.obtainMessage(
21180                ProcessLoggingHandler.LOG_APP_PROCESS_START_MSG);
21181        msg.setData(data);
21182        mProcessLoggingHandler.sendMessage(msg);
21183    }
21184
21185    public CompilerStats.PackageStats getCompilerPackageStats(String pkgName) {
21186        return mCompilerStats.getPackageStats(pkgName);
21187    }
21188
21189    public CompilerStats.PackageStats getOrCreateCompilerPackageStats(PackageParser.Package pkg) {
21190        return getOrCreateCompilerPackageStats(pkg.packageName);
21191    }
21192
21193    public CompilerStats.PackageStats getOrCreateCompilerPackageStats(String pkgName) {
21194        return mCompilerStats.getOrCreatePackageStats(pkgName);
21195    }
21196
21197    public void deleteCompilerPackageStats(String pkgName) {
21198        mCompilerStats.deletePackageStats(pkgName);
21199    }
21200}
21201