PackageManagerService.java revision c35e8c9c31ffc0419e2c3f75aa933368b20a56f2
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.READ_EXTERNAL_STORAGE;
20import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
21import static android.Manifest.permission.WRITE_MEDIA_STORAGE;
22import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
23import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
24import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED;
25import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER;
26import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
27import static android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
28import static android.content.pm.PackageManager.FLAG_PERMISSION_POLICY_FIXED;
29import static android.content.pm.PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
30import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE;
31import static android.content.pm.PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
32import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_FIXED;
33import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET;
34import static android.content.pm.PackageManager.INSTALL_EXTERNAL;
35import static android.content.pm.PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
36import static android.content.pm.PackageManager.INSTALL_FAILED_CONFLICTING_PROVIDER;
37import static android.content.pm.PackageManager.INSTALL_FAILED_DEXOPT;
38import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE;
39import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION;
40import static android.content.pm.PackageManager.INSTALL_FAILED_EPHEMERAL_INVALID;
41import static android.content.pm.PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
42import static android.content.pm.PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
43import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_APK;
44import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
45import static android.content.pm.PackageManager.INSTALL_FAILED_MISSING_SHARED_LIBRARY;
46import static android.content.pm.PackageManager.INSTALL_FAILED_PACKAGE_CHANGED;
47import static android.content.pm.PackageManager.INSTALL_FAILED_REPLACE_COULDNT_DELETE;
48import static android.content.pm.PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE;
49import static android.content.pm.PackageManager.INSTALL_FAILED_TEST_ONLY;
50import static android.content.pm.PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE;
51import static android.content.pm.PackageManager.INSTALL_FAILED_USER_RESTRICTED;
52import static android.content.pm.PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
53import static android.content.pm.PackageManager.INSTALL_FORWARD_LOCK;
54import static android.content.pm.PackageManager.INSTALL_INTERNAL;
55import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
56import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
57import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK;
58import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK;
59import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER;
60import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
61import static android.content.pm.PackageManager.MATCH_ALL;
62import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
63import static android.content.pm.PackageManager.MATCH_DISABLED_COMPONENTS;
64import static android.content.pm.PackageManager.MATCH_ENCRYPTION_AWARE_AND_UNAWARE;
65import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
66import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
67import static android.content.pm.PackageManager.MOVE_FAILED_DOESNT_EXIST;
68import static android.content.pm.PackageManager.MOVE_FAILED_INTERNAL_ERROR;
69import static android.content.pm.PackageManager.MOVE_FAILED_OPERATION_PENDING;
70import static android.content.pm.PackageManager.MOVE_FAILED_SYSTEM_PACKAGE;
71import static android.content.pm.PackageManager.PERMISSION_DENIED;
72import static android.content.pm.PackageManager.PERMISSION_GRANTED;
73import static android.content.pm.PackageParser.isApkFile;
74import static android.os.Process.PACKAGE_INFO_GID;
75import static android.os.Process.SYSTEM_UID;
76import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
77import static android.system.OsConstants.O_CREAT;
78import static android.system.OsConstants.O_RDWR;
79
80import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE;
81import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_PARENT;
82import static com.android.internal.content.NativeLibraryHelper.LIB64_DIR_NAME;
83import static com.android.internal.content.NativeLibraryHelper.LIB_DIR_NAME;
84import static com.android.internal.util.ArrayUtils.appendInt;
85import static com.android.server.pm.Installer.DEXOPT_PUBLIC;
86import static com.android.server.pm.InstructionSets.getAppDexInstructionSets;
87import static com.android.server.pm.InstructionSets.getDexCodeInstructionSet;
88import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets;
89import static com.android.server.pm.InstructionSets.getPreferredInstructionSet;
90import static com.android.server.pm.InstructionSets.getPrimaryInstructionSet;
91import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_FAILURE;
92import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_SUCCESS;
93import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED;
94
95import android.Manifest;
96import android.annotation.NonNull;
97import android.annotation.Nullable;
98import android.app.ActivityManager;
99import android.app.ActivityManagerNative;
100import android.app.AppGlobals;
101import android.app.IActivityManager;
102import android.app.admin.IDevicePolicyManager;
103import android.app.backup.IBackupManager;
104import android.content.BroadcastReceiver;
105import android.content.ComponentName;
106import android.content.Context;
107import android.content.IIntentReceiver;
108import android.content.Intent;
109import android.content.IntentFilter;
110import android.content.IntentSender;
111import android.content.IntentSender.SendIntentException;
112import android.content.ServiceConnection;
113import android.content.pm.ActivityInfo;
114import android.content.pm.ApplicationInfo;
115import android.content.pm.AppsQueryHelper;
116import android.content.pm.ComponentInfo;
117import android.content.pm.EphemeralApplicationInfo;
118import android.content.pm.EphemeralResolveInfo;
119import android.content.pm.EphemeralResolveInfo.EphemeralResolveIntentInfo;
120import android.content.pm.FeatureInfo;
121import android.content.pm.IOnPermissionsChangeListener;
122import android.content.pm.IPackageDataObserver;
123import android.content.pm.IPackageDeleteObserver;
124import android.content.pm.IPackageDeleteObserver2;
125import android.content.pm.IPackageInstallObserver2;
126import android.content.pm.IPackageInstaller;
127import android.content.pm.IPackageManager;
128import android.content.pm.IPackageMoveObserver;
129import android.content.pm.IPackageStatsObserver;
130import android.content.pm.InstrumentationInfo;
131import android.content.pm.IntentFilterVerificationInfo;
132import android.content.pm.KeySet;
133import android.content.pm.PackageCleanItem;
134import android.content.pm.PackageInfo;
135import android.content.pm.PackageInfoLite;
136import android.content.pm.PackageInstaller;
137import android.content.pm.PackageManager;
138import android.content.pm.PackageManager.LegacyPackageDeleteObserver;
139import android.content.pm.PackageManagerInternal;
140import android.content.pm.PackageParser;
141import android.content.pm.PackageParser.ActivityIntentInfo;
142import android.content.pm.PackageParser.PackageLite;
143import android.content.pm.PackageParser.PackageParserException;
144import android.content.pm.PackageStats;
145import android.content.pm.PackageUserState;
146import android.content.pm.ParceledListSlice;
147import android.content.pm.PermissionGroupInfo;
148import android.content.pm.PermissionInfo;
149import android.content.pm.ProviderInfo;
150import android.content.pm.ResolveInfo;
151import android.content.pm.ServiceInfo;
152import android.content.pm.Signature;
153import android.content.pm.UserInfo;
154import android.content.pm.VerificationParams;
155import android.content.pm.VerifierDeviceIdentity;
156import android.content.pm.VerifierInfo;
157import android.content.res.Resources;
158import android.graphics.Bitmap;
159import android.hardware.display.DisplayManager;
160import android.net.Uri;
161import android.os.Binder;
162import android.os.Build;
163import android.os.Bundle;
164import android.os.Debug;
165import android.os.Environment;
166import android.os.Environment.UserEnvironment;
167import android.os.FileUtils;
168import android.os.Handler;
169import android.os.IBinder;
170import android.os.Looper;
171import android.os.Message;
172import android.os.Parcel;
173import android.os.ParcelFileDescriptor;
174import android.os.Process;
175import android.os.RemoteCallbackList;
176import android.os.RemoteException;
177import android.os.ResultReceiver;
178import android.os.SELinux;
179import android.os.ServiceManager;
180import android.os.SystemClock;
181import android.os.SystemProperties;
182import android.os.Trace;
183import android.os.UserHandle;
184import android.os.UserManager;
185import android.os.storage.IMountService;
186import android.os.storage.MountServiceInternal;
187import android.os.storage.StorageEventListener;
188import android.os.storage.StorageManager;
189import android.os.storage.VolumeInfo;
190import android.os.storage.VolumeRecord;
191import android.security.KeyStore;
192import android.security.SystemKeyStore;
193import android.system.ErrnoException;
194import android.system.Os;
195import android.text.TextUtils;
196import android.text.format.DateUtils;
197import android.util.ArrayMap;
198import android.util.ArraySet;
199import android.util.AtomicFile;
200import android.util.DisplayMetrics;
201import android.util.EventLog;
202import android.util.ExceptionUtils;
203import android.util.Log;
204import android.util.LogPrinter;
205import android.util.MathUtils;
206import android.util.PrintStreamPrinter;
207import android.util.Slog;
208import android.util.SparseArray;
209import android.util.SparseBooleanArray;
210import android.util.SparseIntArray;
211import android.util.Xml;
212import android.view.Display;
213
214import com.android.internal.R;
215import com.android.internal.annotations.GuardedBy;
216import com.android.internal.app.IMediaContainerService;
217import com.android.internal.app.ResolverActivity;
218import com.android.internal.content.NativeLibraryHelper;
219import com.android.internal.content.PackageHelper;
220import com.android.internal.os.IParcelFileDescriptorFactory;
221import com.android.internal.os.InstallerConnection.InstallerException;
222import com.android.internal.os.SomeArgs;
223import com.android.internal.os.Zygote;
224import com.android.internal.util.ArrayUtils;
225import com.android.internal.util.FastPrintWriter;
226import com.android.internal.util.FastXmlSerializer;
227import com.android.internal.util.IndentingPrintWriter;
228import com.android.internal.util.Preconditions;
229import com.android.internal.util.XmlUtils;
230import com.android.server.EventLogTags;
231import com.android.server.FgThread;
232import com.android.server.IntentResolver;
233import com.android.server.LocalServices;
234import com.android.server.ServiceThread;
235import com.android.server.SystemConfig;
236import com.android.server.Watchdog;
237import com.android.server.pm.Installer.StorageFlags;
238import com.android.server.pm.PermissionsState.PermissionState;
239import com.android.server.pm.Settings.DatabaseVersion;
240import com.android.server.pm.Settings.VersionInfo;
241import com.android.server.storage.DeviceStorageMonitorInternal;
242
243import dalvik.system.DexFile;
244import dalvik.system.VMRuntime;
245
246import libcore.io.IoUtils;
247import libcore.util.EmptyArray;
248
249import org.xmlpull.v1.XmlPullParser;
250import org.xmlpull.v1.XmlPullParserException;
251import org.xmlpull.v1.XmlSerializer;
252
253import java.io.BufferedInputStream;
254import java.io.BufferedOutputStream;
255import java.io.BufferedReader;
256import java.io.ByteArrayInputStream;
257import java.io.ByteArrayOutputStream;
258import java.io.File;
259import java.io.FileDescriptor;
260import java.io.FileNotFoundException;
261import java.io.FileOutputStream;
262import java.io.FileReader;
263import java.io.FilenameFilter;
264import java.io.IOException;
265import java.io.InputStream;
266import java.io.PrintWriter;
267import java.nio.charset.StandardCharsets;
268import java.security.MessageDigest;
269import java.security.NoSuchAlgorithmException;
270import java.security.PublicKey;
271import java.security.cert.CertificateEncodingException;
272import java.security.cert.CertificateException;
273import java.text.SimpleDateFormat;
274import java.util.ArrayList;
275import java.util.Arrays;
276import java.util.Collection;
277import java.util.Collections;
278import java.util.Comparator;
279import java.util.Date;
280import java.util.Iterator;
281import java.util.List;
282import java.util.Map;
283import java.util.Objects;
284import java.util.Set;
285import java.util.concurrent.CountDownLatch;
286import java.util.concurrent.TimeUnit;
287import java.util.concurrent.atomic.AtomicBoolean;
288import java.util.concurrent.atomic.AtomicInteger;
289import java.util.concurrent.atomic.AtomicLong;
290
291/**
292 * Keep track of all those .apks everywhere.
293 *
294 * This is very central to the platform's security; please run the unit
295 * tests whenever making modifications here:
296 *
297runtest -c android.content.pm.PackageManagerTests frameworks-core
298 *
299 * {@hide}
300 */
301public class PackageManagerService extends IPackageManager.Stub {
302    static final String TAG = "PackageManager";
303    static final boolean DEBUG_SETTINGS = false;
304    static final boolean DEBUG_PREFERRED = false;
305    static final boolean DEBUG_UPGRADE = false;
306    static final boolean DEBUG_DOMAIN_VERIFICATION = false;
307    private static final boolean DEBUG_BACKUP = false;
308    private static final boolean DEBUG_INSTALL = false;
309    private static final boolean DEBUG_REMOVE = false;
310    private static final boolean DEBUG_BROADCASTS = false;
311    private static final boolean DEBUG_SHOW_INFO = false;
312    private static final boolean DEBUG_PACKAGE_INFO = false;
313    private static final boolean DEBUG_INTENT_MATCHING = false;
314    private static final boolean DEBUG_PACKAGE_SCANNING = false;
315    private static final boolean DEBUG_VERIFY = false;
316    private static final boolean DEBUG_DEXOPT = false;
317    private static final boolean DEBUG_ABI_SELECTION = false;
318    private static final boolean DEBUG_EPHEMERAL = false;
319    private static final boolean DEBUG_TRIAGED_MISSING = false;
320    private static final boolean DEBUG_APP_DATA = false;
321
322    static final boolean CLEAR_RUNTIME_PERMISSIONS_ON_UPGRADE = false;
323
324    private static final boolean DISABLE_EPHEMERAL_APPS = true;
325
326    private static final int RADIO_UID = Process.PHONE_UID;
327    private static final int LOG_UID = Process.LOG_UID;
328    private static final int NFC_UID = Process.NFC_UID;
329    private static final int BLUETOOTH_UID = Process.BLUETOOTH_UID;
330    private static final int SHELL_UID = Process.SHELL_UID;
331
332    // Cap the size of permission trees that 3rd party apps can define
333    private static final int MAX_PERMISSION_TREE_FOOTPRINT = 32768;     // characters of text
334
335    // Suffix used during package installation when copying/moving
336    // package apks to install directory.
337    private static final String INSTALL_PACKAGE_SUFFIX = "-";
338
339    static final int SCAN_NO_DEX = 1<<1;
340    static final int SCAN_FORCE_DEX = 1<<2;
341    static final int SCAN_UPDATE_SIGNATURE = 1<<3;
342    static final int SCAN_NEW_INSTALL = 1<<4;
343    static final int SCAN_NO_PATHS = 1<<5;
344    static final int SCAN_UPDATE_TIME = 1<<6;
345    static final int SCAN_DEFER_DEX = 1<<7;
346    static final int SCAN_BOOTING = 1<<8;
347    static final int SCAN_TRUSTED_OVERLAY = 1<<9;
348    static final int SCAN_DELETE_DATA_ON_FAILURES = 1<<10;
349    static final int SCAN_REPLACING = 1<<11;
350    static final int SCAN_REQUIRE_KNOWN = 1<<12;
351    static final int SCAN_MOVE = 1<<13;
352    static final int SCAN_INITIAL = 1<<14;
353
354    static final int REMOVE_CHATTY = 1<<16;
355
356    private static final int[] EMPTY_INT_ARRAY = new int[0];
357
358    /**
359     * Timeout (in milliseconds) after which the watchdog should declare that
360     * our handler thread is wedged.  The usual default for such things is one
361     * minute but we sometimes do very lengthy I/O operations on this thread,
362     * such as installing multi-gigabyte applications, so ours needs to be longer.
363     */
364    private static final long WATCHDOG_TIMEOUT = 1000*60*10;     // ten minutes
365
366    /**
367     * Wall-clock timeout (in milliseconds) after which we *require* that an fstrim
368     * be run on this device.  We use the value in the Settings.Global.MANDATORY_FSTRIM_INTERVAL
369     * settings entry if available, otherwise we use the hardcoded default.  If it's been
370     * more than this long since the last fstrim, we force one during the boot sequence.
371     *
372     * This backstops other fstrim scheduling:  if the device is alive at midnight+idle,
373     * one gets run at the next available charging+idle time.  This final mandatory
374     * no-fstrim check kicks in only of the other scheduling criteria is never met.
375     */
376    private static final long DEFAULT_MANDATORY_FSTRIM_INTERVAL = 3 * DateUtils.DAY_IN_MILLIS;
377
378    /**
379     * Whether verification is enabled by default.
380     */
381    private static final boolean DEFAULT_VERIFY_ENABLE = true;
382
383    /**
384     * The default maximum time to wait for the verification agent to return in
385     * milliseconds.
386     */
387    private static final long DEFAULT_VERIFICATION_TIMEOUT = 10 * 1000;
388
389    /**
390     * The default response for package verification timeout.
391     *
392     * This can be either PackageManager.VERIFICATION_ALLOW or
393     * PackageManager.VERIFICATION_REJECT.
394     */
395    private static final int DEFAULT_VERIFICATION_RESPONSE = PackageManager.VERIFICATION_ALLOW;
396
397    static final String DEFAULT_CONTAINER_PACKAGE = "com.android.defcontainer";
398
399    static final ComponentName DEFAULT_CONTAINER_COMPONENT = new ComponentName(
400            DEFAULT_CONTAINER_PACKAGE,
401            "com.android.defcontainer.DefaultContainerService");
402
403    private static final String KILL_APP_REASON_GIDS_CHANGED =
404            "permission grant or revoke changed gids";
405
406    private static final String KILL_APP_REASON_PERMISSIONS_REVOKED =
407            "permissions revoked";
408
409    private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive";
410
411    private static final String VENDOR_OVERLAY_DIR = "/vendor/overlay";
412
413    /** Permission grant: not grant the permission. */
414    private static final int GRANT_DENIED = 1;
415
416    /** Permission grant: grant the permission as an install permission. */
417    private static final int GRANT_INSTALL = 2;
418
419    /** Permission grant: grant the permission as a runtime one. */
420    private static final int GRANT_RUNTIME = 3;
421
422    /** Permission grant: grant as runtime a permission that was granted as an install time one. */
423    private static final int GRANT_UPGRADE = 4;
424
425    /** Canonical intent used to identify what counts as a "web browser" app */
426    private static final Intent sBrowserIntent;
427    static {
428        sBrowserIntent = new Intent();
429        sBrowserIntent.setAction(Intent.ACTION_VIEW);
430        sBrowserIntent.addCategory(Intent.CATEGORY_BROWSABLE);
431        sBrowserIntent.setData(Uri.parse("http:"));
432    }
433
434    final ServiceThread mHandlerThread;
435
436    final PackageHandler mHandler;
437
438    /**
439     * Messages for {@link #mHandler} that need to wait for system ready before
440     * being dispatched.
441     */
442    private ArrayList<Message> mPostSystemReadyMessages;
443
444    final int mSdkVersion = Build.VERSION.SDK_INT;
445
446    final Context mContext;
447    final boolean mFactoryTest;
448    final boolean mOnlyCore;
449    final DisplayMetrics mMetrics;
450    final int mDefParseFlags;
451    final String[] mSeparateProcesses;
452    final boolean mIsUpgrade;
453
454    /** The location for ASEC container files on internal storage. */
455    final String mAsecInternalPath;
456
457    // Used for privilege escalation. MUST NOT BE CALLED WITH mPackages
458    // LOCK HELD.  Can be called with mInstallLock held.
459    @GuardedBy("mInstallLock")
460    final Installer mInstaller;
461
462    /** Directory where installed third-party apps stored */
463    final File mAppInstallDir;
464    final File mEphemeralInstallDir;
465
466    /**
467     * Directory to which applications installed internally have their
468     * 32 bit native libraries copied.
469     */
470    private File mAppLib32InstallDir;
471
472    // Directory containing the private parts (e.g. code and non-resource assets) of forward-locked
473    // apps.
474    final File mDrmAppPrivateInstallDir;
475
476    // ----------------------------------------------------------------
477
478    // Lock for state used when installing and doing other long running
479    // operations.  Methods that must be called with this lock held have
480    // the suffix "LI".
481    final Object mInstallLock = new Object();
482
483    // ----------------------------------------------------------------
484
485    // Keys are String (package name), values are Package.  This also serves
486    // as the lock for the global state.  Methods that must be called with
487    // this lock held have the prefix "LP".
488    @GuardedBy("mPackages")
489    final ArrayMap<String, PackageParser.Package> mPackages =
490            new ArrayMap<String, PackageParser.Package>();
491
492    // Tracks available target package names -> overlay package paths.
493    final ArrayMap<String, ArrayMap<String, PackageParser.Package>> mOverlays =
494        new ArrayMap<String, ArrayMap<String, PackageParser.Package>>();
495
496    /**
497     * Tracks new system packages [received in an OTA] that we expect to
498     * find updated user-installed versions. Keys are package name, values
499     * are package location.
500     */
501    final private ArrayMap<String, File> mExpectingBetter = new ArrayMap<>();
502
503    /**
504     * Tracks existing system packages prior to receiving an OTA. Keys are package name.
505     */
506    final private ArraySet<String> mExistingSystemPackages = new ArraySet<>();
507    /**
508     * Whether or not system app permissions should be promoted from install to runtime.
509     */
510    boolean mPromoteSystemApps;
511
512    final Settings mSettings;
513    boolean mRestoredSettings;
514
515    // System configuration read by SystemConfig.
516    final int[] mGlobalGids;
517    final SparseArray<ArraySet<String>> mSystemPermissions;
518    final ArrayMap<String, FeatureInfo> mAvailableFeatures;
519
520    // If mac_permissions.xml was found for seinfo labeling.
521    boolean mFoundPolicyFile;
522
523    private final EphemeralApplicationRegistry mEphemeralApplicationRegistry;
524
525    public static final class SharedLibraryEntry {
526        public final String path;
527        public final String apk;
528
529        SharedLibraryEntry(String _path, String _apk) {
530            path = _path;
531            apk = _apk;
532        }
533    }
534
535    // Currently known shared libraries.
536    final ArrayMap<String, SharedLibraryEntry> mSharedLibraries =
537            new ArrayMap<String, SharedLibraryEntry>();
538
539    // All available activities, for your resolving pleasure.
540    final ActivityIntentResolver mActivities =
541            new ActivityIntentResolver();
542
543    // All available receivers, for your resolving pleasure.
544    final ActivityIntentResolver mReceivers =
545            new ActivityIntentResolver();
546
547    // All available services, for your resolving pleasure.
548    final ServiceIntentResolver mServices = new ServiceIntentResolver();
549
550    // All available providers, for your resolving pleasure.
551    final ProviderIntentResolver mProviders = new ProviderIntentResolver();
552
553    // Mapping from provider base names (first directory in content URI codePath)
554    // to the provider information.
555    final ArrayMap<String, PackageParser.Provider> mProvidersByAuthority =
556            new ArrayMap<String, PackageParser.Provider>();
557
558    // Mapping from instrumentation class names to info about them.
559    final ArrayMap<ComponentName, PackageParser.Instrumentation> mInstrumentation =
560            new ArrayMap<ComponentName, PackageParser.Instrumentation>();
561
562    // Mapping from permission names to info about them.
563    final ArrayMap<String, PackageParser.PermissionGroup> mPermissionGroups =
564            new ArrayMap<String, PackageParser.PermissionGroup>();
565
566    // Packages whose data we have transfered into another package, thus
567    // should no longer exist.
568    final ArraySet<String> mTransferedPackages = new ArraySet<String>();
569
570    // Broadcast actions that are only available to the system.
571    final ArraySet<String> mProtectedBroadcasts = new ArraySet<String>();
572
573    /** List of packages waiting for verification. */
574    final SparseArray<PackageVerificationState> mPendingVerification
575            = new SparseArray<PackageVerificationState>();
576
577    /** Set of packages associated with each app op permission. */
578    final ArrayMap<String, ArraySet<String>> mAppOpPermissionPackages = new ArrayMap<>();
579
580    final PackageInstallerService mInstallerService;
581
582    private final PackageDexOptimizer mPackageDexOptimizer;
583
584    private AtomicInteger mNextMoveId = new AtomicInteger();
585    private final MoveCallbacks mMoveCallbacks;
586
587    private final OnPermissionChangeListeners mOnPermissionChangeListeners;
588
589    // Cache of users who need badging.
590    SparseBooleanArray mUserNeedsBadging = new SparseBooleanArray();
591
592    /** Token for keys in mPendingVerification. */
593    private int mPendingVerificationToken = 0;
594
595    volatile boolean mSystemReady;
596    volatile boolean mSafeMode;
597    volatile boolean mHasSystemUidErrors;
598
599    ApplicationInfo mAndroidApplication;
600    final ActivityInfo mResolveActivity = new ActivityInfo();
601    final ResolveInfo mResolveInfo = new ResolveInfo();
602    ComponentName mResolveComponentName;
603    PackageParser.Package mPlatformPackage;
604    ComponentName mCustomResolverComponentName;
605
606    boolean mResolverReplaced = false;
607
608    private final @Nullable ComponentName mIntentFilterVerifierComponent;
609    private final @Nullable IntentFilterVerifier<ActivityIntentInfo> mIntentFilterVerifier;
610
611    private int mIntentFilterVerificationToken = 0;
612
613    /** Component that knows whether or not an ephemeral application exists */
614    final ComponentName mEphemeralResolverComponent;
615    /** The service connection to the ephemeral resolver */
616    final EphemeralResolverConnection mEphemeralResolverConnection;
617
618    /** Component used to install ephemeral applications */
619    final ComponentName mEphemeralInstallerComponent;
620    final ActivityInfo mEphemeralInstallerActivity = new ActivityInfo();
621    final ResolveInfo mEphemeralInstallerInfo = new ResolveInfo();
622
623    final SparseArray<IntentFilterVerificationState> mIntentFilterVerificationStates
624            = new SparseArray<IntentFilterVerificationState>();
625
626    final DefaultPermissionGrantPolicy mDefaultPermissionPolicy =
627            new DefaultPermissionGrantPolicy(this);
628
629    // List of packages names to keep cached, even if they are uninstalled for all users
630    private List<String> mKeepUninstalledPackages;
631
632    private boolean mUseJitProfiles =
633            SystemProperties.getBoolean("dalvik.vm.usejitprofiles", false);
634
635    private static class IFVerificationParams {
636        PackageParser.Package pkg;
637        boolean replacing;
638        int userId;
639        int verifierUid;
640
641        public IFVerificationParams(PackageParser.Package _pkg, boolean _replacing,
642                int _userId, int _verifierUid) {
643            pkg = _pkg;
644            replacing = _replacing;
645            userId = _userId;
646            replacing = _replacing;
647            verifierUid = _verifierUid;
648        }
649    }
650
651    private interface IntentFilterVerifier<T extends IntentFilter> {
652        boolean addOneIntentFilterVerification(int verifierId, int userId, int verificationId,
653                                               T filter, String packageName);
654        void startVerifications(int userId);
655        void receiveVerificationResponse(int verificationId);
656    }
657
658    private class IntentVerifierProxy implements IntentFilterVerifier<ActivityIntentInfo> {
659        private Context mContext;
660        private ComponentName mIntentFilterVerifierComponent;
661        private ArrayList<Integer> mCurrentIntentFilterVerifications = new ArrayList<Integer>();
662
663        public IntentVerifierProxy(Context context, ComponentName verifierComponent) {
664            mContext = context;
665            mIntentFilterVerifierComponent = verifierComponent;
666        }
667
668        private String getDefaultScheme() {
669            return IntentFilter.SCHEME_HTTPS;
670        }
671
672        @Override
673        public void startVerifications(int userId) {
674            // Launch verifications requests
675            int count = mCurrentIntentFilterVerifications.size();
676            for (int n=0; n<count; n++) {
677                int verificationId = mCurrentIntentFilterVerifications.get(n);
678                final IntentFilterVerificationState ivs =
679                        mIntentFilterVerificationStates.get(verificationId);
680
681                String packageName = ivs.getPackageName();
682
683                ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters();
684                final int filterCount = filters.size();
685                ArraySet<String> domainsSet = new ArraySet<>();
686                for (int m=0; m<filterCount; m++) {
687                    PackageParser.ActivityIntentInfo filter = filters.get(m);
688                    domainsSet.addAll(filter.getHostsList());
689                }
690                ArrayList<String> domainsList = new ArrayList<>(domainsSet);
691                synchronized (mPackages) {
692                    if (mSettings.createIntentFilterVerificationIfNeededLPw(
693                            packageName, domainsList) != null) {
694                        scheduleWriteSettingsLocked();
695                    }
696                }
697                sendVerificationRequest(userId, verificationId, ivs);
698            }
699            mCurrentIntentFilterVerifications.clear();
700        }
701
702        private void sendVerificationRequest(int userId, int verificationId,
703                IntentFilterVerificationState ivs) {
704
705            Intent verificationIntent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION);
706            verificationIntent.putExtra(
707                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_ID,
708                    verificationId);
709            verificationIntent.putExtra(
710                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_URI_SCHEME,
711                    getDefaultScheme());
712            verificationIntent.putExtra(
713                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_HOSTS,
714                    ivs.getHostsString());
715            verificationIntent.putExtra(
716                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_PACKAGE_NAME,
717                    ivs.getPackageName());
718            verificationIntent.setComponent(mIntentFilterVerifierComponent);
719            verificationIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
720
721            UserHandle user = new UserHandle(userId);
722            mContext.sendBroadcastAsUser(verificationIntent, user);
723            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
724                    "Sending IntentFilter verification broadcast");
725        }
726
727        public void receiveVerificationResponse(int verificationId) {
728            IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId);
729
730            final boolean verified = ivs.isVerified();
731
732            ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters();
733            final int count = filters.size();
734            if (DEBUG_DOMAIN_VERIFICATION) {
735                Slog.i(TAG, "Received verification response " + verificationId
736                        + " for " + count + " filters, verified=" + verified);
737            }
738            for (int n=0; n<count; n++) {
739                PackageParser.ActivityIntentInfo filter = filters.get(n);
740                filter.setVerified(verified);
741
742                if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "IntentFilter " + filter.toString()
743                        + " verified with result:" + verified + " and hosts:"
744                        + ivs.getHostsString());
745            }
746
747            mIntentFilterVerificationStates.remove(verificationId);
748
749            final String packageName = ivs.getPackageName();
750            IntentFilterVerificationInfo ivi = null;
751
752            synchronized (mPackages) {
753                ivi = mSettings.getIntentFilterVerificationLPr(packageName);
754            }
755            if (ivi == null) {
756                Slog.w(TAG, "IntentFilterVerificationInfo not found for verificationId:"
757                        + verificationId + " packageName:" + packageName);
758                return;
759            }
760            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
761                    "Updating IntentFilterVerificationInfo for package " + packageName
762                            +" verificationId:" + verificationId);
763
764            synchronized (mPackages) {
765                if (verified) {
766                    ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS);
767                } else {
768                    ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK);
769                }
770                scheduleWriteSettingsLocked();
771
772                final int userId = ivs.getUserId();
773                if (userId != UserHandle.USER_ALL) {
774                    final int userStatus =
775                            mSettings.getIntentFilterVerificationStatusLPr(packageName, userId);
776
777                    int updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
778                    boolean needUpdate = false;
779
780                    // We cannot override the STATUS_ALWAYS / STATUS_NEVER states if they have
781                    // already been set by the User thru the Disambiguation dialog
782                    switch (userStatus) {
783                        case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED:
784                            if (verified) {
785                                updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
786                            } else {
787                                updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK;
788                            }
789                            needUpdate = true;
790                            break;
791
792                        case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK:
793                            if (verified) {
794                                updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
795                                needUpdate = true;
796                            }
797                            break;
798
799                        default:
800                            // Nothing to do
801                    }
802
803                    if (needUpdate) {
804                        mSettings.updateIntentFilterVerificationStatusLPw(
805                                packageName, updatedStatus, userId);
806                        scheduleWritePackageRestrictionsLocked(userId);
807                    }
808                }
809            }
810        }
811
812        @Override
813        public boolean addOneIntentFilterVerification(int verifierUid, int userId, int verificationId,
814                    ActivityIntentInfo filter, String packageName) {
815            if (!hasValidDomains(filter)) {
816                return false;
817            }
818            IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId);
819            if (ivs == null) {
820                ivs = createDomainVerificationState(verifierUid, userId, verificationId,
821                        packageName);
822            }
823            if (DEBUG_DOMAIN_VERIFICATION) {
824                Slog.d(TAG, "Adding verification filter for " + packageName + ": " + filter);
825            }
826            ivs.addFilter(filter);
827            return true;
828        }
829
830        private IntentFilterVerificationState createDomainVerificationState(int verifierUid,
831                int userId, int verificationId, String packageName) {
832            IntentFilterVerificationState ivs = new IntentFilterVerificationState(
833                    verifierUid, userId, packageName);
834            ivs.setPendingState();
835            synchronized (mPackages) {
836                mIntentFilterVerificationStates.append(verificationId, ivs);
837                mCurrentIntentFilterVerifications.add(verificationId);
838            }
839            return ivs;
840        }
841    }
842
843    private static boolean hasValidDomains(ActivityIntentInfo filter) {
844        return filter.hasCategory(Intent.CATEGORY_BROWSABLE)
845                && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) ||
846                        filter.hasDataScheme(IntentFilter.SCHEME_HTTPS));
847    }
848
849    // Set of pending broadcasts for aggregating enable/disable of components.
850    static class PendingPackageBroadcasts {
851        // for each user id, a map of <package name -> components within that package>
852        final SparseArray<ArrayMap<String, ArrayList<String>>> mUidMap;
853
854        public PendingPackageBroadcasts() {
855            mUidMap = new SparseArray<ArrayMap<String, ArrayList<String>>>(2);
856        }
857
858        public ArrayList<String> get(int userId, String packageName) {
859            ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId);
860            return packages.get(packageName);
861        }
862
863        public void put(int userId, String packageName, ArrayList<String> components) {
864            ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId);
865            packages.put(packageName, components);
866        }
867
868        public void remove(int userId, String packageName) {
869            ArrayMap<String, ArrayList<String>> packages = mUidMap.get(userId);
870            if (packages != null) {
871                packages.remove(packageName);
872            }
873        }
874
875        public void remove(int userId) {
876            mUidMap.remove(userId);
877        }
878
879        public int userIdCount() {
880            return mUidMap.size();
881        }
882
883        public int userIdAt(int n) {
884            return mUidMap.keyAt(n);
885        }
886
887        public ArrayMap<String, ArrayList<String>> packagesForUserId(int userId) {
888            return mUidMap.get(userId);
889        }
890
891        public int size() {
892            // total number of pending broadcast entries across all userIds
893            int num = 0;
894            for (int i = 0; i< mUidMap.size(); i++) {
895                num += mUidMap.valueAt(i).size();
896            }
897            return num;
898        }
899
900        public void clear() {
901            mUidMap.clear();
902        }
903
904        private ArrayMap<String, ArrayList<String>> getOrAllocate(int userId) {
905            ArrayMap<String, ArrayList<String>> map = mUidMap.get(userId);
906            if (map == null) {
907                map = new ArrayMap<String, ArrayList<String>>();
908                mUidMap.put(userId, map);
909            }
910            return map;
911        }
912    }
913    final PendingPackageBroadcasts mPendingBroadcasts = new PendingPackageBroadcasts();
914
915    // Service Connection to remote media container service to copy
916    // package uri's from external media onto secure containers
917    // or internal storage.
918    private IMediaContainerService mContainerService = null;
919
920    static final int SEND_PENDING_BROADCAST = 1;
921    static final int MCS_BOUND = 3;
922    static final int END_COPY = 4;
923    static final int INIT_COPY = 5;
924    static final int MCS_UNBIND = 6;
925    static final int START_CLEANING_PACKAGE = 7;
926    static final int FIND_INSTALL_LOC = 8;
927    static final int POST_INSTALL = 9;
928    static final int MCS_RECONNECT = 10;
929    static final int MCS_GIVE_UP = 11;
930    static final int UPDATED_MEDIA_STATUS = 12;
931    static final int WRITE_SETTINGS = 13;
932    static final int WRITE_PACKAGE_RESTRICTIONS = 14;
933    static final int PACKAGE_VERIFIED = 15;
934    static final int CHECK_PENDING_VERIFICATION = 16;
935    static final int START_INTENT_FILTER_VERIFICATIONS = 17;
936    static final int INTENT_FILTER_VERIFIED = 18;
937
938    static final int WRITE_SETTINGS_DELAY = 10*1000;  // 10 seconds
939
940    // Delay time in millisecs
941    static final int BROADCAST_DELAY = 10 * 1000;
942
943    static UserManagerService sUserManager;
944
945    // Stores a list of users whose package restrictions file needs to be updated
946    private ArraySet<Integer> mDirtyUsers = new ArraySet<Integer>();
947
948    final private DefaultContainerConnection mDefContainerConn =
949            new DefaultContainerConnection();
950    class DefaultContainerConnection implements ServiceConnection {
951        public void onServiceConnected(ComponentName name, IBinder service) {
952            if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceConnected");
953            IMediaContainerService imcs =
954                IMediaContainerService.Stub.asInterface(service);
955            mHandler.sendMessage(mHandler.obtainMessage(MCS_BOUND, imcs));
956        }
957
958        public void onServiceDisconnected(ComponentName name) {
959            if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceDisconnected");
960        }
961    }
962
963    // Recordkeeping of restore-after-install operations that are currently in flight
964    // between the Package Manager and the Backup Manager
965    static class PostInstallData {
966        public InstallArgs args;
967        public PackageInstalledInfo res;
968
969        PostInstallData(InstallArgs _a, PackageInstalledInfo _r) {
970            args = _a;
971            res = _r;
972        }
973    }
974
975    final SparseArray<PostInstallData> mRunningInstalls = new SparseArray<PostInstallData>();
976    int mNextInstallToken = 1;  // nonzero; will be wrapped back to 1 when ++ overflows
977
978    // XML tags for backup/restore of various bits of state
979    private static final String TAG_PREFERRED_BACKUP = "pa";
980    private static final String TAG_DEFAULT_APPS = "da";
981    private static final String TAG_INTENT_FILTER_VERIFICATION = "iv";
982
983    private static final String TAG_PERMISSION_BACKUP = "perm-grant-backup";
984    private static final String TAG_ALL_GRANTS = "rt-grants";
985    private static final String TAG_GRANT = "grant";
986    private static final String ATTR_PACKAGE_NAME = "pkg";
987
988    private static final String TAG_PERMISSION = "perm";
989    private static final String ATTR_PERMISSION_NAME = "name";
990    private static final String ATTR_IS_GRANTED = "g";
991    private static final String ATTR_USER_SET = "set";
992    private static final String ATTR_USER_FIXED = "fixed";
993    private static final String ATTR_REVOKE_ON_UPGRADE = "rou";
994
995    // System/policy permission grants are not backed up
996    private static final int SYSTEM_RUNTIME_GRANT_MASK =
997            FLAG_PERMISSION_POLICY_FIXED
998            | FLAG_PERMISSION_SYSTEM_FIXED
999            | FLAG_PERMISSION_GRANTED_BY_DEFAULT;
1000
1001    // And we back up these user-adjusted states
1002    private static final int USER_RUNTIME_GRANT_MASK =
1003            FLAG_PERMISSION_USER_SET
1004            | FLAG_PERMISSION_USER_FIXED
1005            | FLAG_PERMISSION_REVOKE_ON_UPGRADE;
1006
1007    final @Nullable String mRequiredVerifierPackage;
1008    final @Nullable String mRequiredInstallerPackage;
1009
1010    private final PackageUsage mPackageUsage = new PackageUsage();
1011
1012    private class PackageUsage {
1013        private static final int WRITE_INTERVAL
1014            = (DEBUG_DEXOPT) ? 0 : 30*60*1000; // 30m in ms
1015
1016        private final Object mFileLock = new Object();
1017        private final AtomicLong mLastWritten = new AtomicLong(0);
1018        private final AtomicBoolean mBackgroundWriteRunning = new AtomicBoolean(false);
1019
1020        private boolean mIsHistoricalPackageUsageAvailable = true;
1021
1022        boolean isHistoricalPackageUsageAvailable() {
1023            return mIsHistoricalPackageUsageAvailable;
1024        }
1025
1026        void write(boolean force) {
1027            if (force) {
1028                writeInternal();
1029                return;
1030            }
1031            if (SystemClock.elapsedRealtime() - mLastWritten.get() < WRITE_INTERVAL
1032                && !DEBUG_DEXOPT) {
1033                return;
1034            }
1035            if (mBackgroundWriteRunning.compareAndSet(false, true)) {
1036                new Thread("PackageUsage_DiskWriter") {
1037                    @Override
1038                    public void run() {
1039                        try {
1040                            writeInternal();
1041                        } finally {
1042                            mBackgroundWriteRunning.set(false);
1043                        }
1044                    }
1045                }.start();
1046            }
1047        }
1048
1049        private void writeInternal() {
1050            synchronized (mPackages) {
1051                synchronized (mFileLock) {
1052                    AtomicFile file = getFile();
1053                    FileOutputStream f = null;
1054                    try {
1055                        f = file.startWrite();
1056                        BufferedOutputStream out = new BufferedOutputStream(f);
1057                        FileUtils.setPermissions(file.getBaseFile().getPath(), 0640, SYSTEM_UID, PACKAGE_INFO_GID);
1058                        StringBuilder sb = new StringBuilder();
1059                        for (PackageParser.Package pkg : mPackages.values()) {
1060                            if (pkg.mLastPackageUsageTimeInMills == 0) {
1061                                continue;
1062                            }
1063                            sb.setLength(0);
1064                            sb.append(pkg.packageName);
1065                            sb.append(' ');
1066                            sb.append((long)pkg.mLastPackageUsageTimeInMills);
1067                            sb.append('\n');
1068                            out.write(sb.toString().getBytes(StandardCharsets.US_ASCII));
1069                        }
1070                        out.flush();
1071                        file.finishWrite(f);
1072                    } catch (IOException e) {
1073                        if (f != null) {
1074                            file.failWrite(f);
1075                        }
1076                        Log.e(TAG, "Failed to write package usage times", e);
1077                    }
1078                }
1079            }
1080            mLastWritten.set(SystemClock.elapsedRealtime());
1081        }
1082
1083        void readLP() {
1084            synchronized (mFileLock) {
1085                AtomicFile file = getFile();
1086                BufferedInputStream in = null;
1087                try {
1088                    in = new BufferedInputStream(file.openRead());
1089                    StringBuffer sb = new StringBuffer();
1090                    while (true) {
1091                        String packageName = readToken(in, sb, ' ');
1092                        if (packageName == null) {
1093                            break;
1094                        }
1095                        String timeInMillisString = readToken(in, sb, '\n');
1096                        if (timeInMillisString == null) {
1097                            throw new IOException("Failed to find last usage time for package "
1098                                                  + packageName);
1099                        }
1100                        PackageParser.Package pkg = mPackages.get(packageName);
1101                        if (pkg == null) {
1102                            continue;
1103                        }
1104                        long timeInMillis;
1105                        try {
1106                            timeInMillis = Long.parseLong(timeInMillisString);
1107                        } catch (NumberFormatException e) {
1108                            throw new IOException("Failed to parse " + timeInMillisString
1109                                                  + " as a long.", e);
1110                        }
1111                        pkg.mLastPackageUsageTimeInMills = timeInMillis;
1112                    }
1113                } catch (FileNotFoundException expected) {
1114                    mIsHistoricalPackageUsageAvailable = false;
1115                } catch (IOException e) {
1116                    Log.w(TAG, "Failed to read package usage times", e);
1117                } finally {
1118                    IoUtils.closeQuietly(in);
1119                }
1120            }
1121            mLastWritten.set(SystemClock.elapsedRealtime());
1122        }
1123
1124        private String readToken(InputStream in, StringBuffer sb, char endOfToken)
1125                throws IOException {
1126            sb.setLength(0);
1127            while (true) {
1128                int ch = in.read();
1129                if (ch == -1) {
1130                    if (sb.length() == 0) {
1131                        return null;
1132                    }
1133                    throw new IOException("Unexpected EOF");
1134                }
1135                if (ch == endOfToken) {
1136                    return sb.toString();
1137                }
1138                sb.append((char)ch);
1139            }
1140        }
1141
1142        private AtomicFile getFile() {
1143            File dataDir = Environment.getDataDirectory();
1144            File systemDir = new File(dataDir, "system");
1145            File fname = new File(systemDir, "package-usage.list");
1146            return new AtomicFile(fname);
1147        }
1148    }
1149
1150    class PackageHandler extends Handler {
1151        private boolean mBound = false;
1152        final ArrayList<HandlerParams> mPendingInstalls =
1153            new ArrayList<HandlerParams>();
1154
1155        private boolean connectToService() {
1156            if (DEBUG_SD_INSTALL) Log.i(TAG, "Trying to bind to" +
1157                    " DefaultContainerService");
1158            Intent service = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
1159            Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1160            if (mContext.bindServiceAsUser(service, mDefContainerConn,
1161                    Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) {
1162                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1163                mBound = true;
1164                return true;
1165            }
1166            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1167            return false;
1168        }
1169
1170        private void disconnectService() {
1171            mContainerService = null;
1172            mBound = false;
1173            Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1174            mContext.unbindService(mDefContainerConn);
1175            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1176        }
1177
1178        PackageHandler(Looper looper) {
1179            super(looper);
1180        }
1181
1182        public void handleMessage(Message msg) {
1183            try {
1184                doHandleMessage(msg);
1185            } finally {
1186                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1187            }
1188        }
1189
1190        void doHandleMessage(Message msg) {
1191            switch (msg.what) {
1192                case INIT_COPY: {
1193                    HandlerParams params = (HandlerParams) msg.obj;
1194                    int idx = mPendingInstalls.size();
1195                    if (DEBUG_INSTALL) Slog.i(TAG, "init_copy idx=" + idx + ": " + params);
1196                    // If a bind was already initiated we dont really
1197                    // need to do anything. The pending install
1198                    // will be processed later on.
1199                    if (!mBound) {
1200                        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1201                                System.identityHashCode(mHandler));
1202                        // If this is the only one pending we might
1203                        // have to bind to the service again.
1204                        if (!connectToService()) {
1205                            Slog.e(TAG, "Failed to bind to media container service");
1206                            params.serviceError();
1207                            Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1208                                    System.identityHashCode(mHandler));
1209                            if (params.traceMethod != null) {
1210                                Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, params.traceMethod,
1211                                        params.traceCookie);
1212                            }
1213                            return;
1214                        } else {
1215                            // Once we bind to the service, the first
1216                            // pending request will be processed.
1217                            mPendingInstalls.add(idx, params);
1218                        }
1219                    } else {
1220                        mPendingInstalls.add(idx, params);
1221                        // Already bound to the service. Just make
1222                        // sure we trigger off processing the first request.
1223                        if (idx == 0) {
1224                            mHandler.sendEmptyMessage(MCS_BOUND);
1225                        }
1226                    }
1227                    break;
1228                }
1229                case MCS_BOUND: {
1230                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_bound");
1231                    if (msg.obj != null) {
1232                        mContainerService = (IMediaContainerService) msg.obj;
1233                        Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1234                                System.identityHashCode(mHandler));
1235                    }
1236                    if (mContainerService == null) {
1237                        if (!mBound) {
1238                            // Something seriously wrong since we are not bound and we are not
1239                            // waiting for connection. Bail out.
1240                            Slog.e(TAG, "Cannot bind to media container service");
1241                            for (HandlerParams params : mPendingInstalls) {
1242                                // Indicate service bind error
1243                                params.serviceError();
1244                                Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1245                                        System.identityHashCode(params));
1246                                if (params.traceMethod != null) {
1247                                    Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER,
1248                                            params.traceMethod, params.traceCookie);
1249                                }
1250                                return;
1251                            }
1252                            mPendingInstalls.clear();
1253                        } else {
1254                            Slog.w(TAG, "Waiting to connect to media container service");
1255                        }
1256                    } else if (mPendingInstalls.size() > 0) {
1257                        HandlerParams params = mPendingInstalls.get(0);
1258                        if (params != null) {
1259                            Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1260                                    System.identityHashCode(params));
1261                            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "startCopy");
1262                            if (params.startCopy()) {
1263                                // We are done...  look for more work or to
1264                                // go idle.
1265                                if (DEBUG_SD_INSTALL) Log.i(TAG,
1266                                        "Checking for more work or unbind...");
1267                                // Delete pending install
1268                                if (mPendingInstalls.size() > 0) {
1269                                    mPendingInstalls.remove(0);
1270                                }
1271                                if (mPendingInstalls.size() == 0) {
1272                                    if (mBound) {
1273                                        if (DEBUG_SD_INSTALL) Log.i(TAG,
1274                                                "Posting delayed MCS_UNBIND");
1275                                        removeMessages(MCS_UNBIND);
1276                                        Message ubmsg = obtainMessage(MCS_UNBIND);
1277                                        // Unbind after a little delay, to avoid
1278                                        // continual thrashing.
1279                                        sendMessageDelayed(ubmsg, 10000);
1280                                    }
1281                                } else {
1282                                    // There are more pending requests in queue.
1283                                    // Just post MCS_BOUND message to trigger processing
1284                                    // of next pending install.
1285                                    if (DEBUG_SD_INSTALL) Log.i(TAG,
1286                                            "Posting MCS_BOUND for next work");
1287                                    mHandler.sendEmptyMessage(MCS_BOUND);
1288                                }
1289                            }
1290                            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
1291                        }
1292                    } else {
1293                        // Should never happen ideally.
1294                        Slog.w(TAG, "Empty queue");
1295                    }
1296                    break;
1297                }
1298                case MCS_RECONNECT: {
1299                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_reconnect");
1300                    if (mPendingInstalls.size() > 0) {
1301                        if (mBound) {
1302                            disconnectService();
1303                        }
1304                        if (!connectToService()) {
1305                            Slog.e(TAG, "Failed to bind to media container service");
1306                            for (HandlerParams params : mPendingInstalls) {
1307                                // Indicate service bind error
1308                                params.serviceError();
1309                                Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1310                                        System.identityHashCode(params));
1311                            }
1312                            mPendingInstalls.clear();
1313                        }
1314                    }
1315                    break;
1316                }
1317                case MCS_UNBIND: {
1318                    // If there is no actual work left, then time to unbind.
1319                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_unbind");
1320
1321                    if (mPendingInstalls.size() == 0 && mPendingVerification.size() == 0) {
1322                        if (mBound) {
1323                            if (DEBUG_INSTALL) Slog.i(TAG, "calling disconnectService()");
1324
1325                            disconnectService();
1326                        }
1327                    } else if (mPendingInstalls.size() > 0) {
1328                        // There are more pending requests in queue.
1329                        // Just post MCS_BOUND message to trigger processing
1330                        // of next pending install.
1331                        mHandler.sendEmptyMessage(MCS_BOUND);
1332                    }
1333
1334                    break;
1335                }
1336                case MCS_GIVE_UP: {
1337                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_giveup too many retries");
1338                    HandlerParams params = mPendingInstalls.remove(0);
1339                    Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1340                            System.identityHashCode(params));
1341                    break;
1342                }
1343                case SEND_PENDING_BROADCAST: {
1344                    String packages[];
1345                    ArrayList<String> components[];
1346                    int size = 0;
1347                    int uids[];
1348                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1349                    synchronized (mPackages) {
1350                        if (mPendingBroadcasts == null) {
1351                            return;
1352                        }
1353                        size = mPendingBroadcasts.size();
1354                        if (size <= 0) {
1355                            // Nothing to be done. Just return
1356                            return;
1357                        }
1358                        packages = new String[size];
1359                        components = new ArrayList[size];
1360                        uids = new int[size];
1361                        int i = 0;  // filling out the above arrays
1362
1363                        for (int n = 0; n < mPendingBroadcasts.userIdCount(); n++) {
1364                            int packageUserId = mPendingBroadcasts.userIdAt(n);
1365                            Iterator<Map.Entry<String, ArrayList<String>>> it
1366                                    = mPendingBroadcasts.packagesForUserId(packageUserId)
1367                                            .entrySet().iterator();
1368                            while (it.hasNext() && i < size) {
1369                                Map.Entry<String, ArrayList<String>> ent = it.next();
1370                                packages[i] = ent.getKey();
1371                                components[i] = ent.getValue();
1372                                PackageSetting ps = mSettings.mPackages.get(ent.getKey());
1373                                uids[i] = (ps != null)
1374                                        ? UserHandle.getUid(packageUserId, ps.appId)
1375                                        : -1;
1376                                i++;
1377                            }
1378                        }
1379                        size = i;
1380                        mPendingBroadcasts.clear();
1381                    }
1382                    // Send broadcasts
1383                    for (int i = 0; i < size; i++) {
1384                        sendPackageChangedBroadcast(packages[i], true, components[i], uids[i]);
1385                    }
1386                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1387                    break;
1388                }
1389                case START_CLEANING_PACKAGE: {
1390                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1391                    final String packageName = (String)msg.obj;
1392                    final int userId = msg.arg1;
1393                    final boolean andCode = msg.arg2 != 0;
1394                    synchronized (mPackages) {
1395                        if (userId == UserHandle.USER_ALL) {
1396                            int[] users = sUserManager.getUserIds();
1397                            for (int user : users) {
1398                                mSettings.addPackageToCleanLPw(
1399                                        new PackageCleanItem(user, packageName, andCode));
1400                            }
1401                        } else {
1402                            mSettings.addPackageToCleanLPw(
1403                                    new PackageCleanItem(userId, packageName, andCode));
1404                        }
1405                    }
1406                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1407                    startCleaningPackages();
1408                } break;
1409                case POST_INSTALL: {
1410                    if (DEBUG_INSTALL) Log.v(TAG, "Handling post-install for " + msg.arg1);
1411
1412                    PostInstallData data = mRunningInstalls.get(msg.arg1);
1413                    mRunningInstalls.delete(msg.arg1);
1414                    boolean deleteOld = false;
1415
1416                    if (data != null) {
1417                        InstallArgs args = data.args;
1418                        PackageInstalledInfo res = data.res;
1419
1420                        if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
1421                            final String packageName = res.pkg.applicationInfo.packageName;
1422                            res.removedInfo.sendBroadcast(false, true, false);
1423                            Bundle extras = new Bundle(1);
1424                            extras.putInt(Intent.EXTRA_UID, res.uid);
1425
1426                            // Now that we successfully installed the package, grant runtime
1427                            // permissions if requested before broadcasting the install.
1428                            if ((args.installFlags
1429                                    & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0
1430                                    && res.pkg.applicationInfo.targetSdkVersion
1431                                            >= Build.VERSION_CODES.M) {
1432                                grantRequestedRuntimePermissions(res.pkg, args.user.getIdentifier(),
1433                                        args.installGrantPermissions);
1434                            }
1435
1436                            synchronized (mPackages) {
1437                                mEphemeralApplicationRegistry.onPackageInstalledLPw(res.pkg);
1438                            }
1439
1440                            // Determine the set of users who are adding this
1441                            // package for the first time vs. those who are seeing
1442                            // an update.
1443                            int[] firstUsers;
1444                            int[] updateUsers = new int[0];
1445                            if (res.origUsers == null || res.origUsers.length == 0) {
1446                                firstUsers = res.newUsers;
1447                            } else {
1448                                firstUsers = new int[0];
1449                                for (int i=0; i<res.newUsers.length; i++) {
1450                                    int user = res.newUsers[i];
1451                                    boolean isNew = true;
1452                                    for (int j=0; j<res.origUsers.length; j++) {
1453                                        if (res.origUsers[j] == user) {
1454                                            isNew = false;
1455                                            break;
1456                                        }
1457                                    }
1458                                    if (isNew) {
1459                                        int[] newFirst = new int[firstUsers.length+1];
1460                                        System.arraycopy(firstUsers, 0, newFirst, 0,
1461                                                firstUsers.length);
1462                                        newFirst[firstUsers.length] = user;
1463                                        firstUsers = newFirst;
1464                                    } else {
1465                                        int[] newUpdate = new int[updateUsers.length+1];
1466                                        System.arraycopy(updateUsers, 0, newUpdate, 0,
1467                                                updateUsers.length);
1468                                        newUpdate[updateUsers.length] = user;
1469                                        updateUsers = newUpdate;
1470                                    }
1471                                }
1472                            }
1473                            // don't broadcast for ephemeral installs/updates
1474                            final boolean isEphemeral = isEphemeral(res.pkg);
1475                            if (!isEphemeral) {
1476                                sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
1477                                        extras, 0 /*flags*/, null /*targetPackage*/,
1478                                        null /*finishedReceiver*/, firstUsers);
1479                            }
1480                            final boolean update = res.removedInfo.removedPackage != null;
1481                            if (update) {
1482                                extras.putBoolean(Intent.EXTRA_REPLACING, true);
1483                            }
1484                            if (!isEphemeral) {
1485                                sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
1486                                        extras, 0 /*flags*/, null /*targetPackage*/,
1487                                        null /*finishedReceiver*/, updateUsers);
1488                            }
1489                            if (update) {
1490                                if (!isEphemeral) {
1491                                    sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
1492                                            packageName, extras, 0 /*flags*/,
1493                                            null /*targetPackage*/, null /*finishedReceiver*/,
1494                                            updateUsers);
1495                                    sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
1496                                            null /*package*/, null /*extras*/, 0 /*flags*/,
1497                                            packageName /*targetPackage*/,
1498                                            null /*finishedReceiver*/, updateUsers);
1499                                }
1500
1501                                // treat asec-hosted packages like removable media on upgrade
1502                                if (res.pkg.isForwardLocked() || isExternal(res.pkg)) {
1503                                    if (DEBUG_INSTALL) {
1504                                        Slog.i(TAG, "upgrading pkg " + res.pkg
1505                                                + " is ASEC-hosted -> AVAILABLE");
1506                                    }
1507                                    int[] uidArray = new int[] { res.pkg.applicationInfo.uid };
1508                                    ArrayList<String> pkgList = new ArrayList<String>(1);
1509                                    pkgList.add(packageName);
1510                                    sendResourcesChangedBroadcast(true, true,
1511                                            pkgList,uidArray, null);
1512                                }
1513                            }
1514                            if (res.removedInfo.args != null) {
1515                                // Remove the replaced package's older resources safely now
1516                                deleteOld = true;
1517                            }
1518
1519
1520                            // Work that needs to happen on first install within each user
1521                            if (firstUsers.length > 0) {
1522                                for (int userId : firstUsers) {
1523                                    synchronized (mPackages) {
1524                                        // If this app is a browser and it's newly-installed for
1525                                        // some users, clear any default-browser state in those
1526                                        // users.  The app's nature doesn't depend on the user,
1527                                        // so we can just check its browser nature in any user
1528                                        // and generalize.
1529                                        if (packageIsBrowser(packageName, firstUsers[0])) {
1530                                            mSettings.setDefaultBrowserPackageNameLPw(
1531                                                    null, userId);
1532                                        }
1533
1534                                        // We may also need to apply pending (restored) runtime
1535                                        // permission grants within these users.
1536                                        mSettings.applyPendingPermissionGrantsLPw(
1537                                                packageName, userId);
1538                                    }
1539                                }
1540                            }
1541                            // Log current value of "unknown sources" setting
1542                            EventLog.writeEvent(EventLogTags.UNKNOWN_SOURCES_ENABLED,
1543                                getUnknownSourcesSettings());
1544                        }
1545                        // Force a gc to clear up things
1546                        Runtime.getRuntime().gc();
1547                        // We delete after a gc for applications  on sdcard.
1548                        if (deleteOld) {
1549                            synchronized (mInstallLock) {
1550                                res.removedInfo.args.doPostDeleteLI(true);
1551                            }
1552                        }
1553                        if (args.observer != null) {
1554                            try {
1555                                Bundle extras = extrasForInstallResult(res);
1556                                args.observer.onPackageInstalled(res.name, res.returnCode,
1557                                        res.returnMsg, extras);
1558                            } catch (RemoteException e) {
1559                                Slog.i(TAG, "Observer no longer exists.");
1560                            }
1561                        }
1562                        if (args.traceMethod != null) {
1563                            Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, args.traceMethod,
1564                                    args.traceCookie);
1565                        }
1566                        return;
1567                    } else {
1568                        Slog.e(TAG, "Bogus post-install token " + msg.arg1);
1569                    }
1570
1571                    Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "postInstall", msg.arg1);
1572                } break;
1573                case UPDATED_MEDIA_STATUS: {
1574                    if (DEBUG_SD_INSTALL) Log.i(TAG, "Got message UPDATED_MEDIA_STATUS");
1575                    boolean reportStatus = msg.arg1 == 1;
1576                    boolean doGc = msg.arg2 == 1;
1577                    if (DEBUG_SD_INSTALL) Log.i(TAG, "reportStatus=" + reportStatus + ", doGc = " + doGc);
1578                    if (doGc) {
1579                        // Force a gc to clear up stale containers.
1580                        Runtime.getRuntime().gc();
1581                    }
1582                    if (msg.obj != null) {
1583                        @SuppressWarnings("unchecked")
1584                        Set<AsecInstallArgs> args = (Set<AsecInstallArgs>) msg.obj;
1585                        if (DEBUG_SD_INSTALL) Log.i(TAG, "Unloading all containers");
1586                        // Unload containers
1587                        unloadAllContainers(args);
1588                    }
1589                    if (reportStatus) {
1590                        try {
1591                            if (DEBUG_SD_INSTALL) Log.i(TAG, "Invoking MountService call back");
1592                            PackageHelper.getMountService().finishMediaUpdate();
1593                        } catch (RemoteException e) {
1594                            Log.e(TAG, "MountService not running?");
1595                        }
1596                    }
1597                } break;
1598                case WRITE_SETTINGS: {
1599                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1600                    synchronized (mPackages) {
1601                        removeMessages(WRITE_SETTINGS);
1602                        removeMessages(WRITE_PACKAGE_RESTRICTIONS);
1603                        mSettings.writeLPr();
1604                        mDirtyUsers.clear();
1605                    }
1606                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1607                } break;
1608                case WRITE_PACKAGE_RESTRICTIONS: {
1609                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1610                    synchronized (mPackages) {
1611                        removeMessages(WRITE_PACKAGE_RESTRICTIONS);
1612                        for (int userId : mDirtyUsers) {
1613                            mSettings.writePackageRestrictionsLPr(userId);
1614                        }
1615                        mDirtyUsers.clear();
1616                    }
1617                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1618                } break;
1619                case CHECK_PENDING_VERIFICATION: {
1620                    final int verificationId = msg.arg1;
1621                    final PackageVerificationState state = mPendingVerification.get(verificationId);
1622
1623                    if ((state != null) && !state.timeoutExtended()) {
1624                        final InstallArgs args = state.getInstallArgs();
1625                        final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
1626
1627                        Slog.i(TAG, "Verification timed out for " + originUri);
1628                        mPendingVerification.remove(verificationId);
1629
1630                        int ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
1631
1632                        if (getDefaultVerificationResponse() == PackageManager.VERIFICATION_ALLOW) {
1633                            Slog.i(TAG, "Continuing with installation of " + originUri);
1634                            state.setVerifierResponse(Binder.getCallingUid(),
1635                                    PackageManager.VERIFICATION_ALLOW_WITHOUT_SUFFICIENT);
1636                            broadcastPackageVerified(verificationId, originUri,
1637                                    PackageManager.VERIFICATION_ALLOW,
1638                                    state.getInstallArgs().getUser());
1639                            try {
1640                                ret = args.copyApk(mContainerService, true);
1641                            } catch (RemoteException e) {
1642                                Slog.e(TAG, "Could not contact the ContainerService");
1643                            }
1644                        } else {
1645                            broadcastPackageVerified(verificationId, originUri,
1646                                    PackageManager.VERIFICATION_REJECT,
1647                                    state.getInstallArgs().getUser());
1648                        }
1649
1650                        Trace.asyncTraceEnd(
1651                                TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
1652
1653                        processPendingInstall(args, ret);
1654                        mHandler.sendEmptyMessage(MCS_UNBIND);
1655                    }
1656                    break;
1657                }
1658                case PACKAGE_VERIFIED: {
1659                    final int verificationId = msg.arg1;
1660
1661                    final PackageVerificationState state = mPendingVerification.get(verificationId);
1662                    if (state == null) {
1663                        Slog.w(TAG, "Invalid verification token " + verificationId + " received");
1664                        break;
1665                    }
1666
1667                    final PackageVerificationResponse response = (PackageVerificationResponse) msg.obj;
1668
1669                    state.setVerifierResponse(response.callerUid, response.code);
1670
1671                    if (state.isVerificationComplete()) {
1672                        mPendingVerification.remove(verificationId);
1673
1674                        final InstallArgs args = state.getInstallArgs();
1675                        final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
1676
1677                        int ret;
1678                        if (state.isInstallAllowed()) {
1679                            ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
1680                            broadcastPackageVerified(verificationId, originUri,
1681                                    response.code, state.getInstallArgs().getUser());
1682                            try {
1683                                ret = args.copyApk(mContainerService, true);
1684                            } catch (RemoteException e) {
1685                                Slog.e(TAG, "Could not contact the ContainerService");
1686                            }
1687                        } else {
1688                            ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
1689                        }
1690
1691                        Trace.asyncTraceEnd(
1692                                TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
1693
1694                        processPendingInstall(args, ret);
1695                        mHandler.sendEmptyMessage(MCS_UNBIND);
1696                    }
1697
1698                    break;
1699                }
1700                case START_INTENT_FILTER_VERIFICATIONS: {
1701                    IFVerificationParams params = (IFVerificationParams) msg.obj;
1702                    verifyIntentFiltersIfNeeded(params.userId, params.verifierUid,
1703                            params.replacing, params.pkg);
1704                    break;
1705                }
1706                case INTENT_FILTER_VERIFIED: {
1707                    final int verificationId = msg.arg1;
1708
1709                    final IntentFilterVerificationState state = mIntentFilterVerificationStates.get(
1710                            verificationId);
1711                    if (state == null) {
1712                        Slog.w(TAG, "Invalid IntentFilter verification token "
1713                                + verificationId + " received");
1714                        break;
1715                    }
1716
1717                    final int userId = state.getUserId();
1718
1719                    if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1720                            "Processing IntentFilter verification with token:"
1721                            + verificationId + " and userId:" + userId);
1722
1723                    final IntentFilterVerificationResponse response =
1724                            (IntentFilterVerificationResponse) msg.obj;
1725
1726                    state.setVerifierResponse(response.callerUid, response.code);
1727
1728                    if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1729                            "IntentFilter verification with token:" + verificationId
1730                            + " and userId:" + userId
1731                            + " is settings verifier response with response code:"
1732                            + response.code);
1733
1734                    if (response.code == PackageManager.INTENT_FILTER_VERIFICATION_FAILURE) {
1735                        if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Domains failing verification: "
1736                                + response.getFailedDomainsString());
1737                    }
1738
1739                    if (state.isVerificationComplete()) {
1740                        mIntentFilterVerifier.receiveVerificationResponse(verificationId);
1741                    } else {
1742                        if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1743                                "IntentFilter verification with token:" + verificationId
1744                                + " was not said to be complete");
1745                    }
1746
1747                    break;
1748                }
1749            }
1750        }
1751    }
1752
1753    private StorageEventListener mStorageListener = new StorageEventListener() {
1754        @Override
1755        public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState) {
1756            if (vol.type == VolumeInfo.TYPE_PRIVATE) {
1757                if (vol.state == VolumeInfo.STATE_MOUNTED) {
1758                    final String volumeUuid = vol.getFsUuid();
1759
1760                    // Clean up any users or apps that were removed or recreated
1761                    // while this volume was missing
1762                    reconcileUsers(volumeUuid);
1763                    reconcileApps(volumeUuid);
1764
1765                    // Clean up any install sessions that expired or were
1766                    // cancelled while this volume was missing
1767                    mInstallerService.onPrivateVolumeMounted(volumeUuid);
1768
1769                    loadPrivatePackages(vol);
1770
1771                } else if (vol.state == VolumeInfo.STATE_EJECTING) {
1772                    unloadPrivatePackages(vol);
1773                }
1774            }
1775
1776            if (vol.type == VolumeInfo.TYPE_PUBLIC && vol.isPrimary()) {
1777                if (vol.state == VolumeInfo.STATE_MOUNTED) {
1778                    updateExternalMediaStatus(true, false);
1779                } else if (vol.state == VolumeInfo.STATE_EJECTING) {
1780                    updateExternalMediaStatus(false, false);
1781                }
1782            }
1783        }
1784
1785        @Override
1786        public void onVolumeForgotten(String fsUuid) {
1787            if (TextUtils.isEmpty(fsUuid)) {
1788                Slog.e(TAG, "Forgetting internal storage is probably a mistake; ignoring");
1789                return;
1790            }
1791
1792            // Remove any apps installed on the forgotten volume
1793            synchronized (mPackages) {
1794                final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(fsUuid);
1795                for (PackageSetting ps : packages) {
1796                    Slog.d(TAG, "Destroying " + ps.name + " because volume was forgotten");
1797                    deletePackage(ps.name, new LegacyPackageDeleteObserver(null).getBinder(),
1798                            UserHandle.USER_SYSTEM, PackageManager.DELETE_ALL_USERS);
1799                }
1800
1801                mSettings.onVolumeForgotten(fsUuid);
1802                mSettings.writeLPr();
1803            }
1804        }
1805    };
1806
1807    private void grantRequestedRuntimePermissions(PackageParser.Package pkg, int userId,
1808            String[] grantedPermissions) {
1809        if (userId >= UserHandle.USER_SYSTEM) {
1810            grantRequestedRuntimePermissionsForUser(pkg, userId, grantedPermissions);
1811        } else if (userId == UserHandle.USER_ALL) {
1812            final int[] userIds;
1813            synchronized (mPackages) {
1814                userIds = UserManagerService.getInstance().getUserIds();
1815            }
1816            for (int someUserId : userIds) {
1817                grantRequestedRuntimePermissionsForUser(pkg, someUserId, grantedPermissions);
1818            }
1819        }
1820
1821        // We could have touched GID membership, so flush out packages.list
1822        synchronized (mPackages) {
1823            mSettings.writePackageListLPr();
1824        }
1825    }
1826
1827    private void grantRequestedRuntimePermissionsForUser(PackageParser.Package pkg, int userId,
1828            String[] grantedPermissions) {
1829        SettingBase sb = (SettingBase) pkg.mExtras;
1830        if (sb == null) {
1831            return;
1832        }
1833
1834        PermissionsState permissionsState = sb.getPermissionsState();
1835
1836        final int immutableFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
1837                | PackageManager.FLAG_PERMISSION_POLICY_FIXED;
1838
1839        synchronized (mPackages) {
1840            for (String permission : pkg.requestedPermissions) {
1841                BasePermission bp = mSettings.mPermissions.get(permission);
1842                if (bp != null && (bp.isRuntime() || bp.isDevelopment())
1843                        && (grantedPermissions == null
1844                               || ArrayUtils.contains(grantedPermissions, permission))) {
1845                    final int flags = permissionsState.getPermissionFlags(permission, userId);
1846                    // Installer cannot change immutable permissions.
1847                    if ((flags & immutableFlags) == 0) {
1848                        grantRuntimePermission(pkg.packageName, permission, userId);
1849                    }
1850                }
1851            }
1852        }
1853    }
1854
1855    Bundle extrasForInstallResult(PackageInstalledInfo res) {
1856        Bundle extras = null;
1857        switch (res.returnCode) {
1858            case PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION: {
1859                extras = new Bundle();
1860                extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PERMISSION,
1861                        res.origPermission);
1862                extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PACKAGE,
1863                        res.origPackage);
1864                break;
1865            }
1866            case PackageManager.INSTALL_SUCCEEDED: {
1867                extras = new Bundle();
1868                extras.putBoolean(Intent.EXTRA_REPLACING,
1869                        res.removedInfo != null && res.removedInfo.removedPackage != null);
1870                break;
1871            }
1872        }
1873        return extras;
1874    }
1875
1876    void scheduleWriteSettingsLocked() {
1877        if (!mHandler.hasMessages(WRITE_SETTINGS)) {
1878            mHandler.sendEmptyMessageDelayed(WRITE_SETTINGS, WRITE_SETTINGS_DELAY);
1879        }
1880    }
1881
1882    void scheduleWritePackageRestrictionsLocked(int userId) {
1883        if (!sUserManager.exists(userId)) return;
1884        mDirtyUsers.add(userId);
1885        if (!mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) {
1886            mHandler.sendEmptyMessageDelayed(WRITE_PACKAGE_RESTRICTIONS, WRITE_SETTINGS_DELAY);
1887        }
1888    }
1889
1890    public static PackageManagerService main(Context context, Installer installer,
1891            boolean factoryTest, boolean onlyCore) {
1892        PackageManagerService m = new PackageManagerService(context, installer,
1893                factoryTest, onlyCore);
1894        m.enableSystemUserPackages();
1895        ServiceManager.addService("package", m);
1896        return m;
1897    }
1898
1899    private void enableSystemUserPackages() {
1900        if (!UserManager.isSplitSystemUser()) {
1901            return;
1902        }
1903        // For system user, enable apps based on the following conditions:
1904        // - app is whitelisted or belong to one of these groups:
1905        //   -- system app which has no launcher icons
1906        //   -- system app which has INTERACT_ACROSS_USERS permission
1907        //   -- system IME app
1908        // - app is not in the blacklist
1909        AppsQueryHelper queryHelper = new AppsQueryHelper(this);
1910        Set<String> enableApps = new ArraySet<>();
1911        enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_NON_LAUNCHABLE_APPS
1912                | AppsQueryHelper.GET_APPS_WITH_INTERACT_ACROSS_USERS_PERM
1913                | AppsQueryHelper.GET_IMES, /* systemAppsOnly */ true, UserHandle.SYSTEM));
1914        ArraySet<String> wlApps = SystemConfig.getInstance().getSystemUserWhitelistedApps();
1915        enableApps.addAll(wlApps);
1916        enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_REQUIRED_FOR_SYSTEM_USER,
1917                /* systemAppsOnly */ false, UserHandle.SYSTEM));
1918        ArraySet<String> blApps = SystemConfig.getInstance().getSystemUserBlacklistedApps();
1919        enableApps.removeAll(blApps);
1920        Log.i(TAG, "Applications installed for system user: " + enableApps);
1921        List<String> allAps = queryHelper.queryApps(0, /* systemAppsOnly */ false,
1922                UserHandle.SYSTEM);
1923        final int allAppsSize = allAps.size();
1924        synchronized (mPackages) {
1925            for (int i = 0; i < allAppsSize; i++) {
1926                String pName = allAps.get(i);
1927                PackageSetting pkgSetting = mSettings.mPackages.get(pName);
1928                // Should not happen, but we shouldn't be failing if it does
1929                if (pkgSetting == null) {
1930                    continue;
1931                }
1932                boolean install = enableApps.contains(pName);
1933                if (pkgSetting.getInstalled(UserHandle.USER_SYSTEM) != install) {
1934                    Log.i(TAG, (install ? "Installing " : "Uninstalling ") + pName
1935                            + " for system user");
1936                    pkgSetting.setInstalled(install, UserHandle.USER_SYSTEM);
1937                }
1938            }
1939        }
1940    }
1941
1942    private static void getDefaultDisplayMetrics(Context context, DisplayMetrics metrics) {
1943        DisplayManager displayManager = (DisplayManager) context.getSystemService(
1944                Context.DISPLAY_SERVICE);
1945        displayManager.getDisplay(Display.DEFAULT_DISPLAY).getMetrics(metrics);
1946    }
1947
1948    public PackageManagerService(Context context, Installer installer,
1949            boolean factoryTest, boolean onlyCore) {
1950        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START,
1951                SystemClock.uptimeMillis());
1952
1953        if (mSdkVersion <= 0) {
1954            Slog.w(TAG, "**** ro.build.version.sdk not set!");
1955        }
1956
1957        mContext = context;
1958        mFactoryTest = factoryTest;
1959        mOnlyCore = onlyCore;
1960        mMetrics = new DisplayMetrics();
1961        mSettings = new Settings(mPackages);
1962        mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID,
1963                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
1964        mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID,
1965                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
1966        mSettings.addSharedUserLPw("android.uid.log", LOG_UID,
1967                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
1968        mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID,
1969                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
1970        mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID,
1971                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
1972        mSettings.addSharedUserLPw("android.uid.shell", SHELL_UID,
1973                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
1974
1975        String separateProcesses = SystemProperties.get("debug.separate_processes");
1976        if (separateProcesses != null && separateProcesses.length() > 0) {
1977            if ("*".equals(separateProcesses)) {
1978                mDefParseFlags = PackageParser.PARSE_IGNORE_PROCESSES;
1979                mSeparateProcesses = null;
1980                Slog.w(TAG, "Running with debug.separate_processes: * (ALL)");
1981            } else {
1982                mDefParseFlags = 0;
1983                mSeparateProcesses = separateProcesses.split(",");
1984                Slog.w(TAG, "Running with debug.separate_processes: "
1985                        + separateProcesses);
1986            }
1987        } else {
1988            mDefParseFlags = 0;
1989            mSeparateProcesses = null;
1990        }
1991
1992        mInstaller = installer;
1993        mPackageDexOptimizer = new PackageDexOptimizer(this);
1994        mMoveCallbacks = new MoveCallbacks(FgThread.get().getLooper());
1995
1996        mOnPermissionChangeListeners = new OnPermissionChangeListeners(
1997                FgThread.get().getLooper());
1998
1999        getDefaultDisplayMetrics(context, mMetrics);
2000
2001        SystemConfig systemConfig = SystemConfig.getInstance();
2002        mGlobalGids = systemConfig.getGlobalGids();
2003        mSystemPermissions = systemConfig.getSystemPermissions();
2004        mAvailableFeatures = systemConfig.getAvailableFeatures();
2005
2006        synchronized (mInstallLock) {
2007        // writer
2008        synchronized (mPackages) {
2009            mHandlerThread = new ServiceThread(TAG,
2010                    Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
2011            mHandlerThread.start();
2012            mHandler = new PackageHandler(mHandlerThread.getLooper());
2013            Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT);
2014
2015            File dataDir = Environment.getDataDirectory();
2016            mAppInstallDir = new File(dataDir, "app");
2017            mAppLib32InstallDir = new File(dataDir, "app-lib");
2018            mEphemeralInstallDir = new File(dataDir, "app-ephemeral");
2019            mAsecInternalPath = new File(dataDir, "app-asec").getPath();
2020            mDrmAppPrivateInstallDir = new File(dataDir, "app-private");
2021
2022            sUserManager = new UserManagerService(context, this, mPackages);
2023
2024            // Propagate permission configuration in to package manager.
2025            ArrayMap<String, SystemConfig.PermissionEntry> permConfig
2026                    = systemConfig.getPermissions();
2027            for (int i=0; i<permConfig.size(); i++) {
2028                SystemConfig.PermissionEntry perm = permConfig.valueAt(i);
2029                BasePermission bp = mSettings.mPermissions.get(perm.name);
2030                if (bp == null) {
2031                    bp = new BasePermission(perm.name, "android", BasePermission.TYPE_BUILTIN);
2032                    mSettings.mPermissions.put(perm.name, bp);
2033                }
2034                if (perm.gids != null) {
2035                    bp.setGids(perm.gids, perm.perUser);
2036                }
2037            }
2038
2039            ArrayMap<String, String> libConfig = systemConfig.getSharedLibraries();
2040            for (int i=0; i<libConfig.size(); i++) {
2041                mSharedLibraries.put(libConfig.keyAt(i),
2042                        new SharedLibraryEntry(libConfig.valueAt(i), null));
2043            }
2044
2045            mFoundPolicyFile = SELinuxMMAC.readInstallPolicy();
2046
2047            mRestoredSettings = mSettings.readLPw(sUserManager.getUsers(false));
2048
2049            String customResolverActivity = Resources.getSystem().getString(
2050                    R.string.config_customResolverActivity);
2051            if (TextUtils.isEmpty(customResolverActivity)) {
2052                customResolverActivity = null;
2053            } else {
2054                mCustomResolverComponentName = ComponentName.unflattenFromString(
2055                        customResolverActivity);
2056            }
2057
2058            long startTime = SystemClock.uptimeMillis();
2059
2060            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START,
2061                    startTime);
2062
2063            // Set flag to monitor and not change apk file paths when
2064            // scanning install directories.
2065            final int scanFlags = SCAN_NO_PATHS | SCAN_DEFER_DEX | SCAN_BOOTING | SCAN_INITIAL;
2066
2067            final String bootClassPath = System.getenv("BOOTCLASSPATH");
2068            final String systemServerClassPath = System.getenv("SYSTEMSERVERCLASSPATH");
2069
2070            if (bootClassPath == null) {
2071                Slog.w(TAG, "No BOOTCLASSPATH found!");
2072            }
2073
2074            if (systemServerClassPath == null) {
2075                Slog.w(TAG, "No SYSTEMSERVERCLASSPATH found!");
2076            }
2077
2078            final List<String> allInstructionSets = InstructionSets.getAllInstructionSets();
2079            final String[] dexCodeInstructionSets =
2080                    getDexCodeInstructionSets(
2081                            allInstructionSets.toArray(new String[allInstructionSets.size()]));
2082
2083            /**
2084             * Ensure all external libraries have had dexopt run on them.
2085             */
2086            if (mSharedLibraries.size() > 0) {
2087                // NOTE: For now, we're compiling these system "shared libraries"
2088                // (and framework jars) into all available architectures. It's possible
2089                // to compile them only when we come across an app that uses them (there's
2090                // already logic for that in scanPackageLI) but that adds some complexity.
2091                for (String dexCodeInstructionSet : dexCodeInstructionSets) {
2092                    for (SharedLibraryEntry libEntry : mSharedLibraries.values()) {
2093                        final String lib = libEntry.path;
2094                        if (lib == null) {
2095                            continue;
2096                        }
2097
2098                        try {
2099                            int dexoptNeeded = DexFile.getDexOptNeeded(lib, null, dexCodeInstructionSet, false);
2100                            if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) {
2101                                // Shared libraries do not have profiles so we perform a full
2102                                // AOT compilation.
2103                                mInstaller.dexopt(lib, Process.SYSTEM_UID, dexCodeInstructionSet,
2104                                        dexoptNeeded, DEXOPT_PUBLIC /*dexFlags*/,
2105                                        StorageManager.UUID_PRIVATE_INTERNAL,
2106                                        false /*useProfiles*/);
2107                            }
2108                        } catch (FileNotFoundException e) {
2109                            Slog.w(TAG, "Library not found: " + lib);
2110                        } catch (IOException | InstallerException e) {
2111                            Slog.w(TAG, "Cannot dexopt " + lib + "; is it an APK or JAR? "
2112                                    + e.getMessage());
2113                        }
2114                    }
2115                }
2116            }
2117
2118            File frameworkDir = new File(Environment.getRootDirectory(), "framework");
2119
2120            final VersionInfo ver = mSettings.getInternalVersion();
2121            mIsUpgrade = !Build.FINGERPRINT.equals(ver.fingerprint);
2122            // when upgrading from pre-M, promote system app permissions from install to runtime
2123            mPromoteSystemApps =
2124                    mIsUpgrade && ver.sdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1;
2125
2126            // save off the names of pre-existing system packages prior to scanning; we don't
2127            // want to automatically grant runtime permissions for new system apps
2128            if (mPromoteSystemApps) {
2129                Iterator<PackageSetting> pkgSettingIter = mSettings.mPackages.values().iterator();
2130                while (pkgSettingIter.hasNext()) {
2131                    PackageSetting ps = pkgSettingIter.next();
2132                    if (isSystemApp(ps)) {
2133                        mExistingSystemPackages.add(ps.name);
2134                    }
2135                }
2136            }
2137
2138            // Collect vendor overlay packages.
2139            // (Do this before scanning any apps.)
2140            // For security and version matching reason, only consider
2141            // overlay packages if they reside in VENDOR_OVERLAY_DIR.
2142            File vendorOverlayDir = new File(VENDOR_OVERLAY_DIR);
2143            scanDirTracedLI(vendorOverlayDir, PackageParser.PARSE_IS_SYSTEM
2144                    | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags | SCAN_TRUSTED_OVERLAY, 0);
2145
2146            // Find base frameworks (resource packages without code).
2147            scanDirTracedLI(frameworkDir, PackageParser.PARSE_IS_SYSTEM
2148                    | PackageParser.PARSE_IS_SYSTEM_DIR
2149                    | PackageParser.PARSE_IS_PRIVILEGED,
2150                    scanFlags | SCAN_NO_DEX, 0);
2151
2152            // Collected privileged system packages.
2153            final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app");
2154            scanDirTracedLI(privilegedAppDir, PackageParser.PARSE_IS_SYSTEM
2155                    | PackageParser.PARSE_IS_SYSTEM_DIR
2156                    | PackageParser.PARSE_IS_PRIVILEGED, scanFlags, 0);
2157
2158            // Collect ordinary system packages.
2159            final File systemAppDir = new File(Environment.getRootDirectory(), "app");
2160            scanDirTracedLI(systemAppDir, PackageParser.PARSE_IS_SYSTEM
2161                    | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
2162
2163            // Collect all vendor packages.
2164            File vendorAppDir = new File("/vendor/app");
2165            try {
2166                vendorAppDir = vendorAppDir.getCanonicalFile();
2167            } catch (IOException e) {
2168                // failed to look up canonical path, continue with original one
2169            }
2170            scanDirTracedLI(vendorAppDir, PackageParser.PARSE_IS_SYSTEM
2171                    | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
2172
2173            // Collect all OEM packages.
2174            final File oemAppDir = new File(Environment.getOemDirectory(), "app");
2175            scanDirTracedLI(oemAppDir, PackageParser.PARSE_IS_SYSTEM
2176                    | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
2177
2178            if (DEBUG_UPGRADE) Log.v(TAG, "Running installd update commands");
2179            try {
2180                mInstaller.moveFiles();
2181            } catch (InstallerException e) {
2182                logCriticalInfo(Log.WARN, "Update commands failed: " + e);
2183            }
2184
2185            // Prune any system packages that no longer exist.
2186            final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<String>();
2187            if (!mOnlyCore) {
2188                Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
2189                while (psit.hasNext()) {
2190                    PackageSetting ps = psit.next();
2191
2192                    /*
2193                     * If this is not a system app, it can't be a
2194                     * disable system app.
2195                     */
2196                    if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
2197                        continue;
2198                    }
2199
2200                    /*
2201                     * If the package is scanned, it's not erased.
2202                     */
2203                    final PackageParser.Package scannedPkg = mPackages.get(ps.name);
2204                    if (scannedPkg != null) {
2205                        /*
2206                         * If the system app is both scanned and in the
2207                         * disabled packages list, then it must have been
2208                         * added via OTA. Remove it from the currently
2209                         * scanned package so the previously user-installed
2210                         * application can be scanned.
2211                         */
2212                        if (mSettings.isDisabledSystemPackageLPr(ps.name)) {
2213                            logCriticalInfo(Log.WARN, "Expecting better updated system app for "
2214                                    + ps.name + "; removing system app.  Last known codePath="
2215                                    + ps.codePathString + ", installStatus=" + ps.installStatus
2216                                    + ", versionCode=" + ps.versionCode + "; scanned versionCode="
2217                                    + scannedPkg.mVersionCode);
2218                            removePackageLI(ps, true);
2219                            mExpectingBetter.put(ps.name, ps.codePath);
2220                        }
2221
2222                        continue;
2223                    }
2224
2225                    if (!mSettings.isDisabledSystemPackageLPr(ps.name)) {
2226                        psit.remove();
2227                        logCriticalInfo(Log.WARN, "System package " + ps.name
2228                                + " no longer exists; wiping its data");
2229                        removeDataDirsLI(null, ps.name);
2230                    } else {
2231                        final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(ps.name);
2232                        if (disabledPs.codePath == null || !disabledPs.codePath.exists()) {
2233                            possiblyDeletedUpdatedSystemApps.add(ps.name);
2234                        }
2235                    }
2236                }
2237            }
2238
2239            //look for any incomplete package installations
2240            ArrayList<PackageSetting> deletePkgsList = mSettings.getListOfIncompleteInstallPackagesLPr();
2241            //clean up list
2242            for(int i = 0; i < deletePkgsList.size(); i++) {
2243                //clean up here
2244                cleanupInstallFailedPackage(deletePkgsList.get(i));
2245            }
2246            //delete tmp files
2247            deleteTempPackageFiles();
2248
2249            // Remove any shared userIDs that have no associated packages
2250            mSettings.pruneSharedUsersLPw();
2251
2252            if (!mOnlyCore) {
2253                EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,
2254                        SystemClock.uptimeMillis());
2255                scanDirTracedLI(mAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0);
2256
2257                scanDirTracedLI(mDrmAppPrivateInstallDir, PackageParser.PARSE_FORWARD_LOCK,
2258                        scanFlags | SCAN_REQUIRE_KNOWN, 0);
2259
2260                scanDirLI(mEphemeralInstallDir, PackageParser.PARSE_IS_EPHEMERAL,
2261                        scanFlags | SCAN_REQUIRE_KNOWN, 0);
2262
2263                /**
2264                 * Remove disable package settings for any updated system
2265                 * apps that were removed via an OTA. If they're not a
2266                 * previously-updated app, remove them completely.
2267                 * Otherwise, just revoke their system-level permissions.
2268                 */
2269                for (String deletedAppName : possiblyDeletedUpdatedSystemApps) {
2270                    PackageParser.Package deletedPkg = mPackages.get(deletedAppName);
2271                    mSettings.removeDisabledSystemPackageLPw(deletedAppName);
2272
2273                    String msg;
2274                    if (deletedPkg == null) {
2275                        msg = "Updated system package " + deletedAppName
2276                                + " no longer exists; wiping its data";
2277                        removeDataDirsLI(null, deletedAppName);
2278                    } else {
2279                        msg = "Updated system app + " + deletedAppName
2280                                + " no longer present; removing system privileges for "
2281                                + deletedAppName;
2282
2283                        deletedPkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM;
2284
2285                        PackageSetting deletedPs = mSettings.mPackages.get(deletedAppName);
2286                        deletedPs.pkgFlags &= ~ApplicationInfo.FLAG_SYSTEM;
2287                    }
2288                    logCriticalInfo(Log.WARN, msg);
2289                }
2290
2291                /**
2292                 * Make sure all system apps that we expected to appear on
2293                 * the userdata partition actually showed up. If they never
2294                 * appeared, crawl back and revive the system version.
2295                 */
2296                for (int i = 0; i < mExpectingBetter.size(); i++) {
2297                    final String packageName = mExpectingBetter.keyAt(i);
2298                    if (!mPackages.containsKey(packageName)) {
2299                        final File scanFile = mExpectingBetter.valueAt(i);
2300
2301                        logCriticalInfo(Log.WARN, "Expected better " + packageName
2302                                + " but never showed up; reverting to system");
2303
2304                        final int reparseFlags;
2305                        if (FileUtils.contains(privilegedAppDir, scanFile)) {
2306                            reparseFlags = PackageParser.PARSE_IS_SYSTEM
2307                                    | PackageParser.PARSE_IS_SYSTEM_DIR
2308                                    | PackageParser.PARSE_IS_PRIVILEGED;
2309                        } else if (FileUtils.contains(systemAppDir, scanFile)) {
2310                            reparseFlags = PackageParser.PARSE_IS_SYSTEM
2311                                    | PackageParser.PARSE_IS_SYSTEM_DIR;
2312                        } else if (FileUtils.contains(vendorAppDir, scanFile)) {
2313                            reparseFlags = PackageParser.PARSE_IS_SYSTEM
2314                                    | PackageParser.PARSE_IS_SYSTEM_DIR;
2315                        } else if (FileUtils.contains(oemAppDir, scanFile)) {
2316                            reparseFlags = PackageParser.PARSE_IS_SYSTEM
2317                                    | PackageParser.PARSE_IS_SYSTEM_DIR;
2318                        } else {
2319                            Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile);
2320                            continue;
2321                        }
2322
2323                        mSettings.enableSystemPackageLPw(packageName);
2324
2325                        try {
2326                            scanPackageTracedLI(scanFile, reparseFlags, scanFlags, 0, null);
2327                        } catch (PackageManagerException e) {
2328                            Slog.e(TAG, "Failed to parse original system package: "
2329                                    + e.getMessage());
2330                        }
2331                    }
2332                }
2333            }
2334            mExpectingBetter.clear();
2335
2336            // Now that we know all of the shared libraries, update all clients to have
2337            // the correct library paths.
2338            updateAllSharedLibrariesLPw();
2339
2340            for (SharedUserSetting setting : mSettings.getAllSharedUsersLPw()) {
2341                // NOTE: We ignore potential failures here during a system scan (like
2342                // the rest of the commands above) because there's precious little we
2343                // can do about it. A settings error is reported, though.
2344                adjustCpuAbisForSharedUserLPw(setting.packages, null /* scanned package */,
2345                        false /* boot complete */);
2346            }
2347
2348            // Now that we know all the packages we are keeping,
2349            // read and update their last usage times.
2350            mPackageUsage.readLP();
2351
2352            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END,
2353                    SystemClock.uptimeMillis());
2354            Slog.i(TAG, "Time to scan packages: "
2355                    + ((SystemClock.uptimeMillis()-startTime)/1000f)
2356                    + " seconds");
2357
2358            // If the platform SDK has changed since the last time we booted,
2359            // we need to re-grant app permission to catch any new ones that
2360            // appear.  This is really a hack, and means that apps can in some
2361            // cases get permissions that the user didn't initially explicitly
2362            // allow...  it would be nice to have some better way to handle
2363            // this situation.
2364            int updateFlags = UPDATE_PERMISSIONS_ALL;
2365            if (ver.sdkVersion != mSdkVersion) {
2366                Slog.i(TAG, "Platform changed from " + ver.sdkVersion + " to "
2367                        + mSdkVersion + "; regranting permissions for internal storage");
2368                updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
2369            }
2370            updatePermissionsLPw(null, null, StorageManager.UUID_PRIVATE_INTERNAL, updateFlags);
2371            ver.sdkVersion = mSdkVersion;
2372
2373            // If this is the first boot or an update from pre-M, and it is a normal
2374            // boot, then we need to initialize the default preferred apps across
2375            // all defined users.
2376            if (!onlyCore && (mPromoteSystemApps || !mRestoredSettings)) {
2377                for (UserInfo user : sUserManager.getUsers(true)) {
2378                    mSettings.applyDefaultPreferredAppsLPw(this, user.id);
2379                    applyFactoryDefaultBrowserLPw(user.id);
2380                    primeDomainVerificationsLPw(user.id);
2381                }
2382            }
2383
2384            // Prepare storage for system user really early during boot,
2385            // since core system apps like SettingsProvider and SystemUI
2386            // can't wait for user to start
2387            final int flags;
2388            if (StorageManager.isFileBasedEncryptionEnabled()) {
2389                flags = Installer.FLAG_DE_STORAGE;
2390            } else {
2391                flags = Installer.FLAG_DE_STORAGE | Installer.FLAG_CE_STORAGE;
2392            }
2393            reconcileAppsData(StorageManager.UUID_PRIVATE_INTERNAL, UserHandle.USER_SYSTEM, flags);
2394
2395            // If this is first boot after an OTA, and a normal boot, then
2396            // we need to clear code cache directories.
2397            if (mIsUpgrade && !onlyCore) {
2398                Slog.i(TAG, "Build fingerprint changed; clearing code caches");
2399                for (int i = 0; i < mSettings.mPackages.size(); i++) {
2400                    final PackageSetting ps = mSettings.mPackages.valueAt(i);
2401                    if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, ps.volumeUuid)) {
2402                        deleteCodeCacheDirsLI(ps.volumeUuid, ps.name);
2403                    }
2404                }
2405                ver.fingerprint = Build.FINGERPRINT;
2406            }
2407
2408            checkDefaultBrowser();
2409
2410            // clear only after permissions and other defaults have been updated
2411            mExistingSystemPackages.clear();
2412            mPromoteSystemApps = false;
2413
2414            // All the changes are done during package scanning.
2415            ver.databaseVersion = Settings.CURRENT_DATABASE_VERSION;
2416
2417            // can downgrade to reader
2418            mSettings.writeLPr();
2419
2420            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY,
2421                    SystemClock.uptimeMillis());
2422
2423            if (!mOnlyCore) {
2424                mRequiredVerifierPackage = getRequiredButNotReallyRequiredVerifierLPr();
2425                mRequiredInstallerPackage = getRequiredInstallerLPr();
2426                mIntentFilterVerifierComponent = getIntentFilterVerifierComponentNameLPr();
2427                mIntentFilterVerifier = new IntentVerifierProxy(mContext,
2428                        mIntentFilterVerifierComponent);
2429            } else {
2430                mRequiredVerifierPackage = null;
2431                mRequiredInstallerPackage = null;
2432                mIntentFilterVerifierComponent = null;
2433                mIntentFilterVerifier = null;
2434            }
2435
2436            mInstallerService = new PackageInstallerService(context, this);
2437
2438            final ComponentName ephemeralResolverComponent = getEphemeralResolverLPr();
2439            final ComponentName ephemeralInstallerComponent = getEphemeralInstallerLPr();
2440            // both the installer and resolver must be present to enable ephemeral
2441            if (ephemeralInstallerComponent != null && ephemeralResolverComponent != null) {
2442                if (DEBUG_EPHEMERAL) {
2443                    Slog.i(TAG, "Ephemeral activated; resolver: " + ephemeralResolverComponent
2444                            + " installer:" + ephemeralInstallerComponent);
2445                }
2446                mEphemeralResolverComponent = ephemeralResolverComponent;
2447                mEphemeralInstallerComponent = ephemeralInstallerComponent;
2448                setUpEphemeralInstallerActivityLP(mEphemeralInstallerComponent);
2449                mEphemeralResolverConnection =
2450                        new EphemeralResolverConnection(mContext, mEphemeralResolverComponent);
2451            } else {
2452                if (DEBUG_EPHEMERAL) {
2453                    final String missingComponent =
2454                            (ephemeralResolverComponent == null)
2455                            ? (ephemeralInstallerComponent == null)
2456                                    ? "resolver and installer"
2457                                    : "resolver"
2458                            : "installer";
2459                    Slog.i(TAG, "Ephemeral deactivated; missing " + missingComponent);
2460                }
2461                mEphemeralResolverComponent = null;
2462                mEphemeralInstallerComponent = null;
2463                mEphemeralResolverConnection = null;
2464            }
2465
2466            mEphemeralApplicationRegistry = new EphemeralApplicationRegistry(this);
2467        } // synchronized (mPackages)
2468        } // synchronized (mInstallLock)
2469
2470        // Now after opening every single application zip, make sure they
2471        // are all flushed.  Not really needed, but keeps things nice and
2472        // tidy.
2473        Runtime.getRuntime().gc();
2474
2475        // The initial scanning above does many calls into installd while
2476        // holding the mPackages lock, but we're mostly interested in yelling
2477        // once we have a booted system.
2478        mInstaller.setWarnIfHeld(mPackages);
2479
2480        // Expose private service for system components to use.
2481        LocalServices.addService(PackageManagerInternal.class, new PackageManagerInternalImpl());
2482    }
2483
2484    @Override
2485    public boolean isFirstBoot() {
2486        return !mRestoredSettings;
2487    }
2488
2489    @Override
2490    public boolean isOnlyCoreApps() {
2491        return mOnlyCore;
2492    }
2493
2494    @Override
2495    public boolean isUpgrade() {
2496        return mIsUpgrade;
2497    }
2498
2499    private @Nullable String getRequiredButNotReallyRequiredVerifierLPr() {
2500        final Intent intent = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
2501
2502        final List<ResolveInfo> matches = queryIntentReceivers(intent, PACKAGE_MIME_TYPE,
2503                MATCH_SYSTEM_ONLY | MATCH_ENCRYPTION_AWARE_AND_UNAWARE, UserHandle.USER_SYSTEM);
2504        if (matches.size() == 1) {
2505            return matches.get(0).getComponentInfo().packageName;
2506        } else {
2507            Log.e(TAG, "There should probably be exactly one verifier; found " + matches);
2508            return null;
2509        }
2510    }
2511
2512    private @NonNull String getRequiredInstallerLPr() {
2513        final Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
2514        intent.addCategory(Intent.CATEGORY_DEFAULT);
2515        intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE);
2516
2517        final List<ResolveInfo> matches = queryIntentActivities(intent, PACKAGE_MIME_TYPE,
2518                MATCH_SYSTEM_ONLY | MATCH_ENCRYPTION_AWARE_AND_UNAWARE, UserHandle.USER_SYSTEM);
2519        if (matches.size() == 1) {
2520            return matches.get(0).getComponentInfo().packageName;
2521        } else {
2522            throw new RuntimeException("There must be exactly one installer; found " + matches);
2523        }
2524    }
2525
2526    private @NonNull ComponentName getIntentFilterVerifierComponentNameLPr() {
2527        final Intent intent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION);
2528
2529        final List<ResolveInfo> matches = queryIntentReceivers(intent, PACKAGE_MIME_TYPE,
2530                MATCH_SYSTEM_ONLY | MATCH_ENCRYPTION_AWARE_AND_UNAWARE, UserHandle.USER_SYSTEM);
2531        ResolveInfo best = null;
2532        final int N = matches.size();
2533        for (int i = 0; i < N; i++) {
2534            final ResolveInfo cur = matches.get(i);
2535            final String packageName = cur.getComponentInfo().packageName;
2536            if (checkPermission(android.Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT,
2537                    packageName, UserHandle.USER_SYSTEM) != PackageManager.PERMISSION_GRANTED) {
2538                continue;
2539            }
2540
2541            if (best == null || cur.priority > best.priority) {
2542                best = cur;
2543            }
2544        }
2545
2546        if (best != null) {
2547            return best.getComponentInfo().getComponentName();
2548        } else {
2549            throw new RuntimeException("There must be at least one intent filter verifier");
2550        }
2551    }
2552
2553    private @Nullable ComponentName getEphemeralResolverLPr() {
2554        final String[] packageArray =
2555                mContext.getResources().getStringArray(R.array.config_ephemeralResolverPackage);
2556        if (packageArray.length == 0) {
2557            if (DEBUG_EPHEMERAL) {
2558                Slog.d(TAG, "Ephemeral resolver NOT found; empty package list");
2559            }
2560            return null;
2561        }
2562
2563        final Intent resolverIntent = new Intent(Intent.ACTION_RESOLVE_EPHEMERAL_PACKAGE);
2564        final List<ResolveInfo> resolvers = queryIntentServices(resolverIntent, null,
2565                MATCH_SYSTEM_ONLY | MATCH_ENCRYPTION_AWARE_AND_UNAWARE, UserHandle.USER_SYSTEM);
2566
2567        final int N = resolvers.size();
2568        if (N == 0) {
2569            if (DEBUG_EPHEMERAL) {
2570                Slog.d(TAG, "Ephemeral resolver NOT found; no matching intent filters");
2571            }
2572            return null;
2573        }
2574
2575        final Set<String> possiblePackages = new ArraySet<>(Arrays.asList(packageArray));
2576        for (int i = 0; i < N; i++) {
2577            final ResolveInfo info = resolvers.get(i);
2578
2579            if (info.serviceInfo == null) {
2580                continue;
2581            }
2582
2583            final String packageName = info.serviceInfo.packageName;
2584            if (!possiblePackages.contains(packageName)) {
2585                if (DEBUG_EPHEMERAL) {
2586                    Slog.d(TAG, "Ephemeral resolver not in allowed package list;"
2587                            + " pkg: " + packageName + ", info:" + info);
2588                }
2589                continue;
2590            }
2591
2592            if (DEBUG_EPHEMERAL) {
2593                Slog.v(TAG, "Ephemeral resolver found;"
2594                        + " pkg: " + packageName + ", info:" + info);
2595            }
2596            return new ComponentName(packageName, info.serviceInfo.name);
2597        }
2598        if (DEBUG_EPHEMERAL) {
2599            Slog.v(TAG, "Ephemeral resolver NOT found");
2600        }
2601        return null;
2602    }
2603
2604    private @Nullable ComponentName getEphemeralInstallerLPr() {
2605        final Intent intent = new Intent(Intent.ACTION_INSTALL_EPHEMERAL_PACKAGE);
2606        intent.addCategory(Intent.CATEGORY_DEFAULT);
2607        intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE);
2608
2609        final List<ResolveInfo> matches = queryIntentActivities(intent, PACKAGE_MIME_TYPE,
2610                MATCH_SYSTEM_ONLY | MATCH_ENCRYPTION_AWARE_AND_UNAWARE, UserHandle.USER_SYSTEM);
2611        if (matches.size() == 0) {
2612            return null;
2613        } else if (matches.size() == 1) {
2614            return matches.get(0).getComponentInfo().getComponentName();
2615        } else {
2616            throw new RuntimeException(
2617                    "There must be at most one ephemeral installer; found " + matches);
2618        }
2619    }
2620
2621    private void primeDomainVerificationsLPw(int userId) {
2622        if (DEBUG_DOMAIN_VERIFICATION) {
2623            Slog.d(TAG, "Priming domain verifications in user " + userId);
2624        }
2625
2626        SystemConfig systemConfig = SystemConfig.getInstance();
2627        ArraySet<String> packages = systemConfig.getLinkedApps();
2628        ArraySet<String> domains = new ArraySet<String>();
2629
2630        for (String packageName : packages) {
2631            PackageParser.Package pkg = mPackages.get(packageName);
2632            if (pkg != null) {
2633                if (!pkg.isSystemApp()) {
2634                    Slog.w(TAG, "Non-system app '" + packageName + "' in sysconfig <app-link>");
2635                    continue;
2636                }
2637
2638                domains.clear();
2639                for (PackageParser.Activity a : pkg.activities) {
2640                    for (ActivityIntentInfo filter : a.intents) {
2641                        if (hasValidDomains(filter)) {
2642                            domains.addAll(filter.getHostsList());
2643                        }
2644                    }
2645                }
2646
2647                if (domains.size() > 0) {
2648                    if (DEBUG_DOMAIN_VERIFICATION) {
2649                        Slog.v(TAG, "      + " + packageName);
2650                    }
2651                    // 'Undefined' in the global IntentFilterVerificationInfo, i.e. the usual
2652                    // state w.r.t. the formal app-linkage "no verification attempted" state;
2653                    // and then 'always' in the per-user state actually used for intent resolution.
2654                    final IntentFilterVerificationInfo ivi;
2655                    ivi = mSettings.createIntentFilterVerificationIfNeededLPw(packageName,
2656                            new ArrayList<String>(domains));
2657                    ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED);
2658                    mSettings.updateIntentFilterVerificationStatusLPw(packageName,
2659                            INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS, userId);
2660                } else {
2661                    Slog.w(TAG, "Sysconfig <app-link> package '" + packageName
2662                            + "' does not handle web links");
2663                }
2664            } else {
2665                Slog.w(TAG, "Unknown package " + packageName + " in sysconfig <app-link>");
2666            }
2667        }
2668
2669        scheduleWritePackageRestrictionsLocked(userId);
2670        scheduleWriteSettingsLocked();
2671    }
2672
2673    private void applyFactoryDefaultBrowserLPw(int userId) {
2674        // The default browser app's package name is stored in a string resource,
2675        // with a product-specific overlay used for vendor customization.
2676        String browserPkg = mContext.getResources().getString(
2677                com.android.internal.R.string.default_browser);
2678        if (!TextUtils.isEmpty(browserPkg)) {
2679            // non-empty string => required to be a known package
2680            PackageSetting ps = mSettings.mPackages.get(browserPkg);
2681            if (ps == null) {
2682                Slog.e(TAG, "Product default browser app does not exist: " + browserPkg);
2683                browserPkg = null;
2684            } else {
2685                mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId);
2686            }
2687        }
2688
2689        // Nothing valid explicitly set? Make the factory-installed browser the explicit
2690        // default.  If there's more than one, just leave everything alone.
2691        if (browserPkg == null) {
2692            calculateDefaultBrowserLPw(userId);
2693        }
2694    }
2695
2696    private void calculateDefaultBrowserLPw(int userId) {
2697        List<String> allBrowsers = resolveAllBrowserApps(userId);
2698        final String browserPkg = (allBrowsers.size() == 1) ? allBrowsers.get(0) : null;
2699        mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId);
2700    }
2701
2702    private List<String> resolveAllBrowserApps(int userId) {
2703        // Resolve the canonical browser intent and check that the handleAllWebDataURI boolean is set
2704        List<ResolveInfo> list = queryIntentActivities(sBrowserIntent, null,
2705                PackageManager.MATCH_ALL, userId);
2706
2707        final int count = list.size();
2708        List<String> result = new ArrayList<String>(count);
2709        for (int i=0; i<count; i++) {
2710            ResolveInfo info = list.get(i);
2711            if (info.activityInfo == null
2712                    || !info.handleAllWebDataURI
2713                    || (info.activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0
2714                    || result.contains(info.activityInfo.packageName)) {
2715                continue;
2716            }
2717            result.add(info.activityInfo.packageName);
2718        }
2719
2720        return result;
2721    }
2722
2723    private boolean packageIsBrowser(String packageName, int userId) {
2724        List<ResolveInfo> list = queryIntentActivities(sBrowserIntent, null,
2725                PackageManager.MATCH_ALL, userId);
2726        final int N = list.size();
2727        for (int i = 0; i < N; i++) {
2728            ResolveInfo info = list.get(i);
2729            if (packageName.equals(info.activityInfo.packageName)) {
2730                return true;
2731            }
2732        }
2733        return false;
2734    }
2735
2736    private void checkDefaultBrowser() {
2737        final int myUserId = UserHandle.myUserId();
2738        final String packageName = getDefaultBrowserPackageName(myUserId);
2739        if (packageName != null) {
2740            PackageInfo info = getPackageInfo(packageName, 0, myUserId);
2741            if (info == null) {
2742                Slog.w(TAG, "Default browser no longer installed: " + packageName);
2743                synchronized (mPackages) {
2744                    applyFactoryDefaultBrowserLPw(myUserId);    // leaves ambiguous when > 1
2745                }
2746            }
2747        }
2748    }
2749
2750    @Override
2751    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2752            throws RemoteException {
2753        try {
2754            return super.onTransact(code, data, reply, flags);
2755        } catch (RuntimeException e) {
2756            if (!(e instanceof SecurityException) && !(e instanceof IllegalArgumentException)) {
2757                Slog.wtf(TAG, "Package Manager Crash", e);
2758            }
2759            throw e;
2760        }
2761    }
2762
2763    void cleanupInstallFailedPackage(PackageSetting ps) {
2764        logCriticalInfo(Log.WARN, "Cleaning up incompletely installed app: " + ps.name);
2765
2766        removeDataDirsLI(ps.volumeUuid, ps.name);
2767        if (ps.codePath != null) {
2768            removeCodePathLI(ps.codePath);
2769        }
2770        if (ps.resourcePath != null && !ps.resourcePath.equals(ps.codePath)) {
2771            if (ps.resourcePath.isDirectory()) {
2772                FileUtils.deleteContents(ps.resourcePath);
2773            }
2774            ps.resourcePath.delete();
2775        }
2776        mSettings.removePackageLPw(ps.name);
2777    }
2778
2779    static int[] appendInts(int[] cur, int[] add) {
2780        if (add == null) return cur;
2781        if (cur == null) return add;
2782        final int N = add.length;
2783        for (int i=0; i<N; i++) {
2784            cur = appendInt(cur, add[i]);
2785        }
2786        return cur;
2787    }
2788
2789    PackageInfo generatePackageInfo(PackageParser.Package p, int flags, int userId) {
2790        if (!sUserManager.exists(userId)) return null;
2791        final PackageSetting ps = (PackageSetting) p.mExtras;
2792        if (ps == null) {
2793            return null;
2794        }
2795
2796        final PermissionsState permissionsState = ps.getPermissionsState();
2797
2798        final int[] gids = permissionsState.computeGids(userId);
2799        final Set<String> permissions = permissionsState.getPermissions(userId);
2800        final PackageUserState state = ps.readUserState(userId);
2801
2802        return PackageParser.generatePackageInfo(p, gids, flags,
2803                ps.firstInstallTime, ps.lastUpdateTime, permissions, state, userId);
2804    }
2805
2806    @Override
2807    public void checkPackageStartable(String packageName, int userId) {
2808        final boolean userKeyUnlocked = isUserKeyUnlocked(userId);
2809
2810        synchronized (mPackages) {
2811            final PackageSetting ps = mSettings.mPackages.get(packageName);
2812            if (ps == null) {
2813                throw new SecurityException("Package " + packageName + " was not found!");
2814            }
2815
2816            if (ps.frozen) {
2817                throw new SecurityException("Package " + packageName + " is currently frozen!");
2818            }
2819
2820            if (!userKeyUnlocked && !(ps.pkg.applicationInfo.isEncryptionAware()
2821                    || ps.pkg.applicationInfo.isPartiallyEncryptionAware())) {
2822                throw new SecurityException("Package " + packageName + " is not encryption aware!");
2823            }
2824        }
2825    }
2826
2827    @Override
2828    public boolean isPackageAvailable(String packageName, int userId) {
2829        if (!sUserManager.exists(userId)) return false;
2830        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "is package available");
2831        synchronized (mPackages) {
2832            PackageParser.Package p = mPackages.get(packageName);
2833            if (p != null) {
2834                final PackageSetting ps = (PackageSetting) p.mExtras;
2835                if (ps != null) {
2836                    final PackageUserState state = ps.readUserState(userId);
2837                    if (state != null) {
2838                        return PackageParser.isAvailable(state);
2839                    }
2840                }
2841            }
2842        }
2843        return false;
2844    }
2845
2846    @Override
2847    public PackageInfo getPackageInfo(String packageName, int flags, int userId) {
2848        if (!sUserManager.exists(userId)) return null;
2849        flags = updateFlagsForPackage(flags, userId, packageName);
2850        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get package info");
2851        // reader
2852        synchronized (mPackages) {
2853            PackageParser.Package p = mPackages.get(packageName);
2854            if (DEBUG_PACKAGE_INFO)
2855                Log.v(TAG, "getPackageInfo " + packageName + ": " + p);
2856            if (p != null) {
2857                return generatePackageInfo(p, flags, userId);
2858            }
2859            if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0) {
2860                return generatePackageInfoFromSettingsLPw(packageName, flags, userId);
2861            }
2862        }
2863        return null;
2864    }
2865
2866    @Override
2867    public String[] currentToCanonicalPackageNames(String[] names) {
2868        String[] out = new String[names.length];
2869        // reader
2870        synchronized (mPackages) {
2871            for (int i=names.length-1; i>=0; i--) {
2872                PackageSetting ps = mSettings.mPackages.get(names[i]);
2873                out[i] = ps != null && ps.realName != null ? ps.realName : names[i];
2874            }
2875        }
2876        return out;
2877    }
2878
2879    @Override
2880    public String[] canonicalToCurrentPackageNames(String[] names) {
2881        String[] out = new String[names.length];
2882        // reader
2883        synchronized (mPackages) {
2884            for (int i=names.length-1; i>=0; i--) {
2885                String cur = mSettings.mRenamedPackages.get(names[i]);
2886                out[i] = cur != null ? cur : names[i];
2887            }
2888        }
2889        return out;
2890    }
2891
2892    @Override
2893    public int getPackageUid(String packageName, int flags, int userId) {
2894        if (!sUserManager.exists(userId)) return -1;
2895        flags = updateFlagsForPackage(flags, userId, packageName);
2896        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get package uid");
2897
2898        // reader
2899        synchronized (mPackages) {
2900            final PackageParser.Package p = mPackages.get(packageName);
2901            if (p != null && p.isMatch(flags)) {
2902                return UserHandle.getUid(userId, p.applicationInfo.uid);
2903            }
2904            if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0) {
2905                final PackageSetting ps = mSettings.mPackages.get(packageName);
2906                if (ps != null && ps.isMatch(flags)) {
2907                    return UserHandle.getUid(userId, ps.appId);
2908                }
2909            }
2910        }
2911
2912        return -1;
2913    }
2914
2915    @Override
2916    public int[] getPackageGids(String packageName, int flags, int userId) {
2917        if (!sUserManager.exists(userId)) return null;
2918        flags = updateFlagsForPackage(flags, userId, packageName);
2919        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false,
2920                "getPackageGids");
2921
2922        // reader
2923        synchronized (mPackages) {
2924            final PackageParser.Package p = mPackages.get(packageName);
2925            if (p != null && p.isMatch(flags)) {
2926                PackageSetting ps = (PackageSetting) p.mExtras;
2927                return ps.getPermissionsState().computeGids(userId);
2928            }
2929            if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0) {
2930                final PackageSetting ps = mSettings.mPackages.get(packageName);
2931                if (ps != null && ps.isMatch(flags)) {
2932                    return ps.getPermissionsState().computeGids(userId);
2933                }
2934            }
2935        }
2936
2937        return null;
2938    }
2939
2940    static PermissionInfo generatePermissionInfo(BasePermission bp, int flags) {
2941        if (bp.perm != null) {
2942            return PackageParser.generatePermissionInfo(bp.perm, flags);
2943        }
2944        PermissionInfo pi = new PermissionInfo();
2945        pi.name = bp.name;
2946        pi.packageName = bp.sourcePackage;
2947        pi.nonLocalizedLabel = bp.name;
2948        pi.protectionLevel = bp.protectionLevel;
2949        return pi;
2950    }
2951
2952    @Override
2953    public PermissionInfo getPermissionInfo(String name, int flags) {
2954        // reader
2955        synchronized (mPackages) {
2956            final BasePermission p = mSettings.mPermissions.get(name);
2957            if (p != null) {
2958                return generatePermissionInfo(p, flags);
2959            }
2960            return null;
2961        }
2962    }
2963
2964    @Override
2965    public List<PermissionInfo> queryPermissionsByGroup(String group, int flags) {
2966        // reader
2967        synchronized (mPackages) {
2968            ArrayList<PermissionInfo> out = new ArrayList<PermissionInfo>(10);
2969            for (BasePermission p : mSettings.mPermissions.values()) {
2970                if (group == null) {
2971                    if (p.perm == null || p.perm.info.group == null) {
2972                        out.add(generatePermissionInfo(p, flags));
2973                    }
2974                } else {
2975                    if (p.perm != null && group.equals(p.perm.info.group)) {
2976                        out.add(PackageParser.generatePermissionInfo(p.perm, flags));
2977                    }
2978                }
2979            }
2980
2981            if (out.size() > 0) {
2982                return out;
2983            }
2984            return mPermissionGroups.containsKey(group) ? out : null;
2985        }
2986    }
2987
2988    @Override
2989    public PermissionGroupInfo getPermissionGroupInfo(String name, int flags) {
2990        // reader
2991        synchronized (mPackages) {
2992            return PackageParser.generatePermissionGroupInfo(
2993                    mPermissionGroups.get(name), flags);
2994        }
2995    }
2996
2997    @Override
2998    public List<PermissionGroupInfo> getAllPermissionGroups(int flags) {
2999        // reader
3000        synchronized (mPackages) {
3001            final int N = mPermissionGroups.size();
3002            ArrayList<PermissionGroupInfo> out
3003                    = new ArrayList<PermissionGroupInfo>(N);
3004            for (PackageParser.PermissionGroup pg : mPermissionGroups.values()) {
3005                out.add(PackageParser.generatePermissionGroupInfo(pg, flags));
3006            }
3007            return out;
3008        }
3009    }
3010
3011    private ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName, int flags,
3012            int userId) {
3013        if (!sUserManager.exists(userId)) return null;
3014        PackageSetting ps = mSettings.mPackages.get(packageName);
3015        if (ps != null) {
3016            if (ps.pkg == null) {
3017                PackageInfo pInfo = generatePackageInfoFromSettingsLPw(packageName,
3018                        flags, userId);
3019                if (pInfo != null) {
3020                    return pInfo.applicationInfo;
3021                }
3022                return null;
3023            }
3024            return PackageParser.generateApplicationInfo(ps.pkg, flags,
3025                    ps.readUserState(userId), userId);
3026        }
3027        return null;
3028    }
3029
3030    private PackageInfo generatePackageInfoFromSettingsLPw(String packageName, int flags,
3031            int userId) {
3032        if (!sUserManager.exists(userId)) return null;
3033        PackageSetting ps = mSettings.mPackages.get(packageName);
3034        if (ps != null) {
3035            PackageParser.Package pkg = ps.pkg;
3036            if (pkg == null) {
3037                if ((flags & MATCH_UNINSTALLED_PACKAGES) == 0) {
3038                    return null;
3039                }
3040                // Only data remains, so we aren't worried about code paths
3041                pkg = new PackageParser.Package(packageName);
3042                pkg.applicationInfo.packageName = packageName;
3043                pkg.applicationInfo.flags = ps.pkgFlags | ApplicationInfo.FLAG_IS_DATA_ONLY;
3044                pkg.applicationInfo.privateFlags = ps.pkgPrivateFlags;
3045                pkg.applicationInfo.uid = ps.appId;
3046                pkg.applicationInfo.initForUser(userId);
3047                pkg.applicationInfo.primaryCpuAbi = ps.primaryCpuAbiString;
3048                pkg.applicationInfo.secondaryCpuAbi = ps.secondaryCpuAbiString;
3049            }
3050            return generatePackageInfo(pkg, flags, userId);
3051        }
3052        return null;
3053    }
3054
3055    @Override
3056    public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) {
3057        if (!sUserManager.exists(userId)) return null;
3058        flags = updateFlagsForApplication(flags, userId, packageName);
3059        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get application info");
3060        // writer
3061        synchronized (mPackages) {
3062            PackageParser.Package p = mPackages.get(packageName);
3063            if (DEBUG_PACKAGE_INFO) Log.v(
3064                    TAG, "getApplicationInfo " + packageName
3065                    + ": " + p);
3066            if (p != null) {
3067                PackageSetting ps = mSettings.mPackages.get(packageName);
3068                if (ps == null) return null;
3069                // Note: isEnabledLP() does not apply here - always return info
3070                return PackageParser.generateApplicationInfo(
3071                        p, flags, ps.readUserState(userId), userId);
3072            }
3073            if ("android".equals(packageName)||"system".equals(packageName)) {
3074                return mAndroidApplication;
3075            }
3076            if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0) {
3077                return generateApplicationInfoFromSettingsLPw(packageName, flags, userId);
3078            }
3079        }
3080        return null;
3081    }
3082
3083    @Override
3084    public void freeStorageAndNotify(final String volumeUuid, final long freeStorageSize,
3085            final IPackageDataObserver observer) {
3086        mContext.enforceCallingOrSelfPermission(
3087                android.Manifest.permission.CLEAR_APP_CACHE, null);
3088        // Queue up an async operation since clearing cache may take a little while.
3089        mHandler.post(new Runnable() {
3090            public void run() {
3091                mHandler.removeCallbacks(this);
3092                boolean success = true;
3093                synchronized (mInstallLock) {
3094                    try {
3095                        mInstaller.freeCache(volumeUuid, freeStorageSize);
3096                    } catch (InstallerException e) {
3097                        Slog.w(TAG, "Couldn't clear application caches: " + e);
3098                        success = false;
3099                    }
3100                }
3101                if (observer != null) {
3102                    try {
3103                        observer.onRemoveCompleted(null, success);
3104                    } catch (RemoteException e) {
3105                        Slog.w(TAG, "RemoveException when invoking call back");
3106                    }
3107                }
3108            }
3109        });
3110    }
3111
3112    @Override
3113    public void freeStorage(final String volumeUuid, final long freeStorageSize,
3114            final IntentSender pi) {
3115        mContext.enforceCallingOrSelfPermission(
3116                android.Manifest.permission.CLEAR_APP_CACHE, null);
3117        // Queue up an async operation since clearing cache may take a little while.
3118        mHandler.post(new Runnable() {
3119            public void run() {
3120                mHandler.removeCallbacks(this);
3121                boolean success = true;
3122                synchronized (mInstallLock) {
3123                    try {
3124                        mInstaller.freeCache(volumeUuid, freeStorageSize);
3125                    } catch (InstallerException e) {
3126                        Slog.w(TAG, "Couldn't clear application caches: " + e);
3127                        success = false;
3128                    }
3129                }
3130                if(pi != null) {
3131                    try {
3132                        // Callback via pending intent
3133                        int code = success ? 1 : 0;
3134                        pi.sendIntent(null, code, null,
3135                                null, null);
3136                    } catch (SendIntentException e1) {
3137                        Slog.i(TAG, "Failed to send pending intent");
3138                    }
3139                }
3140            }
3141        });
3142    }
3143
3144    void freeStorage(String volumeUuid, long freeStorageSize) throws IOException {
3145        synchronized (mInstallLock) {
3146            try {
3147                mInstaller.freeCache(volumeUuid, freeStorageSize);
3148            } catch (InstallerException e) {
3149                throw new IOException("Failed to free enough space", e);
3150            }
3151        }
3152    }
3153
3154    /**
3155     * Return if the user key is currently unlocked.
3156     */
3157    private boolean isUserKeyUnlocked(int userId) {
3158        if (StorageManager.isFileBasedEncryptionEnabled()) {
3159            final IMountService mount = IMountService.Stub
3160                    .asInterface(ServiceManager.getService("mount"));
3161            if (mount == null) {
3162                Slog.w(TAG, "Early during boot, assuming locked");
3163                return false;
3164            }
3165            final long token = Binder.clearCallingIdentity();
3166            try {
3167                return mount.isUserKeyUnlocked(userId);
3168            } catch (RemoteException e) {
3169                throw e.rethrowAsRuntimeException();
3170            } finally {
3171                Binder.restoreCallingIdentity(token);
3172            }
3173        } else {
3174            return true;
3175        }
3176    }
3177
3178    /**
3179     * Update given flags based on encryption status of current user.
3180     */
3181    private int updateFlags(int flags, int userId) {
3182        if ((flags & (PackageManager.MATCH_ENCRYPTION_UNAWARE
3183                | PackageManager.MATCH_ENCRYPTION_AWARE)) != 0) {
3184            // Caller expressed an explicit opinion about what encryption
3185            // aware/unaware components they want to see, so fall through and
3186            // give them what they want
3187        } else {
3188            // Caller expressed no opinion, so match based on user state
3189            if (isUserKeyUnlocked(userId)) {
3190                flags |= PackageManager.MATCH_ENCRYPTION_AWARE_AND_UNAWARE;
3191            } else {
3192                flags |= PackageManager.MATCH_ENCRYPTION_AWARE;
3193            }
3194        }
3195
3196        // Safe mode means we should ignore any third-party apps
3197        if (mSafeMode) {
3198            flags |= PackageManager.MATCH_SYSTEM_ONLY;
3199        }
3200
3201        return flags;
3202    }
3203
3204    /**
3205     * Update given flags when being used to request {@link PackageInfo}.
3206     */
3207    private int updateFlagsForPackage(int flags, int userId, Object cookie) {
3208        boolean triaged = true;
3209        if ((flags & (PackageManager.GET_ACTIVITIES | PackageManager.GET_RECEIVERS
3210                | PackageManager.GET_SERVICES | PackageManager.GET_PROVIDERS)) != 0) {
3211            // Caller is asking for component details, so they'd better be
3212            // asking for specific encryption matching behavior, or be triaged
3213            if ((flags & (PackageManager.MATCH_ENCRYPTION_UNAWARE
3214                    | PackageManager.MATCH_ENCRYPTION_AWARE
3215                    | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
3216                triaged = false;
3217            }
3218        }
3219        if ((flags & (PackageManager.MATCH_UNINSTALLED_PACKAGES
3220                | PackageManager.MATCH_SYSTEM_ONLY
3221                | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
3222            triaged = false;
3223        }
3224        if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) {
3225            Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie
3226                    + " with flags 0x" + Integer.toHexString(flags), new Throwable());
3227        }
3228        return updateFlags(flags, userId);
3229    }
3230
3231    /**
3232     * Update given flags when being used to request {@link ApplicationInfo}.
3233     */
3234    private int updateFlagsForApplication(int flags, int userId, Object cookie) {
3235        return updateFlagsForPackage(flags, userId, cookie);
3236    }
3237
3238    /**
3239     * Update given flags when being used to request {@link ComponentInfo}.
3240     */
3241    private int updateFlagsForComponent(int flags, int userId, Object cookie) {
3242        if (cookie instanceof Intent) {
3243            if ((((Intent) cookie).getFlags() & Intent.FLAG_DEBUG_TRIAGED_MISSING) != 0) {
3244                flags |= PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
3245            }
3246        }
3247
3248        boolean triaged = true;
3249        // Caller is asking for component details, so they'd better be
3250        // asking for specific encryption matching behavior, or be triaged
3251        if ((flags & (PackageManager.MATCH_ENCRYPTION_UNAWARE
3252                | PackageManager.MATCH_ENCRYPTION_AWARE
3253                | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
3254            triaged = false;
3255        }
3256        if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) {
3257            Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie
3258                    + " with flags 0x" + Integer.toHexString(flags), new Throwable());
3259        }
3260        return updateFlags(flags, userId);
3261    }
3262
3263    /**
3264     * Update given flags when being used to request {@link ResolveInfo}.
3265     */
3266    int updateFlagsForResolve(int flags, int userId, Object cookie) {
3267        return updateFlagsForComponent(flags, userId, cookie);
3268    }
3269
3270    @Override
3271    public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) {
3272        if (!sUserManager.exists(userId)) return null;
3273        flags = updateFlagsForComponent(flags, userId, component);
3274        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get activity info");
3275        synchronized (mPackages) {
3276            PackageParser.Activity a = mActivities.mActivities.get(component);
3277
3278            if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a);
3279            if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) {
3280                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
3281                if (ps == null) return null;
3282                return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId),
3283                        userId);
3284            }
3285            if (mResolveComponentName.equals(component)) {
3286                return PackageParser.generateActivityInfo(mResolveActivity, flags,
3287                        new PackageUserState(), userId);
3288            }
3289        }
3290        return null;
3291    }
3292
3293    @Override
3294    public boolean activitySupportsIntent(ComponentName component, Intent intent,
3295            String resolvedType) {
3296        synchronized (mPackages) {
3297            if (component.equals(mResolveComponentName)) {
3298                // The resolver supports EVERYTHING!
3299                return true;
3300            }
3301            PackageParser.Activity a = mActivities.mActivities.get(component);
3302            if (a == null) {
3303                return false;
3304            }
3305            for (int i=0; i<a.intents.size(); i++) {
3306                if (a.intents.get(i).match(intent.getAction(), resolvedType, intent.getScheme(),
3307                        intent.getData(), intent.getCategories(), TAG) >= 0) {
3308                    return true;
3309                }
3310            }
3311            return false;
3312        }
3313    }
3314
3315    @Override
3316    public ActivityInfo getReceiverInfo(ComponentName component, int flags, int userId) {
3317        if (!sUserManager.exists(userId)) return null;
3318        flags = updateFlagsForComponent(flags, userId, component);
3319        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get receiver info");
3320        synchronized (mPackages) {
3321            PackageParser.Activity a = mReceivers.mActivities.get(component);
3322            if (DEBUG_PACKAGE_INFO) Log.v(
3323                TAG, "getReceiverInfo " + component + ": " + a);
3324            if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) {
3325                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
3326                if (ps == null) return null;
3327                return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId),
3328                        userId);
3329            }
3330        }
3331        return null;
3332    }
3333
3334    @Override
3335    public ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) {
3336        if (!sUserManager.exists(userId)) return null;
3337        flags = updateFlagsForComponent(flags, userId, component);
3338        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get service info");
3339        synchronized (mPackages) {
3340            PackageParser.Service s = mServices.mServices.get(component);
3341            if (DEBUG_PACKAGE_INFO) Log.v(
3342                TAG, "getServiceInfo " + component + ": " + s);
3343            if (s != null && mSettings.isEnabledAndMatchLPr(s.info, flags, userId)) {
3344                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
3345                if (ps == null) return null;
3346                return PackageParser.generateServiceInfo(s, flags, ps.readUserState(userId),
3347                        userId);
3348            }
3349        }
3350        return null;
3351    }
3352
3353    @Override
3354    public ProviderInfo getProviderInfo(ComponentName component, int flags, int userId) {
3355        if (!sUserManager.exists(userId)) return null;
3356        flags = updateFlagsForComponent(flags, userId, component);
3357        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get provider info");
3358        synchronized (mPackages) {
3359            PackageParser.Provider p = mProviders.mProviders.get(component);
3360            if (DEBUG_PACKAGE_INFO) Log.v(
3361                TAG, "getProviderInfo " + component + ": " + p);
3362            if (p != null && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) {
3363                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
3364                if (ps == null) return null;
3365                return PackageParser.generateProviderInfo(p, flags, ps.readUserState(userId),
3366                        userId);
3367            }
3368        }
3369        return null;
3370    }
3371
3372    @Override
3373    public String[] getSystemSharedLibraryNames() {
3374        Set<String> libSet;
3375        synchronized (mPackages) {
3376            libSet = mSharedLibraries.keySet();
3377            int size = libSet.size();
3378            if (size > 0) {
3379                String[] libs = new String[size];
3380                libSet.toArray(libs);
3381                return libs;
3382            }
3383        }
3384        return null;
3385    }
3386
3387    /**
3388     * @hide
3389     */
3390    PackageParser.Package findSharedNonSystemLibrary(String libName) {
3391        synchronized (mPackages) {
3392            PackageManagerService.SharedLibraryEntry lib = mSharedLibraries.get(libName);
3393            if (lib != null && lib.apk != null) {
3394                return mPackages.get(lib.apk);
3395            }
3396        }
3397        return null;
3398    }
3399
3400    @Override
3401    public FeatureInfo[] getSystemAvailableFeatures() {
3402        Collection<FeatureInfo> featSet;
3403        synchronized (mPackages) {
3404            featSet = mAvailableFeatures.values();
3405            int size = featSet.size();
3406            if (size > 0) {
3407                FeatureInfo[] features = new FeatureInfo[size+1];
3408                featSet.toArray(features);
3409                FeatureInfo fi = new FeatureInfo();
3410                fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version",
3411                        FeatureInfo.GL_ES_VERSION_UNDEFINED);
3412                features[size] = fi;
3413                return features;
3414            }
3415        }
3416        return null;
3417    }
3418
3419    @Override
3420    public boolean hasSystemFeature(String name) {
3421        synchronized (mPackages) {
3422            return mAvailableFeatures.containsKey(name);
3423        }
3424    }
3425
3426    @Override
3427    public int checkPermission(String permName, String pkgName, int userId) {
3428        if (!sUserManager.exists(userId)) {
3429            return PackageManager.PERMISSION_DENIED;
3430        }
3431
3432        synchronized (mPackages) {
3433            final PackageParser.Package p = mPackages.get(pkgName);
3434            if (p != null && p.mExtras != null) {
3435                final PackageSetting ps = (PackageSetting) p.mExtras;
3436                final PermissionsState permissionsState = ps.getPermissionsState();
3437                if (permissionsState.hasPermission(permName, userId)) {
3438                    return PackageManager.PERMISSION_GRANTED;
3439                }
3440                // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION
3441                if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState
3442                        .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) {
3443                    return PackageManager.PERMISSION_GRANTED;
3444                }
3445            }
3446        }
3447
3448        return PackageManager.PERMISSION_DENIED;
3449    }
3450
3451    @Override
3452    public int checkUidPermission(String permName, int uid) {
3453        final int userId = UserHandle.getUserId(uid);
3454
3455        if (!sUserManager.exists(userId)) {
3456            return PackageManager.PERMISSION_DENIED;
3457        }
3458
3459        synchronized (mPackages) {
3460            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
3461            if (obj != null) {
3462                final SettingBase ps = (SettingBase) obj;
3463                final PermissionsState permissionsState = ps.getPermissionsState();
3464                if (permissionsState.hasPermission(permName, userId)) {
3465                    return PackageManager.PERMISSION_GRANTED;
3466                }
3467                // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION
3468                if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState
3469                        .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) {
3470                    return PackageManager.PERMISSION_GRANTED;
3471                }
3472            } else {
3473                ArraySet<String> perms = mSystemPermissions.get(uid);
3474                if (perms != null) {
3475                    if (perms.contains(permName)) {
3476                        return PackageManager.PERMISSION_GRANTED;
3477                    }
3478                    if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && perms
3479                            .contains(Manifest.permission.ACCESS_FINE_LOCATION)) {
3480                        return PackageManager.PERMISSION_GRANTED;
3481                    }
3482                }
3483            }
3484        }
3485
3486        return PackageManager.PERMISSION_DENIED;
3487    }
3488
3489    @Override
3490    public boolean isPermissionRevokedByPolicy(String permission, String packageName, int userId) {
3491        if (UserHandle.getCallingUserId() != userId) {
3492            mContext.enforceCallingPermission(
3493                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
3494                    "isPermissionRevokedByPolicy for user " + userId);
3495        }
3496
3497        if (checkPermission(permission, packageName, userId)
3498                == PackageManager.PERMISSION_GRANTED) {
3499            return false;
3500        }
3501
3502        final long identity = Binder.clearCallingIdentity();
3503        try {
3504            final int flags = getPermissionFlags(permission, packageName, userId);
3505            return (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0;
3506        } finally {
3507            Binder.restoreCallingIdentity(identity);
3508        }
3509    }
3510
3511    @Override
3512    public String getPermissionControllerPackageName() {
3513        synchronized (mPackages) {
3514            return mRequiredInstallerPackage;
3515        }
3516    }
3517
3518    /**
3519     * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS
3520     * or INTERACT_ACROSS_USERS_FULL permissions, if the userid is not for the caller.
3521     * @param checkShell whether to prevent shell from access if there's a debugging restriction
3522     * @param message the message to log on security exception
3523     */
3524    void enforceCrossUserPermission(int callingUid, int userId, boolean requireFullPermission,
3525            boolean checkShell, String message) {
3526        if (userId < 0) {
3527            throw new IllegalArgumentException("Invalid userId " + userId);
3528        }
3529        if (checkShell) {
3530            enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId);
3531        }
3532        if (userId == UserHandle.getUserId(callingUid)) return;
3533        if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
3534            if (requireFullPermission) {
3535                mContext.enforceCallingOrSelfPermission(
3536                        android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
3537            } else {
3538                try {
3539                    mContext.enforceCallingOrSelfPermission(
3540                            android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
3541                } catch (SecurityException se) {
3542                    mContext.enforceCallingOrSelfPermission(
3543                            android.Manifest.permission.INTERACT_ACROSS_USERS, message);
3544                }
3545            }
3546        }
3547    }
3548
3549    void enforceShellRestriction(String restriction, int callingUid, int userHandle) {
3550        if (callingUid == Process.SHELL_UID) {
3551            if (userHandle >= 0
3552                    && sUserManager.hasUserRestriction(restriction, userHandle)) {
3553                throw new SecurityException("Shell does not have permission to access user "
3554                        + userHandle);
3555            } else if (userHandle < 0) {
3556                Slog.e(TAG, "Unable to check shell permission for user " + userHandle + "\n\t"
3557                        + Debug.getCallers(3));
3558            }
3559        }
3560    }
3561
3562    private BasePermission findPermissionTreeLP(String permName) {
3563        for(BasePermission bp : mSettings.mPermissionTrees.values()) {
3564            if (permName.startsWith(bp.name) &&
3565                    permName.length() > bp.name.length() &&
3566                    permName.charAt(bp.name.length()) == '.') {
3567                return bp;
3568            }
3569        }
3570        return null;
3571    }
3572
3573    private BasePermission checkPermissionTreeLP(String permName) {
3574        if (permName != null) {
3575            BasePermission bp = findPermissionTreeLP(permName);
3576            if (bp != null) {
3577                if (bp.uid == UserHandle.getAppId(Binder.getCallingUid())) {
3578                    return bp;
3579                }
3580                throw new SecurityException("Calling uid "
3581                        + Binder.getCallingUid()
3582                        + " is not allowed to add to permission tree "
3583                        + bp.name + " owned by uid " + bp.uid);
3584            }
3585        }
3586        throw new SecurityException("No permission tree found for " + permName);
3587    }
3588
3589    static boolean compareStrings(CharSequence s1, CharSequence s2) {
3590        if (s1 == null) {
3591            return s2 == null;
3592        }
3593        if (s2 == null) {
3594            return false;
3595        }
3596        if (s1.getClass() != s2.getClass()) {
3597            return false;
3598        }
3599        return s1.equals(s2);
3600    }
3601
3602    static boolean comparePermissionInfos(PermissionInfo pi1, PermissionInfo pi2) {
3603        if (pi1.icon != pi2.icon) return false;
3604        if (pi1.logo != pi2.logo) return false;
3605        if (pi1.protectionLevel != pi2.protectionLevel) return false;
3606        if (!compareStrings(pi1.name, pi2.name)) return false;
3607        if (!compareStrings(pi1.nonLocalizedLabel, pi2.nonLocalizedLabel)) return false;
3608        // We'll take care of setting this one.
3609        if (!compareStrings(pi1.packageName, pi2.packageName)) return false;
3610        // These are not currently stored in settings.
3611        //if (!compareStrings(pi1.group, pi2.group)) return false;
3612        //if (!compareStrings(pi1.nonLocalizedDescription, pi2.nonLocalizedDescription)) return false;
3613        //if (pi1.labelRes != pi2.labelRes) return false;
3614        //if (pi1.descriptionRes != pi2.descriptionRes) return false;
3615        return true;
3616    }
3617
3618    int permissionInfoFootprint(PermissionInfo info) {
3619        int size = info.name.length();
3620        if (info.nonLocalizedLabel != null) size += info.nonLocalizedLabel.length();
3621        if (info.nonLocalizedDescription != null) size += info.nonLocalizedDescription.length();
3622        return size;
3623    }
3624
3625    int calculateCurrentPermissionFootprintLocked(BasePermission tree) {
3626        int size = 0;
3627        for (BasePermission perm : mSettings.mPermissions.values()) {
3628            if (perm.uid == tree.uid) {
3629                size += perm.name.length() + permissionInfoFootprint(perm.perm.info);
3630            }
3631        }
3632        return size;
3633    }
3634
3635    void enforcePermissionCapLocked(PermissionInfo info, BasePermission tree) {
3636        // We calculate the max size of permissions defined by this uid and throw
3637        // if that plus the size of 'info' would exceed our stated maximum.
3638        if (tree.uid != Process.SYSTEM_UID) {
3639            final int curTreeSize = calculateCurrentPermissionFootprintLocked(tree);
3640            if (curTreeSize + permissionInfoFootprint(info) > MAX_PERMISSION_TREE_FOOTPRINT) {
3641                throw new SecurityException("Permission tree size cap exceeded");
3642            }
3643        }
3644    }
3645
3646    boolean addPermissionLocked(PermissionInfo info, boolean async) {
3647        if (info.labelRes == 0 && info.nonLocalizedLabel == null) {
3648            throw new SecurityException("Label must be specified in permission");
3649        }
3650        BasePermission tree = checkPermissionTreeLP(info.name);
3651        BasePermission bp = mSettings.mPermissions.get(info.name);
3652        boolean added = bp == null;
3653        boolean changed = true;
3654        int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel);
3655        if (added) {
3656            enforcePermissionCapLocked(info, tree);
3657            bp = new BasePermission(info.name, tree.sourcePackage,
3658                    BasePermission.TYPE_DYNAMIC);
3659        } else if (bp.type != BasePermission.TYPE_DYNAMIC) {
3660            throw new SecurityException(
3661                    "Not allowed to modify non-dynamic permission "
3662                    + info.name);
3663        } else {
3664            if (bp.protectionLevel == fixedLevel
3665                    && bp.perm.owner.equals(tree.perm.owner)
3666                    && bp.uid == tree.uid
3667                    && comparePermissionInfos(bp.perm.info, info)) {
3668                changed = false;
3669            }
3670        }
3671        bp.protectionLevel = fixedLevel;
3672        info = new PermissionInfo(info);
3673        info.protectionLevel = fixedLevel;
3674        bp.perm = new PackageParser.Permission(tree.perm.owner, info);
3675        bp.perm.info.packageName = tree.perm.info.packageName;
3676        bp.uid = tree.uid;
3677        if (added) {
3678            mSettings.mPermissions.put(info.name, bp);
3679        }
3680        if (changed) {
3681            if (!async) {
3682                mSettings.writeLPr();
3683            } else {
3684                scheduleWriteSettingsLocked();
3685            }
3686        }
3687        return added;
3688    }
3689
3690    @Override
3691    public boolean addPermission(PermissionInfo info) {
3692        synchronized (mPackages) {
3693            return addPermissionLocked(info, false);
3694        }
3695    }
3696
3697    @Override
3698    public boolean addPermissionAsync(PermissionInfo info) {
3699        synchronized (mPackages) {
3700            return addPermissionLocked(info, true);
3701        }
3702    }
3703
3704    @Override
3705    public void removePermission(String name) {
3706        synchronized (mPackages) {
3707            checkPermissionTreeLP(name);
3708            BasePermission bp = mSettings.mPermissions.get(name);
3709            if (bp != null) {
3710                if (bp.type != BasePermission.TYPE_DYNAMIC) {
3711                    throw new SecurityException(
3712                            "Not allowed to modify non-dynamic permission "
3713                            + name);
3714                }
3715                mSettings.mPermissions.remove(name);
3716                mSettings.writeLPr();
3717            }
3718        }
3719    }
3720
3721    private static void enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(PackageParser.Package pkg,
3722            BasePermission bp) {
3723        int index = pkg.requestedPermissions.indexOf(bp.name);
3724        if (index == -1) {
3725            throw new SecurityException("Package " + pkg.packageName
3726                    + " has not requested permission " + bp.name);
3727        }
3728        if (!bp.isRuntime() && !bp.isDevelopment()) {
3729            throw new SecurityException("Permission " + bp.name
3730                    + " is not a changeable permission type");
3731        }
3732    }
3733
3734    @Override
3735    public void grantRuntimePermission(String packageName, String name, final int userId) {
3736        if (!sUserManager.exists(userId)) {
3737            Log.e(TAG, "No such user:" + userId);
3738            return;
3739        }
3740
3741        mContext.enforceCallingOrSelfPermission(
3742                android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
3743                "grantRuntimePermission");
3744
3745        enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false,
3746                "grantRuntimePermission");
3747
3748        final int uid;
3749        final SettingBase sb;
3750
3751        synchronized (mPackages) {
3752            final PackageParser.Package pkg = mPackages.get(packageName);
3753            if (pkg == null) {
3754                throw new IllegalArgumentException("Unknown package: " + packageName);
3755            }
3756
3757            final BasePermission bp = mSettings.mPermissions.get(name);
3758            if (bp == null) {
3759                throw new IllegalArgumentException("Unknown permission: " + name);
3760            }
3761
3762            enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(pkg, bp);
3763
3764            // If a permission review is required for legacy apps we represent
3765            // their permissions as always granted runtime ones since we need
3766            // to keep the review required permission flag per user while an
3767            // install permission's state is shared across all users.
3768            if (Build.PERMISSIONS_REVIEW_REQUIRED
3769                    && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
3770                    && bp.isRuntime()) {
3771                return;
3772            }
3773
3774            uid = UserHandle.getUid(userId, pkg.applicationInfo.uid);
3775            sb = (SettingBase) pkg.mExtras;
3776            if (sb == null) {
3777                throw new IllegalArgumentException("Unknown package: " + packageName);
3778            }
3779
3780            final PermissionsState permissionsState = sb.getPermissionsState();
3781
3782            final int flags = permissionsState.getPermissionFlags(name, userId);
3783            if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
3784                throw new SecurityException("Cannot grant system fixed permission "
3785                        + name + " for package " + packageName);
3786            }
3787
3788            if (bp.isDevelopment()) {
3789                // Development permissions must be handled specially, since they are not
3790                // normal runtime permissions.  For now they apply to all users.
3791                if (permissionsState.grantInstallPermission(bp) !=
3792                        PermissionsState.PERMISSION_OPERATION_FAILURE) {
3793                    scheduleWriteSettingsLocked();
3794                }
3795                return;
3796            }
3797
3798            if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
3799                Slog.w(TAG, "Cannot grant runtime permission to a legacy app");
3800                return;
3801            }
3802
3803            final int result = permissionsState.grantRuntimePermission(bp, userId);
3804            switch (result) {
3805                case PermissionsState.PERMISSION_OPERATION_FAILURE: {
3806                    return;
3807                }
3808
3809                case PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
3810                    final int appId = UserHandle.getAppId(pkg.applicationInfo.uid);
3811                    mHandler.post(new Runnable() {
3812                        @Override
3813                        public void run() {
3814                            killUid(appId, userId, KILL_APP_REASON_GIDS_CHANGED);
3815                        }
3816                    });
3817                }
3818                break;
3819            }
3820
3821            mOnPermissionChangeListeners.onPermissionsChanged(uid);
3822
3823            // Not critical if that is lost - app has to request again.
3824            mSettings.writeRuntimePermissionsForUserLPr(userId, false);
3825        }
3826
3827        // Only need to do this if user is initialized. Otherwise it's a new user
3828        // and there are no processes running as the user yet and there's no need
3829        // to make an expensive call to remount processes for the changed permissions.
3830        if (READ_EXTERNAL_STORAGE.equals(name)
3831                || WRITE_EXTERNAL_STORAGE.equals(name)) {
3832            final long token = Binder.clearCallingIdentity();
3833            try {
3834                if (sUserManager.isInitialized(userId)) {
3835                    MountServiceInternal mountServiceInternal = LocalServices.getService(
3836                            MountServiceInternal.class);
3837                    mountServiceInternal.onExternalStoragePolicyChanged(uid, packageName);
3838                }
3839            } finally {
3840                Binder.restoreCallingIdentity(token);
3841            }
3842        }
3843    }
3844
3845    @Override
3846    public void revokeRuntimePermission(String packageName, String name, int userId) {
3847        if (!sUserManager.exists(userId)) {
3848            Log.e(TAG, "No such user:" + userId);
3849            return;
3850        }
3851
3852        mContext.enforceCallingOrSelfPermission(
3853                android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
3854                "revokeRuntimePermission");
3855
3856        enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false,
3857                "revokeRuntimePermission");
3858
3859        final int appId;
3860
3861        synchronized (mPackages) {
3862            final PackageParser.Package pkg = mPackages.get(packageName);
3863            if (pkg == null) {
3864                throw new IllegalArgumentException("Unknown package: " + packageName);
3865            }
3866
3867            final BasePermission bp = mSettings.mPermissions.get(name);
3868            if (bp == null) {
3869                throw new IllegalArgumentException("Unknown permission: " + name);
3870            }
3871
3872            enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(pkg, bp);
3873
3874            // If a permission review is required for legacy apps we represent
3875            // their permissions as always granted runtime ones since we need
3876            // to keep the review required permission flag per user while an
3877            // install permission's state is shared across all users.
3878            if (Build.PERMISSIONS_REVIEW_REQUIRED
3879                    && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
3880                    && bp.isRuntime()) {
3881                return;
3882            }
3883
3884            SettingBase sb = (SettingBase) pkg.mExtras;
3885            if (sb == null) {
3886                throw new IllegalArgumentException("Unknown package: " + packageName);
3887            }
3888
3889            final PermissionsState permissionsState = sb.getPermissionsState();
3890
3891            final int flags = permissionsState.getPermissionFlags(name, userId);
3892            if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
3893                throw new SecurityException("Cannot revoke system fixed permission "
3894                        + name + " for package " + packageName);
3895            }
3896
3897            if (bp.isDevelopment()) {
3898                // Development permissions must be handled specially, since they are not
3899                // normal runtime permissions.  For now they apply to all users.
3900                if (permissionsState.revokeInstallPermission(bp) !=
3901                        PermissionsState.PERMISSION_OPERATION_FAILURE) {
3902                    scheduleWriteSettingsLocked();
3903                }
3904                return;
3905            }
3906
3907            if (permissionsState.revokeRuntimePermission(bp, userId) ==
3908                    PermissionsState.PERMISSION_OPERATION_FAILURE) {
3909                return;
3910            }
3911
3912            mOnPermissionChangeListeners.onPermissionsChanged(pkg.applicationInfo.uid);
3913
3914            // Critical, after this call app should never have the permission.
3915            mSettings.writeRuntimePermissionsForUserLPr(userId, true);
3916
3917            appId = UserHandle.getAppId(pkg.applicationInfo.uid);
3918        }
3919
3920        killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED);
3921    }
3922
3923    @Override
3924    public void resetRuntimePermissions() {
3925        mContext.enforceCallingOrSelfPermission(
3926                android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
3927                "revokeRuntimePermission");
3928
3929        int callingUid = Binder.getCallingUid();
3930        if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
3931            mContext.enforceCallingOrSelfPermission(
3932                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
3933                    "resetRuntimePermissions");
3934        }
3935
3936        synchronized (mPackages) {
3937            updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL);
3938            for (int userId : UserManagerService.getInstance().getUserIds()) {
3939                final int packageCount = mPackages.size();
3940                for (int i = 0; i < packageCount; i++) {
3941                    PackageParser.Package pkg = mPackages.valueAt(i);
3942                    if (!(pkg.mExtras instanceof PackageSetting)) {
3943                        continue;
3944                    }
3945                    PackageSetting ps = (PackageSetting) pkg.mExtras;
3946                    resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
3947                }
3948            }
3949        }
3950    }
3951
3952    @Override
3953    public int getPermissionFlags(String name, String packageName, int userId) {
3954        if (!sUserManager.exists(userId)) {
3955            return 0;
3956        }
3957
3958        enforceGrantRevokeRuntimePermissionPermissions("getPermissionFlags");
3959
3960        enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false,
3961                "getPermissionFlags");
3962
3963        synchronized (mPackages) {
3964            final PackageParser.Package pkg = mPackages.get(packageName);
3965            if (pkg == null) {
3966                throw new IllegalArgumentException("Unknown package: " + packageName);
3967            }
3968
3969            final BasePermission bp = mSettings.mPermissions.get(name);
3970            if (bp == null) {
3971                throw new IllegalArgumentException("Unknown permission: " + name);
3972            }
3973
3974            SettingBase sb = (SettingBase) pkg.mExtras;
3975            if (sb == null) {
3976                throw new IllegalArgumentException("Unknown package: " + packageName);
3977            }
3978
3979            PermissionsState permissionsState = sb.getPermissionsState();
3980            return permissionsState.getPermissionFlags(name, userId);
3981        }
3982    }
3983
3984    @Override
3985    public void updatePermissionFlags(String name, String packageName, int flagMask,
3986            int flagValues, int userId) {
3987        if (!sUserManager.exists(userId)) {
3988            return;
3989        }
3990
3991        enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlags");
3992
3993        enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false,
3994                "updatePermissionFlags");
3995
3996        // Only the system can change these flags and nothing else.
3997        if (getCallingUid() != Process.SYSTEM_UID) {
3998            flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
3999            flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
4000            flagMask &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
4001            flagValues &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
4002            flagValues &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
4003        }
4004
4005        synchronized (mPackages) {
4006            final PackageParser.Package pkg = mPackages.get(packageName);
4007            if (pkg == null) {
4008                throw new IllegalArgumentException("Unknown package: " + packageName);
4009            }
4010
4011            final BasePermission bp = mSettings.mPermissions.get(name);
4012            if (bp == null) {
4013                throw new IllegalArgumentException("Unknown permission: " + name);
4014            }
4015
4016            SettingBase sb = (SettingBase) pkg.mExtras;
4017            if (sb == null) {
4018                throw new IllegalArgumentException("Unknown package: " + packageName);
4019            }
4020
4021            PermissionsState permissionsState = sb.getPermissionsState();
4022
4023            boolean hadState = permissionsState.getRuntimePermissionState(name, userId) != null;
4024
4025            if (permissionsState.updatePermissionFlags(bp, userId, flagMask, flagValues)) {
4026                // Install and runtime permissions are stored in different places,
4027                // so figure out what permission changed and persist the change.
4028                if (permissionsState.getInstallPermissionState(name) != null) {
4029                    scheduleWriteSettingsLocked();
4030                } else if (permissionsState.getRuntimePermissionState(name, userId) != null
4031                        || hadState) {
4032                    mSettings.writeRuntimePermissionsForUserLPr(userId, false);
4033                }
4034            }
4035        }
4036    }
4037
4038    /**
4039     * Update the permission flags for all packages and runtime permissions of a user in order
4040     * to allow device or profile owner to remove POLICY_FIXED.
4041     */
4042    @Override
4043    public void updatePermissionFlagsForAllApps(int flagMask, int flagValues, int userId) {
4044        if (!sUserManager.exists(userId)) {
4045            return;
4046        }
4047
4048        enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlagsForAllApps");
4049
4050        enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false,
4051                "updatePermissionFlagsForAllApps");
4052
4053        // Only the system can change system fixed flags.
4054        if (getCallingUid() != Process.SYSTEM_UID) {
4055            flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
4056            flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
4057        }
4058
4059        synchronized (mPackages) {
4060            boolean changed = false;
4061            final int packageCount = mPackages.size();
4062            for (int pkgIndex = 0; pkgIndex < packageCount; pkgIndex++) {
4063                final PackageParser.Package pkg = mPackages.valueAt(pkgIndex);
4064                SettingBase sb = (SettingBase) pkg.mExtras;
4065                if (sb == null) {
4066                    continue;
4067                }
4068                PermissionsState permissionsState = sb.getPermissionsState();
4069                changed |= permissionsState.updatePermissionFlagsForAllPermissions(
4070                        userId, flagMask, flagValues);
4071            }
4072            if (changed) {
4073                mSettings.writeRuntimePermissionsForUserLPr(userId, false);
4074            }
4075        }
4076    }
4077
4078    private void enforceGrantRevokeRuntimePermissionPermissions(String message) {
4079        if (mContext.checkCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS)
4080                != PackageManager.PERMISSION_GRANTED
4081            && mContext.checkCallingOrSelfPermission(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS)
4082                != PackageManager.PERMISSION_GRANTED) {
4083            throw new SecurityException(message + " requires "
4084                    + Manifest.permission.GRANT_RUNTIME_PERMISSIONS + " or "
4085                    + Manifest.permission.REVOKE_RUNTIME_PERMISSIONS);
4086        }
4087    }
4088
4089    @Override
4090    public boolean shouldShowRequestPermissionRationale(String permissionName,
4091            String packageName, int userId) {
4092        if (UserHandle.getCallingUserId() != userId) {
4093            mContext.enforceCallingPermission(
4094                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
4095                    "canShowRequestPermissionRationale for user " + userId);
4096        }
4097
4098        final int uid = getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
4099        if (UserHandle.getAppId(getCallingUid()) != UserHandle.getAppId(uid)) {
4100            return false;
4101        }
4102
4103        if (checkPermission(permissionName, packageName, userId)
4104                == PackageManager.PERMISSION_GRANTED) {
4105            return false;
4106        }
4107
4108        final int flags;
4109
4110        final long identity = Binder.clearCallingIdentity();
4111        try {
4112            flags = getPermissionFlags(permissionName,
4113                    packageName, userId);
4114        } finally {
4115            Binder.restoreCallingIdentity(identity);
4116        }
4117
4118        final int fixedFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
4119                | PackageManager.FLAG_PERMISSION_POLICY_FIXED
4120                | PackageManager.FLAG_PERMISSION_USER_FIXED;
4121
4122        if ((flags & fixedFlags) != 0) {
4123            return false;
4124        }
4125
4126        return (flags & PackageManager.FLAG_PERMISSION_USER_SET) != 0;
4127    }
4128
4129    @Override
4130    public void addOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
4131        mContext.enforceCallingOrSelfPermission(
4132                Manifest.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS,
4133                "addOnPermissionsChangeListener");
4134
4135        synchronized (mPackages) {
4136            mOnPermissionChangeListeners.addListenerLocked(listener);
4137        }
4138    }
4139
4140    @Override
4141    public void removeOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
4142        synchronized (mPackages) {
4143            mOnPermissionChangeListeners.removeListenerLocked(listener);
4144        }
4145    }
4146
4147    @Override
4148    public boolean isProtectedBroadcast(String actionName) {
4149        synchronized (mPackages) {
4150            if (mProtectedBroadcasts.contains(actionName)) {
4151                return true;
4152            } else if (actionName != null) {
4153                // TODO: remove these terrible hacks
4154                if (actionName.startsWith("android.net.netmon.lingerExpired")
4155                        || actionName.startsWith("com.android.server.sip.SipWakeupTimer")) {
4156                    return true;
4157                }
4158            }
4159        }
4160        return false;
4161    }
4162
4163    @Override
4164    public int checkSignatures(String pkg1, String pkg2) {
4165        synchronized (mPackages) {
4166            final PackageParser.Package p1 = mPackages.get(pkg1);
4167            final PackageParser.Package p2 = mPackages.get(pkg2);
4168            if (p1 == null || p1.mExtras == null
4169                    || p2 == null || p2.mExtras == null) {
4170                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
4171            }
4172            return compareSignatures(p1.mSignatures, p2.mSignatures);
4173        }
4174    }
4175
4176    @Override
4177    public int checkUidSignatures(int uid1, int uid2) {
4178        // Map to base uids.
4179        uid1 = UserHandle.getAppId(uid1);
4180        uid2 = UserHandle.getAppId(uid2);
4181        // reader
4182        synchronized (mPackages) {
4183            Signature[] s1;
4184            Signature[] s2;
4185            Object obj = mSettings.getUserIdLPr(uid1);
4186            if (obj != null) {
4187                if (obj instanceof SharedUserSetting) {
4188                    s1 = ((SharedUserSetting)obj).signatures.mSignatures;
4189                } else if (obj instanceof PackageSetting) {
4190                    s1 = ((PackageSetting)obj).signatures.mSignatures;
4191                } else {
4192                    return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
4193                }
4194            } else {
4195                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
4196            }
4197            obj = mSettings.getUserIdLPr(uid2);
4198            if (obj != null) {
4199                if (obj instanceof SharedUserSetting) {
4200                    s2 = ((SharedUserSetting)obj).signatures.mSignatures;
4201                } else if (obj instanceof PackageSetting) {
4202                    s2 = ((PackageSetting)obj).signatures.mSignatures;
4203                } else {
4204                    return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
4205                }
4206            } else {
4207                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
4208            }
4209            return compareSignatures(s1, s2);
4210        }
4211    }
4212
4213    private void killUid(int appId, int userId, String reason) {
4214        final long identity = Binder.clearCallingIdentity();
4215        try {
4216            IActivityManager am = ActivityManagerNative.getDefault();
4217            if (am != null) {
4218                try {
4219                    am.killUid(appId, userId, reason);
4220                } catch (RemoteException e) {
4221                    /* ignore - same process */
4222                }
4223            }
4224        } finally {
4225            Binder.restoreCallingIdentity(identity);
4226        }
4227    }
4228
4229    /**
4230     * Compares two sets of signatures. Returns:
4231     * <br />
4232     * {@link PackageManager#SIGNATURE_NEITHER_SIGNED}: if both signature sets are null,
4233     * <br />
4234     * {@link PackageManager#SIGNATURE_FIRST_NOT_SIGNED}: if the first signature set is null,
4235     * <br />
4236     * {@link PackageManager#SIGNATURE_SECOND_NOT_SIGNED}: if the second signature set is null,
4237     * <br />
4238     * {@link PackageManager#SIGNATURE_MATCH}: if the two signature sets are identical,
4239     * <br />
4240     * {@link PackageManager#SIGNATURE_NO_MATCH}: if the two signature sets differ.
4241     */
4242    static int compareSignatures(Signature[] s1, Signature[] s2) {
4243        if (s1 == null) {
4244            return s2 == null
4245                    ? PackageManager.SIGNATURE_NEITHER_SIGNED
4246                    : PackageManager.SIGNATURE_FIRST_NOT_SIGNED;
4247        }
4248
4249        if (s2 == null) {
4250            return PackageManager.SIGNATURE_SECOND_NOT_SIGNED;
4251        }
4252
4253        if (s1.length != s2.length) {
4254            return PackageManager.SIGNATURE_NO_MATCH;
4255        }
4256
4257        // Since both signature sets are of size 1, we can compare without HashSets.
4258        if (s1.length == 1) {
4259            return s1[0].equals(s2[0]) ?
4260                    PackageManager.SIGNATURE_MATCH :
4261                    PackageManager.SIGNATURE_NO_MATCH;
4262        }
4263
4264        ArraySet<Signature> set1 = new ArraySet<Signature>();
4265        for (Signature sig : s1) {
4266            set1.add(sig);
4267        }
4268        ArraySet<Signature> set2 = new ArraySet<Signature>();
4269        for (Signature sig : s2) {
4270            set2.add(sig);
4271        }
4272        // Make sure s2 contains all signatures in s1.
4273        if (set1.equals(set2)) {
4274            return PackageManager.SIGNATURE_MATCH;
4275        }
4276        return PackageManager.SIGNATURE_NO_MATCH;
4277    }
4278
4279    /**
4280     * If the database version for this type of package (internal storage or
4281     * external storage) is less than the version where package signatures
4282     * were updated, return true.
4283     */
4284    private boolean isCompatSignatureUpdateNeeded(PackageParser.Package scannedPkg) {
4285        final VersionInfo ver = getSettingsVersionForPackage(scannedPkg);
4286        return ver.databaseVersion < DatabaseVersion.SIGNATURE_END_ENTITY;
4287    }
4288
4289    /**
4290     * Used for backward compatibility to make sure any packages with
4291     * certificate chains get upgraded to the new style. {@code existingSigs}
4292     * will be in the old format (since they were stored on disk from before the
4293     * system upgrade) and {@code scannedSigs} will be in the newer format.
4294     */
4295    private int compareSignaturesCompat(PackageSignatures existingSigs,
4296            PackageParser.Package scannedPkg) {
4297        if (!isCompatSignatureUpdateNeeded(scannedPkg)) {
4298            return PackageManager.SIGNATURE_NO_MATCH;
4299        }
4300
4301        ArraySet<Signature> existingSet = new ArraySet<Signature>();
4302        for (Signature sig : existingSigs.mSignatures) {
4303            existingSet.add(sig);
4304        }
4305        ArraySet<Signature> scannedCompatSet = new ArraySet<Signature>();
4306        for (Signature sig : scannedPkg.mSignatures) {
4307            try {
4308                Signature[] chainSignatures = sig.getChainSignatures();
4309                for (Signature chainSig : chainSignatures) {
4310                    scannedCompatSet.add(chainSig);
4311                }
4312            } catch (CertificateEncodingException e) {
4313                scannedCompatSet.add(sig);
4314            }
4315        }
4316        /*
4317         * Make sure the expanded scanned set contains all signatures in the
4318         * existing one.
4319         */
4320        if (scannedCompatSet.equals(existingSet)) {
4321            // Migrate the old signatures to the new scheme.
4322            existingSigs.assignSignatures(scannedPkg.mSignatures);
4323            // The new KeySets will be re-added later in the scanning process.
4324            synchronized (mPackages) {
4325                mSettings.mKeySetManagerService.removeAppKeySetDataLPw(scannedPkg.packageName);
4326            }
4327            return PackageManager.SIGNATURE_MATCH;
4328        }
4329        return PackageManager.SIGNATURE_NO_MATCH;
4330    }
4331
4332    private boolean isRecoverSignatureUpdateNeeded(PackageParser.Package scannedPkg) {
4333        final VersionInfo ver = getSettingsVersionForPackage(scannedPkg);
4334        return ver.databaseVersion < DatabaseVersion.SIGNATURE_MALFORMED_RECOVER;
4335    }
4336
4337    private int compareSignaturesRecover(PackageSignatures existingSigs,
4338            PackageParser.Package scannedPkg) {
4339        if (!isRecoverSignatureUpdateNeeded(scannedPkg)) {
4340            return PackageManager.SIGNATURE_NO_MATCH;
4341        }
4342
4343        String msg = null;
4344        try {
4345            if (Signature.areEffectiveMatch(existingSigs.mSignatures, scannedPkg.mSignatures)) {
4346                logCriticalInfo(Log.INFO, "Recovered effectively matching certificates for "
4347                        + scannedPkg.packageName);
4348                return PackageManager.SIGNATURE_MATCH;
4349            }
4350        } catch (CertificateException e) {
4351            msg = e.getMessage();
4352        }
4353
4354        logCriticalInfo(Log.INFO,
4355                "Failed to recover certificates for " + scannedPkg.packageName + ": " + msg);
4356        return PackageManager.SIGNATURE_NO_MATCH;
4357    }
4358
4359    @Override
4360    public String[] getPackagesForUid(int uid) {
4361        uid = UserHandle.getAppId(uid);
4362        // reader
4363        synchronized (mPackages) {
4364            Object obj = mSettings.getUserIdLPr(uid);
4365            if (obj instanceof SharedUserSetting) {
4366                final SharedUserSetting sus = (SharedUserSetting) obj;
4367                final int N = sus.packages.size();
4368                final String[] res = new String[N];
4369                final Iterator<PackageSetting> it = sus.packages.iterator();
4370                int i = 0;
4371                while (it.hasNext()) {
4372                    res[i++] = it.next().name;
4373                }
4374                return res;
4375            } else if (obj instanceof PackageSetting) {
4376                final PackageSetting ps = (PackageSetting) obj;
4377                return new String[] { ps.name };
4378            }
4379        }
4380        return null;
4381    }
4382
4383    @Override
4384    public String getNameForUid(int uid) {
4385        // reader
4386        synchronized (mPackages) {
4387            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
4388            if (obj instanceof SharedUserSetting) {
4389                final SharedUserSetting sus = (SharedUserSetting) obj;
4390                return sus.name + ":" + sus.userId;
4391            } else if (obj instanceof PackageSetting) {
4392                final PackageSetting ps = (PackageSetting) obj;
4393                return ps.name;
4394            }
4395        }
4396        return null;
4397    }
4398
4399    @Override
4400    public int getUidForSharedUser(String sharedUserName) {
4401        if(sharedUserName == null) {
4402            return -1;
4403        }
4404        // reader
4405        synchronized (mPackages) {
4406            final SharedUserSetting suid = mSettings.getSharedUserLPw(sharedUserName, 0, 0, false);
4407            if (suid == null) {
4408                return -1;
4409            }
4410            return suid.userId;
4411        }
4412    }
4413
4414    @Override
4415    public int getFlagsForUid(int uid) {
4416        synchronized (mPackages) {
4417            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
4418            if (obj instanceof SharedUserSetting) {
4419                final SharedUserSetting sus = (SharedUserSetting) obj;
4420                return sus.pkgFlags;
4421            } else if (obj instanceof PackageSetting) {
4422                final PackageSetting ps = (PackageSetting) obj;
4423                return ps.pkgFlags;
4424            }
4425        }
4426        return 0;
4427    }
4428
4429    @Override
4430    public int getPrivateFlagsForUid(int uid) {
4431        synchronized (mPackages) {
4432            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
4433            if (obj instanceof SharedUserSetting) {
4434                final SharedUserSetting sus = (SharedUserSetting) obj;
4435                return sus.pkgPrivateFlags;
4436            } else if (obj instanceof PackageSetting) {
4437                final PackageSetting ps = (PackageSetting) obj;
4438                return ps.pkgPrivateFlags;
4439            }
4440        }
4441        return 0;
4442    }
4443
4444    @Override
4445    public boolean isUidPrivileged(int uid) {
4446        uid = UserHandle.getAppId(uid);
4447        // reader
4448        synchronized (mPackages) {
4449            Object obj = mSettings.getUserIdLPr(uid);
4450            if (obj instanceof SharedUserSetting) {
4451                final SharedUserSetting sus = (SharedUserSetting) obj;
4452                final Iterator<PackageSetting> it = sus.packages.iterator();
4453                while (it.hasNext()) {
4454                    if (it.next().isPrivileged()) {
4455                        return true;
4456                    }
4457                }
4458            } else if (obj instanceof PackageSetting) {
4459                final PackageSetting ps = (PackageSetting) obj;
4460                return ps.isPrivileged();
4461            }
4462        }
4463        return false;
4464    }
4465
4466    @Override
4467    public String[] getAppOpPermissionPackages(String permissionName) {
4468        synchronized (mPackages) {
4469            ArraySet<String> pkgs = mAppOpPermissionPackages.get(permissionName);
4470            if (pkgs == null) {
4471                return null;
4472            }
4473            return pkgs.toArray(new String[pkgs.size()]);
4474        }
4475    }
4476
4477    @Override
4478    public ResolveInfo resolveIntent(Intent intent, String resolvedType,
4479            int flags, int userId) {
4480        if (!sUserManager.exists(userId)) return null;
4481        flags = updateFlagsForResolve(flags, userId, intent);
4482        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "resolve intent");
4483        List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId);
4484        final ResolveInfo bestChoice =
4485                chooseBestActivity(intent, resolvedType, flags, query, userId);
4486
4487        if (isEphemeralAllowed(intent, query, userId)) {
4488            final EphemeralResolveInfo ai =
4489                    getEphemeralResolveInfo(intent, resolvedType, userId);
4490            if (ai != null) {
4491                if (DEBUG_EPHEMERAL) {
4492                    Slog.v(TAG, "Returning an EphemeralResolveInfo");
4493                }
4494                bestChoice.ephemeralInstaller = mEphemeralInstallerInfo;
4495                bestChoice.ephemeralResolveInfo = ai;
4496            }
4497        }
4498        return bestChoice;
4499    }
4500
4501    @Override
4502    public void setLastChosenActivity(Intent intent, String resolvedType, int flags,
4503            IntentFilter filter, int match, ComponentName activity) {
4504        final int userId = UserHandle.getCallingUserId();
4505        if (DEBUG_PREFERRED) {
4506            Log.v(TAG, "setLastChosenActivity intent=" + intent
4507                + " resolvedType=" + resolvedType
4508                + " flags=" + flags
4509                + " filter=" + filter
4510                + " match=" + match
4511                + " activity=" + activity);
4512            filter.dump(new PrintStreamPrinter(System.out), "    ");
4513        }
4514        intent.setComponent(null);
4515        List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId);
4516        // Find any earlier preferred or last chosen entries and nuke them
4517        findPreferredActivity(intent, resolvedType,
4518                flags, query, 0, false, true, false, userId);
4519        // Add the new activity as the last chosen for this filter
4520        addPreferredActivityInternal(filter, match, null, activity, false, userId,
4521                "Setting last chosen");
4522    }
4523
4524    @Override
4525    public ResolveInfo getLastChosenActivity(Intent intent, String resolvedType, int flags) {
4526        final int userId = UserHandle.getCallingUserId();
4527        if (DEBUG_PREFERRED) Log.v(TAG, "Querying last chosen activity for " + intent);
4528        List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId);
4529        return findPreferredActivity(intent, resolvedType, flags, query, 0,
4530                false, false, false, userId);
4531    }
4532
4533
4534    private boolean isEphemeralAllowed(
4535            Intent intent, List<ResolveInfo> resolvedActivites, int userId) {
4536        // Short circuit and return early if possible.
4537        if (DISABLE_EPHEMERAL_APPS) {
4538            return false;
4539        }
4540        final int callingUser = UserHandle.getCallingUserId();
4541        if (callingUser != UserHandle.USER_SYSTEM) {
4542            return false;
4543        }
4544        if (mEphemeralResolverConnection == null) {
4545            return false;
4546        }
4547        if (intent.getComponent() != null) {
4548            return false;
4549        }
4550        if (intent.getPackage() != null) {
4551            return false;
4552        }
4553        final boolean isWebUri = hasWebURI(intent);
4554        if (!isWebUri) {
4555            return false;
4556        }
4557        // Deny ephemeral apps if the user chose _ALWAYS or _ALWAYS_ASK for intent resolution.
4558        synchronized (mPackages) {
4559            final int count = resolvedActivites.size();
4560            for (int n = 0; n < count; n++) {
4561                ResolveInfo info = resolvedActivites.get(n);
4562                String packageName = info.activityInfo.packageName;
4563                PackageSetting ps = mSettings.mPackages.get(packageName);
4564                if (ps != null) {
4565                    // Try to get the status from User settings first
4566                    long packedStatus = getDomainVerificationStatusLPr(ps, userId);
4567                    int status = (int) (packedStatus >> 32);
4568                    if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS
4569                            || status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
4570                        if (DEBUG_EPHEMERAL) {
4571                            Slog.v(TAG, "DENY ephemeral apps;"
4572                                + " pkg: " + packageName + ", status: " + status);
4573                        }
4574                        return false;
4575                    }
4576                }
4577            }
4578        }
4579        // We've exhausted all ways to deny ephemeral application; let the system look for them.
4580        return true;
4581    }
4582
4583    private EphemeralResolveInfo getEphemeralResolveInfo(Intent intent, String resolvedType,
4584            int userId) {
4585        MessageDigest digest = null;
4586        try {
4587            digest = MessageDigest.getInstance(EphemeralResolveInfo.SHA_ALGORITHM);
4588        } catch (NoSuchAlgorithmException e) {
4589            // If we can't create a digest, ignore ephemeral apps.
4590            return null;
4591        }
4592
4593        final byte[] hostBytes = intent.getData().getHost().getBytes();
4594        final byte[] digestBytes = digest.digest(hostBytes);
4595        int shaPrefix =
4596                digestBytes[0] << 24
4597                | digestBytes[1] << 16
4598                | digestBytes[2] << 8
4599                | digestBytes[3] << 0;
4600        final List<EphemeralResolveInfo> ephemeralResolveInfoList =
4601                mEphemeralResolverConnection.getEphemeralResolveInfoList(shaPrefix);
4602        if (ephemeralResolveInfoList == null || ephemeralResolveInfoList.size() == 0) {
4603            // No hash prefix match; there are no ephemeral apps for this domain.
4604            return null;
4605        }
4606        for (int i = ephemeralResolveInfoList.size() - 1; i >= 0; --i) {
4607            EphemeralResolveInfo ephemeralApplication = ephemeralResolveInfoList.get(i);
4608            if (!Arrays.equals(digestBytes, ephemeralApplication.getDigestBytes())) {
4609                continue;
4610            }
4611            final List<IntentFilter> filters = ephemeralApplication.getFilters();
4612            // No filters; this should never happen.
4613            if (filters.isEmpty()) {
4614                continue;
4615            }
4616            // We have a domain match; resolve the filters to see if anything matches.
4617            final EphemeralIntentResolver ephemeralResolver = new EphemeralIntentResolver();
4618            for (int j = filters.size() - 1; j >= 0; --j) {
4619                final EphemeralResolveIntentInfo intentInfo =
4620                        new EphemeralResolveIntentInfo(filters.get(j), ephemeralApplication);
4621                ephemeralResolver.addFilter(intentInfo);
4622            }
4623            List<EphemeralResolveInfo> matchedResolveInfoList = ephemeralResolver.queryIntent(
4624                    intent, resolvedType, false /*defaultOnly*/, userId);
4625            if (!matchedResolveInfoList.isEmpty()) {
4626                return matchedResolveInfoList.get(0);
4627            }
4628        }
4629        // Hash or filter mis-match; no ephemeral apps for this domain.
4630        return null;
4631    }
4632
4633    private ResolveInfo chooseBestActivity(Intent intent, String resolvedType,
4634            int flags, List<ResolveInfo> query, int userId) {
4635        if (query != null) {
4636            final int N = query.size();
4637            if (N == 1) {
4638                return query.get(0);
4639            } else if (N > 1) {
4640                final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4641                // If there is more than one activity with the same priority,
4642                // then let the user decide between them.
4643                ResolveInfo r0 = query.get(0);
4644                ResolveInfo r1 = query.get(1);
4645                if (DEBUG_INTENT_MATCHING || debug) {
4646                    Slog.v(TAG, r0.activityInfo.name + "=" + r0.priority + " vs "
4647                            + r1.activityInfo.name + "=" + r1.priority);
4648                }
4649                // If the first activity has a higher priority, or a different
4650                // default, then it is always desirable to pick it.
4651                if (r0.priority != r1.priority
4652                        || r0.preferredOrder != r1.preferredOrder
4653                        || r0.isDefault != r1.isDefault) {
4654                    return query.get(0);
4655                }
4656                // If we have saved a preference for a preferred activity for
4657                // this Intent, use that.
4658                ResolveInfo ri = findPreferredActivity(intent, resolvedType,
4659                        flags, query, r0.priority, true, false, debug, userId);
4660                if (ri != null) {
4661                    return ri;
4662                }
4663                ri = new ResolveInfo(mResolveInfo);
4664                ri.activityInfo = new ActivityInfo(ri.activityInfo);
4665                ri.activityInfo.applicationInfo = new ApplicationInfo(
4666                        ri.activityInfo.applicationInfo);
4667                if (userId != 0) {
4668                    ri.activityInfo.applicationInfo.uid = UserHandle.getUid(userId,
4669                            UserHandle.getAppId(ri.activityInfo.applicationInfo.uid));
4670                }
4671                // Make sure that the resolver is displayable in car mode
4672                if (ri.activityInfo.metaData == null) ri.activityInfo.metaData = new Bundle();
4673                ri.activityInfo.metaData.putBoolean(Intent.METADATA_DOCK_HOME, true);
4674                return ri;
4675            }
4676        }
4677        return null;
4678    }
4679
4680    private ResolveInfo findPersistentPreferredActivityLP(Intent intent, String resolvedType,
4681            int flags, List<ResolveInfo> query, boolean debug, int userId) {
4682        final int N = query.size();
4683        PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
4684                .get(userId);
4685        // Get the list of persistent preferred activities that handle the intent
4686        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for presistent preferred activities...");
4687        List<PersistentPreferredActivity> pprefs = ppir != null
4688                ? ppir.queryIntent(intent, resolvedType,
4689                        (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId)
4690                : null;
4691        if (pprefs != null && pprefs.size() > 0) {
4692            final int M = pprefs.size();
4693            for (int i=0; i<M; i++) {
4694                final PersistentPreferredActivity ppa = pprefs.get(i);
4695                if (DEBUG_PREFERRED || debug) {
4696                    Slog.v(TAG, "Checking PersistentPreferredActivity ds="
4697                            + (ppa.countDataSchemes() > 0 ? ppa.getDataScheme(0) : "<none>")
4698                            + "\n  component=" + ppa.mComponent);
4699                    ppa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
4700                }
4701                final ActivityInfo ai = getActivityInfo(ppa.mComponent,
4702                        flags | MATCH_DISABLED_COMPONENTS, userId);
4703                if (DEBUG_PREFERRED || debug) {
4704                    Slog.v(TAG, "Found persistent preferred activity:");
4705                    if (ai != null) {
4706                        ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
4707                    } else {
4708                        Slog.v(TAG, "  null");
4709                    }
4710                }
4711                if (ai == null) {
4712                    // This previously registered persistent preferred activity
4713                    // component is no longer known. Ignore it and do NOT remove it.
4714                    continue;
4715                }
4716                for (int j=0; j<N; j++) {
4717                    final ResolveInfo ri = query.get(j);
4718                    if (!ri.activityInfo.applicationInfo.packageName
4719                            .equals(ai.applicationInfo.packageName)) {
4720                        continue;
4721                    }
4722                    if (!ri.activityInfo.name.equals(ai.name)) {
4723                        continue;
4724                    }
4725                    //  Found a persistent preference that can handle the intent.
4726                    if (DEBUG_PREFERRED || debug) {
4727                        Slog.v(TAG, "Returning persistent preferred activity: " +
4728                                ri.activityInfo.packageName + "/" + ri.activityInfo.name);
4729                    }
4730                    return ri;
4731                }
4732            }
4733        }
4734        return null;
4735    }
4736
4737    // TODO: handle preferred activities missing while user has amnesia
4738    ResolveInfo findPreferredActivity(Intent intent, String resolvedType, int flags,
4739            List<ResolveInfo> query, int priority, boolean always,
4740            boolean removeMatches, boolean debug, int userId) {
4741        if (!sUserManager.exists(userId)) return null;
4742        flags = updateFlagsForResolve(flags, userId, intent);
4743        // writer
4744        synchronized (mPackages) {
4745            if (intent.getSelector() != null) {
4746                intent = intent.getSelector();
4747            }
4748            if (DEBUG_PREFERRED) intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION);
4749
4750            // Try to find a matching persistent preferred activity.
4751            ResolveInfo pri = findPersistentPreferredActivityLP(intent, resolvedType, flags, query,
4752                    debug, userId);
4753
4754            // If a persistent preferred activity matched, use it.
4755            if (pri != null) {
4756                return pri;
4757            }
4758
4759            PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
4760            // Get the list of preferred activities that handle the intent
4761            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for preferred activities...");
4762            List<PreferredActivity> prefs = pir != null
4763                    ? pir.queryIntent(intent, resolvedType,
4764                            (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId)
4765                    : null;
4766            if (prefs != null && prefs.size() > 0) {
4767                boolean changed = false;
4768                try {
4769                    // First figure out how good the original match set is.
4770                    // We will only allow preferred activities that came
4771                    // from the same match quality.
4772                    int match = 0;
4773
4774                    if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Figuring out best match...");
4775
4776                    final int N = query.size();
4777                    for (int j=0; j<N; j++) {
4778                        final ResolveInfo ri = query.get(j);
4779                        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Match for " + ri.activityInfo
4780                                + ": 0x" + Integer.toHexString(match));
4781                        if (ri.match > match) {
4782                            match = ri.match;
4783                        }
4784                    }
4785
4786                    if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Best match: 0x"
4787                            + Integer.toHexString(match));
4788
4789                    match &= IntentFilter.MATCH_CATEGORY_MASK;
4790                    final int M = prefs.size();
4791                    for (int i=0; i<M; i++) {
4792                        final PreferredActivity pa = prefs.get(i);
4793                        if (DEBUG_PREFERRED || debug) {
4794                            Slog.v(TAG, "Checking PreferredActivity ds="
4795                                    + (pa.countDataSchemes() > 0 ? pa.getDataScheme(0) : "<none>")
4796                                    + "\n  component=" + pa.mPref.mComponent);
4797                            pa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
4798                        }
4799                        if (pa.mPref.mMatch != match) {
4800                            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping bad match "
4801                                    + Integer.toHexString(pa.mPref.mMatch));
4802                            continue;
4803                        }
4804                        // If it's not an "always" type preferred activity and that's what we're
4805                        // looking for, skip it.
4806                        if (always && !pa.mPref.mAlways) {
4807                            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping mAlways=false entry");
4808                            continue;
4809                        }
4810                        final ActivityInfo ai = getActivityInfo(pa.mPref.mComponent,
4811                                flags | MATCH_DISABLED_COMPONENTS, userId);
4812                        if (DEBUG_PREFERRED || debug) {
4813                            Slog.v(TAG, "Found preferred activity:");
4814                            if (ai != null) {
4815                                ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
4816                            } else {
4817                                Slog.v(TAG, "  null");
4818                            }
4819                        }
4820                        if (ai == null) {
4821                            // This previously registered preferred activity
4822                            // component is no longer known.  Most likely an update
4823                            // to the app was installed and in the new version this
4824                            // component no longer exists.  Clean it up by removing
4825                            // it from the preferred activities list, and skip it.
4826                            Slog.w(TAG, "Removing dangling preferred activity: "
4827                                    + pa.mPref.mComponent);
4828                            pir.removeFilter(pa);
4829                            changed = true;
4830                            continue;
4831                        }
4832                        for (int j=0; j<N; j++) {
4833                            final ResolveInfo ri = query.get(j);
4834                            if (!ri.activityInfo.applicationInfo.packageName
4835                                    .equals(ai.applicationInfo.packageName)) {
4836                                continue;
4837                            }
4838                            if (!ri.activityInfo.name.equals(ai.name)) {
4839                                continue;
4840                            }
4841
4842                            if (removeMatches) {
4843                                pir.removeFilter(pa);
4844                                changed = true;
4845                                if (DEBUG_PREFERRED) {
4846                                    Slog.v(TAG, "Removing match " + pa.mPref.mComponent);
4847                                }
4848                                break;
4849                            }
4850
4851                            // Okay we found a previously set preferred or last chosen app.
4852                            // If the result set is different from when this
4853                            // was created, we need to clear it and re-ask the
4854                            // user their preference, if we're looking for an "always" type entry.
4855                            if (always && !pa.mPref.sameSet(query)) {
4856                                Slog.i(TAG, "Result set changed, dropping preferred activity for "
4857                                        + intent + " type " + resolvedType);
4858                                if (DEBUG_PREFERRED) {
4859                                    Slog.v(TAG, "Removing preferred activity since set changed "
4860                                            + pa.mPref.mComponent);
4861                                }
4862                                pir.removeFilter(pa);
4863                                // Re-add the filter as a "last chosen" entry (!always)
4864                                PreferredActivity lastChosen = new PreferredActivity(
4865                                        pa, pa.mPref.mMatch, null, pa.mPref.mComponent, false);
4866                                pir.addFilter(lastChosen);
4867                                changed = true;
4868                                return null;
4869                            }
4870
4871                            // Yay! Either the set matched or we're looking for the last chosen
4872                            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Returning preferred activity: "
4873                                    + ri.activityInfo.packageName + "/" + ri.activityInfo.name);
4874                            return ri;
4875                        }
4876                    }
4877                } finally {
4878                    if (changed) {
4879                        if (DEBUG_PREFERRED) {
4880                            Slog.v(TAG, "Preferred activity bookkeeping changed; writing restrictions");
4881                        }
4882                        scheduleWritePackageRestrictionsLocked(userId);
4883                    }
4884                }
4885            }
4886        }
4887        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "No preferred activity to return");
4888        return null;
4889    }
4890
4891    /*
4892     * Returns if intent can be forwarded from the sourceUserId to the targetUserId
4893     */
4894    @Override
4895    public boolean canForwardTo(Intent intent, String resolvedType, int sourceUserId,
4896            int targetUserId) {
4897        mContext.enforceCallingOrSelfPermission(
4898                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
4899        List<CrossProfileIntentFilter> matches =
4900                getMatchingCrossProfileIntentFilters(intent, resolvedType, sourceUserId);
4901        if (matches != null) {
4902            int size = matches.size();
4903            for (int i = 0; i < size; i++) {
4904                if (matches.get(i).getTargetUserId() == targetUserId) return true;
4905            }
4906        }
4907        if (hasWebURI(intent)) {
4908            // cross-profile app linking works only towards the parent.
4909            final UserInfo parent = getProfileParent(sourceUserId);
4910            synchronized(mPackages) {
4911                CrossProfileDomainInfo xpDomainInfo = getCrossProfileDomainPreferredLpr(
4912                        intent, resolvedType, 0, sourceUserId, parent.id);
4913                return xpDomainInfo != null;
4914            }
4915        }
4916        return false;
4917    }
4918
4919    private UserInfo getProfileParent(int userId) {
4920        final long identity = Binder.clearCallingIdentity();
4921        try {
4922            return sUserManager.getProfileParent(userId);
4923        } finally {
4924            Binder.restoreCallingIdentity(identity);
4925        }
4926    }
4927
4928    private List<CrossProfileIntentFilter> getMatchingCrossProfileIntentFilters(Intent intent,
4929            String resolvedType, int userId) {
4930        CrossProfileIntentResolver resolver = mSettings.mCrossProfileIntentResolvers.get(userId);
4931        if (resolver != null) {
4932            return resolver.queryIntent(intent, resolvedType, false, userId);
4933        }
4934        return null;
4935    }
4936
4937    @Override
4938    public List<ResolveInfo> queryIntentActivities(Intent intent,
4939            String resolvedType, int flags, int userId) {
4940        if (!sUserManager.exists(userId)) return Collections.emptyList();
4941        flags = updateFlagsForResolve(flags, userId, intent);
4942        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "query intent activities");
4943        ComponentName comp = intent.getComponent();
4944        if (comp == null) {
4945            if (intent.getSelector() != null) {
4946                intent = intent.getSelector();
4947                comp = intent.getComponent();
4948            }
4949        }
4950
4951        if (comp != null) {
4952            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
4953            final ActivityInfo ai = getActivityInfo(comp, flags, userId);
4954            if (ai != null) {
4955                final ResolveInfo ri = new ResolveInfo();
4956                ri.activityInfo = ai;
4957                list.add(ri);
4958            }
4959            return list;
4960        }
4961
4962        // reader
4963        synchronized (mPackages) {
4964            final String pkgName = intent.getPackage();
4965            if (pkgName == null) {
4966                List<CrossProfileIntentFilter> matchingFilters =
4967                        getMatchingCrossProfileIntentFilters(intent, resolvedType, userId);
4968                // Check for results that need to skip the current profile.
4969                ResolveInfo xpResolveInfo  = querySkipCurrentProfileIntents(matchingFilters, intent,
4970                        resolvedType, flags, userId);
4971                if (xpResolveInfo != null) {
4972                    List<ResolveInfo> result = new ArrayList<ResolveInfo>(1);
4973                    result.add(xpResolveInfo);
4974                    return filterIfNotSystemUser(result, userId);
4975                }
4976
4977                // Check for results in the current profile.
4978                List<ResolveInfo> result = mActivities.queryIntent(
4979                        intent, resolvedType, flags, userId);
4980                result = filterIfNotSystemUser(result, userId);
4981
4982                // Check for cross profile results.
4983                boolean hasNonNegativePriorityResult = hasNonNegativePriority(result);
4984                xpResolveInfo = queryCrossProfileIntents(
4985                        matchingFilters, intent, resolvedType, flags, userId,
4986                        hasNonNegativePriorityResult);
4987                if (xpResolveInfo != null && isUserEnabled(xpResolveInfo.targetUserId)) {
4988                    boolean isVisibleToUser = filterIfNotSystemUser(
4989                            Collections.singletonList(xpResolveInfo), userId).size() > 0;
4990                    if (isVisibleToUser) {
4991                        result.add(xpResolveInfo);
4992                        Collections.sort(result, mResolvePrioritySorter);
4993                    }
4994                }
4995                if (hasWebURI(intent)) {
4996                    CrossProfileDomainInfo xpDomainInfo = null;
4997                    final UserInfo parent = getProfileParent(userId);
4998                    if (parent != null) {
4999                        xpDomainInfo = getCrossProfileDomainPreferredLpr(intent, resolvedType,
5000                                flags, userId, parent.id);
5001                    }
5002                    if (xpDomainInfo != null) {
5003                        if (xpResolveInfo != null) {
5004                            // If we didn't remove it, the cross-profile ResolveInfo would be twice
5005                            // in the result.
5006                            result.remove(xpResolveInfo);
5007                        }
5008                        if (result.size() == 0) {
5009                            result.add(xpDomainInfo.resolveInfo);
5010                            return result;
5011                        }
5012                    } else if (result.size() <= 1) {
5013                        return result;
5014                    }
5015                    result = filterCandidatesWithDomainPreferredActivitiesLPr(intent, flags, result,
5016                            xpDomainInfo, userId);
5017                    Collections.sort(result, mResolvePrioritySorter);
5018                }
5019                return result;
5020            }
5021            final PackageParser.Package pkg = mPackages.get(pkgName);
5022            if (pkg != null) {
5023                return filterIfNotSystemUser(
5024                        mActivities.queryIntentForPackage(
5025                                intent, resolvedType, flags, pkg.activities, userId),
5026                        userId);
5027            }
5028            return new ArrayList<ResolveInfo>();
5029        }
5030    }
5031
5032    private static class CrossProfileDomainInfo {
5033        /* ResolveInfo for IntentForwarderActivity to send the intent to the other profile */
5034        ResolveInfo resolveInfo;
5035        /* Best domain verification status of the activities found in the other profile */
5036        int bestDomainVerificationStatus;
5037    }
5038
5039    private CrossProfileDomainInfo getCrossProfileDomainPreferredLpr(Intent intent,
5040            String resolvedType, int flags, int sourceUserId, int parentUserId) {
5041        if (!sUserManager.hasUserRestriction(UserManager.ALLOW_PARENT_PROFILE_APP_LINKING,
5042                sourceUserId)) {
5043            return null;
5044        }
5045        List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent,
5046                resolvedType, flags, parentUserId);
5047
5048        if (resultTargetUser == null || resultTargetUser.isEmpty()) {
5049            return null;
5050        }
5051        CrossProfileDomainInfo result = null;
5052        int size = resultTargetUser.size();
5053        for (int i = 0; i < size; i++) {
5054            ResolveInfo riTargetUser = resultTargetUser.get(i);
5055            // Intent filter verification is only for filters that specify a host. So don't return
5056            // those that handle all web uris.
5057            if (riTargetUser.handleAllWebDataURI) {
5058                continue;
5059            }
5060            String packageName = riTargetUser.activityInfo.packageName;
5061            PackageSetting ps = mSettings.mPackages.get(packageName);
5062            if (ps == null) {
5063                continue;
5064            }
5065            long verificationState = getDomainVerificationStatusLPr(ps, parentUserId);
5066            int status = (int)(verificationState >> 32);
5067            if (result == null) {
5068                result = new CrossProfileDomainInfo();
5069                result.resolveInfo = createForwardingResolveInfoUnchecked(new IntentFilter(),
5070                        sourceUserId, parentUserId);
5071                result.bestDomainVerificationStatus = status;
5072            } else {
5073                result.bestDomainVerificationStatus = bestDomainVerificationStatus(status,
5074                        result.bestDomainVerificationStatus);
5075            }
5076        }
5077        // Don't consider matches with status NEVER across profiles.
5078        if (result != null && result.bestDomainVerificationStatus
5079                == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
5080            return null;
5081        }
5082        return result;
5083    }
5084
5085    /**
5086     * Verification statuses are ordered from the worse to the best, except for
5087     * INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER, which is the worse.
5088     */
5089    private int bestDomainVerificationStatus(int status1, int status2) {
5090        if (status1 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
5091            return status2;
5092        }
5093        if (status2 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
5094            return status1;
5095        }
5096        return (int) MathUtils.max(status1, status2);
5097    }
5098
5099    private boolean isUserEnabled(int userId) {
5100        long callingId = Binder.clearCallingIdentity();
5101        try {
5102            UserInfo userInfo = sUserManager.getUserInfo(userId);
5103            return userInfo != null && userInfo.isEnabled();
5104        } finally {
5105            Binder.restoreCallingIdentity(callingId);
5106        }
5107    }
5108
5109    /**
5110     * Filter out activities with systemUserOnly flag set, when current user is not System.
5111     *
5112     * @return filtered list
5113     */
5114    private List<ResolveInfo> filterIfNotSystemUser(List<ResolveInfo> resolveInfos, int userId) {
5115        if (userId == UserHandle.USER_SYSTEM) {
5116            return resolveInfos;
5117        }
5118        for (int i = resolveInfos.size() - 1; i >= 0; i--) {
5119            ResolveInfo info = resolveInfos.get(i);
5120            if ((info.activityInfo.flags & ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
5121                resolveInfos.remove(i);
5122            }
5123        }
5124        return resolveInfos;
5125    }
5126
5127    /**
5128     * @param resolveInfos list of resolve infos in descending priority order
5129     * @return if the list contains a resolve info with non-negative priority
5130     */
5131    private boolean hasNonNegativePriority(List<ResolveInfo> resolveInfos) {
5132        return resolveInfos.size() > 0 && resolveInfos.get(0).priority >= 0;
5133    }
5134
5135    private static boolean hasWebURI(Intent intent) {
5136        if (intent.getData() == null) {
5137            return false;
5138        }
5139        final String scheme = intent.getScheme();
5140        if (TextUtils.isEmpty(scheme)) {
5141            return false;
5142        }
5143        return scheme.equals(IntentFilter.SCHEME_HTTP) || scheme.equals(IntentFilter.SCHEME_HTTPS);
5144    }
5145
5146    private List<ResolveInfo> filterCandidatesWithDomainPreferredActivitiesLPr(Intent intent,
5147            int matchFlags, List<ResolveInfo> candidates, CrossProfileDomainInfo xpDomainInfo,
5148            int userId) {
5149        final boolean debug = (intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0;
5150
5151        if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) {
5152            Slog.v(TAG, "Filtering results with preferred activities. Candidates count: " +
5153                    candidates.size());
5154        }
5155
5156        ArrayList<ResolveInfo> result = new ArrayList<ResolveInfo>();
5157        ArrayList<ResolveInfo> alwaysList = new ArrayList<ResolveInfo>();
5158        ArrayList<ResolveInfo> undefinedList = new ArrayList<ResolveInfo>();
5159        ArrayList<ResolveInfo> alwaysAskList = new ArrayList<ResolveInfo>();
5160        ArrayList<ResolveInfo> neverList = new ArrayList<ResolveInfo>();
5161        ArrayList<ResolveInfo> matchAllList = new ArrayList<ResolveInfo>();
5162
5163        synchronized (mPackages) {
5164            final int count = candidates.size();
5165            // First, try to use linked apps. Partition the candidates into four lists:
5166            // one for the final results, one for the "do not use ever", one for "undefined status"
5167            // and finally one for "browser app type".
5168            for (int n=0; n<count; n++) {
5169                ResolveInfo info = candidates.get(n);
5170                String packageName = info.activityInfo.packageName;
5171                PackageSetting ps = mSettings.mPackages.get(packageName);
5172                if (ps != null) {
5173                    // Add to the special match all list (Browser use case)
5174                    if (info.handleAllWebDataURI) {
5175                        matchAllList.add(info);
5176                        continue;
5177                    }
5178                    // Try to get the status from User settings first
5179                    long packedStatus = getDomainVerificationStatusLPr(ps, userId);
5180                    int status = (int)(packedStatus >> 32);
5181                    int linkGeneration = (int)(packedStatus & 0xFFFFFFFF);
5182                    if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) {
5183                        if (DEBUG_DOMAIN_VERIFICATION) {
5184                            Slog.i(TAG, "  + always: " + info.activityInfo.packageName
5185                                    + " : linkgen=" + linkGeneration);
5186                        }
5187                        // Use link-enabled generation as preferredOrder, i.e.
5188                        // prefer newly-enabled over earlier-enabled.
5189                        info.preferredOrder = linkGeneration;
5190                        alwaysList.add(info);
5191                    } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
5192                        if (DEBUG_DOMAIN_VERIFICATION) {
5193                            Slog.i(TAG, "  + never: " + info.activityInfo.packageName);
5194                        }
5195                        neverList.add(info);
5196                    } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
5197                        if (DEBUG_DOMAIN_VERIFICATION) {
5198                            Slog.i(TAG, "  + always-ask: " + info.activityInfo.packageName);
5199                        }
5200                        alwaysAskList.add(info);
5201                    } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED ||
5202                            status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK) {
5203                        if (DEBUG_DOMAIN_VERIFICATION) {
5204                            Slog.i(TAG, "  + ask: " + info.activityInfo.packageName);
5205                        }
5206                        undefinedList.add(info);
5207                    }
5208                }
5209            }
5210
5211            // We'll want to include browser possibilities in a few cases
5212            boolean includeBrowser = false;
5213
5214            // First try to add the "always" resolution(s) for the current user, if any
5215            if (alwaysList.size() > 0) {
5216                result.addAll(alwaysList);
5217            } else {
5218                // Add all undefined apps as we want them to appear in the disambiguation dialog.
5219                result.addAll(undefinedList);
5220                // Maybe add one for the other profile.
5221                if (xpDomainInfo != null && (
5222                        xpDomainInfo.bestDomainVerificationStatus
5223                        != INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER)) {
5224                    result.add(xpDomainInfo.resolveInfo);
5225                }
5226                includeBrowser = true;
5227            }
5228
5229            // The presence of any 'always ask' alternatives means we'll also offer browsers.
5230            // If there were 'always' entries their preferred order has been set, so we also
5231            // back that off to make the alternatives equivalent
5232            if (alwaysAskList.size() > 0) {
5233                for (ResolveInfo i : result) {
5234                    i.preferredOrder = 0;
5235                }
5236                result.addAll(alwaysAskList);
5237                includeBrowser = true;
5238            }
5239
5240            if (includeBrowser) {
5241                // Also add browsers (all of them or only the default one)
5242                if (DEBUG_DOMAIN_VERIFICATION) {
5243                    Slog.v(TAG, "   ...including browsers in candidate set");
5244                }
5245                if ((matchFlags & MATCH_ALL) != 0) {
5246                    result.addAll(matchAllList);
5247                } else {
5248                    // Browser/generic handling case.  If there's a default browser, go straight
5249                    // to that (but only if there is no other higher-priority match).
5250                    final String defaultBrowserPackageName = getDefaultBrowserPackageName(userId);
5251                    int maxMatchPrio = 0;
5252                    ResolveInfo defaultBrowserMatch = null;
5253                    final int numCandidates = matchAllList.size();
5254                    for (int n = 0; n < numCandidates; n++) {
5255                        ResolveInfo info = matchAllList.get(n);
5256                        // track the highest overall match priority...
5257                        if (info.priority > maxMatchPrio) {
5258                            maxMatchPrio = info.priority;
5259                        }
5260                        // ...and the highest-priority default browser match
5261                        if (info.activityInfo.packageName.equals(defaultBrowserPackageName)) {
5262                            if (defaultBrowserMatch == null
5263                                    || (defaultBrowserMatch.priority < info.priority)) {
5264                                if (debug) {
5265                                    Slog.v(TAG, "Considering default browser match " + info);
5266                                }
5267                                defaultBrowserMatch = info;
5268                            }
5269                        }
5270                    }
5271                    if (defaultBrowserMatch != null
5272                            && defaultBrowserMatch.priority >= maxMatchPrio
5273                            && !TextUtils.isEmpty(defaultBrowserPackageName))
5274                    {
5275                        if (debug) {
5276                            Slog.v(TAG, "Default browser match " + defaultBrowserMatch);
5277                        }
5278                        result.add(defaultBrowserMatch);
5279                    } else {
5280                        result.addAll(matchAllList);
5281                    }
5282                }
5283
5284                // If there is nothing selected, add all candidates and remove the ones that the user
5285                // has explicitly put into the INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER state
5286                if (result.size() == 0) {
5287                    result.addAll(candidates);
5288                    result.removeAll(neverList);
5289                }
5290            }
5291        }
5292        if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) {
5293            Slog.v(TAG, "Filtered results with preferred activities. New candidates count: " +
5294                    result.size());
5295            for (ResolveInfo info : result) {
5296                Slog.v(TAG, "  + " + info.activityInfo);
5297            }
5298        }
5299        return result;
5300    }
5301
5302    // Returns a packed value as a long:
5303    //
5304    // high 'int'-sized word: link status: undefined/ask/never/always.
5305    // low 'int'-sized word: relative priority among 'always' results.
5306    private long getDomainVerificationStatusLPr(PackageSetting ps, int userId) {
5307        long result = ps.getDomainVerificationStatusForUser(userId);
5308        // if none available, get the master status
5309        if (result >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) {
5310            if (ps.getIntentFilterVerificationInfo() != null) {
5311                result = ((long)ps.getIntentFilterVerificationInfo().getStatus()) << 32;
5312            }
5313        }
5314        return result;
5315    }
5316
5317    private ResolveInfo querySkipCurrentProfileIntents(
5318            List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
5319            int flags, int sourceUserId) {
5320        if (matchingFilters != null) {
5321            int size = matchingFilters.size();
5322            for (int i = 0; i < size; i ++) {
5323                CrossProfileIntentFilter filter = matchingFilters.get(i);
5324                if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0) {
5325                    // Checking if there are activities in the target user that can handle the
5326                    // intent.
5327                    ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent,
5328                            resolvedType, flags, sourceUserId);
5329                    if (resolveInfo != null) {
5330                        return resolveInfo;
5331                    }
5332                }
5333            }
5334        }
5335        return null;
5336    }
5337
5338    // Return matching ResolveInfo in target user if any.
5339    private ResolveInfo queryCrossProfileIntents(
5340            List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
5341            int flags, int sourceUserId, boolean matchInCurrentProfile) {
5342        if (matchingFilters != null) {
5343            // Two {@link CrossProfileIntentFilter}s can have the same targetUserId and
5344            // match the same intent. For performance reasons, it is better not to
5345            // run queryIntent twice for the same userId
5346            SparseBooleanArray alreadyTriedUserIds = new SparseBooleanArray();
5347            int size = matchingFilters.size();
5348            for (int i = 0; i < size; i++) {
5349                CrossProfileIntentFilter filter = matchingFilters.get(i);
5350                int targetUserId = filter.getTargetUserId();
5351                boolean skipCurrentProfile =
5352                        (filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0;
5353                boolean skipCurrentProfileIfNoMatchFound =
5354                        (filter.getFlags() & PackageManager.ONLY_IF_NO_MATCH_FOUND) != 0;
5355                if (!skipCurrentProfile && !alreadyTriedUserIds.get(targetUserId)
5356                        && (!skipCurrentProfileIfNoMatchFound || !matchInCurrentProfile)) {
5357                    // Checking if there are activities in the target user that can handle the
5358                    // intent.
5359                    ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent,
5360                            resolvedType, flags, sourceUserId);
5361                    if (resolveInfo != null) return resolveInfo;
5362                    alreadyTriedUserIds.put(targetUserId, true);
5363                }
5364            }
5365        }
5366        return null;
5367    }
5368
5369    /**
5370     * If the filter's target user can handle the intent and is enabled: returns a ResolveInfo that
5371     * will forward the intent to the filter's target user.
5372     * Otherwise, returns null.
5373     */
5374    private ResolveInfo createForwardingResolveInfo(CrossProfileIntentFilter filter, Intent intent,
5375            String resolvedType, int flags, int sourceUserId) {
5376        int targetUserId = filter.getTargetUserId();
5377        List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent,
5378                resolvedType, flags, targetUserId);
5379        if (resultTargetUser != null && !resultTargetUser.isEmpty()
5380                && isUserEnabled(targetUserId)) {
5381            return createForwardingResolveInfoUnchecked(filter, sourceUserId, targetUserId);
5382        }
5383        return null;
5384    }
5385
5386    private ResolveInfo createForwardingResolveInfoUnchecked(IntentFilter filter,
5387            int sourceUserId, int targetUserId) {
5388        ResolveInfo forwardingResolveInfo = new ResolveInfo();
5389        long ident = Binder.clearCallingIdentity();
5390        boolean targetIsProfile;
5391        try {
5392            targetIsProfile = sUserManager.getUserInfo(targetUserId).isManagedProfile();
5393        } finally {
5394            Binder.restoreCallingIdentity(ident);
5395        }
5396        String className;
5397        if (targetIsProfile) {
5398            className = FORWARD_INTENT_TO_MANAGED_PROFILE;
5399        } else {
5400            className = FORWARD_INTENT_TO_PARENT;
5401        }
5402        ComponentName forwardingActivityComponentName = new ComponentName(
5403                mAndroidApplication.packageName, className);
5404        ActivityInfo forwardingActivityInfo = getActivityInfo(forwardingActivityComponentName, 0,
5405                sourceUserId);
5406        if (!targetIsProfile) {
5407            forwardingActivityInfo.showUserIcon = targetUserId;
5408            forwardingResolveInfo.noResourceId = true;
5409        }
5410        forwardingResolveInfo.activityInfo = forwardingActivityInfo;
5411        forwardingResolveInfo.priority = 0;
5412        forwardingResolveInfo.preferredOrder = 0;
5413        forwardingResolveInfo.match = 0;
5414        forwardingResolveInfo.isDefault = true;
5415        forwardingResolveInfo.filter = filter;
5416        forwardingResolveInfo.targetUserId = targetUserId;
5417        return forwardingResolveInfo;
5418    }
5419
5420    @Override
5421    public List<ResolveInfo> queryIntentActivityOptions(ComponentName caller,
5422            Intent[] specifics, String[] specificTypes, Intent intent,
5423            String resolvedType, int flags, int userId) {
5424        if (!sUserManager.exists(userId)) return Collections.emptyList();
5425        flags = updateFlagsForResolve(flags, userId, intent);
5426        enforceCrossUserPermission(Binder.getCallingUid(), userId, false,
5427                false, "query intent activity options");
5428        final String resultsAction = intent.getAction();
5429
5430        List<ResolveInfo> results = queryIntentActivities(intent, resolvedType, flags
5431                | PackageManager.GET_RESOLVED_FILTER, userId);
5432
5433        if (DEBUG_INTENT_MATCHING) {
5434            Log.v(TAG, "Query " + intent + ": " + results);
5435        }
5436
5437        int specificsPos = 0;
5438        int N;
5439
5440        // todo: note that the algorithm used here is O(N^2).  This
5441        // isn't a problem in our current environment, but if we start running
5442        // into situations where we have more than 5 or 10 matches then this
5443        // should probably be changed to something smarter...
5444
5445        // First we go through and resolve each of the specific items
5446        // that were supplied, taking care of removing any corresponding
5447        // duplicate items in the generic resolve list.
5448        if (specifics != null) {
5449            for (int i=0; i<specifics.length; i++) {
5450                final Intent sintent = specifics[i];
5451                if (sintent == null) {
5452                    continue;
5453                }
5454
5455                if (DEBUG_INTENT_MATCHING) {
5456                    Log.v(TAG, "Specific #" + i + ": " + sintent);
5457                }
5458
5459                String action = sintent.getAction();
5460                if (resultsAction != null && resultsAction.equals(action)) {
5461                    // If this action was explicitly requested, then don't
5462                    // remove things that have it.
5463                    action = null;
5464                }
5465
5466                ResolveInfo ri = null;
5467                ActivityInfo ai = null;
5468
5469                ComponentName comp = sintent.getComponent();
5470                if (comp == null) {
5471                    ri = resolveIntent(
5472                        sintent,
5473                        specificTypes != null ? specificTypes[i] : null,
5474                            flags, userId);
5475                    if (ri == null) {
5476                        continue;
5477                    }
5478                    if (ri == mResolveInfo) {
5479                        // ACK!  Must do something better with this.
5480                    }
5481                    ai = ri.activityInfo;
5482                    comp = new ComponentName(ai.applicationInfo.packageName,
5483                            ai.name);
5484                } else {
5485                    ai = getActivityInfo(comp, flags, userId);
5486                    if (ai == null) {
5487                        continue;
5488                    }
5489                }
5490
5491                // Look for any generic query activities that are duplicates
5492                // of this specific one, and remove them from the results.
5493                if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Specific #" + i + ": " + ai);
5494                N = results.size();
5495                int j;
5496                for (j=specificsPos; j<N; j++) {
5497                    ResolveInfo sri = results.get(j);
5498                    if ((sri.activityInfo.name.equals(comp.getClassName())
5499                            && sri.activityInfo.applicationInfo.packageName.equals(
5500                                    comp.getPackageName()))
5501                        || (action != null && sri.filter.matchAction(action))) {
5502                        results.remove(j);
5503                        if (DEBUG_INTENT_MATCHING) Log.v(
5504                            TAG, "Removing duplicate item from " + j
5505                            + " due to specific " + specificsPos);
5506                        if (ri == null) {
5507                            ri = sri;
5508                        }
5509                        j--;
5510                        N--;
5511                    }
5512                }
5513
5514                // Add this specific item to its proper place.
5515                if (ri == null) {
5516                    ri = new ResolveInfo();
5517                    ri.activityInfo = ai;
5518                }
5519                results.add(specificsPos, ri);
5520                ri.specificIndex = i;
5521                specificsPos++;
5522            }
5523        }
5524
5525        // Now we go through the remaining generic results and remove any
5526        // duplicate actions that are found here.
5527        N = results.size();
5528        for (int i=specificsPos; i<N-1; i++) {
5529            final ResolveInfo rii = results.get(i);
5530            if (rii.filter == null) {
5531                continue;
5532            }
5533
5534            // Iterate over all of the actions of this result's intent
5535            // filter...  typically this should be just one.
5536            final Iterator<String> it = rii.filter.actionsIterator();
5537            if (it == null) {
5538                continue;
5539            }
5540            while (it.hasNext()) {
5541                final String action = it.next();
5542                if (resultsAction != null && resultsAction.equals(action)) {
5543                    // If this action was explicitly requested, then don't
5544                    // remove things that have it.
5545                    continue;
5546                }
5547                for (int j=i+1; j<N; j++) {
5548                    final ResolveInfo rij = results.get(j);
5549                    if (rij.filter != null && rij.filter.hasAction(action)) {
5550                        results.remove(j);
5551                        if (DEBUG_INTENT_MATCHING) Log.v(
5552                            TAG, "Removing duplicate item from " + j
5553                            + " due to action " + action + " at " + i);
5554                        j--;
5555                        N--;
5556                    }
5557                }
5558            }
5559
5560            // If the caller didn't request filter information, drop it now
5561            // so we don't have to marshall/unmarshall it.
5562            if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
5563                rii.filter = null;
5564            }
5565        }
5566
5567        // Filter out the caller activity if so requested.
5568        if (caller != null) {
5569            N = results.size();
5570            for (int i=0; i<N; i++) {
5571                ActivityInfo ainfo = results.get(i).activityInfo;
5572                if (caller.getPackageName().equals(ainfo.applicationInfo.packageName)
5573                        && caller.getClassName().equals(ainfo.name)) {
5574                    results.remove(i);
5575                    break;
5576                }
5577            }
5578        }
5579
5580        // If the caller didn't request filter information,
5581        // drop them now so we don't have to
5582        // marshall/unmarshall it.
5583        if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
5584            N = results.size();
5585            for (int i=0; i<N; i++) {
5586                results.get(i).filter = null;
5587            }
5588        }
5589
5590        if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Result: " + results);
5591        return results;
5592    }
5593
5594    @Override
5595    public List<ResolveInfo> queryIntentReceivers(Intent intent, String resolvedType, int flags,
5596            int userId) {
5597        if (!sUserManager.exists(userId)) return Collections.emptyList();
5598        flags = updateFlagsForResolve(flags, userId, intent);
5599        ComponentName comp = intent.getComponent();
5600        if (comp == null) {
5601            if (intent.getSelector() != null) {
5602                intent = intent.getSelector();
5603                comp = intent.getComponent();
5604            }
5605        }
5606        if (comp != null) {
5607            List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
5608            ActivityInfo ai = getReceiverInfo(comp, flags, userId);
5609            if (ai != null) {
5610                ResolveInfo ri = new ResolveInfo();
5611                ri.activityInfo = ai;
5612                list.add(ri);
5613            }
5614            return list;
5615        }
5616
5617        // reader
5618        synchronized (mPackages) {
5619            String pkgName = intent.getPackage();
5620            if (pkgName == null) {
5621                return mReceivers.queryIntent(intent, resolvedType, flags, userId);
5622            }
5623            final PackageParser.Package pkg = mPackages.get(pkgName);
5624            if (pkg != null) {
5625                return mReceivers.queryIntentForPackage(intent, resolvedType, flags, pkg.receivers,
5626                        userId);
5627            }
5628            return null;
5629        }
5630    }
5631
5632    @Override
5633    public ResolveInfo resolveService(Intent intent, String resolvedType, int flags, int userId) {
5634        if (!sUserManager.exists(userId)) return null;
5635        flags = updateFlagsForResolve(flags, userId, intent);
5636        List<ResolveInfo> query = queryIntentServices(intent, resolvedType, flags, userId);
5637        if (query != null) {
5638            if (query.size() >= 1) {
5639                // If there is more than one service with the same priority,
5640                // just arbitrarily pick the first one.
5641                return query.get(0);
5642            }
5643        }
5644        return null;
5645    }
5646
5647    @Override
5648    public List<ResolveInfo> queryIntentServices(Intent intent, String resolvedType, int flags,
5649            int userId) {
5650        if (!sUserManager.exists(userId)) return Collections.emptyList();
5651        flags = updateFlagsForResolve(flags, userId, intent);
5652        ComponentName comp = intent.getComponent();
5653        if (comp == null) {
5654            if (intent.getSelector() != null) {
5655                intent = intent.getSelector();
5656                comp = intent.getComponent();
5657            }
5658        }
5659        if (comp != null) {
5660            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
5661            final ServiceInfo si = getServiceInfo(comp, flags, userId);
5662            if (si != null) {
5663                final ResolveInfo ri = new ResolveInfo();
5664                ri.serviceInfo = si;
5665                list.add(ri);
5666            }
5667            return list;
5668        }
5669
5670        // reader
5671        synchronized (mPackages) {
5672            String pkgName = intent.getPackage();
5673            if (pkgName == null) {
5674                return mServices.queryIntent(intent, resolvedType, flags, userId);
5675            }
5676            final PackageParser.Package pkg = mPackages.get(pkgName);
5677            if (pkg != null) {
5678                return mServices.queryIntentForPackage(intent, resolvedType, flags, pkg.services,
5679                        userId);
5680            }
5681            return null;
5682        }
5683    }
5684
5685    @Override
5686    public List<ResolveInfo> queryIntentContentProviders(
5687            Intent intent, String resolvedType, int flags, int userId) {
5688        if (!sUserManager.exists(userId)) return Collections.emptyList();
5689        flags = updateFlagsForResolve(flags, userId, intent);
5690        ComponentName comp = intent.getComponent();
5691        if (comp == null) {
5692            if (intent.getSelector() != null) {
5693                intent = intent.getSelector();
5694                comp = intent.getComponent();
5695            }
5696        }
5697        if (comp != null) {
5698            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
5699            final ProviderInfo pi = getProviderInfo(comp, flags, userId);
5700            if (pi != null) {
5701                final ResolveInfo ri = new ResolveInfo();
5702                ri.providerInfo = pi;
5703                list.add(ri);
5704            }
5705            return list;
5706        }
5707
5708        // reader
5709        synchronized (mPackages) {
5710            String pkgName = intent.getPackage();
5711            if (pkgName == null) {
5712                return mProviders.queryIntent(intent, resolvedType, flags, userId);
5713            }
5714            final PackageParser.Package pkg = mPackages.get(pkgName);
5715            if (pkg != null) {
5716                return mProviders.queryIntentForPackage(
5717                        intent, resolvedType, flags, pkg.providers, userId);
5718            }
5719            return null;
5720        }
5721    }
5722
5723    @Override
5724    public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) {
5725        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
5726        flags = updateFlagsForPackage(flags, userId, null);
5727        final boolean listUninstalled = (flags & MATCH_UNINSTALLED_PACKAGES) != 0;
5728        enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, "get installed packages");
5729
5730        // writer
5731        synchronized (mPackages) {
5732            ArrayList<PackageInfo> list;
5733            if (listUninstalled) {
5734                list = new ArrayList<PackageInfo>(mSettings.mPackages.size());
5735                for (PackageSetting ps : mSettings.mPackages.values()) {
5736                    PackageInfo pi;
5737                    if (ps.pkg != null) {
5738                        pi = generatePackageInfo(ps.pkg, flags, userId);
5739                    } else {
5740                        pi = generatePackageInfoFromSettingsLPw(ps.name, flags, userId);
5741                    }
5742                    if (pi != null) {
5743                        list.add(pi);
5744                    }
5745                }
5746            } else {
5747                list = new ArrayList<PackageInfo>(mPackages.size());
5748                for (PackageParser.Package p : mPackages.values()) {
5749                    PackageInfo pi = generatePackageInfo(p, flags, userId);
5750                    if (pi != null) {
5751                        list.add(pi);
5752                    }
5753                }
5754            }
5755
5756            return new ParceledListSlice<PackageInfo>(list);
5757        }
5758    }
5759
5760    private void addPackageHoldingPermissions(ArrayList<PackageInfo> list, PackageSetting ps,
5761            String[] permissions, boolean[] tmp, int flags, int userId) {
5762        int numMatch = 0;
5763        final PermissionsState permissionsState = ps.getPermissionsState();
5764        for (int i=0; i<permissions.length; i++) {
5765            final String permission = permissions[i];
5766            if (permissionsState.hasPermission(permission, userId)) {
5767                tmp[i] = true;
5768                numMatch++;
5769            } else {
5770                tmp[i] = false;
5771            }
5772        }
5773        if (numMatch == 0) {
5774            return;
5775        }
5776        PackageInfo pi;
5777        if (ps.pkg != null) {
5778            pi = generatePackageInfo(ps.pkg, flags, userId);
5779        } else {
5780            pi = generatePackageInfoFromSettingsLPw(ps.name, flags, userId);
5781        }
5782        // The above might return null in cases of uninstalled apps or install-state
5783        // skew across users/profiles.
5784        if (pi != null) {
5785            if ((flags&PackageManager.GET_PERMISSIONS) == 0) {
5786                if (numMatch == permissions.length) {
5787                    pi.requestedPermissions = permissions;
5788                } else {
5789                    pi.requestedPermissions = new String[numMatch];
5790                    numMatch = 0;
5791                    for (int i=0; i<permissions.length; i++) {
5792                        if (tmp[i]) {
5793                            pi.requestedPermissions[numMatch] = permissions[i];
5794                            numMatch++;
5795                        }
5796                    }
5797                }
5798            }
5799            list.add(pi);
5800        }
5801    }
5802
5803    @Override
5804    public ParceledListSlice<PackageInfo> getPackagesHoldingPermissions(
5805            String[] permissions, int flags, int userId) {
5806        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
5807        flags = updateFlagsForPackage(flags, userId, permissions);
5808        final boolean listUninstalled = (flags & MATCH_UNINSTALLED_PACKAGES) != 0;
5809
5810        // writer
5811        synchronized (mPackages) {
5812            ArrayList<PackageInfo> list = new ArrayList<PackageInfo>();
5813            boolean[] tmpBools = new boolean[permissions.length];
5814            if (listUninstalled) {
5815                for (PackageSetting ps : mSettings.mPackages.values()) {
5816                    addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags, userId);
5817                }
5818            } else {
5819                for (PackageParser.Package pkg : mPackages.values()) {
5820                    PackageSetting ps = (PackageSetting)pkg.mExtras;
5821                    if (ps != null) {
5822                        addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags,
5823                                userId);
5824                    }
5825                }
5826            }
5827
5828            return new ParceledListSlice<PackageInfo>(list);
5829        }
5830    }
5831
5832    @Override
5833    public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags, int userId) {
5834        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
5835        flags = updateFlagsForApplication(flags, userId, null);
5836        final boolean listUninstalled = (flags & MATCH_UNINSTALLED_PACKAGES) != 0;
5837
5838        // writer
5839        synchronized (mPackages) {
5840            ArrayList<ApplicationInfo> list;
5841            if (listUninstalled) {
5842                list = new ArrayList<ApplicationInfo>(mSettings.mPackages.size());
5843                for (PackageSetting ps : mSettings.mPackages.values()) {
5844                    ApplicationInfo ai;
5845                    if (ps.pkg != null) {
5846                        ai = PackageParser.generateApplicationInfo(ps.pkg, flags,
5847                                ps.readUserState(userId), userId);
5848                    } else {
5849                        ai = generateApplicationInfoFromSettingsLPw(ps.name, flags, userId);
5850                    }
5851                    if (ai != null) {
5852                        list.add(ai);
5853                    }
5854                }
5855            } else {
5856                list = new ArrayList<ApplicationInfo>(mPackages.size());
5857                for (PackageParser.Package p : mPackages.values()) {
5858                    if (p.mExtras != null) {
5859                        ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
5860                                ((PackageSetting)p.mExtras).readUserState(userId), userId);
5861                        if (ai != null) {
5862                            list.add(ai);
5863                        }
5864                    }
5865                }
5866            }
5867
5868            return new ParceledListSlice<ApplicationInfo>(list);
5869        }
5870    }
5871
5872    @Override
5873    public ParceledListSlice<EphemeralApplicationInfo> getEphemeralApplications(int userId) {
5874        if (DISABLE_EPHEMERAL_APPS) {
5875            return null;
5876        }
5877
5878        mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_EPHEMERAL_APPS,
5879                "getEphemeralApplications");
5880        enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false,
5881                "getEphemeralApplications");
5882        synchronized (mPackages) {
5883            List<EphemeralApplicationInfo> ephemeralApps = mEphemeralApplicationRegistry
5884                    .getEphemeralApplicationsLPw(userId);
5885            if (ephemeralApps != null) {
5886                return new ParceledListSlice<>(ephemeralApps);
5887            }
5888        }
5889        return null;
5890    }
5891
5892    @Override
5893    public boolean isEphemeralApplication(String packageName, int userId) {
5894        enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false,
5895                "isEphemeral");
5896        if (DISABLE_EPHEMERAL_APPS) {
5897            return false;
5898        }
5899
5900        if (!isCallerSameApp(packageName)) {
5901            return false;
5902        }
5903        synchronized (mPackages) {
5904            PackageParser.Package pkg = mPackages.get(packageName);
5905            if (pkg != null) {
5906                return pkg.applicationInfo.isEphemeralApp();
5907            }
5908        }
5909        return false;
5910    }
5911
5912    @Override
5913    public byte[] getEphemeralApplicationCookie(String packageName, int userId) {
5914        if (DISABLE_EPHEMERAL_APPS) {
5915            return null;
5916        }
5917
5918        enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false,
5919                "getCookie");
5920        if (!isCallerSameApp(packageName)) {
5921            return null;
5922        }
5923        synchronized (mPackages) {
5924            return mEphemeralApplicationRegistry.getEphemeralApplicationCookieLPw(
5925                    packageName, userId);
5926        }
5927    }
5928
5929    @Override
5930    public boolean setEphemeralApplicationCookie(String packageName, byte[] cookie, int userId) {
5931        if (DISABLE_EPHEMERAL_APPS) {
5932            return true;
5933        }
5934
5935        enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false,
5936                "setCookie");
5937        if (!isCallerSameApp(packageName)) {
5938            return false;
5939        }
5940        synchronized (mPackages) {
5941            return mEphemeralApplicationRegistry.setEphemeralApplicationCookieLPw(
5942                    packageName, cookie, userId);
5943        }
5944    }
5945
5946    @Override
5947    public Bitmap getEphemeralApplicationIcon(String packageName, int userId) {
5948        if (DISABLE_EPHEMERAL_APPS) {
5949            return null;
5950        }
5951
5952        mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_EPHEMERAL_APPS,
5953                "getEphemeralApplicationIcon");
5954        enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false,
5955                "getEphemeralApplicationIcon");
5956        synchronized (mPackages) {
5957            return mEphemeralApplicationRegistry.getEphemeralApplicationIconLPw(
5958                    packageName, userId);
5959        }
5960    }
5961
5962    private boolean isCallerSameApp(String packageName) {
5963        PackageParser.Package pkg = mPackages.get(packageName);
5964        return pkg != null
5965                && UserHandle.getAppId(Binder.getCallingUid()) == pkg.applicationInfo.uid;
5966    }
5967
5968    public List<ApplicationInfo> getPersistentApplications(int flags) {
5969        final ArrayList<ApplicationInfo> finalList = new ArrayList<ApplicationInfo>();
5970
5971        // reader
5972        synchronized (mPackages) {
5973            final Iterator<PackageParser.Package> i = mPackages.values().iterator();
5974            final int userId = UserHandle.getCallingUserId();
5975            while (i.hasNext()) {
5976                final PackageParser.Package p = i.next();
5977                if (p.applicationInfo != null
5978                        && (p.applicationInfo.flags&ApplicationInfo.FLAG_PERSISTENT) != 0
5979                        && (!mSafeMode || isSystemApp(p))) {
5980                    PackageSetting ps = mSettings.mPackages.get(p.packageName);
5981                    if (ps != null) {
5982                        ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
5983                                ps.readUserState(userId), userId);
5984                        if (ai != null) {
5985                            finalList.add(ai);
5986                        }
5987                    }
5988                }
5989            }
5990        }
5991
5992        return finalList;
5993    }
5994
5995    @Override
5996    public ProviderInfo resolveContentProvider(String name, int flags, int userId) {
5997        if (!sUserManager.exists(userId)) return null;
5998        flags = updateFlagsForComponent(flags, userId, name);
5999        // reader
6000        synchronized (mPackages) {
6001            final PackageParser.Provider provider = mProvidersByAuthority.get(name);
6002            PackageSetting ps = provider != null
6003                    ? mSettings.mPackages.get(provider.owner.packageName)
6004                    : null;
6005            return ps != null
6006                    && mSettings.isEnabledAndMatchLPr(provider.info, flags, userId)
6007                    ? PackageParser.generateProviderInfo(provider, flags,
6008                            ps.readUserState(userId), userId)
6009                    : null;
6010        }
6011    }
6012
6013    /**
6014     * @deprecated
6015     */
6016    @Deprecated
6017    public void querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo) {
6018        // reader
6019        synchronized (mPackages) {
6020            final Iterator<Map.Entry<String, PackageParser.Provider>> i = mProvidersByAuthority
6021                    .entrySet().iterator();
6022            final int userId = UserHandle.getCallingUserId();
6023            while (i.hasNext()) {
6024                Map.Entry<String, PackageParser.Provider> entry = i.next();
6025                PackageParser.Provider p = entry.getValue();
6026                PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
6027
6028                if (ps != null && p.syncable
6029                        && (!mSafeMode || (p.info.applicationInfo.flags
6030                                &ApplicationInfo.FLAG_SYSTEM) != 0)) {
6031                    ProviderInfo info = PackageParser.generateProviderInfo(p, 0,
6032                            ps.readUserState(userId), userId);
6033                    if (info != null) {
6034                        outNames.add(entry.getKey());
6035                        outInfo.add(info);
6036                    }
6037                }
6038            }
6039        }
6040    }
6041
6042    @Override
6043    public ParceledListSlice<ProviderInfo> queryContentProviders(String processName,
6044            int uid, int flags) {
6045        final int userId = processName != null ? UserHandle.getUserId(uid)
6046                : UserHandle.getCallingUserId();
6047        if (!sUserManager.exists(userId)) return null;
6048        flags = updateFlagsForComponent(flags, userId, processName);
6049
6050        ArrayList<ProviderInfo> finalList = null;
6051        // reader
6052        synchronized (mPackages) {
6053            final Iterator<PackageParser.Provider> i = mProviders.mProviders.values().iterator();
6054            while (i.hasNext()) {
6055                final PackageParser.Provider p = i.next();
6056                PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
6057                if (ps != null && p.info.authority != null
6058                        && (processName == null
6059                                || (p.info.processName.equals(processName)
6060                                        && UserHandle.isSameApp(p.info.applicationInfo.uid, uid)))
6061                        && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) {
6062                    if (finalList == null) {
6063                        finalList = new ArrayList<ProviderInfo>(3);
6064                    }
6065                    ProviderInfo info = PackageParser.generateProviderInfo(p, flags,
6066                            ps.readUserState(userId), userId);
6067                    if (info != null) {
6068                        finalList.add(info);
6069                    }
6070                }
6071            }
6072        }
6073
6074        if (finalList != null) {
6075            Collections.sort(finalList, mProviderInitOrderSorter);
6076            return new ParceledListSlice<ProviderInfo>(finalList);
6077        }
6078
6079        return null;
6080    }
6081
6082    @Override
6083    public InstrumentationInfo getInstrumentationInfo(ComponentName name, int flags) {
6084        // reader
6085        synchronized (mPackages) {
6086            final PackageParser.Instrumentation i = mInstrumentation.get(name);
6087            return PackageParser.generateInstrumentationInfo(i, flags);
6088        }
6089    }
6090
6091    @Override
6092    public List<InstrumentationInfo> queryInstrumentation(String targetPackage,
6093            int flags) {
6094        ArrayList<InstrumentationInfo> finalList =
6095            new ArrayList<InstrumentationInfo>();
6096
6097        // reader
6098        synchronized (mPackages) {
6099            final Iterator<PackageParser.Instrumentation> i = mInstrumentation.values().iterator();
6100            while (i.hasNext()) {
6101                final PackageParser.Instrumentation p = i.next();
6102                if (targetPackage == null
6103                        || targetPackage.equals(p.info.targetPackage)) {
6104                    InstrumentationInfo ii = PackageParser.generateInstrumentationInfo(p,
6105                            flags);
6106                    if (ii != null) {
6107                        finalList.add(ii);
6108                    }
6109                }
6110            }
6111        }
6112
6113        return finalList;
6114    }
6115
6116    private void createIdmapsForPackageLI(PackageParser.Package pkg) {
6117        ArrayMap<String, PackageParser.Package> overlays = mOverlays.get(pkg.packageName);
6118        if (overlays == null) {
6119            Slog.w(TAG, "Unable to create idmap for " + pkg.packageName + ": no overlay packages");
6120            return;
6121        }
6122        for (PackageParser.Package opkg : overlays.values()) {
6123            // Not much to do if idmap fails: we already logged the error
6124            // and we certainly don't want to abort installation of pkg simply
6125            // because an overlay didn't fit properly. For these reasons,
6126            // ignore the return value of createIdmapForPackagePairLI.
6127            createIdmapForPackagePairLI(pkg, opkg);
6128        }
6129    }
6130
6131    private boolean createIdmapForPackagePairLI(PackageParser.Package pkg,
6132            PackageParser.Package opkg) {
6133        if (!opkg.mTrustedOverlay) {
6134            Slog.w(TAG, "Skipping target and overlay pair " + pkg.baseCodePath + " and " +
6135                    opkg.baseCodePath + ": overlay not trusted");
6136            return false;
6137        }
6138        ArrayMap<String, PackageParser.Package> overlaySet = mOverlays.get(pkg.packageName);
6139        if (overlaySet == null) {
6140            Slog.e(TAG, "was about to create idmap for " + pkg.baseCodePath + " and " +
6141                    opkg.baseCodePath + " but target package has no known overlays");
6142            return false;
6143        }
6144        final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
6145        // TODO: generate idmap for split APKs
6146        try {
6147            mInstaller.idmap(pkg.baseCodePath, opkg.baseCodePath, sharedGid);
6148        } catch (InstallerException e) {
6149            Slog.e(TAG, "Failed to generate idmap for " + pkg.baseCodePath + " and "
6150                    + opkg.baseCodePath);
6151            return false;
6152        }
6153        PackageParser.Package[] overlayArray =
6154            overlaySet.values().toArray(new PackageParser.Package[0]);
6155        Comparator<PackageParser.Package> cmp = new Comparator<PackageParser.Package>() {
6156            public int compare(PackageParser.Package p1, PackageParser.Package p2) {
6157                return p1.mOverlayPriority - p2.mOverlayPriority;
6158            }
6159        };
6160        Arrays.sort(overlayArray, cmp);
6161
6162        pkg.applicationInfo.resourceDirs = new String[overlayArray.length];
6163        int i = 0;
6164        for (PackageParser.Package p : overlayArray) {
6165            pkg.applicationInfo.resourceDirs[i++] = p.baseCodePath;
6166        }
6167        return true;
6168    }
6169
6170    private void scanDirTracedLI(File dir, int parseFlags, int scanFlags, long currentTime) {
6171        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanDir");
6172        try {
6173            scanDirLI(dir, parseFlags, scanFlags, currentTime);
6174        } finally {
6175            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
6176        }
6177    }
6178
6179    private void scanDirLI(File dir, int parseFlags, int scanFlags, long currentTime) {
6180        final File[] files = dir.listFiles();
6181        if (ArrayUtils.isEmpty(files)) {
6182            Log.d(TAG, "No files in app dir " + dir);
6183            return;
6184        }
6185
6186        if (DEBUG_PACKAGE_SCANNING) {
6187            Log.d(TAG, "Scanning app dir " + dir + " scanFlags=" + scanFlags
6188                    + " flags=0x" + Integer.toHexString(parseFlags));
6189        }
6190
6191        for (File file : files) {
6192            final boolean isPackage = (isApkFile(file) || file.isDirectory())
6193                    && !PackageInstallerService.isStageName(file.getName());
6194            if (!isPackage) {
6195                // Ignore entries which are not packages
6196                continue;
6197            }
6198            try {
6199                scanPackageTracedLI(file, parseFlags | PackageParser.PARSE_MUST_BE_APK,
6200                        scanFlags, currentTime, null);
6201            } catch (PackageManagerException e) {
6202                Slog.w(TAG, "Failed to parse " + file + ": " + e.getMessage());
6203
6204                // Delete invalid userdata apps
6205                if ((parseFlags & PackageParser.PARSE_IS_SYSTEM) == 0 &&
6206                        e.error == PackageManager.INSTALL_FAILED_INVALID_APK) {
6207                    logCriticalInfo(Log.WARN, "Deleting invalid package at " + file);
6208                    removeCodePathLI(file);
6209                }
6210            }
6211        }
6212    }
6213
6214    private static File getSettingsProblemFile() {
6215        File dataDir = Environment.getDataDirectory();
6216        File systemDir = new File(dataDir, "system");
6217        File fname = new File(systemDir, "uiderrors.txt");
6218        return fname;
6219    }
6220
6221    static void reportSettingsProblem(int priority, String msg) {
6222        logCriticalInfo(priority, msg);
6223    }
6224
6225    static void logCriticalInfo(int priority, String msg) {
6226        Slog.println(priority, TAG, msg);
6227        EventLogTags.writePmCriticalInfo(msg);
6228        try {
6229            File fname = getSettingsProblemFile();
6230            FileOutputStream out = new FileOutputStream(fname, true);
6231            PrintWriter pw = new FastPrintWriter(out);
6232            SimpleDateFormat formatter = new SimpleDateFormat();
6233            String dateString = formatter.format(new Date(System.currentTimeMillis()));
6234            pw.println(dateString + ": " + msg);
6235            pw.close();
6236            FileUtils.setPermissions(
6237                    fname.toString(),
6238                    FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IROTH,
6239                    -1, -1);
6240        } catch (java.io.IOException e) {
6241        }
6242    }
6243
6244    private void collectCertificatesLI(PackageParser pp, PackageSetting ps,
6245            PackageParser.Package pkg, File srcFile, int parseFlags)
6246            throws PackageManagerException {
6247        if (ps != null
6248                && ps.codePath.equals(srcFile)
6249                && ps.timeStamp == srcFile.lastModified()
6250                && !isCompatSignatureUpdateNeeded(pkg)
6251                && !isRecoverSignatureUpdateNeeded(pkg)) {
6252            long mSigningKeySetId = ps.keySetData.getProperSigningKeySet();
6253            KeySetManagerService ksms = mSettings.mKeySetManagerService;
6254            ArraySet<PublicKey> signingKs;
6255            synchronized (mPackages) {
6256                signingKs = ksms.getPublicKeysFromKeySetLPr(mSigningKeySetId);
6257            }
6258            if (ps.signatures.mSignatures != null
6259                    && ps.signatures.mSignatures.length != 0
6260                    && signingKs != null) {
6261                // Optimization: reuse the existing cached certificates
6262                // if the package appears to be unchanged.
6263                pkg.mSignatures = ps.signatures.mSignatures;
6264                pkg.mSigningKeys = signingKs;
6265                return;
6266            }
6267
6268            Slog.w(TAG, "PackageSetting for " + ps.name
6269                    + " is missing signatures.  Collecting certs again to recover them.");
6270        } else {
6271            Log.i(TAG, srcFile.toString() + " changed; collecting certs");
6272        }
6273
6274        try {
6275            pp.collectCertificates(pkg, parseFlags);
6276        } catch (PackageParserException e) {
6277            throw PackageManagerException.from(e);
6278        }
6279    }
6280
6281    /**
6282     *  Traces a package scan.
6283     *  @see #scanPackageLI(File, int, int, long, UserHandle)
6284     */
6285    private PackageParser.Package scanPackageTracedLI(File scanFile, int parseFlags, int scanFlags,
6286            long currentTime, UserHandle user) throws PackageManagerException {
6287        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage");
6288        try {
6289            return scanPackageLI(scanFile, parseFlags, scanFlags, currentTime, user);
6290        } finally {
6291            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
6292        }
6293    }
6294
6295    /**
6296     *  Scans a package and returns the newly parsed package.
6297     *  Returns {@code null} in case of errors and the error code is stored in mLastScanError
6298     */
6299    private PackageParser.Package scanPackageLI(File scanFile, int parseFlags, int scanFlags,
6300            long currentTime, UserHandle user) throws PackageManagerException {
6301        if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanFile);
6302        parseFlags |= mDefParseFlags;
6303        PackageParser pp = new PackageParser();
6304        pp.setSeparateProcesses(mSeparateProcesses);
6305        pp.setOnlyCoreApps(mOnlyCore);
6306        pp.setDisplayMetrics(mMetrics);
6307
6308        if ((scanFlags & SCAN_TRUSTED_OVERLAY) != 0) {
6309            parseFlags |= PackageParser.PARSE_TRUSTED_OVERLAY;
6310        }
6311
6312        final PackageParser.Package pkg;
6313        try {
6314            pkg = pp.parsePackage(scanFile, parseFlags);
6315        } catch (PackageParserException e) {
6316            throw PackageManagerException.from(e);
6317        }
6318
6319        PackageSetting ps = null;
6320        PackageSetting updatedPkg;
6321        // reader
6322        synchronized (mPackages) {
6323            // Look to see if we already know about this package.
6324            String oldName = mSettings.mRenamedPackages.get(pkg.packageName);
6325            if (pkg.mOriginalPackages != null && pkg.mOriginalPackages.contains(oldName)) {
6326                // This package has been renamed to its original name.  Let's
6327                // use that.
6328                ps = mSettings.peekPackageLPr(oldName);
6329            }
6330            // If there was no original package, see one for the real package name.
6331            if (ps == null) {
6332                ps = mSettings.peekPackageLPr(pkg.packageName);
6333            }
6334            // Check to see if this package could be hiding/updating a system
6335            // package.  Must look for it either under the original or real
6336            // package name depending on our state.
6337            updatedPkg = mSettings.getDisabledSystemPkgLPr(ps != null ? ps.name : pkg.packageName);
6338            if (DEBUG_INSTALL && updatedPkg != null) Slog.d(TAG, "updatedPkg = " + updatedPkg);
6339        }
6340        boolean updatedPkgBetter = false;
6341        // First check if this is a system package that may involve an update
6342        if (updatedPkg != null && (parseFlags & PackageParser.PARSE_IS_SYSTEM) != 0) {
6343            // If new package is not located in "/system/priv-app" (e.g. due to an OTA),
6344            // it needs to drop FLAG_PRIVILEGED.
6345            if (locationIsPrivileged(scanFile)) {
6346                updatedPkg.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
6347            } else {
6348                updatedPkg.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
6349            }
6350
6351            if (ps != null && !ps.codePath.equals(scanFile)) {
6352                // The path has changed from what was last scanned...  check the
6353                // version of the new path against what we have stored to determine
6354                // what to do.
6355                if (DEBUG_INSTALL) Slog.d(TAG, "Path changing from " + ps.codePath);
6356                if (pkg.mVersionCode <= ps.versionCode) {
6357                    // The system package has been updated and the code path does not match
6358                    // Ignore entry. Skip it.
6359                    if (DEBUG_INSTALL) Slog.i(TAG, "Package " + ps.name + " at " + scanFile
6360                            + " ignored: updated version " + ps.versionCode
6361                            + " better than this " + pkg.mVersionCode);
6362                    if (!updatedPkg.codePath.equals(scanFile)) {
6363                        Slog.w(PackageManagerService.TAG, "Code path for hidden system pkg "
6364                                + ps.name + " changing from " + updatedPkg.codePathString
6365                                + " to " + scanFile);
6366                        updatedPkg.codePath = scanFile;
6367                        updatedPkg.codePathString = scanFile.toString();
6368                        updatedPkg.resourcePath = scanFile;
6369                        updatedPkg.resourcePathString = scanFile.toString();
6370                    }
6371                    updatedPkg.pkg = pkg;
6372                    throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
6373                            "Package " + ps.name + " at " + scanFile
6374                                    + " ignored: updated version " + ps.versionCode
6375                                    + " better than this " + pkg.mVersionCode);
6376                } else {
6377                    // The current app on the system partition is better than
6378                    // what we have updated to on the data partition; switch
6379                    // back to the system partition version.
6380                    // At this point, its safely assumed that package installation for
6381                    // apps in system partition will go through. If not there won't be a working
6382                    // version of the app
6383                    // writer
6384                    synchronized (mPackages) {
6385                        // Just remove the loaded entries from package lists.
6386                        mPackages.remove(ps.name);
6387                    }
6388
6389                    logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile
6390                            + " reverting from " + ps.codePathString
6391                            + ": new version " + pkg.mVersionCode
6392                            + " better than installed " + ps.versionCode);
6393
6394                    InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
6395                            ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
6396                    synchronized (mInstallLock) {
6397                        args.cleanUpResourcesLI();
6398                    }
6399                    synchronized (mPackages) {
6400                        mSettings.enableSystemPackageLPw(ps.name);
6401                    }
6402                    updatedPkgBetter = true;
6403                }
6404            }
6405        }
6406
6407        if (updatedPkg != null) {
6408            // An updated system app will not have the PARSE_IS_SYSTEM flag set
6409            // initially
6410            parseFlags |= PackageParser.PARSE_IS_SYSTEM;
6411
6412            // An updated privileged app will not have the PARSE_IS_PRIVILEGED
6413            // flag set initially
6414            if ((updatedPkg.pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0) {
6415                parseFlags |= PackageParser.PARSE_IS_PRIVILEGED;
6416            }
6417        }
6418
6419        // Verify certificates against what was last scanned
6420        collectCertificatesLI(pp, ps, pkg, scanFile, parseFlags);
6421
6422        /*
6423         * A new system app appeared, but we already had a non-system one of the
6424         * same name installed earlier.
6425         */
6426        boolean shouldHideSystemApp = false;
6427        if (updatedPkg == null && ps != null
6428                && (parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0 && !isSystemApp(ps)) {
6429            /*
6430             * Check to make sure the signatures match first. If they don't,
6431             * wipe the installed application and its data.
6432             */
6433            if (compareSignatures(ps.signatures.mSignatures, pkg.mSignatures)
6434                    != PackageManager.SIGNATURE_MATCH) {
6435                logCriticalInfo(Log.WARN, "Package " + ps.name + " appeared on system, but"
6436                        + " signatures don't match existing userdata copy; removing");
6437                deletePackageLI(pkg.packageName, null, true, null, null, 0, null, false);
6438                ps = null;
6439            } else {
6440                /*
6441                 * If the newly-added system app is an older version than the
6442                 * already installed version, hide it. It will be scanned later
6443                 * and re-added like an update.
6444                 */
6445                if (pkg.mVersionCode <= ps.versionCode) {
6446                    shouldHideSystemApp = true;
6447                    logCriticalInfo(Log.INFO, "Package " + ps.name + " appeared at " + scanFile
6448                            + " but new version " + pkg.mVersionCode + " better than installed "
6449                            + ps.versionCode + "; hiding system");
6450                } else {
6451                    /*
6452                     * The newly found system app is a newer version that the
6453                     * one previously installed. Simply remove the
6454                     * already-installed application and replace it with our own
6455                     * while keeping the application data.
6456                     */
6457                    logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile
6458                            + " reverting from " + ps.codePathString + ": new version "
6459                            + pkg.mVersionCode + " better than installed " + ps.versionCode);
6460                    InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
6461                            ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
6462                    synchronized (mInstallLock) {
6463                        args.cleanUpResourcesLI();
6464                    }
6465                }
6466            }
6467        }
6468
6469        // The apk is forward locked (not public) if its code and resources
6470        // are kept in different files. (except for app in either system or
6471        // vendor path).
6472        // TODO grab this value from PackageSettings
6473        if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
6474            if (ps != null && !ps.codePath.equals(ps.resourcePath)) {
6475                parseFlags |= PackageParser.PARSE_FORWARD_LOCK;
6476            }
6477        }
6478
6479        // TODO: extend to support forward-locked splits
6480        String resourcePath = null;
6481        String baseResourcePath = null;
6482        if ((parseFlags & PackageParser.PARSE_FORWARD_LOCK) != 0 && !updatedPkgBetter) {
6483            if (ps != null && ps.resourcePathString != null) {
6484                resourcePath = ps.resourcePathString;
6485                baseResourcePath = ps.resourcePathString;
6486            } else {
6487                // Should not happen at all. Just log an error.
6488                Slog.e(TAG, "Resource path not set for package " + pkg.packageName);
6489            }
6490        } else {
6491            resourcePath = pkg.codePath;
6492            baseResourcePath = pkg.baseCodePath;
6493        }
6494
6495        // Set application objects path explicitly.
6496        pkg.applicationInfo.volumeUuid = pkg.volumeUuid;
6497        pkg.applicationInfo.setCodePath(pkg.codePath);
6498        pkg.applicationInfo.setBaseCodePath(pkg.baseCodePath);
6499        pkg.applicationInfo.setSplitCodePaths(pkg.splitCodePaths);
6500        pkg.applicationInfo.setResourcePath(resourcePath);
6501        pkg.applicationInfo.setBaseResourcePath(baseResourcePath);
6502        pkg.applicationInfo.setSplitResourcePaths(pkg.splitCodePaths);
6503
6504        // Note that we invoke the following method only if we are about to unpack an application
6505        PackageParser.Package scannedPkg = scanPackageLI(pkg, parseFlags, scanFlags
6506                | SCAN_UPDATE_SIGNATURE, currentTime, user);
6507
6508        /*
6509         * If the system app should be overridden by a previously installed
6510         * data, hide the system app now and let the /data/app scan pick it up
6511         * again.
6512         */
6513        if (shouldHideSystemApp) {
6514            synchronized (mPackages) {
6515                mSettings.disableSystemPackageLPw(pkg.packageName);
6516            }
6517        }
6518
6519        return scannedPkg;
6520    }
6521
6522    private static String fixProcessName(String defProcessName,
6523            String processName, int uid) {
6524        if (processName == null) {
6525            return defProcessName;
6526        }
6527        return processName;
6528    }
6529
6530    private void verifySignaturesLP(PackageSetting pkgSetting, PackageParser.Package pkg)
6531            throws PackageManagerException {
6532        if (pkgSetting.signatures.mSignatures != null) {
6533            // Already existing package. Make sure signatures match
6534            boolean match = compareSignatures(pkgSetting.signatures.mSignatures, pkg.mSignatures)
6535                    == PackageManager.SIGNATURE_MATCH;
6536            if (!match) {
6537                match = compareSignaturesCompat(pkgSetting.signatures, pkg)
6538                        == PackageManager.SIGNATURE_MATCH;
6539            }
6540            if (!match) {
6541                match = compareSignaturesRecover(pkgSetting.signatures, pkg)
6542                        == PackageManager.SIGNATURE_MATCH;
6543            }
6544            if (!match) {
6545                throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
6546                        + pkg.packageName + " signatures do not match the "
6547                        + "previously installed version; ignoring!");
6548            }
6549        }
6550
6551        // Check for shared user signatures
6552        if (pkgSetting.sharedUser != null && pkgSetting.sharedUser.signatures.mSignatures != null) {
6553            // Already existing package. Make sure signatures match
6554            boolean match = compareSignatures(pkgSetting.sharedUser.signatures.mSignatures,
6555                    pkg.mSignatures) == PackageManager.SIGNATURE_MATCH;
6556            if (!match) {
6557                match = compareSignaturesCompat(pkgSetting.sharedUser.signatures, pkg)
6558                        == PackageManager.SIGNATURE_MATCH;
6559            }
6560            if (!match) {
6561                match = compareSignaturesRecover(pkgSetting.sharedUser.signatures, pkg)
6562                        == PackageManager.SIGNATURE_MATCH;
6563            }
6564            if (!match) {
6565                throw new PackageManagerException(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
6566                        "Package " + pkg.packageName
6567                        + " has no signatures that match those in shared user "
6568                        + pkgSetting.sharedUser.name + "; ignoring!");
6569            }
6570        }
6571    }
6572
6573    /**
6574     * Enforces that only the system UID or root's UID can call a method exposed
6575     * via Binder.
6576     *
6577     * @param message used as message if SecurityException is thrown
6578     * @throws SecurityException if the caller is not system or root
6579     */
6580    private static final void enforceSystemOrRoot(String message) {
6581        final int uid = Binder.getCallingUid();
6582        if (uid != Process.SYSTEM_UID && uid != 0) {
6583            throw new SecurityException(message);
6584        }
6585    }
6586
6587    @Override
6588    public void performFstrimIfNeeded() {
6589        enforceSystemOrRoot("Only the system can request fstrim");
6590
6591        // Before everything else, see whether we need to fstrim.
6592        try {
6593            IMountService ms = PackageHelper.getMountService();
6594            if (ms != null) {
6595                final boolean isUpgrade = isUpgrade();
6596                boolean doTrim = isUpgrade;
6597                if (doTrim) {
6598                    Slog.w(TAG, "Running disk maintenance immediately due to system update");
6599                } else {
6600                    final long interval = android.provider.Settings.Global.getLong(
6601                            mContext.getContentResolver(),
6602                            android.provider.Settings.Global.FSTRIM_MANDATORY_INTERVAL,
6603                            DEFAULT_MANDATORY_FSTRIM_INTERVAL);
6604                    if (interval > 0) {
6605                        final long timeSinceLast = System.currentTimeMillis() - ms.lastMaintenance();
6606                        if (timeSinceLast > interval) {
6607                            doTrim = true;
6608                            Slog.w(TAG, "No disk maintenance in " + timeSinceLast
6609                                    + "; running immediately");
6610                        }
6611                    }
6612                }
6613                if (doTrim) {
6614                    if (!isFirstBoot()) {
6615                        try {
6616                            ActivityManagerNative.getDefault().showBootMessage(
6617                                    mContext.getResources().getString(
6618                                            R.string.android_upgrading_fstrim), true);
6619                        } catch (RemoteException e) {
6620                        }
6621                    }
6622                    ms.runMaintenance();
6623                }
6624            } else {
6625                Slog.e(TAG, "Mount service unavailable!");
6626            }
6627        } catch (RemoteException e) {
6628            // Can't happen; MountService is local
6629        }
6630    }
6631
6632    @Override
6633    public void extractPackagesIfNeeded() {
6634        enforceSystemOrRoot("Only the system can request package extraction");
6635
6636        // Extract pacakges only if profile-guided compilation is enabled because
6637        // otherwise BackgroundDexOptService will not dexopt them later.
6638        if (mUseJitProfiles) {
6639            ArraySet<String> pkgs = getOptimizablePackages();
6640            if (pkgs != null) {
6641                for (String pkg : pkgs) {
6642                    performDexOpt(pkg, null /* instructionSet */, false /* useProfiles */,
6643                            true /* extractOnly */);
6644                }
6645            }
6646        }
6647    }
6648
6649    private ArraySet<String> getPackageNamesForIntent(Intent intent, int userId) {
6650        List<ResolveInfo> ris = null;
6651        try {
6652            ris = AppGlobals.getPackageManager().queryIntentReceivers(
6653                    intent, null, 0, userId);
6654        } catch (RemoteException e) {
6655        }
6656        ArraySet<String> pkgNames = new ArraySet<String>();
6657        if (ris != null) {
6658            for (ResolveInfo ri : ris) {
6659                pkgNames.add(ri.activityInfo.packageName);
6660            }
6661        }
6662        return pkgNames;
6663    }
6664
6665    @Override
6666    public void notifyPackageUse(String packageName) {
6667        synchronized (mPackages) {
6668            PackageParser.Package p = mPackages.get(packageName);
6669            if (p == null) {
6670                return;
6671            }
6672            p.mLastPackageUsageTimeInMills = System.currentTimeMillis();
6673        }
6674    }
6675
6676    // TODO: this is not used nor needed. Delete it.
6677    @Override
6678    public boolean performDexOptIfNeeded(String packageName, String instructionSet) {
6679        return performDexOptTraced(packageName, instructionSet, false /* useProfiles */,
6680                false /* extractOnly */);
6681    }
6682
6683    public boolean performDexOpt(String packageName, String instructionSet, boolean useProfiles,
6684            boolean extractOnly) {
6685        return performDexOptTraced(packageName, instructionSet, useProfiles, extractOnly);
6686    }
6687
6688    private boolean performDexOptTraced(String packageName, String instructionSet,
6689                boolean useProfiles, boolean extractOnly) {
6690        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
6691        try {
6692            return performDexOptInternal(packageName, instructionSet, useProfiles, extractOnly);
6693        } finally {
6694            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
6695        }
6696    }
6697
6698    private boolean performDexOptInternal(String packageName, String instructionSet,
6699                boolean useProfiles, boolean extractOnly) {
6700        PackageParser.Package p;
6701        final String targetInstructionSet;
6702        synchronized (mPackages) {
6703            p = mPackages.get(packageName);
6704            if (p == null) {
6705                return false;
6706            }
6707            mPackageUsage.write(false);
6708
6709            targetInstructionSet = instructionSet != null ? instructionSet :
6710                    getPrimaryInstructionSet(p.applicationInfo);
6711            if (!useProfiles && p.mDexOptPerformed.contains(targetInstructionSet)) {
6712                // Skip only if we do not use profiles since they might trigger a recompilation.
6713                return false;
6714            }
6715        }
6716        long callingId = Binder.clearCallingIdentity();
6717        try {
6718            synchronized (mInstallLock) {
6719                final String[] instructionSets = new String[] { targetInstructionSet };
6720                int result = mPackageDexOptimizer.performDexOpt(p, instructionSets,
6721                        true /* inclDependencies */, useProfiles, extractOnly);
6722                return result == PackageDexOptimizer.DEX_OPT_PERFORMED;
6723            }
6724        } finally {
6725            Binder.restoreCallingIdentity(callingId);
6726        }
6727    }
6728
6729    public ArraySet<String> getOptimizablePackages() {
6730        ArraySet<String> pkgs = new ArraySet<String>();
6731        synchronized (mPackages) {
6732            for (PackageParser.Package p : mPackages.values()) {
6733                if (PackageDexOptimizer.canOptimizePackage(p)) {
6734                    pkgs.add(p.packageName);
6735                }
6736            }
6737        }
6738        return pkgs;
6739    }
6740
6741    public void shutdown() {
6742        mPackageUsage.write(true);
6743    }
6744
6745    @Override
6746    public void forceDexOpt(String packageName) {
6747        enforceSystemOrRoot("forceDexOpt");
6748
6749        PackageParser.Package pkg;
6750        synchronized (mPackages) {
6751            pkg = mPackages.get(packageName);
6752            if (pkg == null) {
6753                throw new IllegalArgumentException("Unknown package: " + packageName);
6754            }
6755        }
6756
6757        synchronized (mInstallLock) {
6758            final String[] instructionSets = new String[] {
6759                    getPrimaryInstructionSet(pkg.applicationInfo) };
6760
6761            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
6762
6763            // Whoever is calling forceDexOpt wants a fully compiled package.
6764            // Don't use profiles since that may cause compilation to be skipped.
6765            final int res = mPackageDexOptimizer.performDexOpt(pkg, instructionSets,
6766                    true /* inclDependencies */, false /* useProfiles */,
6767                    false /* extractOnly */);
6768
6769            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
6770            if (res != PackageDexOptimizer.DEX_OPT_PERFORMED) {
6771                throw new IllegalStateException("Failed to dexopt: " + res);
6772            }
6773        }
6774    }
6775
6776    private boolean verifyPackageUpdateLPr(PackageSetting oldPkg, PackageParser.Package newPkg) {
6777        if ((oldPkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) {
6778            Slog.w(TAG, "Unable to update from " + oldPkg.name
6779                    + " to " + newPkg.packageName
6780                    + ": old package not in system partition");
6781            return false;
6782        } else if (mPackages.get(oldPkg.name) != null) {
6783            Slog.w(TAG, "Unable to update from " + oldPkg.name
6784                    + " to " + newPkg.packageName
6785                    + ": old package still exists");
6786            return false;
6787        }
6788        return true;
6789    }
6790
6791    private boolean removeDataDirsLI(String volumeUuid, String packageName) {
6792        // TODO: triage flags as part of 26466827
6793        final int flags = Installer.FLAG_CE_STORAGE | Installer.FLAG_DE_STORAGE;
6794
6795        boolean res = true;
6796        final int[] users = sUserManager.getUserIds();
6797        for (int user : users) {
6798            try {
6799                mInstaller.destroyAppData(volumeUuid, packageName, user, flags);
6800            } catch (InstallerException e) {
6801                Slog.w(TAG, "Failed to delete data directory", e);
6802                res = false;
6803            }
6804        }
6805        return res;
6806    }
6807
6808    void removeCodePathLI(File codePath) {
6809        if (codePath.isDirectory()) {
6810            try {
6811                mInstaller.rmPackageDir(codePath.getAbsolutePath());
6812            } catch (InstallerException e) {
6813                Slog.w(TAG, "Failed to remove code path", e);
6814            }
6815        } else {
6816            codePath.delete();
6817        }
6818    }
6819
6820    void destroyAppDataLI(String volumeUuid, String packageName, int userId, int flags) {
6821        try {
6822            mInstaller.destroyAppData(volumeUuid, packageName, userId, flags);
6823        } catch (InstallerException e) {
6824            Slog.w(TAG, "Failed to destroy app data", e);
6825        }
6826    }
6827
6828    void restoreconAppDataLI(String volumeUuid, String packageName, int userId, int flags,
6829            int appId, String seinfo) {
6830        try {
6831            mInstaller.restoreconAppData(volumeUuid, packageName, userId, flags, appId, seinfo);
6832        } catch (InstallerException e) {
6833            Slog.e(TAG, "Failed to restorecon for " + packageName + ": " + e);
6834        }
6835    }
6836
6837    private void deleteCodeCacheDirsLI(String volumeUuid, String packageName) {
6838        // TODO: triage flags as part of 26466827
6839        final int flags = Installer.FLAG_CE_STORAGE | Installer.FLAG_DE_STORAGE;
6840
6841        final int[] users = sUserManager.getUserIds();
6842        for (int user : users) {
6843            try {
6844                mInstaller.clearAppData(volumeUuid, packageName, user,
6845                        flags | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
6846            } catch (InstallerException e) {
6847                Slog.w(TAG, "Failed to delete code cache directory", e);
6848            }
6849        }
6850    }
6851
6852    private void addSharedLibraryLPw(ArraySet<String> usesLibraryFiles, SharedLibraryEntry file,
6853            PackageParser.Package changingLib) {
6854        if (file.path != null) {
6855            usesLibraryFiles.add(file.path);
6856            return;
6857        }
6858        PackageParser.Package p = mPackages.get(file.apk);
6859        if (changingLib != null && changingLib.packageName.equals(file.apk)) {
6860            // If we are doing this while in the middle of updating a library apk,
6861            // then we need to make sure to use that new apk for determining the
6862            // dependencies here.  (We haven't yet finished committing the new apk
6863            // to the package manager state.)
6864            if (p == null || p.packageName.equals(changingLib.packageName)) {
6865                p = changingLib;
6866            }
6867        }
6868        if (p != null) {
6869            usesLibraryFiles.addAll(p.getAllCodePaths());
6870        }
6871    }
6872
6873    private void updateSharedLibrariesLPw(PackageParser.Package pkg,
6874            PackageParser.Package changingLib) throws PackageManagerException {
6875        if (pkg.usesLibraries != null || pkg.usesOptionalLibraries != null) {
6876            final ArraySet<String> usesLibraryFiles = new ArraySet<>();
6877            int N = pkg.usesLibraries != null ? pkg.usesLibraries.size() : 0;
6878            for (int i=0; i<N; i++) {
6879                final SharedLibraryEntry file = mSharedLibraries.get(pkg.usesLibraries.get(i));
6880                if (file == null) {
6881                    throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
6882                            "Package " + pkg.packageName + " requires unavailable shared library "
6883                            + pkg.usesLibraries.get(i) + "; failing!");
6884                }
6885                addSharedLibraryLPw(usesLibraryFiles, file, changingLib);
6886            }
6887            N = pkg.usesOptionalLibraries != null ? pkg.usesOptionalLibraries.size() : 0;
6888            for (int i=0; i<N; i++) {
6889                final SharedLibraryEntry file = mSharedLibraries.get(pkg.usesOptionalLibraries.get(i));
6890                if (file == null) {
6891                    Slog.w(TAG, "Package " + pkg.packageName
6892                            + " desires unavailable shared library "
6893                            + pkg.usesOptionalLibraries.get(i) + "; ignoring!");
6894                } else {
6895                    addSharedLibraryLPw(usesLibraryFiles, file, changingLib);
6896                }
6897            }
6898            N = usesLibraryFiles.size();
6899            if (N > 0) {
6900                pkg.usesLibraryFiles = usesLibraryFiles.toArray(new String[N]);
6901            } else {
6902                pkg.usesLibraryFiles = null;
6903            }
6904        }
6905    }
6906
6907    private static boolean hasString(List<String> list, List<String> which) {
6908        if (list == null) {
6909            return false;
6910        }
6911        for (int i=list.size()-1; i>=0; i--) {
6912            for (int j=which.size()-1; j>=0; j--) {
6913                if (which.get(j).equals(list.get(i))) {
6914                    return true;
6915                }
6916            }
6917        }
6918        return false;
6919    }
6920
6921    private void updateAllSharedLibrariesLPw() {
6922        for (PackageParser.Package pkg : mPackages.values()) {
6923            try {
6924                updateSharedLibrariesLPw(pkg, null);
6925            } catch (PackageManagerException e) {
6926                Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
6927            }
6928        }
6929    }
6930
6931    private ArrayList<PackageParser.Package> updateAllSharedLibrariesLPw(
6932            PackageParser.Package changingPkg) {
6933        ArrayList<PackageParser.Package> res = null;
6934        for (PackageParser.Package pkg : mPackages.values()) {
6935            if (hasString(pkg.usesLibraries, changingPkg.libraryNames)
6936                    || hasString(pkg.usesOptionalLibraries, changingPkg.libraryNames)) {
6937                if (res == null) {
6938                    res = new ArrayList<PackageParser.Package>();
6939                }
6940                res.add(pkg);
6941                try {
6942                    updateSharedLibrariesLPw(pkg, changingPkg);
6943                } catch (PackageManagerException e) {
6944                    Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
6945                }
6946            }
6947        }
6948        return res;
6949    }
6950
6951    /**
6952     * Derive the value of the {@code cpuAbiOverride} based on the provided
6953     * value and an optional stored value from the package settings.
6954     */
6955    private static String deriveAbiOverride(String abiOverride, PackageSetting settings) {
6956        String cpuAbiOverride = null;
6957
6958        if (NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(abiOverride)) {
6959            cpuAbiOverride = null;
6960        } else if (abiOverride != null) {
6961            cpuAbiOverride = abiOverride;
6962        } else if (settings != null) {
6963            cpuAbiOverride = settings.cpuAbiOverrideString;
6964        }
6965
6966        return cpuAbiOverride;
6967    }
6968
6969    private PackageParser.Package scanPackageTracedLI(PackageParser.Package pkg, int parseFlags,
6970            int scanFlags, long currentTime, UserHandle user) throws PackageManagerException {
6971        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage");
6972        try {
6973            return scanPackageLI(pkg, parseFlags, scanFlags, currentTime, user);
6974        } finally {
6975            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
6976        }
6977    }
6978
6979    private PackageParser.Package scanPackageLI(PackageParser.Package pkg, int parseFlags,
6980            int scanFlags, long currentTime, UserHandle user) throws PackageManagerException {
6981        boolean success = false;
6982        try {
6983            final PackageParser.Package res = scanPackageDirtyLI(pkg, parseFlags, scanFlags,
6984                    currentTime, user);
6985            success = true;
6986            return res;
6987        } finally {
6988            if (!success && (scanFlags & SCAN_DELETE_DATA_ON_FAILURES) != 0) {
6989                removeDataDirsLI(pkg.volumeUuid, pkg.packageName);
6990            }
6991        }
6992    }
6993
6994    private PackageParser.Package scanPackageDirtyLI(PackageParser.Package pkg, int parseFlags,
6995            int scanFlags, long currentTime, UserHandle user) throws PackageManagerException {
6996        final File scanFile = new File(pkg.codePath);
6997        if (pkg.applicationInfo.getCodePath() == null ||
6998                pkg.applicationInfo.getResourcePath() == null) {
6999            // Bail out. The resource and code paths haven't been set.
7000            throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
7001                    "Code and resource paths haven't been set correctly");
7002        }
7003
7004        if ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) {
7005            pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
7006        } else {
7007            // Only allow system apps to be flagged as core apps.
7008            pkg.coreApp = false;
7009        }
7010
7011        if ((parseFlags&PackageParser.PARSE_IS_PRIVILEGED) != 0) {
7012            pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
7013        }
7014
7015        if (mCustomResolverComponentName != null &&
7016                mCustomResolverComponentName.getPackageName().equals(pkg.packageName)) {
7017            setUpCustomResolverActivity(pkg);
7018        }
7019
7020        if (pkg.packageName.equals("android")) {
7021            synchronized (mPackages) {
7022                if (mAndroidApplication != null) {
7023                    Slog.w(TAG, "*************************************************");
7024                    Slog.w(TAG, "Core android package being redefined.  Skipping.");
7025                    Slog.w(TAG, " file=" + scanFile);
7026                    Slog.w(TAG, "*************************************************");
7027                    throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
7028                            "Core android package being redefined.  Skipping.");
7029                }
7030
7031                // Set up information for our fall-back user intent resolution activity.
7032                mPlatformPackage = pkg;
7033                pkg.mVersionCode = mSdkVersion;
7034                mAndroidApplication = pkg.applicationInfo;
7035
7036                if (!mResolverReplaced) {
7037                    mResolveActivity.applicationInfo = mAndroidApplication;
7038                    mResolveActivity.name = ResolverActivity.class.getName();
7039                    mResolveActivity.packageName = mAndroidApplication.packageName;
7040                    mResolveActivity.processName = "system:ui";
7041                    mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
7042                    mResolveActivity.documentLaunchMode = ActivityInfo.DOCUMENT_LAUNCH_NEVER;
7043                    mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS;
7044                    mResolveActivity.theme = R.style.Theme_Holo_Dialog_Alert;
7045                    mResolveActivity.exported = true;
7046                    mResolveActivity.enabled = true;
7047                    mResolveInfo.activityInfo = mResolveActivity;
7048                    mResolveInfo.priority = 0;
7049                    mResolveInfo.preferredOrder = 0;
7050                    mResolveInfo.match = 0;
7051                    mResolveComponentName = new ComponentName(
7052                            mAndroidApplication.packageName, mResolveActivity.name);
7053                }
7054            }
7055        }
7056
7057        if (DEBUG_PACKAGE_SCANNING) {
7058            if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
7059                Log.d(TAG, "Scanning package " + pkg.packageName);
7060        }
7061
7062        if (mPackages.containsKey(pkg.packageName)
7063                || mSharedLibraries.containsKey(pkg.packageName)) {
7064            throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
7065                    "Application package " + pkg.packageName
7066                    + " already installed.  Skipping duplicate.");
7067        }
7068
7069        // If we're only installing presumed-existing packages, require that the
7070        // scanned APK is both already known and at the path previously established
7071        // for it.  Previously unknown packages we pick up normally, but if we have an
7072        // a priori expectation about this package's install presence, enforce it.
7073        // With a singular exception for new system packages. When an OTA contains
7074        // a new system package, we allow the codepath to change from a system location
7075        // to the user-installed location. If we don't allow this change, any newer,
7076        // user-installed version of the application will be ignored.
7077        if ((scanFlags & SCAN_REQUIRE_KNOWN) != 0) {
7078            if (mExpectingBetter.containsKey(pkg.packageName)) {
7079                logCriticalInfo(Log.WARN,
7080                        "Relax SCAN_REQUIRE_KNOWN requirement for package " + pkg.packageName);
7081            } else {
7082                PackageSetting known = mSettings.peekPackageLPr(pkg.packageName);
7083                if (known != null) {
7084                    if (DEBUG_PACKAGE_SCANNING) {
7085                        Log.d(TAG, "Examining " + pkg.codePath
7086                                + " and requiring known paths " + known.codePathString
7087                                + " & " + known.resourcePathString);
7088                    }
7089                    if (!pkg.applicationInfo.getCodePath().equals(known.codePathString)
7090                            || !pkg.applicationInfo.getResourcePath().equals(known.resourcePathString)) {
7091                        throw new PackageManagerException(INSTALL_FAILED_PACKAGE_CHANGED,
7092                                "Application package " + pkg.packageName
7093                                + " found at " + pkg.applicationInfo.getCodePath()
7094                                + " but expected at " + known.codePathString + "; ignoring.");
7095                    }
7096                }
7097            }
7098        }
7099
7100        // Initialize package source and resource directories
7101        File destCodeFile = new File(pkg.applicationInfo.getCodePath());
7102        File destResourceFile = new File(pkg.applicationInfo.getResourcePath());
7103
7104        SharedUserSetting suid = null;
7105        PackageSetting pkgSetting = null;
7106
7107        if (!isSystemApp(pkg)) {
7108            // Only system apps can use these features.
7109            pkg.mOriginalPackages = null;
7110            pkg.mRealPackage = null;
7111            pkg.mAdoptPermissions = null;
7112        }
7113
7114        // writer
7115        synchronized (mPackages) {
7116            if (pkg.mSharedUserId != null) {
7117                suid = mSettings.getSharedUserLPw(pkg.mSharedUserId, 0, 0, true);
7118                if (suid == null) {
7119                    throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE,
7120                            "Creating application package " + pkg.packageName
7121                            + " for shared user failed");
7122                }
7123                if (DEBUG_PACKAGE_SCANNING) {
7124                    if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
7125                        Log.d(TAG, "Shared UserID " + pkg.mSharedUserId + " (uid=" + suid.userId
7126                                + "): packages=" + suid.packages);
7127                }
7128            }
7129
7130            // Check if we are renaming from an original package name.
7131            PackageSetting origPackage = null;
7132            String realName = null;
7133            if (pkg.mOriginalPackages != null) {
7134                // This package may need to be renamed to a previously
7135                // installed name.  Let's check on that...
7136                final String renamed = mSettings.mRenamedPackages.get(pkg.mRealPackage);
7137                if (pkg.mOriginalPackages.contains(renamed)) {
7138                    // This package had originally been installed as the
7139                    // original name, and we have already taken care of
7140                    // transitioning to the new one.  Just update the new
7141                    // one to continue using the old name.
7142                    realName = pkg.mRealPackage;
7143                    if (!pkg.packageName.equals(renamed)) {
7144                        // Callers into this function may have already taken
7145                        // care of renaming the package; only do it here if
7146                        // it is not already done.
7147                        pkg.setPackageName(renamed);
7148                    }
7149
7150                } else {
7151                    for (int i=pkg.mOriginalPackages.size()-1; i>=0; i--) {
7152                        if ((origPackage = mSettings.peekPackageLPr(
7153                                pkg.mOriginalPackages.get(i))) != null) {
7154                            // We do have the package already installed under its
7155                            // original name...  should we use it?
7156                            if (!verifyPackageUpdateLPr(origPackage, pkg)) {
7157                                // New package is not compatible with original.
7158                                origPackage = null;
7159                                continue;
7160                            } else if (origPackage.sharedUser != null) {
7161                                // Make sure uid is compatible between packages.
7162                                if (!origPackage.sharedUser.name.equals(pkg.mSharedUserId)) {
7163                                    Slog.w(TAG, "Unable to migrate data from " + origPackage.name
7164                                            + " to " + pkg.packageName + ": old uid "
7165                                            + origPackage.sharedUser.name
7166                                            + " differs from " + pkg.mSharedUserId);
7167                                    origPackage = null;
7168                                    continue;
7169                                }
7170                            } else {
7171                                if (DEBUG_UPGRADE) Log.v(TAG, "Renaming new package "
7172                                        + pkg.packageName + " to old name " + origPackage.name);
7173                            }
7174                            break;
7175                        }
7176                    }
7177                }
7178            }
7179
7180            if (mTransferedPackages.contains(pkg.packageName)) {
7181                Slog.w(TAG, "Package " + pkg.packageName
7182                        + " was transferred to another, but its .apk remains");
7183            }
7184
7185            // Just create the setting, don't add it yet. For already existing packages
7186            // the PkgSetting exists already and doesn't have to be created.
7187            pkgSetting = mSettings.getPackageLPw(pkg, origPackage, realName, suid, destCodeFile,
7188                    destResourceFile, pkg.applicationInfo.nativeLibraryRootDir,
7189                    pkg.applicationInfo.primaryCpuAbi,
7190                    pkg.applicationInfo.secondaryCpuAbi,
7191                    pkg.applicationInfo.flags, pkg.applicationInfo.privateFlags,
7192                    user, false);
7193            if (pkgSetting == null) {
7194                throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE,
7195                        "Creating application package " + pkg.packageName + " failed");
7196            }
7197
7198            if (pkgSetting.origPackage != null) {
7199                // If we are first transitioning from an original package,
7200                // fix up the new package's name now.  We need to do this after
7201                // looking up the package under its new name, so getPackageLP
7202                // can take care of fiddling things correctly.
7203                pkg.setPackageName(origPackage.name);
7204
7205                // File a report about this.
7206                String msg = "New package " + pkgSetting.realName
7207                        + " renamed to replace old package " + pkgSetting.name;
7208                reportSettingsProblem(Log.WARN, msg);
7209
7210                // Make a note of it.
7211                mTransferedPackages.add(origPackage.name);
7212
7213                // No longer need to retain this.
7214                pkgSetting.origPackage = null;
7215            }
7216
7217            if (realName != null) {
7218                // Make a note of it.
7219                mTransferedPackages.add(pkg.packageName);
7220            }
7221
7222            if (mSettings.isDisabledSystemPackageLPr(pkg.packageName)) {
7223                pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
7224            }
7225
7226            if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
7227                // Check all shared libraries and map to their actual file path.
7228                // We only do this here for apps not on a system dir, because those
7229                // are the only ones that can fail an install due to this.  We
7230                // will take care of the system apps by updating all of their
7231                // library paths after the scan is done.
7232                updateSharedLibrariesLPw(pkg, null);
7233            }
7234
7235            if (mFoundPolicyFile) {
7236                SELinuxMMAC.assignSeinfoValue(pkg);
7237            }
7238
7239            pkg.applicationInfo.uid = pkgSetting.appId;
7240            pkg.mExtras = pkgSetting;
7241            if (shouldCheckUpgradeKeySetLP(pkgSetting, scanFlags)) {
7242                if (checkUpgradeKeySetLP(pkgSetting, pkg)) {
7243                    // We just determined the app is signed correctly, so bring
7244                    // over the latest parsed certs.
7245                    pkgSetting.signatures.mSignatures = pkg.mSignatures;
7246                } else {
7247                    if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
7248                        throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
7249                                "Package " + pkg.packageName + " upgrade keys do not match the "
7250                                + "previously installed version");
7251                    } else {
7252                        pkgSetting.signatures.mSignatures = pkg.mSignatures;
7253                        String msg = "System package " + pkg.packageName
7254                            + " signature changed; retaining data.";
7255                        reportSettingsProblem(Log.WARN, msg);
7256                    }
7257                }
7258            } else {
7259                try {
7260                    verifySignaturesLP(pkgSetting, pkg);
7261                    // We just determined the app is signed correctly, so bring
7262                    // over the latest parsed certs.
7263                    pkgSetting.signatures.mSignatures = pkg.mSignatures;
7264                } catch (PackageManagerException e) {
7265                    if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
7266                        throw e;
7267                    }
7268                    // The signature has changed, but this package is in the system
7269                    // image...  let's recover!
7270                    pkgSetting.signatures.mSignatures = pkg.mSignatures;
7271                    // However...  if this package is part of a shared user, but it
7272                    // doesn't match the signature of the shared user, let's fail.
7273                    // What this means is that you can't change the signatures
7274                    // associated with an overall shared user, which doesn't seem all
7275                    // that unreasonable.
7276                    if (pkgSetting.sharedUser != null) {
7277                        if (compareSignatures(pkgSetting.sharedUser.signatures.mSignatures,
7278                                              pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) {
7279                            throw new PackageManagerException(
7280                                    INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES,
7281                                            "Signature mismatch for shared user: "
7282                                            + pkgSetting.sharedUser);
7283                        }
7284                    }
7285                    // File a report about this.
7286                    String msg = "System package " + pkg.packageName
7287                        + " signature changed; retaining data.";
7288                    reportSettingsProblem(Log.WARN, msg);
7289                }
7290            }
7291            // Verify that this new package doesn't have any content providers
7292            // that conflict with existing packages.  Only do this if the
7293            // package isn't already installed, since we don't want to break
7294            // things that are installed.
7295            if ((scanFlags & SCAN_NEW_INSTALL) != 0) {
7296                final int N = pkg.providers.size();
7297                int i;
7298                for (i=0; i<N; i++) {
7299                    PackageParser.Provider p = pkg.providers.get(i);
7300                    if (p.info.authority != null) {
7301                        String names[] = p.info.authority.split(";");
7302                        for (int j = 0; j < names.length; j++) {
7303                            if (mProvidersByAuthority.containsKey(names[j])) {
7304                                PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
7305                                final String otherPackageName =
7306                                        ((other != null && other.getComponentName() != null) ?
7307                                                other.getComponentName().getPackageName() : "?");
7308                                throw new PackageManagerException(
7309                                        INSTALL_FAILED_CONFLICTING_PROVIDER,
7310                                                "Can't install because provider name " + names[j]
7311                                                + " (in package " + pkg.applicationInfo.packageName
7312                                                + ") is already used by " + otherPackageName);
7313                            }
7314                        }
7315                    }
7316                }
7317            }
7318
7319            if (pkg.mAdoptPermissions != null) {
7320                // This package wants to adopt ownership of permissions from
7321                // another package.
7322                for (int i = pkg.mAdoptPermissions.size() - 1; i >= 0; i--) {
7323                    final String origName = pkg.mAdoptPermissions.get(i);
7324                    final PackageSetting orig = mSettings.peekPackageLPr(origName);
7325                    if (orig != null) {
7326                        if (verifyPackageUpdateLPr(orig, pkg)) {
7327                            Slog.i(TAG, "Adopting permissions from " + origName + " to "
7328                                    + pkg.packageName);
7329                            mSettings.transferPermissionsLPw(origName, pkg.packageName);
7330                        }
7331                    }
7332                }
7333            }
7334        }
7335
7336        final String pkgName = pkg.packageName;
7337
7338        final long scanFileTime = scanFile.lastModified();
7339        final boolean forceDex = (scanFlags & SCAN_FORCE_DEX) != 0;
7340        pkg.applicationInfo.processName = fixProcessName(
7341                pkg.applicationInfo.packageName,
7342                pkg.applicationInfo.processName,
7343                pkg.applicationInfo.uid);
7344
7345        if (pkg != mPlatformPackage) {
7346            // Get all of our default paths setup
7347            pkg.applicationInfo.initForUser(UserHandle.USER_SYSTEM);
7348        }
7349
7350        final String path = scanFile.getPath();
7351        final String cpuAbiOverride = deriveAbiOverride(pkg.cpuAbiOverride, pkgSetting);
7352
7353        if ((scanFlags & SCAN_NEW_INSTALL) == 0) {
7354            derivePackageAbi(pkg, scanFile, cpuAbiOverride, true /* extract libs */);
7355
7356            // Some system apps still use directory structure for native libraries
7357            // in which case we might end up not detecting abi solely based on apk
7358            // structure. Try to detect abi based on directory structure.
7359            if (isSystemApp(pkg) && !pkg.isUpdatedSystemApp() &&
7360                    pkg.applicationInfo.primaryCpuAbi == null) {
7361                setBundledAppAbisAndRoots(pkg, pkgSetting);
7362                setNativeLibraryPaths(pkg);
7363            }
7364
7365        } else {
7366            if ((scanFlags & SCAN_MOVE) != 0) {
7367                // We haven't run dex-opt for this move (since we've moved the compiled output too)
7368                // but we already have this packages package info in the PackageSetting. We just
7369                // use that and derive the native library path based on the new codepath.
7370                pkg.applicationInfo.primaryCpuAbi = pkgSetting.primaryCpuAbiString;
7371                pkg.applicationInfo.secondaryCpuAbi = pkgSetting.secondaryCpuAbiString;
7372            }
7373
7374            // Set native library paths again. For moves, the path will be updated based on the
7375            // ABIs we've determined above. For non-moves, the path will be updated based on the
7376            // ABIs we determined during compilation, but the path will depend on the final
7377            // package path (after the rename away from the stage path).
7378            setNativeLibraryPaths(pkg);
7379        }
7380
7381        // This is a special case for the "system" package, where the ABI is
7382        // dictated by the zygote configuration (and init.rc). We should keep track
7383        // of this ABI so that we can deal with "normal" applications that run under
7384        // the same UID correctly.
7385        if (mPlatformPackage == pkg) {
7386            pkg.applicationInfo.primaryCpuAbi = VMRuntime.getRuntime().is64Bit() ?
7387                    Build.SUPPORTED_64_BIT_ABIS[0] : Build.SUPPORTED_32_BIT_ABIS[0];
7388        }
7389
7390        // If there's a mismatch between the abi-override in the package setting
7391        // and the abiOverride specified for the install. Warn about this because we
7392        // would've already compiled the app without taking the package setting into
7393        // account.
7394        if ((scanFlags & SCAN_NO_DEX) == 0 && (scanFlags & SCAN_NEW_INSTALL) != 0) {
7395            if (cpuAbiOverride == null && pkgSetting.cpuAbiOverrideString != null) {
7396                Slog.w(TAG, "Ignoring persisted ABI override " + cpuAbiOverride +
7397                        " for package " + pkg.packageName);
7398            }
7399        }
7400
7401        pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
7402        pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
7403        pkgSetting.cpuAbiOverrideString = cpuAbiOverride;
7404
7405        // Copy the derived override back to the parsed package, so that we can
7406        // update the package settings accordingly.
7407        pkg.cpuAbiOverride = cpuAbiOverride;
7408
7409        if (DEBUG_ABI_SELECTION) {
7410            Slog.d(TAG, "Resolved nativeLibraryRoot for " + pkg.applicationInfo.packageName
7411                    + " to root=" + pkg.applicationInfo.nativeLibraryRootDir + ", isa="
7412                    + pkg.applicationInfo.nativeLibraryRootRequiresIsa);
7413        }
7414
7415        // Push the derived path down into PackageSettings so we know what to
7416        // clean up at uninstall time.
7417        pkgSetting.legacyNativeLibraryPathString = pkg.applicationInfo.nativeLibraryRootDir;
7418
7419        if (DEBUG_ABI_SELECTION) {
7420            Log.d(TAG, "Abis for package[" + pkg.packageName + "] are" +
7421                    " primary=" + pkg.applicationInfo.primaryCpuAbi +
7422                    " secondary=" + pkg.applicationInfo.secondaryCpuAbi);
7423        }
7424
7425        if ((scanFlags & SCAN_BOOTING) == 0 && pkgSetting.sharedUser != null) {
7426            // We don't do this here during boot because we can do it all
7427            // at once after scanning all existing packages.
7428            //
7429            // We also do this *before* we perform dexopt on this package, so that
7430            // we can avoid redundant dexopts, and also to make sure we've got the
7431            // code and package path correct.
7432            adjustCpuAbisForSharedUserLPw(pkgSetting.sharedUser.packages,
7433                    pkg, true /* boot complete */);
7434        }
7435
7436        if (mFactoryTest && pkg.requestedPermissions.contains(
7437                android.Manifest.permission.FACTORY_TEST)) {
7438            pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST;
7439        }
7440
7441        ArrayList<PackageParser.Package> clientLibPkgs = null;
7442
7443        // writer
7444        synchronized (mPackages) {
7445            if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
7446                // Only system apps can add new shared libraries.
7447                if (pkg.libraryNames != null) {
7448                    for (int i=0; i<pkg.libraryNames.size(); i++) {
7449                        String name = pkg.libraryNames.get(i);
7450                        boolean allowed = false;
7451                        if (pkg.isUpdatedSystemApp()) {
7452                            // New library entries can only be added through the
7453                            // system image.  This is important to get rid of a lot
7454                            // of nasty edge cases: for example if we allowed a non-
7455                            // system update of the app to add a library, then uninstalling
7456                            // the update would make the library go away, and assumptions
7457                            // we made such as through app install filtering would now
7458                            // have allowed apps on the device which aren't compatible
7459                            // with it.  Better to just have the restriction here, be
7460                            // conservative, and create many fewer cases that can negatively
7461                            // impact the user experience.
7462                            final PackageSetting sysPs = mSettings
7463                                    .getDisabledSystemPkgLPr(pkg.packageName);
7464                            if (sysPs.pkg != null && sysPs.pkg.libraryNames != null) {
7465                                for (int j=0; j<sysPs.pkg.libraryNames.size(); j++) {
7466                                    if (name.equals(sysPs.pkg.libraryNames.get(j))) {
7467                                        allowed = true;
7468                                        break;
7469                                    }
7470                                }
7471                            }
7472                        } else {
7473                            allowed = true;
7474                        }
7475                        if (allowed) {
7476                            if (!mSharedLibraries.containsKey(name)) {
7477                                mSharedLibraries.put(name, new SharedLibraryEntry(null, pkg.packageName));
7478                            } else if (!name.equals(pkg.packageName)) {
7479                                Slog.w(TAG, "Package " + pkg.packageName + " library "
7480                                        + name + " already exists; skipping");
7481                            }
7482                        } else {
7483                            Slog.w(TAG, "Package " + pkg.packageName + " declares lib "
7484                                    + name + " that is not declared on system image; skipping");
7485                        }
7486                    }
7487                    if ((scanFlags & SCAN_BOOTING) == 0) {
7488                        // If we are not booting, we need to update any applications
7489                        // that are clients of our shared library.  If we are booting,
7490                        // this will all be done once the scan is complete.
7491                        clientLibPkgs = updateAllSharedLibrariesLPw(pkg);
7492                    }
7493                }
7494            }
7495        }
7496
7497        // Request the ActivityManager to kill the process(only for existing packages)
7498        // so that we do not end up in a confused state while the user is still using the older
7499        // version of the application while the new one gets installed.
7500        if ((scanFlags & SCAN_REPLACING) != 0) {
7501            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "killApplication");
7502
7503            killApplication(pkg.applicationInfo.packageName,
7504                        pkg.applicationInfo.uid, "replace pkg");
7505
7506            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
7507        }
7508
7509        // Also need to kill any apps that are dependent on the library.
7510        if (clientLibPkgs != null) {
7511            for (int i=0; i<clientLibPkgs.size(); i++) {
7512                PackageParser.Package clientPkg = clientLibPkgs.get(i);
7513                killApplication(clientPkg.applicationInfo.packageName,
7514                        clientPkg.applicationInfo.uid, "update lib");
7515            }
7516        }
7517
7518        // Make sure we're not adding any bogus keyset info
7519        KeySetManagerService ksms = mSettings.mKeySetManagerService;
7520        ksms.assertScannedPackageValid(pkg);
7521
7522        // writer
7523        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");
7524
7525        boolean createIdmapFailed = false;
7526        synchronized (mPackages) {
7527            // We don't expect installation to fail beyond this point
7528
7529            // Add the new setting to mSettings
7530            mSettings.insertPackageSettingLPw(pkgSetting, pkg);
7531            // Add the new setting to mPackages
7532            mPackages.put(pkg.applicationInfo.packageName, pkg);
7533            // Make sure we don't accidentally delete its data.
7534            final Iterator<PackageCleanItem> iter = mSettings.mPackagesToBeCleaned.iterator();
7535            while (iter.hasNext()) {
7536                PackageCleanItem item = iter.next();
7537                if (pkgName.equals(item.packageName)) {
7538                    iter.remove();
7539                }
7540            }
7541
7542            // Take care of first install / last update times.
7543            if (currentTime != 0) {
7544                if (pkgSetting.firstInstallTime == 0) {
7545                    pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = currentTime;
7546                } else if ((scanFlags&SCAN_UPDATE_TIME) != 0) {
7547                    pkgSetting.lastUpdateTime = currentTime;
7548                }
7549            } else if (pkgSetting.firstInstallTime == 0) {
7550                // We need *something*.  Take time time stamp of the file.
7551                pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = scanFileTime;
7552            } else if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) != 0) {
7553                if (scanFileTime != pkgSetting.timeStamp) {
7554                    // A package on the system image has changed; consider this
7555                    // to be an update.
7556                    pkgSetting.lastUpdateTime = scanFileTime;
7557                }
7558            }
7559
7560            // Add the package's KeySets to the global KeySetManagerService
7561            ksms.addScannedPackageLPw(pkg);
7562
7563            int N = pkg.providers.size();
7564            StringBuilder r = null;
7565            int i;
7566            for (i=0; i<N; i++) {
7567                PackageParser.Provider p = pkg.providers.get(i);
7568                p.info.processName = fixProcessName(pkg.applicationInfo.processName,
7569                        p.info.processName, pkg.applicationInfo.uid);
7570                mProviders.addProvider(p);
7571                p.syncable = p.info.isSyncable;
7572                if (p.info.authority != null) {
7573                    String names[] = p.info.authority.split(";");
7574                    p.info.authority = null;
7575                    for (int j = 0; j < names.length; j++) {
7576                        if (j == 1 && p.syncable) {
7577                            // We only want the first authority for a provider to possibly be
7578                            // syncable, so if we already added this provider using a different
7579                            // authority clear the syncable flag. We copy the provider before
7580                            // changing it because the mProviders object contains a reference
7581                            // to a provider that we don't want to change.
7582                            // Only do this for the second authority since the resulting provider
7583                            // object can be the same for all future authorities for this provider.
7584                            p = new PackageParser.Provider(p);
7585                            p.syncable = false;
7586                        }
7587                        if (!mProvidersByAuthority.containsKey(names[j])) {
7588                            mProvidersByAuthority.put(names[j], p);
7589                            if (p.info.authority == null) {
7590                                p.info.authority = names[j];
7591                            } else {
7592                                p.info.authority = p.info.authority + ";" + names[j];
7593                            }
7594                            if (DEBUG_PACKAGE_SCANNING) {
7595                                if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
7596                                    Log.d(TAG, "Registered content provider: " + names[j]
7597                                            + ", className = " + p.info.name + ", isSyncable = "
7598                                            + p.info.isSyncable);
7599                            }
7600                        } else {
7601                            PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
7602                            Slog.w(TAG, "Skipping provider name " + names[j] +
7603                                    " (in package " + pkg.applicationInfo.packageName +
7604                                    "): name already used by "
7605                                    + ((other != null && other.getComponentName() != null)
7606                                            ? other.getComponentName().getPackageName() : "?"));
7607                        }
7608                    }
7609                }
7610                if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
7611                    if (r == null) {
7612                        r = new StringBuilder(256);
7613                    } else {
7614                        r.append(' ');
7615                    }
7616                    r.append(p.info.name);
7617                }
7618            }
7619            if (r != null) {
7620                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Providers: " + r);
7621            }
7622
7623            N = pkg.services.size();
7624            r = null;
7625            for (i=0; i<N; i++) {
7626                PackageParser.Service s = pkg.services.get(i);
7627                s.info.processName = fixProcessName(pkg.applicationInfo.processName,
7628                        s.info.processName, pkg.applicationInfo.uid);
7629                mServices.addService(s);
7630                if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
7631                    if (r == null) {
7632                        r = new StringBuilder(256);
7633                    } else {
7634                        r.append(' ');
7635                    }
7636                    r.append(s.info.name);
7637                }
7638            }
7639            if (r != null) {
7640                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Services: " + r);
7641            }
7642
7643            N = pkg.receivers.size();
7644            r = null;
7645            for (i=0; i<N; i++) {
7646                PackageParser.Activity a = pkg.receivers.get(i);
7647                a.info.processName = fixProcessName(pkg.applicationInfo.processName,
7648                        a.info.processName, pkg.applicationInfo.uid);
7649                mReceivers.addActivity(a, "receiver");
7650                if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
7651                    if (r == null) {
7652                        r = new StringBuilder(256);
7653                    } else {
7654                        r.append(' ');
7655                    }
7656                    r.append(a.info.name);
7657                }
7658            }
7659            if (r != null) {
7660                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Receivers: " + r);
7661            }
7662
7663            N = pkg.activities.size();
7664            r = null;
7665            for (i=0; i<N; i++) {
7666                PackageParser.Activity a = pkg.activities.get(i);
7667                a.info.processName = fixProcessName(pkg.applicationInfo.processName,
7668                        a.info.processName, pkg.applicationInfo.uid);
7669                mActivities.addActivity(a, "activity");
7670                if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
7671                    if (r == null) {
7672                        r = new StringBuilder(256);
7673                    } else {
7674                        r.append(' ');
7675                    }
7676                    r.append(a.info.name);
7677                }
7678            }
7679            if (r != null) {
7680                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Activities: " + r);
7681            }
7682
7683            N = pkg.permissionGroups.size();
7684            r = null;
7685            for (i=0; i<N; i++) {
7686                PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i);
7687                PackageParser.PermissionGroup cur = mPermissionGroups.get(pg.info.name);
7688                if (cur == null) {
7689                    mPermissionGroups.put(pg.info.name, pg);
7690                    if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
7691                        if (r == null) {
7692                            r = new StringBuilder(256);
7693                        } else {
7694                            r.append(' ');
7695                        }
7696                        r.append(pg.info.name);
7697                    }
7698                } else {
7699                    Slog.w(TAG, "Permission group " + pg.info.name + " from package "
7700                            + pg.info.packageName + " ignored: original from "
7701                            + cur.info.packageName);
7702                    if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
7703                        if (r == null) {
7704                            r = new StringBuilder(256);
7705                        } else {
7706                            r.append(' ');
7707                        }
7708                        r.append("DUP:");
7709                        r.append(pg.info.name);
7710                    }
7711                }
7712            }
7713            if (r != null) {
7714                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Permission Groups: " + r);
7715            }
7716
7717            N = pkg.permissions.size();
7718            r = null;
7719            for (i=0; i<N; i++) {
7720                PackageParser.Permission p = pkg.permissions.get(i);
7721
7722                // Assume by default that we did not install this permission into the system.
7723                p.info.flags &= ~PermissionInfo.FLAG_INSTALLED;
7724
7725                // Now that permission groups have a special meaning, we ignore permission
7726                // groups for legacy apps to prevent unexpected behavior. In particular,
7727                // permissions for one app being granted to someone just becuase they happen
7728                // to be in a group defined by another app (before this had no implications).
7729                if (pkg.applicationInfo.targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1) {
7730                    p.group = mPermissionGroups.get(p.info.group);
7731                    // Warn for a permission in an unknown group.
7732                    if (p.info.group != null && p.group == null) {
7733                        Slog.w(TAG, "Permission " + p.info.name + " from package "
7734                                + p.info.packageName + " in an unknown group " + p.info.group);
7735                    }
7736                }
7737
7738                ArrayMap<String, BasePermission> permissionMap =
7739                        p.tree ? mSettings.mPermissionTrees
7740                                : mSettings.mPermissions;
7741                BasePermission bp = permissionMap.get(p.info.name);
7742
7743                // Allow system apps to redefine non-system permissions
7744                if (bp != null && !Objects.equals(bp.sourcePackage, p.info.packageName)) {
7745                    final boolean currentOwnerIsSystem = (bp.perm != null
7746                            && isSystemApp(bp.perm.owner));
7747                    if (isSystemApp(p.owner)) {
7748                        if (bp.type == BasePermission.TYPE_BUILTIN && bp.perm == null) {
7749                            // It's a built-in permission and no owner, take ownership now
7750                            bp.packageSetting = pkgSetting;
7751                            bp.perm = p;
7752                            bp.uid = pkg.applicationInfo.uid;
7753                            bp.sourcePackage = p.info.packageName;
7754                            p.info.flags |= PermissionInfo.FLAG_INSTALLED;
7755                        } else if (!currentOwnerIsSystem) {
7756                            String msg = "New decl " + p.owner + " of permission  "
7757                                    + p.info.name + " is system; overriding " + bp.sourcePackage;
7758                            reportSettingsProblem(Log.WARN, msg);
7759                            bp = null;
7760                        }
7761                    }
7762                }
7763
7764                if (bp == null) {
7765                    bp = new BasePermission(p.info.name, p.info.packageName,
7766                            BasePermission.TYPE_NORMAL);
7767                    permissionMap.put(p.info.name, bp);
7768                }
7769
7770                if (bp.perm == null) {
7771                    if (bp.sourcePackage == null
7772                            || bp.sourcePackage.equals(p.info.packageName)) {
7773                        BasePermission tree = findPermissionTreeLP(p.info.name);
7774                        if (tree == null
7775                                || tree.sourcePackage.equals(p.info.packageName)) {
7776                            bp.packageSetting = pkgSetting;
7777                            bp.perm = p;
7778                            bp.uid = pkg.applicationInfo.uid;
7779                            bp.sourcePackage = p.info.packageName;
7780                            p.info.flags |= PermissionInfo.FLAG_INSTALLED;
7781                            if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
7782                                if (r == null) {
7783                                    r = new StringBuilder(256);
7784                                } else {
7785                                    r.append(' ');
7786                                }
7787                                r.append(p.info.name);
7788                            }
7789                        } else {
7790                            Slog.w(TAG, "Permission " + p.info.name + " from package "
7791                                    + p.info.packageName + " ignored: base tree "
7792                                    + tree.name + " is from package "
7793                                    + tree.sourcePackage);
7794                        }
7795                    } else {
7796                        Slog.w(TAG, "Permission " + p.info.name + " from package "
7797                                + p.info.packageName + " ignored: original from "
7798                                + bp.sourcePackage);
7799                    }
7800                } else if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
7801                    if (r == null) {
7802                        r = new StringBuilder(256);
7803                    } else {
7804                        r.append(' ');
7805                    }
7806                    r.append("DUP:");
7807                    r.append(p.info.name);
7808                }
7809                if (bp.perm == p) {
7810                    bp.protectionLevel = p.info.protectionLevel;
7811                }
7812            }
7813
7814            if (r != null) {
7815                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Permissions: " + r);
7816            }
7817
7818            N = pkg.instrumentation.size();
7819            r = null;
7820            for (i=0; i<N; i++) {
7821                PackageParser.Instrumentation a = pkg.instrumentation.get(i);
7822                a.info.packageName = pkg.applicationInfo.packageName;
7823                a.info.sourceDir = pkg.applicationInfo.sourceDir;
7824                a.info.publicSourceDir = pkg.applicationInfo.publicSourceDir;
7825                a.info.splitSourceDirs = pkg.applicationInfo.splitSourceDirs;
7826                a.info.splitPublicSourceDirs = pkg.applicationInfo.splitPublicSourceDirs;
7827                a.info.dataDir = pkg.applicationInfo.dataDir;
7828                a.info.deviceEncryptedDataDir = pkg.applicationInfo.deviceEncryptedDataDir;
7829                a.info.credentialEncryptedDataDir = pkg.applicationInfo.credentialEncryptedDataDir;
7830
7831                // TODO: Update instrumentation.nativeLibraryDir as well ? Does it
7832                // need other information about the application, like the ABI and what not ?
7833                a.info.nativeLibraryDir = pkg.applicationInfo.nativeLibraryDir;
7834                mInstrumentation.put(a.getComponentName(), a);
7835                if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
7836                    if (r == null) {
7837                        r = new StringBuilder(256);
7838                    } else {
7839                        r.append(' ');
7840                    }
7841                    r.append(a.info.name);
7842                }
7843            }
7844            if (r != null) {
7845                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Instrumentation: " + r);
7846            }
7847
7848            if (pkg.protectedBroadcasts != null) {
7849                N = pkg.protectedBroadcasts.size();
7850                for (i=0; i<N; i++) {
7851                    mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i));
7852                }
7853            }
7854
7855            pkgSetting.setTimeStamp(scanFileTime);
7856
7857            // Create idmap files for pairs of (packages, overlay packages).
7858            // Note: "android", ie framework-res.apk, is handled by native layers.
7859            if (pkg.mOverlayTarget != null) {
7860                // This is an overlay package.
7861                if (pkg.mOverlayTarget != null && !pkg.mOverlayTarget.equals("android")) {
7862                    if (!mOverlays.containsKey(pkg.mOverlayTarget)) {
7863                        mOverlays.put(pkg.mOverlayTarget,
7864                                new ArrayMap<String, PackageParser.Package>());
7865                    }
7866                    ArrayMap<String, PackageParser.Package> map = mOverlays.get(pkg.mOverlayTarget);
7867                    map.put(pkg.packageName, pkg);
7868                    PackageParser.Package orig = mPackages.get(pkg.mOverlayTarget);
7869                    if (orig != null && !createIdmapForPackagePairLI(orig, pkg)) {
7870                        createIdmapFailed = true;
7871                    }
7872                }
7873            } else if (mOverlays.containsKey(pkg.packageName) &&
7874                    !pkg.packageName.equals("android")) {
7875                // This is a regular package, with one or more known overlay packages.
7876                createIdmapsForPackageLI(pkg);
7877            }
7878        }
7879
7880        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
7881
7882        if (createIdmapFailed) {
7883            throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
7884                    "scanPackageLI failed to createIdmap");
7885        }
7886        return pkg;
7887    }
7888
7889    /**
7890     * Derive the ABI of a non-system package located at {@code scanFile}. This information
7891     * is derived purely on the basis of the contents of {@code scanFile} and
7892     * {@code cpuAbiOverride}.
7893     *
7894     * If {@code extractLibs} is true, native libraries are extracted from the app if required.
7895     */
7896    public void derivePackageAbi(PackageParser.Package pkg, File scanFile,
7897                                 String cpuAbiOverride, boolean extractLibs)
7898            throws PackageManagerException {
7899        // TODO: We can probably be smarter about this stuff. For installed apps,
7900        // we can calculate this information at install time once and for all. For
7901        // system apps, we can probably assume that this information doesn't change
7902        // after the first boot scan. As things stand, we do lots of unnecessary work.
7903
7904        // Give ourselves some initial paths; we'll come back for another
7905        // pass once we've determined ABI below.
7906        setNativeLibraryPaths(pkg);
7907
7908        // We would never need to extract libs for forward-locked and external packages,
7909        // since the container service will do it for us. We shouldn't attempt to
7910        // extract libs from system app when it was not updated.
7911        if (pkg.isForwardLocked() || pkg.applicationInfo.isExternalAsec() ||
7912                (isSystemApp(pkg) && !pkg.isUpdatedSystemApp())) {
7913            extractLibs = false;
7914        }
7915
7916        final String nativeLibraryRootStr = pkg.applicationInfo.nativeLibraryRootDir;
7917        final boolean useIsaSpecificSubdirs = pkg.applicationInfo.nativeLibraryRootRequiresIsa;
7918
7919        NativeLibraryHelper.Handle handle = null;
7920        try {
7921            handle = NativeLibraryHelper.Handle.create(pkg);
7922            // TODO(multiArch): This can be null for apps that didn't go through the
7923            // usual installation process. We can calculate it again, like we
7924            // do during install time.
7925            //
7926            // TODO(multiArch): Why do we need to rescan ASEC apps again ? It seems totally
7927            // unnecessary.
7928            final File nativeLibraryRoot = new File(nativeLibraryRootStr);
7929
7930            // Null out the abis so that they can be recalculated.
7931            pkg.applicationInfo.primaryCpuAbi = null;
7932            pkg.applicationInfo.secondaryCpuAbi = null;
7933            if (isMultiArch(pkg.applicationInfo)) {
7934                // Warn if we've set an abiOverride for multi-lib packages..
7935                // By definition, we need to copy both 32 and 64 bit libraries for
7936                // such packages.
7937                if (pkg.cpuAbiOverride != null
7938                        && !NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(pkg.cpuAbiOverride)) {
7939                    Slog.w(TAG, "Ignoring abiOverride for multi arch application.");
7940                }
7941
7942                int abi32 = PackageManager.NO_NATIVE_LIBRARIES;
7943                int abi64 = PackageManager.NO_NATIVE_LIBRARIES;
7944                if (Build.SUPPORTED_32_BIT_ABIS.length > 0) {
7945                    if (extractLibs) {
7946                        abi32 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
7947                                nativeLibraryRoot, Build.SUPPORTED_32_BIT_ABIS,
7948                                useIsaSpecificSubdirs);
7949                    } else {
7950                        abi32 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_32_BIT_ABIS);
7951                    }
7952                }
7953
7954                maybeThrowExceptionForMultiArchCopy(
7955                        "Error unpackaging 32 bit native libs for multiarch app.", abi32);
7956
7957                if (Build.SUPPORTED_64_BIT_ABIS.length > 0) {
7958                    if (extractLibs) {
7959                        abi64 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
7960                                nativeLibraryRoot, Build.SUPPORTED_64_BIT_ABIS,
7961                                useIsaSpecificSubdirs);
7962                    } else {
7963                        abi64 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_64_BIT_ABIS);
7964                    }
7965                }
7966
7967                maybeThrowExceptionForMultiArchCopy(
7968                        "Error unpackaging 64 bit native libs for multiarch app.", abi64);
7969
7970                if (abi64 >= 0) {
7971                    pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[abi64];
7972                }
7973
7974                if (abi32 >= 0) {
7975                    final String abi = Build.SUPPORTED_32_BIT_ABIS[abi32];
7976                    if (abi64 >= 0) {
7977                        pkg.applicationInfo.secondaryCpuAbi = abi;
7978                    } else {
7979                        pkg.applicationInfo.primaryCpuAbi = abi;
7980                    }
7981                }
7982            } else {
7983                String[] abiList = (cpuAbiOverride != null) ?
7984                        new String[] { cpuAbiOverride } : Build.SUPPORTED_ABIS;
7985
7986                // Enable gross and lame hacks for apps that are built with old
7987                // SDK tools. We must scan their APKs for renderscript bitcode and
7988                // not launch them if it's present. Don't bother checking on devices
7989                // that don't have 64 bit support.
7990                boolean needsRenderScriptOverride = false;
7991                if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && cpuAbiOverride == null &&
7992                        NativeLibraryHelper.hasRenderscriptBitcode(handle)) {
7993                    abiList = Build.SUPPORTED_32_BIT_ABIS;
7994                    needsRenderScriptOverride = true;
7995                }
7996
7997                final int copyRet;
7998                if (extractLibs) {
7999                    copyRet = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
8000                            nativeLibraryRoot, abiList, useIsaSpecificSubdirs);
8001                } else {
8002                    copyRet = NativeLibraryHelper.findSupportedAbi(handle, abiList);
8003                }
8004
8005                if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) {
8006                    throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
8007                            "Error unpackaging native libs for app, errorCode=" + copyRet);
8008                }
8009
8010                if (copyRet >= 0) {
8011                    pkg.applicationInfo.primaryCpuAbi = abiList[copyRet];
8012                } else if (copyRet == PackageManager.NO_NATIVE_LIBRARIES && cpuAbiOverride != null) {
8013                    pkg.applicationInfo.primaryCpuAbi = cpuAbiOverride;
8014                } else if (needsRenderScriptOverride) {
8015                    pkg.applicationInfo.primaryCpuAbi = abiList[0];
8016                }
8017            }
8018        } catch (IOException ioe) {
8019            Slog.e(TAG, "Unable to get canonical file " + ioe.toString());
8020        } finally {
8021            IoUtils.closeQuietly(handle);
8022        }
8023
8024        // Now that we've calculated the ABIs and determined if it's an internal app,
8025        // we will go ahead and populate the nativeLibraryPath.
8026        setNativeLibraryPaths(pkg);
8027    }
8028
8029    /**
8030     * Adjusts ABIs for a set of packages belonging to a shared user so that they all match.
8031     * i.e, so that all packages can be run inside a single process if required.
8032     *
8033     * Optionally, callers can pass in a parsed package via {@code newPackage} in which case
8034     * this function will either try and make the ABI for all packages in {@code packagesForUser}
8035     * match {@code scannedPackage} or will update the ABI of {@code scannedPackage} to match
8036     * the ABI selected for {@code packagesForUser}. This variant is used when installing or
8037     * updating a package that belongs to a shared user.
8038     *
8039     * NOTE: We currently only match for the primary CPU abi string. Matching the secondary
8040     * adds unnecessary complexity.
8041     */
8042    private void adjustCpuAbisForSharedUserLPw(Set<PackageSetting> packagesForUser,
8043            PackageParser.Package scannedPackage, boolean bootComplete) {
8044        String requiredInstructionSet = null;
8045        if (scannedPackage != null && scannedPackage.applicationInfo.primaryCpuAbi != null) {
8046            requiredInstructionSet = VMRuntime.getInstructionSet(
8047                     scannedPackage.applicationInfo.primaryCpuAbi);
8048        }
8049
8050        PackageSetting requirer = null;
8051        for (PackageSetting ps : packagesForUser) {
8052            // If packagesForUser contains scannedPackage, we skip it. This will happen
8053            // when scannedPackage is an update of an existing package. Without this check,
8054            // we will never be able to change the ABI of any package belonging to a shared
8055            // user, even if it's compatible with other packages.
8056            if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
8057                if (ps.primaryCpuAbiString == null) {
8058                    continue;
8059                }
8060
8061                final String instructionSet = VMRuntime.getInstructionSet(ps.primaryCpuAbiString);
8062                if (requiredInstructionSet != null && !instructionSet.equals(requiredInstructionSet)) {
8063                    // We have a mismatch between instruction sets (say arm vs arm64) warn about
8064                    // this but there's not much we can do.
8065                    String errorMessage = "Instruction set mismatch, "
8066                            + ((requirer == null) ? "[caller]" : requirer)
8067                            + " requires " + requiredInstructionSet + " whereas " + ps
8068                            + " requires " + instructionSet;
8069                    Slog.w(TAG, errorMessage);
8070                }
8071
8072                if (requiredInstructionSet == null) {
8073                    requiredInstructionSet = instructionSet;
8074                    requirer = ps;
8075                }
8076            }
8077        }
8078
8079        if (requiredInstructionSet != null) {
8080            String adjustedAbi;
8081            if (requirer != null) {
8082                // requirer != null implies that either scannedPackage was null or that scannedPackage
8083                // did not require an ABI, in which case we have to adjust scannedPackage to match
8084                // the ABI of the set (which is the same as requirer's ABI)
8085                adjustedAbi = requirer.primaryCpuAbiString;
8086                if (scannedPackage != null) {
8087                    scannedPackage.applicationInfo.primaryCpuAbi = adjustedAbi;
8088                }
8089            } else {
8090                // requirer == null implies that we're updating all ABIs in the set to
8091                // match scannedPackage.
8092                adjustedAbi =  scannedPackage.applicationInfo.primaryCpuAbi;
8093            }
8094
8095            for (PackageSetting ps : packagesForUser) {
8096                if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
8097                    if (ps.primaryCpuAbiString != null) {
8098                        continue;
8099                    }
8100
8101                    ps.primaryCpuAbiString = adjustedAbi;
8102                    if (ps.pkg != null && ps.pkg.applicationInfo != null &&
8103                            !TextUtils.equals(adjustedAbi, ps.pkg.applicationInfo.primaryCpuAbi)) {
8104                        ps.pkg.applicationInfo.primaryCpuAbi = adjustedAbi;
8105                        Slog.i(TAG, "Adjusting ABI for " + ps.name + " to " + adjustedAbi
8106                                + " (requirer="
8107                                + (requirer == null ? "null" : requirer.pkg.packageName)
8108                                + ", scannedPackage="
8109                                + (scannedPackage != null ? scannedPackage.packageName : "null")
8110                                + ")");
8111                        try {
8112                            mInstaller.rmdex(ps.codePathString,
8113                                    getDexCodeInstructionSet(getPreferredInstructionSet()));
8114                        } catch (InstallerException ignored) {
8115                        }
8116                    }
8117                }
8118            }
8119        }
8120    }
8121
8122    private void setUpCustomResolverActivity(PackageParser.Package pkg) {
8123        synchronized (mPackages) {
8124            mResolverReplaced = true;
8125            // Set up information for custom user intent resolution activity.
8126            mResolveActivity.applicationInfo = pkg.applicationInfo;
8127            mResolveActivity.name = mCustomResolverComponentName.getClassName();
8128            mResolveActivity.packageName = pkg.applicationInfo.packageName;
8129            mResolveActivity.processName = pkg.applicationInfo.packageName;
8130            mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
8131            mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS |
8132                    ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
8133            mResolveActivity.theme = 0;
8134            mResolveActivity.exported = true;
8135            mResolveActivity.enabled = true;
8136            mResolveInfo.activityInfo = mResolveActivity;
8137            mResolveInfo.priority = 0;
8138            mResolveInfo.preferredOrder = 0;
8139            mResolveInfo.match = 0;
8140            mResolveComponentName = mCustomResolverComponentName;
8141            Slog.i(TAG, "Replacing default ResolverActivity with custom activity: " +
8142                    mResolveComponentName);
8143        }
8144    }
8145
8146    private void setUpEphemeralInstallerActivityLP(ComponentName installerComponent) {
8147        final PackageParser.Package pkg = mPackages.get(installerComponent.getPackageName());
8148
8149        // Set up information for ephemeral installer activity
8150        mEphemeralInstallerActivity.applicationInfo = pkg.applicationInfo;
8151        mEphemeralInstallerActivity.name = mEphemeralInstallerComponent.getClassName();
8152        mEphemeralInstallerActivity.packageName = pkg.applicationInfo.packageName;
8153        mEphemeralInstallerActivity.processName = pkg.applicationInfo.packageName;
8154        mEphemeralInstallerActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
8155        mEphemeralInstallerActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS |
8156                ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
8157        mEphemeralInstallerActivity.theme = 0;
8158        mEphemeralInstallerActivity.exported = true;
8159        mEphemeralInstallerActivity.enabled = true;
8160        mEphemeralInstallerInfo.activityInfo = mEphemeralInstallerActivity;
8161        mEphemeralInstallerInfo.priority = 0;
8162        mEphemeralInstallerInfo.preferredOrder = 0;
8163        mEphemeralInstallerInfo.match = 0;
8164
8165        if (DEBUG_EPHEMERAL) {
8166            Slog.d(TAG, "Set ephemeral installer activity: " + mEphemeralInstallerComponent);
8167        }
8168    }
8169
8170    private static String calculateBundledApkRoot(final String codePathString) {
8171        final File codePath = new File(codePathString);
8172        final File codeRoot;
8173        if (FileUtils.contains(Environment.getRootDirectory(), codePath)) {
8174            codeRoot = Environment.getRootDirectory();
8175        } else if (FileUtils.contains(Environment.getOemDirectory(), codePath)) {
8176            codeRoot = Environment.getOemDirectory();
8177        } else if (FileUtils.contains(Environment.getVendorDirectory(), codePath)) {
8178            codeRoot = Environment.getVendorDirectory();
8179        } else {
8180            // Unrecognized code path; take its top real segment as the apk root:
8181            // e.g. /something/app/blah.apk => /something
8182            try {
8183                File f = codePath.getCanonicalFile();
8184                File parent = f.getParentFile();    // non-null because codePath is a file
8185                File tmp;
8186                while ((tmp = parent.getParentFile()) != null) {
8187                    f = parent;
8188                    parent = tmp;
8189                }
8190                codeRoot = f;
8191                Slog.w(TAG, "Unrecognized code path "
8192                        + codePath + " - using " + codeRoot);
8193            } catch (IOException e) {
8194                // Can't canonicalize the code path -- shenanigans?
8195                Slog.w(TAG, "Can't canonicalize code path " + codePath);
8196                return Environment.getRootDirectory().getPath();
8197            }
8198        }
8199        return codeRoot.getPath();
8200    }
8201
8202    /**
8203     * Derive and set the location of native libraries for the given package,
8204     * which varies depending on where and how the package was installed.
8205     */
8206    private void setNativeLibraryPaths(PackageParser.Package pkg) {
8207        final ApplicationInfo info = pkg.applicationInfo;
8208        final String codePath = pkg.codePath;
8209        final File codeFile = new File(codePath);
8210        final boolean bundledApp = info.isSystemApp() && !info.isUpdatedSystemApp();
8211        final boolean asecApp = info.isForwardLocked() || info.isExternalAsec();
8212
8213        info.nativeLibraryRootDir = null;
8214        info.nativeLibraryRootRequiresIsa = false;
8215        info.nativeLibraryDir = null;
8216        info.secondaryNativeLibraryDir = null;
8217
8218        if (isApkFile(codeFile)) {
8219            // Monolithic install
8220            if (bundledApp) {
8221                // If "/system/lib64/apkname" exists, assume that is the per-package
8222                // native library directory to use; otherwise use "/system/lib/apkname".
8223                final String apkRoot = calculateBundledApkRoot(info.sourceDir);
8224                final boolean is64Bit = VMRuntime.is64BitInstructionSet(
8225                        getPrimaryInstructionSet(info));
8226
8227                // This is a bundled system app so choose the path based on the ABI.
8228                // if it's a 64 bit abi, use lib64 otherwise use lib32. Note that this
8229                // is just the default path.
8230                final String apkName = deriveCodePathName(codePath);
8231                final String libDir = is64Bit ? LIB64_DIR_NAME : LIB_DIR_NAME;
8232                info.nativeLibraryRootDir = Environment.buildPath(new File(apkRoot), libDir,
8233                        apkName).getAbsolutePath();
8234
8235                if (info.secondaryCpuAbi != null) {
8236                    final String secondaryLibDir = is64Bit ? LIB_DIR_NAME : LIB64_DIR_NAME;
8237                    info.secondaryNativeLibraryDir = Environment.buildPath(new File(apkRoot),
8238                            secondaryLibDir, apkName).getAbsolutePath();
8239                }
8240            } else if (asecApp) {
8241                info.nativeLibraryRootDir = new File(codeFile.getParentFile(), LIB_DIR_NAME)
8242                        .getAbsolutePath();
8243            } else {
8244                final String apkName = deriveCodePathName(codePath);
8245                info.nativeLibraryRootDir = new File(mAppLib32InstallDir, apkName)
8246                        .getAbsolutePath();
8247            }
8248
8249            info.nativeLibraryRootRequiresIsa = false;
8250            info.nativeLibraryDir = info.nativeLibraryRootDir;
8251        } else {
8252            // Cluster install
8253            info.nativeLibraryRootDir = new File(codeFile, LIB_DIR_NAME).getAbsolutePath();
8254            info.nativeLibraryRootRequiresIsa = true;
8255
8256            info.nativeLibraryDir = new File(info.nativeLibraryRootDir,
8257                    getPrimaryInstructionSet(info)).getAbsolutePath();
8258
8259            if (info.secondaryCpuAbi != null) {
8260                info.secondaryNativeLibraryDir = new File(info.nativeLibraryRootDir,
8261                        VMRuntime.getInstructionSet(info.secondaryCpuAbi)).getAbsolutePath();
8262            }
8263        }
8264    }
8265
8266    /**
8267     * Calculate the abis and roots for a bundled app. These can uniquely
8268     * be determined from the contents of the system partition, i.e whether
8269     * it contains 64 or 32 bit shared libraries etc. We do not validate any
8270     * of this information, and instead assume that the system was built
8271     * sensibly.
8272     */
8273    private void setBundledAppAbisAndRoots(PackageParser.Package pkg,
8274                                           PackageSetting pkgSetting) {
8275        final String apkName = deriveCodePathName(pkg.applicationInfo.getCodePath());
8276
8277        // If "/system/lib64/apkname" exists, assume that is the per-package
8278        // native library directory to use; otherwise use "/system/lib/apkname".
8279        final String apkRoot = calculateBundledApkRoot(pkg.applicationInfo.sourceDir);
8280        setBundledAppAbi(pkg, apkRoot, apkName);
8281        // pkgSetting might be null during rescan following uninstall of updates
8282        // to a bundled app, so accommodate that possibility.  The settings in
8283        // that case will be established later from the parsed package.
8284        //
8285        // If the settings aren't null, sync them up with what we've just derived.
8286        // note that apkRoot isn't stored in the package settings.
8287        if (pkgSetting != null) {
8288            pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
8289            pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
8290        }
8291    }
8292
8293    /**
8294     * Deduces the ABI of a bundled app and sets the relevant fields on the
8295     * parsed pkg object.
8296     *
8297     * @param apkRoot the root of the installed apk, something like {@code /system} or {@code /oem}
8298     *        under which system libraries are installed.
8299     * @param apkName the name of the installed package.
8300     */
8301    private static void setBundledAppAbi(PackageParser.Package pkg, String apkRoot, String apkName) {
8302        final File codeFile = new File(pkg.codePath);
8303
8304        final boolean has64BitLibs;
8305        final boolean has32BitLibs;
8306        if (isApkFile(codeFile)) {
8307            // Monolithic install
8308            has64BitLibs = (new File(apkRoot, new File(LIB64_DIR_NAME, apkName).getPath())).exists();
8309            has32BitLibs = (new File(apkRoot, new File(LIB_DIR_NAME, apkName).getPath())).exists();
8310        } else {
8311            // Cluster install
8312            final File rootDir = new File(codeFile, LIB_DIR_NAME);
8313            if (!ArrayUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS)
8314                    && !TextUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS[0])) {
8315                final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_64_BIT_ABIS[0]);
8316                has64BitLibs = (new File(rootDir, isa)).exists();
8317            } else {
8318                has64BitLibs = false;
8319            }
8320            if (!ArrayUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS)
8321                    && !TextUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS[0])) {
8322                final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_32_BIT_ABIS[0]);
8323                has32BitLibs = (new File(rootDir, isa)).exists();
8324            } else {
8325                has32BitLibs = false;
8326            }
8327        }
8328
8329        if (has64BitLibs && !has32BitLibs) {
8330            // The package has 64 bit libs, but not 32 bit libs. Its primary
8331            // ABI should be 64 bit. We can safely assume here that the bundled
8332            // native libraries correspond to the most preferred ABI in the list.
8333
8334            pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
8335            pkg.applicationInfo.secondaryCpuAbi = null;
8336        } else if (has32BitLibs && !has64BitLibs) {
8337            // The package has 32 bit libs but not 64 bit libs. Its primary
8338            // ABI should be 32 bit.
8339
8340            pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
8341            pkg.applicationInfo.secondaryCpuAbi = null;
8342        } else if (has32BitLibs && has64BitLibs) {
8343            // The application has both 64 and 32 bit bundled libraries. We check
8344            // here that the app declares multiArch support, and warn if it doesn't.
8345            //
8346            // We will be lenient here and record both ABIs. The primary will be the
8347            // ABI that's higher on the list, i.e, a device that's configured to prefer
8348            // 64 bit apps will see a 64 bit primary ABI,
8349
8350            if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) == 0) {
8351                Slog.e(TAG, "Package " + pkg + " has multiple bundled libs, but is not multiarch.");
8352            }
8353
8354            if (VMRuntime.is64BitInstructionSet(getPreferredInstructionSet())) {
8355                pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
8356                pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
8357            } else {
8358                pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
8359                pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
8360            }
8361        } else {
8362            pkg.applicationInfo.primaryCpuAbi = null;
8363            pkg.applicationInfo.secondaryCpuAbi = null;
8364        }
8365    }
8366
8367    private void killApplication(String pkgName, int appId, String reason) {
8368        // Request the ActivityManager to kill the process(only for existing packages)
8369        // so that we do not end up in a confused state while the user is still using the older
8370        // version of the application while the new one gets installed.
8371        IActivityManager am = ActivityManagerNative.getDefault();
8372        if (am != null) {
8373            try {
8374                am.killApplicationWithAppId(pkgName, appId, reason);
8375            } catch (RemoteException e) {
8376            }
8377        }
8378    }
8379
8380    void removePackageLI(PackageSetting ps, boolean chatty) {
8381        if (DEBUG_INSTALL) {
8382            if (chatty)
8383                Log.d(TAG, "Removing package " + ps.name);
8384        }
8385
8386        // writer
8387        synchronized (mPackages) {
8388            mPackages.remove(ps.name);
8389            final PackageParser.Package pkg = ps.pkg;
8390            if (pkg != null) {
8391                cleanPackageDataStructuresLILPw(pkg, chatty);
8392            }
8393        }
8394    }
8395
8396    void removeInstalledPackageLI(PackageParser.Package pkg, boolean chatty) {
8397        if (DEBUG_INSTALL) {
8398            if (chatty)
8399                Log.d(TAG, "Removing package " + pkg.applicationInfo.packageName);
8400        }
8401
8402        // writer
8403        synchronized (mPackages) {
8404            mPackages.remove(pkg.applicationInfo.packageName);
8405            cleanPackageDataStructuresLILPw(pkg, chatty);
8406        }
8407    }
8408
8409    void cleanPackageDataStructuresLILPw(PackageParser.Package pkg, boolean chatty) {
8410        int N = pkg.providers.size();
8411        StringBuilder r = null;
8412        int i;
8413        for (i=0; i<N; i++) {
8414            PackageParser.Provider p = pkg.providers.get(i);
8415            mProviders.removeProvider(p);
8416            if (p.info.authority == null) {
8417
8418                /* There was another ContentProvider with this authority when
8419                 * this app was installed so this authority is null,
8420                 * Ignore it as we don't have to unregister the provider.
8421                 */
8422                continue;
8423            }
8424            String names[] = p.info.authority.split(";");
8425            for (int j = 0; j < names.length; j++) {
8426                if (mProvidersByAuthority.get(names[j]) == p) {
8427                    mProvidersByAuthority.remove(names[j]);
8428                    if (DEBUG_REMOVE) {
8429                        if (chatty)
8430                            Log.d(TAG, "Unregistered content provider: " + names[j]
8431                                    + ", className = " + p.info.name + ", isSyncable = "
8432                                    + p.info.isSyncable);
8433                    }
8434                }
8435            }
8436            if (DEBUG_REMOVE && chatty) {
8437                if (r == null) {
8438                    r = new StringBuilder(256);
8439                } else {
8440                    r.append(' ');
8441                }
8442                r.append(p.info.name);
8443            }
8444        }
8445        if (r != null) {
8446            if (DEBUG_REMOVE) Log.d(TAG, "  Providers: " + r);
8447        }
8448
8449        N = pkg.services.size();
8450        r = null;
8451        for (i=0; i<N; i++) {
8452            PackageParser.Service s = pkg.services.get(i);
8453            mServices.removeService(s);
8454            if (chatty) {
8455                if (r == null) {
8456                    r = new StringBuilder(256);
8457                } else {
8458                    r.append(' ');
8459                }
8460                r.append(s.info.name);
8461            }
8462        }
8463        if (r != null) {
8464            if (DEBUG_REMOVE) Log.d(TAG, "  Services: " + r);
8465        }
8466
8467        N = pkg.receivers.size();
8468        r = null;
8469        for (i=0; i<N; i++) {
8470            PackageParser.Activity a = pkg.receivers.get(i);
8471            mReceivers.removeActivity(a, "receiver");
8472            if (DEBUG_REMOVE && chatty) {
8473                if (r == null) {
8474                    r = new StringBuilder(256);
8475                } else {
8476                    r.append(' ');
8477                }
8478                r.append(a.info.name);
8479            }
8480        }
8481        if (r != null) {
8482            if (DEBUG_REMOVE) Log.d(TAG, "  Receivers: " + r);
8483        }
8484
8485        N = pkg.activities.size();
8486        r = null;
8487        for (i=0; i<N; i++) {
8488            PackageParser.Activity a = pkg.activities.get(i);
8489            mActivities.removeActivity(a, "activity");
8490            if (DEBUG_REMOVE && chatty) {
8491                if (r == null) {
8492                    r = new StringBuilder(256);
8493                } else {
8494                    r.append(' ');
8495                }
8496                r.append(a.info.name);
8497            }
8498        }
8499        if (r != null) {
8500            if (DEBUG_REMOVE) Log.d(TAG, "  Activities: " + r);
8501        }
8502
8503        N = pkg.permissions.size();
8504        r = null;
8505        for (i=0; i<N; i++) {
8506            PackageParser.Permission p = pkg.permissions.get(i);
8507            BasePermission bp = mSettings.mPermissions.get(p.info.name);
8508            if (bp == null) {
8509                bp = mSettings.mPermissionTrees.get(p.info.name);
8510            }
8511            if (bp != null && bp.perm == p) {
8512                bp.perm = null;
8513                if (DEBUG_REMOVE && chatty) {
8514                    if (r == null) {
8515                        r = new StringBuilder(256);
8516                    } else {
8517                        r.append(' ');
8518                    }
8519                    r.append(p.info.name);
8520                }
8521            }
8522            if ((p.info.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
8523                ArraySet<String> appOpPkgs = mAppOpPermissionPackages.get(p.info.name);
8524                if (appOpPkgs != null) {
8525                    appOpPkgs.remove(pkg.packageName);
8526                }
8527            }
8528        }
8529        if (r != null) {
8530            if (DEBUG_REMOVE) Log.d(TAG, "  Permissions: " + r);
8531        }
8532
8533        N = pkg.requestedPermissions.size();
8534        r = null;
8535        for (i=0; i<N; i++) {
8536            String perm = pkg.requestedPermissions.get(i);
8537            BasePermission bp = mSettings.mPermissions.get(perm);
8538            if (bp != null && (bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
8539                ArraySet<String> appOpPkgs = mAppOpPermissionPackages.get(perm);
8540                if (appOpPkgs != null) {
8541                    appOpPkgs.remove(pkg.packageName);
8542                    if (appOpPkgs.isEmpty()) {
8543                        mAppOpPermissionPackages.remove(perm);
8544                    }
8545                }
8546            }
8547        }
8548        if (r != null) {
8549            if (DEBUG_REMOVE) Log.d(TAG, "  Permissions: " + r);
8550        }
8551
8552        N = pkg.instrumentation.size();
8553        r = null;
8554        for (i=0; i<N; i++) {
8555            PackageParser.Instrumentation a = pkg.instrumentation.get(i);
8556            mInstrumentation.remove(a.getComponentName());
8557            if (DEBUG_REMOVE && chatty) {
8558                if (r == null) {
8559                    r = new StringBuilder(256);
8560                } else {
8561                    r.append(' ');
8562                }
8563                r.append(a.info.name);
8564            }
8565        }
8566        if (r != null) {
8567            if (DEBUG_REMOVE) Log.d(TAG, "  Instrumentation: " + r);
8568        }
8569
8570        r = null;
8571        if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
8572            // Only system apps can hold shared libraries.
8573            if (pkg.libraryNames != null) {
8574                for (i=0; i<pkg.libraryNames.size(); i++) {
8575                    String name = pkg.libraryNames.get(i);
8576                    SharedLibraryEntry cur = mSharedLibraries.get(name);
8577                    if (cur != null && cur.apk != null && cur.apk.equals(pkg.packageName)) {
8578                        mSharedLibraries.remove(name);
8579                        if (DEBUG_REMOVE && chatty) {
8580                            if (r == null) {
8581                                r = new StringBuilder(256);
8582                            } else {
8583                                r.append(' ');
8584                            }
8585                            r.append(name);
8586                        }
8587                    }
8588                }
8589            }
8590        }
8591        if (r != null) {
8592            if (DEBUG_REMOVE) Log.d(TAG, "  Libraries: " + r);
8593        }
8594    }
8595
8596    private static boolean hasPermission(PackageParser.Package pkgInfo, String perm) {
8597        for (int i=pkgInfo.permissions.size()-1; i>=0; i--) {
8598            if (pkgInfo.permissions.get(i).info.name.equals(perm)) {
8599                return true;
8600            }
8601        }
8602        return false;
8603    }
8604
8605    static final int UPDATE_PERMISSIONS_ALL = 1<<0;
8606    static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1<<1;
8607    static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1<<2;
8608
8609    private void updatePermissionsLPw(String changingPkg, PackageParser.Package pkgInfo,
8610            int flags) {
8611        final String volumeUuid = (pkgInfo != null) ? getVolumeUuidForPackage(pkgInfo) : null;
8612        updatePermissionsLPw(changingPkg, pkgInfo, volumeUuid, flags);
8613    }
8614
8615    private void updatePermissionsLPw(String changingPkg,
8616            PackageParser.Package pkgInfo, String replaceVolumeUuid, int flags) {
8617        // Make sure there are no dangling permission trees.
8618        Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator();
8619        while (it.hasNext()) {
8620            final BasePermission bp = it.next();
8621            if (bp.packageSetting == null) {
8622                // We may not yet have parsed the package, so just see if
8623                // we still know about its settings.
8624                bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage);
8625            }
8626            if (bp.packageSetting == null) {
8627                Slog.w(TAG, "Removing dangling permission tree: " + bp.name
8628                        + " from package " + bp.sourcePackage);
8629                it.remove();
8630            } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) {
8631                if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
8632                    Slog.i(TAG, "Removing old permission tree: " + bp.name
8633                            + " from package " + bp.sourcePackage);
8634                    flags |= UPDATE_PERMISSIONS_ALL;
8635                    it.remove();
8636                }
8637            }
8638        }
8639
8640        // Make sure all dynamic permissions have been assigned to a package,
8641        // and make sure there are no dangling permissions.
8642        it = mSettings.mPermissions.values().iterator();
8643        while (it.hasNext()) {
8644            final BasePermission bp = it.next();
8645            if (bp.type == BasePermission.TYPE_DYNAMIC) {
8646                if (DEBUG_SETTINGS) Log.v(TAG, "Dynamic permission: name="
8647                        + bp.name + " pkg=" + bp.sourcePackage
8648                        + " info=" + bp.pendingInfo);
8649                if (bp.packageSetting == null && bp.pendingInfo != null) {
8650                    final BasePermission tree = findPermissionTreeLP(bp.name);
8651                    if (tree != null && tree.perm != null) {
8652                        bp.packageSetting = tree.packageSetting;
8653                        bp.perm = new PackageParser.Permission(tree.perm.owner,
8654                                new PermissionInfo(bp.pendingInfo));
8655                        bp.perm.info.packageName = tree.perm.info.packageName;
8656                        bp.perm.info.name = bp.name;
8657                        bp.uid = tree.uid;
8658                    }
8659                }
8660            }
8661            if (bp.packageSetting == null) {
8662                // We may not yet have parsed the package, so just see if
8663                // we still know about its settings.
8664                bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage);
8665            }
8666            if (bp.packageSetting == null) {
8667                Slog.w(TAG, "Removing dangling permission: " + bp.name
8668                        + " from package " + bp.sourcePackage);
8669                it.remove();
8670            } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) {
8671                if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
8672                    Slog.i(TAG, "Removing old permission: " + bp.name
8673                            + " from package " + bp.sourcePackage);
8674                    flags |= UPDATE_PERMISSIONS_ALL;
8675                    it.remove();
8676                }
8677            }
8678        }
8679
8680        // Now update the permissions for all packages, in particular
8681        // replace the granted permissions of the system packages.
8682        if ((flags&UPDATE_PERMISSIONS_ALL) != 0) {
8683            for (PackageParser.Package pkg : mPackages.values()) {
8684                if (pkg != pkgInfo) {
8685                    // Only replace for packages on requested volume
8686                    final String volumeUuid = getVolumeUuidForPackage(pkg);
8687                    final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_ALL) != 0)
8688                            && Objects.equals(replaceVolumeUuid, volumeUuid);
8689                    grantPermissionsLPw(pkg, replace, changingPkg);
8690                }
8691            }
8692        }
8693
8694        if (pkgInfo != null) {
8695            // Only replace for packages on requested volume
8696            final String volumeUuid = getVolumeUuidForPackage(pkgInfo);
8697            final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_PKG) != 0)
8698                    && Objects.equals(replaceVolumeUuid, volumeUuid);
8699            grantPermissionsLPw(pkgInfo, replace, changingPkg);
8700        }
8701    }
8702
8703    private void grantPermissionsLPw(PackageParser.Package pkg, boolean replace,
8704            String packageOfInterest) {
8705        // IMPORTANT: There are two types of permissions: install and runtime.
8706        // Install time permissions are granted when the app is installed to
8707        // all device users and users added in the future. Runtime permissions
8708        // are granted at runtime explicitly to specific users. Normal and signature
8709        // protected permissions are install time permissions. Dangerous permissions
8710        // are install permissions if the app's target SDK is Lollipop MR1 or older,
8711        // otherwise they are runtime permissions. This function does not manage
8712        // runtime permissions except for the case an app targeting Lollipop MR1
8713        // being upgraded to target a newer SDK, in which case dangerous permissions
8714        // are transformed from install time to runtime ones.
8715
8716        final PackageSetting ps = (PackageSetting) pkg.mExtras;
8717        if (ps == null) {
8718            return;
8719        }
8720
8721        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "grantPermissions");
8722
8723        PermissionsState permissionsState = ps.getPermissionsState();
8724        PermissionsState origPermissions = permissionsState;
8725
8726        final int[] currentUserIds = UserManagerService.getInstance().getUserIds();
8727
8728        boolean runtimePermissionsRevoked = false;
8729        int[] changedRuntimePermissionUserIds = EMPTY_INT_ARRAY;
8730
8731        boolean changedInstallPermission = false;
8732
8733        if (replace) {
8734            ps.installPermissionsFixed = false;
8735            if (!ps.isSharedUser()) {
8736                origPermissions = new PermissionsState(permissionsState);
8737                permissionsState.reset();
8738            } else {
8739                // We need to know only about runtime permission changes since the
8740                // calling code always writes the install permissions state but
8741                // the runtime ones are written only if changed. The only cases of
8742                // changed runtime permissions here are promotion of an install to
8743                // runtime and revocation of a runtime from a shared user.
8744                changedRuntimePermissionUserIds = revokeUnusedSharedUserPermissionsLPw(
8745                        ps.sharedUser, UserManagerService.getInstance().getUserIds());
8746                if (!ArrayUtils.isEmpty(changedRuntimePermissionUserIds)) {
8747                    runtimePermissionsRevoked = true;
8748                }
8749            }
8750        }
8751
8752        permissionsState.setGlobalGids(mGlobalGids);
8753
8754        final int N = pkg.requestedPermissions.size();
8755        for (int i=0; i<N; i++) {
8756            final String name = pkg.requestedPermissions.get(i);
8757            final BasePermission bp = mSettings.mPermissions.get(name);
8758
8759            if (DEBUG_INSTALL) {
8760                Log.i(TAG, "Package " + pkg.packageName + " checking " + name + ": " + bp);
8761            }
8762
8763            if (bp == null || bp.packageSetting == null) {
8764                if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) {
8765                    Slog.w(TAG, "Unknown permission " + name
8766                            + " in package " + pkg.packageName);
8767                }
8768                continue;
8769            }
8770
8771            final String perm = bp.name;
8772            boolean allowedSig = false;
8773            int grant = GRANT_DENIED;
8774
8775            // Keep track of app op permissions.
8776            if ((bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
8777                ArraySet<String> pkgs = mAppOpPermissionPackages.get(bp.name);
8778                if (pkgs == null) {
8779                    pkgs = new ArraySet<>();
8780                    mAppOpPermissionPackages.put(bp.name, pkgs);
8781                }
8782                pkgs.add(pkg.packageName);
8783            }
8784
8785            final int level = bp.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE;
8786            final boolean appSupportsRuntimePermissions = pkg.applicationInfo.targetSdkVersion
8787                    >= Build.VERSION_CODES.M;
8788            switch (level) {
8789                case PermissionInfo.PROTECTION_NORMAL: {
8790                    // For all apps normal permissions are install time ones.
8791                    grant = GRANT_INSTALL;
8792                } break;
8793
8794                case PermissionInfo.PROTECTION_DANGEROUS: {
8795                    // If a permission review is required for legacy apps we represent
8796                    // their permissions as always granted runtime ones since we need
8797                    // to keep the review required permission flag per user while an
8798                    // install permission's state is shared across all users.
8799                    if (!appSupportsRuntimePermissions && !Build.PERMISSIONS_REVIEW_REQUIRED) {
8800                        // For legacy apps dangerous permissions are install time ones.
8801                        grant = GRANT_INSTALL;
8802                    } else if (origPermissions.hasInstallPermission(bp.name)) {
8803                        // For legacy apps that became modern, install becomes runtime.
8804                        grant = GRANT_UPGRADE;
8805                    } else if (mPromoteSystemApps
8806                            && isSystemApp(ps)
8807                            && mExistingSystemPackages.contains(ps.name)) {
8808                        // For legacy system apps, install becomes runtime.
8809                        // We cannot check hasInstallPermission() for system apps since those
8810                        // permissions were granted implicitly and not persisted pre-M.
8811                        grant = GRANT_UPGRADE;
8812                    } else {
8813                        // For modern apps keep runtime permissions unchanged.
8814                        grant = GRANT_RUNTIME;
8815                    }
8816                } break;
8817
8818                case PermissionInfo.PROTECTION_SIGNATURE: {
8819                    // For all apps signature permissions are install time ones.
8820                    allowedSig = grantSignaturePermission(perm, pkg, bp, origPermissions);
8821                    if (allowedSig) {
8822                        grant = GRANT_INSTALL;
8823                    }
8824                } break;
8825            }
8826
8827            if (DEBUG_INSTALL) {
8828                Log.i(TAG, "Package " + pkg.packageName + " granting " + perm);
8829            }
8830
8831            if (grant != GRANT_DENIED) {
8832                if (!isSystemApp(ps) && ps.installPermissionsFixed) {
8833                    // If this is an existing, non-system package, then
8834                    // we can't add any new permissions to it.
8835                    if (!allowedSig && !origPermissions.hasInstallPermission(perm)) {
8836                        // Except...  if this is a permission that was added
8837                        // to the platform (note: need to only do this when
8838                        // updating the platform).
8839                        if (!isNewPlatformPermissionForPackage(perm, pkg)) {
8840                            grant = GRANT_DENIED;
8841                        }
8842                    }
8843                }
8844
8845                switch (grant) {
8846                    case GRANT_INSTALL: {
8847                        // Revoke this as runtime permission to handle the case of
8848                        // a runtime permission being downgraded to an install one. Also in permission review mode we keep dangerous permissions for legacy apps
8849                        for (int userId : UserManagerService.getInstance().getUserIds()) {
8850                            if (origPermissions.getRuntimePermissionState(
8851                                    bp.name, userId) != null) {
8852                                // Revoke the runtime permission and clear the flags.
8853                                origPermissions.revokeRuntimePermission(bp, userId);
8854                                origPermissions.updatePermissionFlags(bp, userId,
8855                                      PackageManager.MASK_PERMISSION_FLAGS, 0);
8856                                // If we revoked a permission permission, we have to write.
8857                                changedRuntimePermissionUserIds = ArrayUtils.appendInt(
8858                                        changedRuntimePermissionUserIds, userId);
8859                            }
8860                        }
8861                        // Grant an install permission.
8862                        if (permissionsState.grantInstallPermission(bp) !=
8863                                PermissionsState.PERMISSION_OPERATION_FAILURE) {
8864                            changedInstallPermission = true;
8865                        }
8866                    } break;
8867
8868                    case GRANT_RUNTIME: {
8869                        // Grant previously granted runtime permissions.
8870                        for (int userId : UserManagerService.getInstance().getUserIds()) {
8871                            PermissionState permissionState = origPermissions
8872                                    .getRuntimePermissionState(bp.name, userId);
8873                            int flags = permissionState != null
8874                                    ? permissionState.getFlags() : 0;
8875                            if (origPermissions.hasRuntimePermission(bp.name, userId)) {
8876                                if (permissionsState.grantRuntimePermission(bp, userId) ==
8877                                        PermissionsState.PERMISSION_OPERATION_FAILURE) {
8878                                    // If we cannot put the permission as it was, we have to write.
8879                                    changedRuntimePermissionUserIds = ArrayUtils.appendInt(
8880                                            changedRuntimePermissionUserIds, userId);
8881                                }
8882                                // If the app supports runtime permissions no need for a review.
8883                                if (Build.PERMISSIONS_REVIEW_REQUIRED
8884                                        && appSupportsRuntimePermissions
8885                                        && (flags & PackageManager
8886                                                .FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
8887                                    flags &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
8888                                    // Since we changed the flags, we have to write.
8889                                    changedRuntimePermissionUserIds = ArrayUtils.appendInt(
8890                                            changedRuntimePermissionUserIds, userId);
8891                                }
8892                            } else if (Build.PERMISSIONS_REVIEW_REQUIRED
8893                                    && !appSupportsRuntimePermissions) {
8894                                // For legacy apps that need a permission review, every new
8895                                // runtime permission is granted but it is pending a review.
8896                                if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) {
8897                                    permissionsState.grantRuntimePermission(bp, userId);
8898                                    flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
8899                                    // We changed the permission and flags, hence have to write.
8900                                    changedRuntimePermissionUserIds = ArrayUtils.appendInt(
8901                                            changedRuntimePermissionUserIds, userId);
8902                                }
8903                            }
8904                            // Propagate the permission flags.
8905                            permissionsState.updatePermissionFlags(bp, userId, flags, flags);
8906                        }
8907                    } break;
8908
8909                    case GRANT_UPGRADE: {
8910                        // Grant runtime permissions for a previously held install permission.
8911                        PermissionState permissionState = origPermissions
8912                                .getInstallPermissionState(bp.name);
8913                        final int flags = permissionState != null ? permissionState.getFlags() : 0;
8914
8915                        if (origPermissions.revokeInstallPermission(bp)
8916                                != PermissionsState.PERMISSION_OPERATION_FAILURE) {
8917                            // We will be transferring the permission flags, so clear them.
8918                            origPermissions.updatePermissionFlags(bp, UserHandle.USER_ALL,
8919                                    PackageManager.MASK_PERMISSION_FLAGS, 0);
8920                            changedInstallPermission = true;
8921                        }
8922
8923                        // If the permission is not to be promoted to runtime we ignore it and
8924                        // also its other flags as they are not applicable to install permissions.
8925                        if ((flags & PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE) == 0) {
8926                            for (int userId : currentUserIds) {
8927                                if (permissionsState.grantRuntimePermission(bp, userId) !=
8928                                        PermissionsState.PERMISSION_OPERATION_FAILURE) {
8929                                    // Transfer the permission flags.
8930                                    permissionsState.updatePermissionFlags(bp, userId,
8931                                            flags, flags);
8932                                    // If we granted the permission, we have to write.
8933                                    changedRuntimePermissionUserIds = ArrayUtils.appendInt(
8934                                            changedRuntimePermissionUserIds, userId);
8935                                }
8936                            }
8937                        }
8938                    } break;
8939
8940                    default: {
8941                        if (packageOfInterest == null
8942                                || packageOfInterest.equals(pkg.packageName)) {
8943                            Slog.w(TAG, "Not granting permission " + perm
8944                                    + " to package " + pkg.packageName
8945                                    + " because it was previously installed without");
8946                        }
8947                    } break;
8948                }
8949            } else {
8950                if (permissionsState.revokeInstallPermission(bp) !=
8951                        PermissionsState.PERMISSION_OPERATION_FAILURE) {
8952                    // Also drop the permission flags.
8953                    permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
8954                            PackageManager.MASK_PERMISSION_FLAGS, 0);
8955                    changedInstallPermission = true;
8956                    Slog.i(TAG, "Un-granting permission " + perm
8957                            + " from package " + pkg.packageName
8958                            + " (protectionLevel=" + bp.protectionLevel
8959                            + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
8960                            + ")");
8961                } else if ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) == 0) {
8962                    // Don't print warning for app op permissions, since it is fine for them
8963                    // not to be granted, there is a UI for the user to decide.
8964                    if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) {
8965                        Slog.w(TAG, "Not granting permission " + perm
8966                                + " to package " + pkg.packageName
8967                                + " (protectionLevel=" + bp.protectionLevel
8968                                + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
8969                                + ")");
8970                    }
8971                }
8972            }
8973        }
8974
8975        if ((changedInstallPermission || replace) && !ps.installPermissionsFixed &&
8976                !isSystemApp(ps) || isUpdatedSystemApp(ps)){
8977            // This is the first that we have heard about this package, so the
8978            // permissions we have now selected are fixed until explicitly
8979            // changed.
8980            ps.installPermissionsFixed = true;
8981        }
8982
8983        // Persist the runtime permissions state for users with changes. If permissions
8984        // were revoked because no app in the shared user declares them we have to
8985        // write synchronously to avoid losing runtime permissions state.
8986        for (int userId : changedRuntimePermissionUserIds) {
8987            mSettings.writeRuntimePermissionsForUserLPr(userId, runtimePermissionsRevoked);
8988        }
8989
8990        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8991    }
8992
8993    private boolean isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg) {
8994        boolean allowed = false;
8995        final int NP = PackageParser.NEW_PERMISSIONS.length;
8996        for (int ip=0; ip<NP; ip++) {
8997            final PackageParser.NewPermissionInfo npi
8998                    = PackageParser.NEW_PERMISSIONS[ip];
8999            if (npi.name.equals(perm)
9000                    && pkg.applicationInfo.targetSdkVersion < npi.sdkVersion) {
9001                allowed = true;
9002                Log.i(TAG, "Auto-granting " + perm + " to old pkg "
9003                        + pkg.packageName);
9004                break;
9005            }
9006        }
9007        return allowed;
9008    }
9009
9010    private boolean grantSignaturePermission(String perm, PackageParser.Package pkg,
9011            BasePermission bp, PermissionsState origPermissions) {
9012        boolean allowed;
9013        allowed = (compareSignatures(
9014                bp.packageSetting.signatures.mSignatures, pkg.mSignatures)
9015                        == PackageManager.SIGNATURE_MATCH)
9016                || (compareSignatures(mPlatformPackage.mSignatures, pkg.mSignatures)
9017                        == PackageManager.SIGNATURE_MATCH);
9018        if (!allowed && (bp.protectionLevel
9019                & PermissionInfo.PROTECTION_FLAG_PRIVILEGED) != 0) {
9020            if (isSystemApp(pkg)) {
9021                // For updated system applications, a system permission
9022                // is granted only if it had been defined by the original application.
9023                if (pkg.isUpdatedSystemApp()) {
9024                    final PackageSetting sysPs = mSettings
9025                            .getDisabledSystemPkgLPr(pkg.packageName);
9026                    if (sysPs.getPermissionsState().hasInstallPermission(perm)) {
9027                        // If the original was granted this permission, we take
9028                        // that grant decision as read and propagate it to the
9029                        // update.
9030                        if (sysPs.isPrivileged()) {
9031                            allowed = true;
9032                        }
9033                    } else {
9034                        // The system apk may have been updated with an older
9035                        // version of the one on the data partition, but which
9036                        // granted a new system permission that it didn't have
9037                        // before.  In this case we do want to allow the app to
9038                        // now get the new permission if the ancestral apk is
9039                        // privileged to get it.
9040                        if (sysPs.pkg != null && sysPs.isPrivileged()) {
9041                            for (int j=0;
9042                                    j<sysPs.pkg.requestedPermissions.size(); j++) {
9043                                if (perm.equals(
9044                                        sysPs.pkg.requestedPermissions.get(j))) {
9045                                    allowed = true;
9046                                    break;
9047                                }
9048                            }
9049                        }
9050                    }
9051                } else {
9052                    allowed = isPrivilegedApp(pkg);
9053                }
9054            }
9055        }
9056        if (!allowed) {
9057            if (!allowed && (bp.protectionLevel
9058                    & PermissionInfo.PROTECTION_FLAG_PRE23) != 0
9059                    && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
9060                // If this was a previously normal/dangerous permission that got moved
9061                // to a system permission as part of the runtime permission redesign, then
9062                // we still want to blindly grant it to old apps.
9063                allowed = true;
9064            }
9065            if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_INSTALLER) != 0
9066                    && pkg.packageName.equals(mRequiredInstallerPackage)) {
9067                // If this permission is to be granted to the system installer and
9068                // this app is an installer, then it gets the permission.
9069                allowed = true;
9070            }
9071            if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_VERIFIER) != 0
9072                    && pkg.packageName.equals(mRequiredVerifierPackage)) {
9073                // If this permission is to be granted to the system verifier and
9074                // this app is a verifier, then it gets the permission.
9075                allowed = true;
9076            }
9077            if (!allowed && (bp.protectionLevel
9078                    & PermissionInfo.PROTECTION_FLAG_PREINSTALLED) != 0
9079                    && isSystemApp(pkg)) {
9080                // Any pre-installed system app is allowed to get this permission.
9081                allowed = true;
9082            }
9083            if (!allowed && (bp.protectionLevel
9084                    & PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0) {
9085                // For development permissions, a development permission
9086                // is granted only if it was already granted.
9087                allowed = origPermissions.hasInstallPermission(perm);
9088            }
9089        }
9090        return allowed;
9091    }
9092
9093    final class ActivityIntentResolver
9094            extends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo> {
9095        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
9096                boolean defaultOnly, int userId) {
9097            if (!sUserManager.exists(userId)) return null;
9098            mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
9099            return super.queryIntent(intent, resolvedType, defaultOnly, userId);
9100        }
9101
9102        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
9103                int userId) {
9104            if (!sUserManager.exists(userId)) return null;
9105            mFlags = flags;
9106            return super.queryIntent(intent, resolvedType,
9107                    (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId);
9108        }
9109
9110        public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
9111                int flags, ArrayList<PackageParser.Activity> packageActivities, int userId) {
9112            if (!sUserManager.exists(userId)) return null;
9113            if (packageActivities == null) {
9114                return null;
9115            }
9116            mFlags = flags;
9117            final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0;
9118            final int N = packageActivities.size();
9119            ArrayList<PackageParser.ActivityIntentInfo[]> listCut =
9120                new ArrayList<PackageParser.ActivityIntentInfo[]>(N);
9121
9122            ArrayList<PackageParser.ActivityIntentInfo> intentFilters;
9123            for (int i = 0; i < N; ++i) {
9124                intentFilters = packageActivities.get(i).intents;
9125                if (intentFilters != null && intentFilters.size() > 0) {
9126                    PackageParser.ActivityIntentInfo[] array =
9127                            new PackageParser.ActivityIntentInfo[intentFilters.size()];
9128                    intentFilters.toArray(array);
9129                    listCut.add(array);
9130                }
9131            }
9132            return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
9133        }
9134
9135        public final void addActivity(PackageParser.Activity a, String type) {
9136            final boolean systemApp = a.info.applicationInfo.isSystemApp();
9137            mActivities.put(a.getComponentName(), a);
9138            if (DEBUG_SHOW_INFO)
9139                Log.v(
9140                TAG, "  " + type + " " +
9141                (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel : a.info.name) + ":");
9142            if (DEBUG_SHOW_INFO)
9143                Log.v(TAG, "    Class=" + a.info.name);
9144            final int NI = a.intents.size();
9145            for (int j=0; j<NI; j++) {
9146                PackageParser.ActivityIntentInfo intent = a.intents.get(j);
9147                if (!systemApp && intent.getPriority() > 0 && "activity".equals(type)) {
9148                    intent.setPriority(0);
9149                    Log.w(TAG, "Package " + a.info.applicationInfo.packageName + " has activity "
9150                            + a.className + " with priority > 0, forcing to 0");
9151                }
9152                if (DEBUG_SHOW_INFO) {
9153                    Log.v(TAG, "    IntentFilter:");
9154                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
9155                }
9156                if (!intent.debugCheck()) {
9157                    Log.w(TAG, "==> For Activity " + a.info.name);
9158                }
9159                addFilter(intent);
9160            }
9161        }
9162
9163        public final void removeActivity(PackageParser.Activity a, String type) {
9164            mActivities.remove(a.getComponentName());
9165            if (DEBUG_SHOW_INFO) {
9166                Log.v(TAG, "  " + type + " "
9167                        + (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel
9168                                : a.info.name) + ":");
9169                Log.v(TAG, "    Class=" + a.info.name);
9170            }
9171            final int NI = a.intents.size();
9172            for (int j=0; j<NI; j++) {
9173                PackageParser.ActivityIntentInfo intent = a.intents.get(j);
9174                if (DEBUG_SHOW_INFO) {
9175                    Log.v(TAG, "    IntentFilter:");
9176                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
9177                }
9178                removeFilter(intent);
9179            }
9180        }
9181
9182        @Override
9183        protected boolean allowFilterResult(
9184                PackageParser.ActivityIntentInfo filter, List<ResolveInfo> dest) {
9185            ActivityInfo filterAi = filter.activity.info;
9186            for (int i=dest.size()-1; i>=0; i--) {
9187                ActivityInfo destAi = dest.get(i).activityInfo;
9188                if (destAi.name == filterAi.name
9189                        && destAi.packageName == filterAi.packageName) {
9190                    return false;
9191                }
9192            }
9193            return true;
9194        }
9195
9196        @Override
9197        protected ActivityIntentInfo[] newArray(int size) {
9198            return new ActivityIntentInfo[size];
9199        }
9200
9201        @Override
9202        protected boolean isFilterStopped(PackageParser.ActivityIntentInfo filter, int userId) {
9203            if (!sUserManager.exists(userId)) return true;
9204            PackageParser.Package p = filter.activity.owner;
9205            if (p != null) {
9206                PackageSetting ps = (PackageSetting)p.mExtras;
9207                if (ps != null) {
9208                    // System apps are never considered stopped for purposes of
9209                    // filtering, because there may be no way for the user to
9210                    // actually re-launch them.
9211                    return (ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0
9212                            && ps.getStopped(userId);
9213                }
9214            }
9215            return false;
9216        }
9217
9218        @Override
9219        protected boolean isPackageForFilter(String packageName,
9220                PackageParser.ActivityIntentInfo info) {
9221            return packageName.equals(info.activity.owner.packageName);
9222        }
9223
9224        @Override
9225        protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info,
9226                int match, int userId) {
9227            if (!sUserManager.exists(userId)) return null;
9228            if (!mSettings.isEnabledAndMatchLPr(info.activity.info, mFlags, userId)) {
9229                return null;
9230            }
9231            final PackageParser.Activity activity = info.activity;
9232            PackageSetting ps = (PackageSetting) activity.owner.mExtras;
9233            if (ps == null) {
9234                return null;
9235            }
9236            ActivityInfo ai = PackageParser.generateActivityInfo(activity, mFlags,
9237                    ps.readUserState(userId), userId);
9238            if (ai == null) {
9239                return null;
9240            }
9241            final ResolveInfo res = new ResolveInfo();
9242            res.activityInfo = ai;
9243            if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
9244                res.filter = info;
9245            }
9246            if (info != null) {
9247                res.handleAllWebDataURI = info.handleAllWebDataURI();
9248            }
9249            res.priority = info.getPriority();
9250            res.preferredOrder = activity.owner.mPreferredOrder;
9251            //System.out.println("Result: " + res.activityInfo.className +
9252            //                   " = " + res.priority);
9253            res.match = match;
9254            res.isDefault = info.hasDefault;
9255            res.labelRes = info.labelRes;
9256            res.nonLocalizedLabel = info.nonLocalizedLabel;
9257            if (userNeedsBadging(userId)) {
9258                res.noResourceId = true;
9259            } else {
9260                res.icon = info.icon;
9261            }
9262            res.iconResourceId = info.icon;
9263            res.system = res.activityInfo.applicationInfo.isSystemApp();
9264            return res;
9265        }
9266
9267        @Override
9268        protected void sortResults(List<ResolveInfo> results) {
9269            Collections.sort(results, mResolvePrioritySorter);
9270        }
9271
9272        @Override
9273        protected void dumpFilter(PrintWriter out, String prefix,
9274                PackageParser.ActivityIntentInfo filter) {
9275            out.print(prefix); out.print(
9276                    Integer.toHexString(System.identityHashCode(filter.activity)));
9277                    out.print(' ');
9278                    filter.activity.printComponentShortName(out);
9279                    out.print(" filter ");
9280                    out.println(Integer.toHexString(System.identityHashCode(filter)));
9281        }
9282
9283        @Override
9284        protected Object filterToLabel(PackageParser.ActivityIntentInfo filter) {
9285            return filter.activity;
9286        }
9287
9288        protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
9289            PackageParser.Activity activity = (PackageParser.Activity)label;
9290            out.print(prefix); out.print(
9291                    Integer.toHexString(System.identityHashCode(activity)));
9292                    out.print(' ');
9293                    activity.printComponentShortName(out);
9294            if (count > 1) {
9295                out.print(" ("); out.print(count); out.print(" filters)");
9296            }
9297            out.println();
9298        }
9299
9300//        List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) {
9301//            final Iterator<ResolveInfo> i = resolveInfoList.iterator();
9302//            final List<ResolveInfo> retList = Lists.newArrayList();
9303//            while (i.hasNext()) {
9304//                final ResolveInfo resolveInfo = i.next();
9305//                if (isEnabledLP(resolveInfo.activityInfo)) {
9306//                    retList.add(resolveInfo);
9307//                }
9308//            }
9309//            return retList;
9310//        }
9311
9312        // Keys are String (activity class name), values are Activity.
9313        private final ArrayMap<ComponentName, PackageParser.Activity> mActivities
9314                = new ArrayMap<ComponentName, PackageParser.Activity>();
9315        private int mFlags;
9316    }
9317
9318    private final class ServiceIntentResolver
9319            extends IntentResolver<PackageParser.ServiceIntentInfo, ResolveInfo> {
9320        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
9321                boolean defaultOnly, int userId) {
9322            mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
9323            return super.queryIntent(intent, resolvedType, defaultOnly, userId);
9324        }
9325
9326        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
9327                int userId) {
9328            if (!sUserManager.exists(userId)) return null;
9329            mFlags = flags;
9330            return super.queryIntent(intent, resolvedType,
9331                    (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId);
9332        }
9333
9334        public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
9335                int flags, ArrayList<PackageParser.Service> packageServices, int userId) {
9336            if (!sUserManager.exists(userId)) return null;
9337            if (packageServices == null) {
9338                return null;
9339            }
9340            mFlags = flags;
9341            final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0;
9342            final int N = packageServices.size();
9343            ArrayList<PackageParser.ServiceIntentInfo[]> listCut =
9344                new ArrayList<PackageParser.ServiceIntentInfo[]>(N);
9345
9346            ArrayList<PackageParser.ServiceIntentInfo> intentFilters;
9347            for (int i = 0; i < N; ++i) {
9348                intentFilters = packageServices.get(i).intents;
9349                if (intentFilters != null && intentFilters.size() > 0) {
9350                    PackageParser.ServiceIntentInfo[] array =
9351                            new PackageParser.ServiceIntentInfo[intentFilters.size()];
9352                    intentFilters.toArray(array);
9353                    listCut.add(array);
9354                }
9355            }
9356            return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
9357        }
9358
9359        public final void addService(PackageParser.Service s) {
9360            mServices.put(s.getComponentName(), s);
9361            if (DEBUG_SHOW_INFO) {
9362                Log.v(TAG, "  "
9363                        + (s.info.nonLocalizedLabel != null
9364                        ? s.info.nonLocalizedLabel : s.info.name) + ":");
9365                Log.v(TAG, "    Class=" + s.info.name);
9366            }
9367            final int NI = s.intents.size();
9368            int j;
9369            for (j=0; j<NI; j++) {
9370                PackageParser.ServiceIntentInfo intent = s.intents.get(j);
9371                if (DEBUG_SHOW_INFO) {
9372                    Log.v(TAG, "    IntentFilter:");
9373                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
9374                }
9375                if (!intent.debugCheck()) {
9376                    Log.w(TAG, "==> For Service " + s.info.name);
9377                }
9378                addFilter(intent);
9379            }
9380        }
9381
9382        public final void removeService(PackageParser.Service s) {
9383            mServices.remove(s.getComponentName());
9384            if (DEBUG_SHOW_INFO) {
9385                Log.v(TAG, "  " + (s.info.nonLocalizedLabel != null
9386                        ? s.info.nonLocalizedLabel : s.info.name) + ":");
9387                Log.v(TAG, "    Class=" + s.info.name);
9388            }
9389            final int NI = s.intents.size();
9390            int j;
9391            for (j=0; j<NI; j++) {
9392                PackageParser.ServiceIntentInfo intent = s.intents.get(j);
9393                if (DEBUG_SHOW_INFO) {
9394                    Log.v(TAG, "    IntentFilter:");
9395                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
9396                }
9397                removeFilter(intent);
9398            }
9399        }
9400
9401        @Override
9402        protected boolean allowFilterResult(
9403                PackageParser.ServiceIntentInfo filter, List<ResolveInfo> dest) {
9404            ServiceInfo filterSi = filter.service.info;
9405            for (int i=dest.size()-1; i>=0; i--) {
9406                ServiceInfo destAi = dest.get(i).serviceInfo;
9407                if (destAi.name == filterSi.name
9408                        && destAi.packageName == filterSi.packageName) {
9409                    return false;
9410                }
9411            }
9412            return true;
9413        }
9414
9415        @Override
9416        protected PackageParser.ServiceIntentInfo[] newArray(int size) {
9417            return new PackageParser.ServiceIntentInfo[size];
9418        }
9419
9420        @Override
9421        protected boolean isFilterStopped(PackageParser.ServiceIntentInfo filter, int userId) {
9422            if (!sUserManager.exists(userId)) return true;
9423            PackageParser.Package p = filter.service.owner;
9424            if (p != null) {
9425                PackageSetting ps = (PackageSetting)p.mExtras;
9426                if (ps != null) {
9427                    // System apps are never considered stopped for purposes of
9428                    // filtering, because there may be no way for the user to
9429                    // actually re-launch them.
9430                    return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
9431                            && ps.getStopped(userId);
9432                }
9433            }
9434            return false;
9435        }
9436
9437        @Override
9438        protected boolean isPackageForFilter(String packageName,
9439                PackageParser.ServiceIntentInfo info) {
9440            return packageName.equals(info.service.owner.packageName);
9441        }
9442
9443        @Override
9444        protected ResolveInfo newResult(PackageParser.ServiceIntentInfo filter,
9445                int match, int userId) {
9446            if (!sUserManager.exists(userId)) return null;
9447            final PackageParser.ServiceIntentInfo info = (PackageParser.ServiceIntentInfo)filter;
9448            if (!mSettings.isEnabledAndMatchLPr(info.service.info, mFlags, userId)) {
9449                return null;
9450            }
9451            final PackageParser.Service service = info.service;
9452            PackageSetting ps = (PackageSetting) service.owner.mExtras;
9453            if (ps == null) {
9454                return null;
9455            }
9456            ServiceInfo si = PackageParser.generateServiceInfo(service, mFlags,
9457                    ps.readUserState(userId), userId);
9458            if (si == null) {
9459                return null;
9460            }
9461            final ResolveInfo res = new ResolveInfo();
9462            res.serviceInfo = si;
9463            if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
9464                res.filter = filter;
9465            }
9466            res.priority = info.getPriority();
9467            res.preferredOrder = service.owner.mPreferredOrder;
9468            res.match = match;
9469            res.isDefault = info.hasDefault;
9470            res.labelRes = info.labelRes;
9471            res.nonLocalizedLabel = info.nonLocalizedLabel;
9472            res.icon = info.icon;
9473            res.system = res.serviceInfo.applicationInfo.isSystemApp();
9474            return res;
9475        }
9476
9477        @Override
9478        protected void sortResults(List<ResolveInfo> results) {
9479            Collections.sort(results, mResolvePrioritySorter);
9480        }
9481
9482        @Override
9483        protected void dumpFilter(PrintWriter out, String prefix,
9484                PackageParser.ServiceIntentInfo filter) {
9485            out.print(prefix); out.print(
9486                    Integer.toHexString(System.identityHashCode(filter.service)));
9487                    out.print(' ');
9488                    filter.service.printComponentShortName(out);
9489                    out.print(" filter ");
9490                    out.println(Integer.toHexString(System.identityHashCode(filter)));
9491        }
9492
9493        @Override
9494        protected Object filterToLabel(PackageParser.ServiceIntentInfo filter) {
9495            return filter.service;
9496        }
9497
9498        protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
9499            PackageParser.Service service = (PackageParser.Service)label;
9500            out.print(prefix); out.print(
9501                    Integer.toHexString(System.identityHashCode(service)));
9502                    out.print(' ');
9503                    service.printComponentShortName(out);
9504            if (count > 1) {
9505                out.print(" ("); out.print(count); out.print(" filters)");
9506            }
9507            out.println();
9508        }
9509
9510//        List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) {
9511//            final Iterator<ResolveInfo> i = resolveInfoList.iterator();
9512//            final List<ResolveInfo> retList = Lists.newArrayList();
9513//            while (i.hasNext()) {
9514//                final ResolveInfo resolveInfo = (ResolveInfo) i;
9515//                if (isEnabledLP(resolveInfo.serviceInfo)) {
9516//                    retList.add(resolveInfo);
9517//                }
9518//            }
9519//            return retList;
9520//        }
9521
9522        // Keys are String (activity class name), values are Activity.
9523        private final ArrayMap<ComponentName, PackageParser.Service> mServices
9524                = new ArrayMap<ComponentName, PackageParser.Service>();
9525        private int mFlags;
9526    };
9527
9528    private final class ProviderIntentResolver
9529            extends IntentResolver<PackageParser.ProviderIntentInfo, ResolveInfo> {
9530        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
9531                boolean defaultOnly, int userId) {
9532            mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
9533            return super.queryIntent(intent, resolvedType, defaultOnly, userId);
9534        }
9535
9536        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
9537                int userId) {
9538            if (!sUserManager.exists(userId))
9539                return null;
9540            mFlags = flags;
9541            return super.queryIntent(intent, resolvedType,
9542                    (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId);
9543        }
9544
9545        public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
9546                int flags, ArrayList<PackageParser.Provider> packageProviders, int userId) {
9547            if (!sUserManager.exists(userId))
9548                return null;
9549            if (packageProviders == null) {
9550                return null;
9551            }
9552            mFlags = flags;
9553            final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0;
9554            final int N = packageProviders.size();
9555            ArrayList<PackageParser.ProviderIntentInfo[]> listCut =
9556                    new ArrayList<PackageParser.ProviderIntentInfo[]>(N);
9557
9558            ArrayList<PackageParser.ProviderIntentInfo> intentFilters;
9559            for (int i = 0; i < N; ++i) {
9560                intentFilters = packageProviders.get(i).intents;
9561                if (intentFilters != null && intentFilters.size() > 0) {
9562                    PackageParser.ProviderIntentInfo[] array =
9563                            new PackageParser.ProviderIntentInfo[intentFilters.size()];
9564                    intentFilters.toArray(array);
9565                    listCut.add(array);
9566                }
9567            }
9568            return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
9569        }
9570
9571        public final void addProvider(PackageParser.Provider p) {
9572            if (mProviders.containsKey(p.getComponentName())) {
9573                Slog.w(TAG, "Provider " + p.getComponentName() + " already defined; ignoring");
9574                return;
9575            }
9576
9577            mProviders.put(p.getComponentName(), p);
9578            if (DEBUG_SHOW_INFO) {
9579                Log.v(TAG, "  "
9580                        + (p.info.nonLocalizedLabel != null
9581                                ? p.info.nonLocalizedLabel : p.info.name) + ":");
9582                Log.v(TAG, "    Class=" + p.info.name);
9583            }
9584            final int NI = p.intents.size();
9585            int j;
9586            for (j = 0; j < NI; j++) {
9587                PackageParser.ProviderIntentInfo intent = p.intents.get(j);
9588                if (DEBUG_SHOW_INFO) {
9589                    Log.v(TAG, "    IntentFilter:");
9590                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
9591                }
9592                if (!intent.debugCheck()) {
9593                    Log.w(TAG, "==> For Provider " + p.info.name);
9594                }
9595                addFilter(intent);
9596            }
9597        }
9598
9599        public final void removeProvider(PackageParser.Provider p) {
9600            mProviders.remove(p.getComponentName());
9601            if (DEBUG_SHOW_INFO) {
9602                Log.v(TAG, "  " + (p.info.nonLocalizedLabel != null
9603                        ? p.info.nonLocalizedLabel : p.info.name) + ":");
9604                Log.v(TAG, "    Class=" + p.info.name);
9605            }
9606            final int NI = p.intents.size();
9607            int j;
9608            for (j = 0; j < NI; j++) {
9609                PackageParser.ProviderIntentInfo intent = p.intents.get(j);
9610                if (DEBUG_SHOW_INFO) {
9611                    Log.v(TAG, "    IntentFilter:");
9612                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
9613                }
9614                removeFilter(intent);
9615            }
9616        }
9617
9618        @Override
9619        protected boolean allowFilterResult(
9620                PackageParser.ProviderIntentInfo filter, List<ResolveInfo> dest) {
9621            ProviderInfo filterPi = filter.provider.info;
9622            for (int i = dest.size() - 1; i >= 0; i--) {
9623                ProviderInfo destPi = dest.get(i).providerInfo;
9624                if (destPi.name == filterPi.name
9625                        && destPi.packageName == filterPi.packageName) {
9626                    return false;
9627                }
9628            }
9629            return true;
9630        }
9631
9632        @Override
9633        protected PackageParser.ProviderIntentInfo[] newArray(int size) {
9634            return new PackageParser.ProviderIntentInfo[size];
9635        }
9636
9637        @Override
9638        protected boolean isFilterStopped(PackageParser.ProviderIntentInfo filter, int userId) {
9639            if (!sUserManager.exists(userId))
9640                return true;
9641            PackageParser.Package p = filter.provider.owner;
9642            if (p != null) {
9643                PackageSetting ps = (PackageSetting) p.mExtras;
9644                if (ps != null) {
9645                    // System apps are never considered stopped for purposes of
9646                    // filtering, because there may be no way for the user to
9647                    // actually re-launch them.
9648                    return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
9649                            && ps.getStopped(userId);
9650                }
9651            }
9652            return false;
9653        }
9654
9655        @Override
9656        protected boolean isPackageForFilter(String packageName,
9657                PackageParser.ProviderIntentInfo info) {
9658            return packageName.equals(info.provider.owner.packageName);
9659        }
9660
9661        @Override
9662        protected ResolveInfo newResult(PackageParser.ProviderIntentInfo filter,
9663                int match, int userId) {
9664            if (!sUserManager.exists(userId))
9665                return null;
9666            final PackageParser.ProviderIntentInfo info = filter;
9667            if (!mSettings.isEnabledAndMatchLPr(info.provider.info, mFlags, userId)) {
9668                return null;
9669            }
9670            final PackageParser.Provider provider = info.provider;
9671            PackageSetting ps = (PackageSetting) provider.owner.mExtras;
9672            if (ps == null) {
9673                return null;
9674            }
9675            ProviderInfo pi = PackageParser.generateProviderInfo(provider, mFlags,
9676                    ps.readUserState(userId), userId);
9677            if (pi == null) {
9678                return null;
9679            }
9680            final ResolveInfo res = new ResolveInfo();
9681            res.providerInfo = pi;
9682            if ((mFlags & PackageManager.GET_RESOLVED_FILTER) != 0) {
9683                res.filter = filter;
9684            }
9685            res.priority = info.getPriority();
9686            res.preferredOrder = provider.owner.mPreferredOrder;
9687            res.match = match;
9688            res.isDefault = info.hasDefault;
9689            res.labelRes = info.labelRes;
9690            res.nonLocalizedLabel = info.nonLocalizedLabel;
9691            res.icon = info.icon;
9692            res.system = res.providerInfo.applicationInfo.isSystemApp();
9693            return res;
9694        }
9695
9696        @Override
9697        protected void sortResults(List<ResolveInfo> results) {
9698            Collections.sort(results, mResolvePrioritySorter);
9699        }
9700
9701        @Override
9702        protected void dumpFilter(PrintWriter out, String prefix,
9703                PackageParser.ProviderIntentInfo filter) {
9704            out.print(prefix);
9705            out.print(
9706                    Integer.toHexString(System.identityHashCode(filter.provider)));
9707            out.print(' ');
9708            filter.provider.printComponentShortName(out);
9709            out.print(" filter ");
9710            out.println(Integer.toHexString(System.identityHashCode(filter)));
9711        }
9712
9713        @Override
9714        protected Object filterToLabel(PackageParser.ProviderIntentInfo filter) {
9715            return filter.provider;
9716        }
9717
9718        protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
9719            PackageParser.Provider provider = (PackageParser.Provider)label;
9720            out.print(prefix); out.print(
9721                    Integer.toHexString(System.identityHashCode(provider)));
9722                    out.print(' ');
9723                    provider.printComponentShortName(out);
9724            if (count > 1) {
9725                out.print(" ("); out.print(count); out.print(" filters)");
9726            }
9727            out.println();
9728        }
9729
9730        private final ArrayMap<ComponentName, PackageParser.Provider> mProviders
9731                = new ArrayMap<ComponentName, PackageParser.Provider>();
9732        private int mFlags;
9733    }
9734
9735    private static final class EphemeralIntentResolver
9736            extends IntentResolver<EphemeralResolveIntentInfo, EphemeralResolveInfo> {
9737        @Override
9738        protected EphemeralResolveIntentInfo[] newArray(int size) {
9739            return new EphemeralResolveIntentInfo[size];
9740        }
9741
9742        @Override
9743        protected boolean isPackageForFilter(String packageName, EphemeralResolveIntentInfo info) {
9744            return true;
9745        }
9746
9747        @Override
9748        protected EphemeralResolveInfo newResult(EphemeralResolveIntentInfo info, int match,
9749                int userId) {
9750            if (!sUserManager.exists(userId)) {
9751                return null;
9752            }
9753            return info.getEphemeralResolveInfo();
9754        }
9755    }
9756
9757    private static final Comparator<ResolveInfo> mResolvePrioritySorter =
9758            new Comparator<ResolveInfo>() {
9759        public int compare(ResolveInfo r1, ResolveInfo r2) {
9760            int v1 = r1.priority;
9761            int v2 = r2.priority;
9762            //System.out.println("Comparing: q1=" + q1 + " q2=" + q2);
9763            if (v1 != v2) {
9764                return (v1 > v2) ? -1 : 1;
9765            }
9766            v1 = r1.preferredOrder;
9767            v2 = r2.preferredOrder;
9768            if (v1 != v2) {
9769                return (v1 > v2) ? -1 : 1;
9770            }
9771            if (r1.isDefault != r2.isDefault) {
9772                return r1.isDefault ? -1 : 1;
9773            }
9774            v1 = r1.match;
9775            v2 = r2.match;
9776            //System.out.println("Comparing: m1=" + m1 + " m2=" + m2);
9777            if (v1 != v2) {
9778                return (v1 > v2) ? -1 : 1;
9779            }
9780            if (r1.system != r2.system) {
9781                return r1.system ? -1 : 1;
9782            }
9783            if (r1.activityInfo != null) {
9784                return r1.activityInfo.packageName.compareTo(r2.activityInfo.packageName);
9785            }
9786            if (r1.serviceInfo != null) {
9787                return r1.serviceInfo.packageName.compareTo(r2.serviceInfo.packageName);
9788            }
9789            if (r1.providerInfo != null) {
9790                return r1.providerInfo.packageName.compareTo(r2.providerInfo.packageName);
9791            }
9792            return 0;
9793        }
9794    };
9795
9796    private static final Comparator<ProviderInfo> mProviderInitOrderSorter =
9797            new Comparator<ProviderInfo>() {
9798        public int compare(ProviderInfo p1, ProviderInfo p2) {
9799            final int v1 = p1.initOrder;
9800            final int v2 = p2.initOrder;
9801            return (v1 > v2) ? -1 : ((v1 < v2) ? 1 : 0);
9802        }
9803    };
9804
9805    final void sendPackageBroadcast(final String action, final String pkg, final Bundle extras,
9806            final int flags, final String targetPkg, final IIntentReceiver finishedReceiver,
9807            final int[] userIds) {
9808        mHandler.post(new Runnable() {
9809            @Override
9810            public void run() {
9811                try {
9812                    final IActivityManager am = ActivityManagerNative.getDefault();
9813                    if (am == null) return;
9814                    final int[] resolvedUserIds;
9815                    if (userIds == null) {
9816                        resolvedUserIds = am.getRunningUserIds();
9817                    } else {
9818                        resolvedUserIds = userIds;
9819                    }
9820                    for (int id : resolvedUserIds) {
9821                        final Intent intent = new Intent(action,
9822                                pkg != null ? Uri.fromParts("package", pkg, null) : null);
9823                        if (extras != null) {
9824                            intent.putExtras(extras);
9825                        }
9826                        if (targetPkg != null) {
9827                            intent.setPackage(targetPkg);
9828                        }
9829                        // Modify the UID when posting to other users
9830                        int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
9831                        if (uid > 0 && UserHandle.getUserId(uid) != id) {
9832                            uid = UserHandle.getUid(id, UserHandle.getAppId(uid));
9833                            intent.putExtra(Intent.EXTRA_UID, uid);
9834                        }
9835                        intent.putExtra(Intent.EXTRA_USER_HANDLE, id);
9836                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT | flags);
9837                        if (DEBUG_BROADCASTS) {
9838                            RuntimeException here = new RuntimeException("here");
9839                            here.fillInStackTrace();
9840                            Slog.d(TAG, "Sending to user " + id + ": "
9841                                    + intent.toShortString(false, true, false, false)
9842                                    + " " + intent.getExtras(), here);
9843                        }
9844                        am.broadcastIntent(null, intent, null, finishedReceiver,
9845                                0, null, null, null, android.app.AppOpsManager.OP_NONE,
9846                                null, finishedReceiver != null, false, id);
9847                    }
9848                } catch (RemoteException ex) {
9849                }
9850            }
9851        });
9852    }
9853
9854    /**
9855     * Check if the external storage media is available. This is true if there
9856     * is a mounted external storage medium or if the external storage is
9857     * emulated.
9858     */
9859    private boolean isExternalMediaAvailable() {
9860        return mMediaMounted || Environment.isExternalStorageEmulated();
9861    }
9862
9863    @Override
9864    public PackageCleanItem nextPackageToClean(PackageCleanItem lastPackage) {
9865        // writer
9866        synchronized (mPackages) {
9867            if (!isExternalMediaAvailable()) {
9868                // If the external storage is no longer mounted at this point,
9869                // the caller may not have been able to delete all of this
9870                // packages files and can not delete any more.  Bail.
9871                return null;
9872            }
9873            final ArrayList<PackageCleanItem> pkgs = mSettings.mPackagesToBeCleaned;
9874            if (lastPackage != null) {
9875                pkgs.remove(lastPackage);
9876            }
9877            if (pkgs.size() > 0) {
9878                return pkgs.get(0);
9879            }
9880        }
9881        return null;
9882    }
9883
9884    void schedulePackageCleaning(String packageName, int userId, boolean andCode) {
9885        final Message msg = mHandler.obtainMessage(START_CLEANING_PACKAGE,
9886                userId, andCode ? 1 : 0, packageName);
9887        if (mSystemReady) {
9888            msg.sendToTarget();
9889        } else {
9890            if (mPostSystemReadyMessages == null) {
9891                mPostSystemReadyMessages = new ArrayList<>();
9892            }
9893            mPostSystemReadyMessages.add(msg);
9894        }
9895    }
9896
9897    void startCleaningPackages() {
9898        // reader
9899        synchronized (mPackages) {
9900            if (!isExternalMediaAvailable()) {
9901                return;
9902            }
9903            if (mSettings.mPackagesToBeCleaned.isEmpty()) {
9904                return;
9905            }
9906        }
9907        Intent intent = new Intent(PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE);
9908        intent.setComponent(DEFAULT_CONTAINER_COMPONENT);
9909        IActivityManager am = ActivityManagerNative.getDefault();
9910        if (am != null) {
9911            try {
9912                am.startService(null, intent, null, mContext.getOpPackageName(),
9913                        UserHandle.USER_SYSTEM);
9914            } catch (RemoteException e) {
9915            }
9916        }
9917    }
9918
9919    @Override
9920    public void installPackage(String originPath, IPackageInstallObserver2 observer,
9921            int installFlags, String installerPackageName, VerificationParams verificationParams,
9922            String packageAbiOverride) {
9923        installPackageAsUser(originPath, observer, installFlags, installerPackageName,
9924                verificationParams, packageAbiOverride, UserHandle.getCallingUserId());
9925    }
9926
9927    @Override
9928    public void installPackageAsUser(String originPath, IPackageInstallObserver2 observer,
9929            int installFlags, String installerPackageName, VerificationParams verificationParams,
9930            String packageAbiOverride, int userId) {
9931        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null);
9932
9933        final int callingUid = Binder.getCallingUid();
9934        enforceCrossUserPermission(callingUid, userId, true, true, "installPackageAsUser");
9935
9936        if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
9937            try {
9938                if (observer != null) {
9939                    observer.onPackageInstalled("", INSTALL_FAILED_USER_RESTRICTED, null, null);
9940                }
9941            } catch (RemoteException re) {
9942            }
9943            return;
9944        }
9945
9946        if ((callingUid == Process.SHELL_UID) || (callingUid == Process.ROOT_UID)) {
9947            installFlags |= PackageManager.INSTALL_FROM_ADB;
9948
9949        } else {
9950            // Caller holds INSTALL_PACKAGES permission, so we're less strict
9951            // about installerPackageName.
9952
9953            installFlags &= ~PackageManager.INSTALL_FROM_ADB;
9954            installFlags &= ~PackageManager.INSTALL_ALL_USERS;
9955        }
9956
9957        UserHandle user;
9958        if ((installFlags & PackageManager.INSTALL_ALL_USERS) != 0) {
9959            user = UserHandle.ALL;
9960        } else {
9961            user = new UserHandle(userId);
9962        }
9963
9964        // Only system components can circumvent runtime permissions when installing.
9965        if ((installFlags & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0
9966                && mContext.checkCallingOrSelfPermission(Manifest.permission
9967                .INSTALL_GRANT_RUNTIME_PERMISSIONS) == PackageManager.PERMISSION_DENIED) {
9968            throw new SecurityException("You need the "
9969                    + "android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS permission "
9970                    + "to use the PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS flag");
9971        }
9972
9973        verificationParams.setInstallerUid(callingUid);
9974
9975        final File originFile = new File(originPath);
9976        final OriginInfo origin = OriginInfo.fromUntrustedFile(originFile);
9977
9978        final Message msg = mHandler.obtainMessage(INIT_COPY);
9979        final InstallParams params = new InstallParams(origin, null, observer, installFlags,
9980                installerPackageName, null, verificationParams, user, packageAbiOverride, null);
9981        params.setTraceMethod("installAsUser").setTraceCookie(System.identityHashCode(params));
9982        msg.obj = params;
9983
9984        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installAsUser",
9985                System.identityHashCode(msg.obj));
9986        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
9987                System.identityHashCode(msg.obj));
9988
9989        mHandler.sendMessage(msg);
9990    }
9991
9992    void installStage(String packageName, File stagedDir, String stagedCid,
9993            IPackageInstallObserver2 observer, PackageInstaller.SessionParams sessionParams,
9994            String installerPackageName, int installerUid, UserHandle user) {
9995        if (DEBUG_EPHEMERAL) {
9996            if ((sessionParams.installFlags & PackageManager.INSTALL_EPHEMERAL) != 0) {
9997                Slog.d(TAG, "Ephemeral install of " + packageName);
9998            }
9999        }
10000        final VerificationParams verifParams = new VerificationParams(
10001                null, sessionParams.originatingUri, sessionParams.referrerUri,
10002                sessionParams.originatingUid);
10003        verifParams.setInstallerUid(installerUid);
10004
10005        final OriginInfo origin;
10006        if (stagedDir != null) {
10007            origin = OriginInfo.fromStagedFile(stagedDir);
10008        } else {
10009            origin = OriginInfo.fromStagedContainer(stagedCid);
10010        }
10011
10012        final Message msg = mHandler.obtainMessage(INIT_COPY);
10013        final InstallParams params = new InstallParams(origin, null, observer,
10014                sessionParams.installFlags, installerPackageName, sessionParams.volumeUuid,
10015                verifParams, user, sessionParams.abiOverride,
10016                sessionParams.grantedRuntimePermissions);
10017        params.setTraceMethod("installStage").setTraceCookie(System.identityHashCode(params));
10018        msg.obj = params;
10019
10020        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installStage",
10021                System.identityHashCode(msg.obj));
10022        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
10023                System.identityHashCode(msg.obj));
10024
10025        mHandler.sendMessage(msg);
10026    }
10027
10028    private void sendPackageAddedForUser(String packageName, PackageSetting pkgSetting, int userId) {
10029        Bundle extras = new Bundle(1);
10030        extras.putInt(Intent.EXTRA_UID, UserHandle.getUid(userId, pkgSetting.appId));
10031
10032        sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
10033                packageName, extras, 0, null, null, new int[] {userId});
10034        try {
10035            IActivityManager am = ActivityManagerNative.getDefault();
10036            final boolean isSystem =
10037                    isSystemApp(pkgSetting) || isUpdatedSystemApp(pkgSetting);
10038            if (isSystem && am.isUserRunning(userId, 0)) {
10039                // The just-installed/enabled app is bundled on the system, so presumed
10040                // to be able to run automatically without needing an explicit launch.
10041                // Send it a BOOT_COMPLETED if it would ordinarily have gotten one.
10042                Intent bcIntent = new Intent(Intent.ACTION_BOOT_COMPLETED)
10043                        .addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES)
10044                        .setPackage(packageName);
10045                am.broadcastIntent(null, bcIntent, null, null, 0, null, null, null,
10046                        android.app.AppOpsManager.OP_NONE, null, false, false, userId);
10047            }
10048        } catch (RemoteException e) {
10049            // shouldn't happen
10050            Slog.w(TAG, "Unable to bootstrap installed package", e);
10051        }
10052    }
10053
10054    @Override
10055    public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden,
10056            int userId) {
10057        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
10058        PackageSetting pkgSetting;
10059        final int uid = Binder.getCallingUid();
10060        enforceCrossUserPermission(uid, userId, true, true,
10061                "setApplicationHiddenSetting for user " + userId);
10062
10063        if (hidden && isPackageDeviceAdmin(packageName, userId)) {
10064            Slog.w(TAG, "Not hiding package " + packageName + ": has active device admin");
10065            return false;
10066        }
10067
10068        long callingId = Binder.clearCallingIdentity();
10069        try {
10070            boolean sendAdded = false;
10071            boolean sendRemoved = false;
10072            // writer
10073            synchronized (mPackages) {
10074                pkgSetting = mSettings.mPackages.get(packageName);
10075                if (pkgSetting == null) {
10076                    return false;
10077                }
10078                if (pkgSetting.getHidden(userId) != hidden) {
10079                    pkgSetting.setHidden(hidden, userId);
10080                    mSettings.writePackageRestrictionsLPr(userId);
10081                    if (hidden) {
10082                        sendRemoved = true;
10083                    } else {
10084                        sendAdded = true;
10085                    }
10086                }
10087            }
10088            if (sendAdded) {
10089                sendPackageAddedForUser(packageName, pkgSetting, userId);
10090                return true;
10091            }
10092            if (sendRemoved) {
10093                killApplication(packageName, UserHandle.getUid(userId, pkgSetting.appId),
10094                        "hiding pkg");
10095                sendApplicationHiddenForUser(packageName, pkgSetting, userId);
10096                return true;
10097            }
10098        } finally {
10099            Binder.restoreCallingIdentity(callingId);
10100        }
10101        return false;
10102    }
10103
10104    private void sendApplicationHiddenForUser(String packageName, PackageSetting pkgSetting,
10105            int userId) {
10106        final PackageRemovedInfo info = new PackageRemovedInfo();
10107        info.removedPackage = packageName;
10108        info.removedUsers = new int[] {userId};
10109        info.uid = UserHandle.getUid(userId, pkgSetting.appId);
10110        info.sendBroadcast(false, false, false);
10111    }
10112
10113    private void sendPackagesSuspendedForUser(String[] pkgList, int userId, boolean suspended) {
10114        if (pkgList.length > 0) {
10115            Bundle extras = new Bundle(1);
10116            extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
10117
10118            sendPackageBroadcast(
10119                    suspended ? Intent.ACTION_PACKAGES_SUSPENDED
10120                            : Intent.ACTION_PACKAGES_UNSUSPENDED,
10121                    null, extras, Intent.FLAG_RECEIVER_REGISTERED_ONLY, null, null,
10122                    new int[] {userId});
10123        }
10124    }
10125
10126    /**
10127     * Returns true if application is not found or there was an error. Otherwise it returns
10128     * the hidden state of the package for the given user.
10129     */
10130    @Override
10131    public boolean getApplicationHiddenSettingAsUser(String packageName, int userId) {
10132        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
10133        enforceCrossUserPermission(Binder.getCallingUid(), userId, true,
10134                false, "getApplicationHidden for user " + userId);
10135        PackageSetting pkgSetting;
10136        long callingId = Binder.clearCallingIdentity();
10137        try {
10138            // writer
10139            synchronized (mPackages) {
10140                pkgSetting = mSettings.mPackages.get(packageName);
10141                if (pkgSetting == null) {
10142                    return true;
10143                }
10144                return pkgSetting.getHidden(userId);
10145            }
10146        } finally {
10147            Binder.restoreCallingIdentity(callingId);
10148        }
10149    }
10150
10151    /**
10152     * @hide
10153     */
10154    @Override
10155    public int installExistingPackageAsUser(String packageName, int userId) {
10156        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES,
10157                null);
10158        PackageSetting pkgSetting;
10159        final int uid = Binder.getCallingUid();
10160        enforceCrossUserPermission(uid, userId, true, true, "installExistingPackage for user "
10161                + userId);
10162        if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
10163            return PackageManager.INSTALL_FAILED_USER_RESTRICTED;
10164        }
10165
10166        long callingId = Binder.clearCallingIdentity();
10167        try {
10168            boolean installed = false;
10169
10170            // writer
10171            synchronized (mPackages) {
10172                pkgSetting = mSettings.mPackages.get(packageName);
10173                if (pkgSetting == null) {
10174                    return PackageManager.INSTALL_FAILED_INVALID_URI;
10175                }
10176                if (!pkgSetting.getInstalled(userId)) {
10177                    pkgSetting.setInstalled(true, userId);
10178                    pkgSetting.setHidden(false, userId);
10179                    mSettings.writePackageRestrictionsLPr(userId);
10180                    if (pkgSetting.pkg != null) {
10181                        prepareAppDataAfterInstall(pkgSetting.pkg);
10182                    }
10183                    installed = true;
10184                }
10185            }
10186
10187            if (installed) {
10188                sendPackageAddedForUser(packageName, pkgSetting, userId);
10189            }
10190        } finally {
10191            Binder.restoreCallingIdentity(callingId);
10192        }
10193
10194        return PackageManager.INSTALL_SUCCEEDED;
10195    }
10196
10197    boolean isUserRestricted(int userId, String restrictionKey) {
10198        Bundle restrictions = sUserManager.getUserRestrictions(userId);
10199        if (restrictions.getBoolean(restrictionKey, false)) {
10200            Log.w(TAG, "User is restricted: " + restrictionKey);
10201            return true;
10202        }
10203        return false;
10204    }
10205
10206    @Override
10207    public boolean setPackageSuspendedAsUser(String packageName, boolean suspended, int userId) {
10208        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
10209        enforceCrossUserPermission(Binder.getCallingUid(), userId, true, true,
10210                "setPackageSuspended for user " + userId);
10211
10212        // TODO: investigate and add more restrictions for suspending crucial packages.
10213        if (isPackageDeviceAdmin(packageName, userId)) {
10214            Slog.w(TAG, "Not suspending/un-suspending package \"" + packageName
10215                    + "\": has active device admin");
10216            return false;
10217        }
10218
10219        long callingId = Binder.clearCallingIdentity();
10220        try {
10221            boolean changed = false;
10222            boolean success = false;
10223            int appId = -1;
10224            synchronized (mPackages) {
10225                final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
10226                if (pkgSetting != null) {
10227                    if (pkgSetting.getSuspended(userId) != suspended) {
10228                        pkgSetting.setSuspended(suspended, userId);
10229                        mSettings.writePackageRestrictionsLPr(userId);
10230                        appId = pkgSetting.appId;
10231                        changed = true;
10232                    }
10233                    success = true;
10234                }
10235            }
10236
10237            if (changed) {
10238                sendPackagesSuspendedForUser(new String[]{packageName}, userId, suspended);
10239                if (suspended) {
10240                    killApplication(packageName, UserHandle.getUid(userId, appId),
10241                            "suspending package");
10242                }
10243            }
10244            return success;
10245        } finally {
10246            Binder.restoreCallingIdentity(callingId);
10247        }
10248    }
10249
10250    @Override
10251    public void verifyPendingInstall(int id, int verificationCode) throws RemoteException {
10252        mContext.enforceCallingOrSelfPermission(
10253                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
10254                "Only package verification agents can verify applications");
10255
10256        final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
10257        final PackageVerificationResponse response = new PackageVerificationResponse(
10258                verificationCode, Binder.getCallingUid());
10259        msg.arg1 = id;
10260        msg.obj = response;
10261        mHandler.sendMessage(msg);
10262    }
10263
10264    @Override
10265    public void extendVerificationTimeout(int id, int verificationCodeAtTimeout,
10266            long millisecondsToDelay) {
10267        mContext.enforceCallingOrSelfPermission(
10268                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
10269                "Only package verification agents can extend verification timeouts");
10270
10271        final PackageVerificationState state = mPendingVerification.get(id);
10272        final PackageVerificationResponse response = new PackageVerificationResponse(
10273                verificationCodeAtTimeout, Binder.getCallingUid());
10274
10275        if (millisecondsToDelay > PackageManager.MAXIMUM_VERIFICATION_TIMEOUT) {
10276            millisecondsToDelay = PackageManager.MAXIMUM_VERIFICATION_TIMEOUT;
10277        }
10278        if (millisecondsToDelay < 0) {
10279            millisecondsToDelay = 0;
10280        }
10281        if ((verificationCodeAtTimeout != PackageManager.VERIFICATION_ALLOW)
10282                && (verificationCodeAtTimeout != PackageManager.VERIFICATION_REJECT)) {
10283            verificationCodeAtTimeout = PackageManager.VERIFICATION_REJECT;
10284        }
10285
10286        if ((state != null) && !state.timeoutExtended()) {
10287            state.extendTimeout();
10288
10289            final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
10290            msg.arg1 = id;
10291            msg.obj = response;
10292            mHandler.sendMessageDelayed(msg, millisecondsToDelay);
10293        }
10294    }
10295
10296    private void broadcastPackageVerified(int verificationId, Uri packageUri,
10297            int verificationCode, UserHandle user) {
10298        final Intent intent = new Intent(Intent.ACTION_PACKAGE_VERIFIED);
10299        intent.setDataAndType(packageUri, PACKAGE_MIME_TYPE);
10300        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
10301        intent.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
10302        intent.putExtra(PackageManager.EXTRA_VERIFICATION_RESULT, verificationCode);
10303
10304        mContext.sendBroadcastAsUser(intent, user,
10305                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT);
10306    }
10307
10308    private ComponentName matchComponentForVerifier(String packageName,
10309            List<ResolveInfo> receivers) {
10310        ActivityInfo targetReceiver = null;
10311
10312        final int NR = receivers.size();
10313        for (int i = 0; i < NR; i++) {
10314            final ResolveInfo info = receivers.get(i);
10315            if (info.activityInfo == null) {
10316                continue;
10317            }
10318
10319            if (packageName.equals(info.activityInfo.packageName)) {
10320                targetReceiver = info.activityInfo;
10321                break;
10322            }
10323        }
10324
10325        if (targetReceiver == null) {
10326            return null;
10327        }
10328
10329        return new ComponentName(targetReceiver.packageName, targetReceiver.name);
10330    }
10331
10332    private List<ComponentName> matchVerifiers(PackageInfoLite pkgInfo,
10333            List<ResolveInfo> receivers, final PackageVerificationState verificationState) {
10334        if (pkgInfo.verifiers.length == 0) {
10335            return null;
10336        }
10337
10338        final int N = pkgInfo.verifiers.length;
10339        final List<ComponentName> sufficientVerifiers = new ArrayList<ComponentName>(N + 1);
10340        for (int i = 0; i < N; i++) {
10341            final VerifierInfo verifierInfo = pkgInfo.verifiers[i];
10342
10343            final ComponentName comp = matchComponentForVerifier(verifierInfo.packageName,
10344                    receivers);
10345            if (comp == null) {
10346                continue;
10347            }
10348
10349            final int verifierUid = getUidForVerifier(verifierInfo);
10350            if (verifierUid == -1) {
10351                continue;
10352            }
10353
10354            if (DEBUG_VERIFY) {
10355                Slog.d(TAG, "Added sufficient verifier " + verifierInfo.packageName
10356                        + " with the correct signature");
10357            }
10358            sufficientVerifiers.add(comp);
10359            verificationState.addSufficientVerifier(verifierUid);
10360        }
10361
10362        return sufficientVerifiers;
10363    }
10364
10365    private int getUidForVerifier(VerifierInfo verifierInfo) {
10366        synchronized (mPackages) {
10367            final PackageParser.Package pkg = mPackages.get(verifierInfo.packageName);
10368            if (pkg == null) {
10369                return -1;
10370            } else if (pkg.mSignatures.length != 1) {
10371                Slog.i(TAG, "Verifier package " + verifierInfo.packageName
10372                        + " has more than one signature; ignoring");
10373                return -1;
10374            }
10375
10376            /*
10377             * If the public key of the package's signature does not match
10378             * our expected public key, then this is a different package and
10379             * we should skip.
10380             */
10381
10382            final byte[] expectedPublicKey;
10383            try {
10384                final Signature verifierSig = pkg.mSignatures[0];
10385                final PublicKey publicKey = verifierSig.getPublicKey();
10386                expectedPublicKey = publicKey.getEncoded();
10387            } catch (CertificateException e) {
10388                return -1;
10389            }
10390
10391            final byte[] actualPublicKey = verifierInfo.publicKey.getEncoded();
10392
10393            if (!Arrays.equals(actualPublicKey, expectedPublicKey)) {
10394                Slog.i(TAG, "Verifier package " + verifierInfo.packageName
10395                        + " does not have the expected public key; ignoring");
10396                return -1;
10397            }
10398
10399            return pkg.applicationInfo.uid;
10400        }
10401    }
10402
10403    @Override
10404    public void finishPackageInstall(int token) {
10405        enforceSystemOrRoot("Only the system is allowed to finish installs");
10406
10407        if (DEBUG_INSTALL) {
10408            Slog.v(TAG, "BM finishing package install for " + token);
10409        }
10410        Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "restore", token);
10411
10412        final Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0);
10413        mHandler.sendMessage(msg);
10414    }
10415
10416    /**
10417     * Get the verification agent timeout.
10418     *
10419     * @return verification timeout in milliseconds
10420     */
10421    private long getVerificationTimeout() {
10422        return android.provider.Settings.Global.getLong(mContext.getContentResolver(),
10423                android.provider.Settings.Global.PACKAGE_VERIFIER_TIMEOUT,
10424                DEFAULT_VERIFICATION_TIMEOUT);
10425    }
10426
10427    /**
10428     * Get the default verification agent response code.
10429     *
10430     * @return default verification response code
10431     */
10432    private int getDefaultVerificationResponse() {
10433        return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
10434                android.provider.Settings.Global.PACKAGE_VERIFIER_DEFAULT_RESPONSE,
10435                DEFAULT_VERIFICATION_RESPONSE);
10436    }
10437
10438    /**
10439     * Check whether or not package verification has been enabled.
10440     *
10441     * @return true if verification should be performed
10442     */
10443    private boolean isVerificationEnabled(int userId, int installFlags) {
10444        if (!DEFAULT_VERIFY_ENABLE) {
10445            return false;
10446        }
10447        // Ephemeral apps don't get the full verification treatment
10448        if ((installFlags & PackageManager.INSTALL_EPHEMERAL) != 0) {
10449            if (DEBUG_EPHEMERAL) {
10450                Slog.d(TAG, "INSTALL_EPHEMERAL so skipping verification");
10451            }
10452            return false;
10453        }
10454
10455        boolean ensureVerifyAppsEnabled = isUserRestricted(userId, UserManager.ENSURE_VERIFY_APPS);
10456
10457        // Check if installing from ADB
10458        if ((installFlags & PackageManager.INSTALL_FROM_ADB) != 0) {
10459            // Do not run verification in a test harness environment
10460            if (ActivityManager.isRunningInTestHarness()) {
10461                return false;
10462            }
10463            if (ensureVerifyAppsEnabled) {
10464                return true;
10465            }
10466            // Check if the developer does not want package verification for ADB installs
10467            if (android.provider.Settings.Global.getInt(mContext.getContentResolver(),
10468                    android.provider.Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, 1) == 0) {
10469                return false;
10470            }
10471        }
10472
10473        if (ensureVerifyAppsEnabled) {
10474            return true;
10475        }
10476
10477        return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
10478                android.provider.Settings.Global.PACKAGE_VERIFIER_ENABLE, 1) == 1;
10479    }
10480
10481    @Override
10482    public void verifyIntentFilter(int id, int verificationCode, List<String> failedDomains)
10483            throws RemoteException {
10484        mContext.enforceCallingOrSelfPermission(
10485                Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT,
10486                "Only intentfilter verification agents can verify applications");
10487
10488        final Message msg = mHandler.obtainMessage(INTENT_FILTER_VERIFIED);
10489        final IntentFilterVerificationResponse response = new IntentFilterVerificationResponse(
10490                Binder.getCallingUid(), verificationCode, failedDomains);
10491        msg.arg1 = id;
10492        msg.obj = response;
10493        mHandler.sendMessage(msg);
10494    }
10495
10496    @Override
10497    public int getIntentVerificationStatus(String packageName, int userId) {
10498        synchronized (mPackages) {
10499            return mSettings.getIntentFilterVerificationStatusLPr(packageName, userId);
10500        }
10501    }
10502
10503    @Override
10504    public boolean updateIntentVerificationStatus(String packageName, int status, int userId) {
10505        mContext.enforceCallingOrSelfPermission(
10506                android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
10507
10508        boolean result = false;
10509        synchronized (mPackages) {
10510            result = mSettings.updateIntentFilterVerificationStatusLPw(packageName, status, userId);
10511        }
10512        if (result) {
10513            scheduleWritePackageRestrictionsLocked(userId);
10514        }
10515        return result;
10516    }
10517
10518    @Override
10519    public List<IntentFilterVerificationInfo> getIntentFilterVerifications(String packageName) {
10520        synchronized (mPackages) {
10521            return mSettings.getIntentFilterVerificationsLPr(packageName);
10522        }
10523    }
10524
10525    @Override
10526    public List<IntentFilter> getAllIntentFilters(String packageName) {
10527        if (TextUtils.isEmpty(packageName)) {
10528            return Collections.<IntentFilter>emptyList();
10529        }
10530        synchronized (mPackages) {
10531            PackageParser.Package pkg = mPackages.get(packageName);
10532            if (pkg == null || pkg.activities == null) {
10533                return Collections.<IntentFilter>emptyList();
10534            }
10535            final int count = pkg.activities.size();
10536            ArrayList<IntentFilter> result = new ArrayList<>();
10537            for (int n=0; n<count; n++) {
10538                PackageParser.Activity activity = pkg.activities.get(n);
10539                if (activity.intents != null && activity.intents.size() > 0) {
10540                    result.addAll(activity.intents);
10541                }
10542            }
10543            return result;
10544        }
10545    }
10546
10547    @Override
10548    public boolean setDefaultBrowserPackageName(String packageName, int userId) {
10549        mContext.enforceCallingOrSelfPermission(
10550                android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
10551
10552        synchronized (mPackages) {
10553            boolean result = mSettings.setDefaultBrowserPackageNameLPw(packageName, userId);
10554            if (packageName != null) {
10555                result |= updateIntentVerificationStatus(packageName,
10556                        PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS,
10557                        userId);
10558                mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultBrowserLPr(
10559                        packageName, userId);
10560            }
10561            return result;
10562        }
10563    }
10564
10565    @Override
10566    public String getDefaultBrowserPackageName(int userId) {
10567        synchronized (mPackages) {
10568            return mSettings.getDefaultBrowserPackageNameLPw(userId);
10569        }
10570    }
10571
10572    /**
10573     * Get the "allow unknown sources" setting.
10574     *
10575     * @return the current "allow unknown sources" setting
10576     */
10577    private int getUnknownSourcesSettings() {
10578        return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
10579                android.provider.Settings.Global.INSTALL_NON_MARKET_APPS,
10580                -1);
10581    }
10582
10583    @Override
10584    public void setInstallerPackageName(String targetPackage, String installerPackageName) {
10585        final int uid = Binder.getCallingUid();
10586        // writer
10587        synchronized (mPackages) {
10588            PackageSetting targetPackageSetting = mSettings.mPackages.get(targetPackage);
10589            if (targetPackageSetting == null) {
10590                throw new IllegalArgumentException("Unknown target package: " + targetPackage);
10591            }
10592
10593            PackageSetting installerPackageSetting;
10594            if (installerPackageName != null) {
10595                installerPackageSetting = mSettings.mPackages.get(installerPackageName);
10596                if (installerPackageSetting == null) {
10597                    throw new IllegalArgumentException("Unknown installer package: "
10598                            + installerPackageName);
10599                }
10600            } else {
10601                installerPackageSetting = null;
10602            }
10603
10604            Signature[] callerSignature;
10605            Object obj = mSettings.getUserIdLPr(uid);
10606            if (obj != null) {
10607                if (obj instanceof SharedUserSetting) {
10608                    callerSignature = ((SharedUserSetting)obj).signatures.mSignatures;
10609                } else if (obj instanceof PackageSetting) {
10610                    callerSignature = ((PackageSetting)obj).signatures.mSignatures;
10611                } else {
10612                    throw new SecurityException("Bad object " + obj + " for uid " + uid);
10613                }
10614            } else {
10615                throw new SecurityException("Unknown calling UID: " + uid);
10616            }
10617
10618            // Verify: can't set installerPackageName to a package that is
10619            // not signed with the same cert as the caller.
10620            if (installerPackageSetting != null) {
10621                if (compareSignatures(callerSignature,
10622                        installerPackageSetting.signatures.mSignatures)
10623                        != PackageManager.SIGNATURE_MATCH) {
10624                    throw new SecurityException(
10625                            "Caller does not have same cert as new installer package "
10626                            + installerPackageName);
10627                }
10628            }
10629
10630            // Verify: if target already has an installer package, it must
10631            // be signed with the same cert as the caller.
10632            if (targetPackageSetting.installerPackageName != null) {
10633                PackageSetting setting = mSettings.mPackages.get(
10634                        targetPackageSetting.installerPackageName);
10635                // If the currently set package isn't valid, then it's always
10636                // okay to change it.
10637                if (setting != null) {
10638                    if (compareSignatures(callerSignature,
10639                            setting.signatures.mSignatures)
10640                            != PackageManager.SIGNATURE_MATCH) {
10641                        throw new SecurityException(
10642                                "Caller does not have same cert as old installer package "
10643                                + targetPackageSetting.installerPackageName);
10644                    }
10645                }
10646            }
10647
10648            // Okay!
10649            targetPackageSetting.installerPackageName = installerPackageName;
10650            scheduleWriteSettingsLocked();
10651        }
10652    }
10653
10654    private void processPendingInstall(final InstallArgs args, final int currentStatus) {
10655        // Queue up an async operation since the package installation may take a little while.
10656        mHandler.post(new Runnable() {
10657            public void run() {
10658                mHandler.removeCallbacks(this);
10659                 // Result object to be returned
10660                PackageInstalledInfo res = new PackageInstalledInfo();
10661                res.returnCode = currentStatus;
10662                res.uid = -1;
10663                res.pkg = null;
10664                res.removedInfo = new PackageRemovedInfo();
10665                if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
10666                    args.doPreInstall(res.returnCode);
10667                    synchronized (mInstallLock) {
10668                        installPackageTracedLI(args, res);
10669                    }
10670                    args.doPostInstall(res.returnCode, res.uid);
10671                }
10672
10673                // A restore should be performed at this point if (a) the install
10674                // succeeded, (b) the operation is not an update, and (c) the new
10675                // package has not opted out of backup participation.
10676                final boolean update = res.removedInfo.removedPackage != null;
10677                final int flags = (res.pkg == null) ? 0 : res.pkg.applicationInfo.flags;
10678                boolean doRestore = !update
10679                        && ((flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0);
10680
10681                // Set up the post-install work request bookkeeping.  This will be used
10682                // and cleaned up by the post-install event handling regardless of whether
10683                // there's a restore pass performed.  Token values are >= 1.
10684                int token;
10685                if (mNextInstallToken < 0) mNextInstallToken = 1;
10686                token = mNextInstallToken++;
10687
10688                PostInstallData data = new PostInstallData(args, res);
10689                mRunningInstalls.put(token, data);
10690                if (DEBUG_INSTALL) Log.v(TAG, "+ starting restore round-trip " + token);
10691
10692                if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && doRestore) {
10693                    // Pass responsibility to the Backup Manager.  It will perform a
10694                    // restore if appropriate, then pass responsibility back to the
10695                    // Package Manager to run the post-install observer callbacks
10696                    // and broadcasts.
10697                    IBackupManager bm = IBackupManager.Stub.asInterface(
10698                            ServiceManager.getService(Context.BACKUP_SERVICE));
10699                    if (bm != null) {
10700                        if (DEBUG_INSTALL) Log.v(TAG, "token " + token
10701                                + " to BM for possible restore");
10702                        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "restore", token);
10703                        try {
10704                            // TODO: http://b/22388012
10705                            if (bm.isBackupServiceActive(UserHandle.USER_SYSTEM)) {
10706                                bm.restoreAtInstall(res.pkg.applicationInfo.packageName, token);
10707                            } else {
10708                                doRestore = false;
10709                            }
10710                        } catch (RemoteException e) {
10711                            // can't happen; the backup manager is local
10712                        } catch (Exception e) {
10713                            Slog.e(TAG, "Exception trying to enqueue restore", e);
10714                            doRestore = false;
10715                        }
10716                    } else {
10717                        Slog.e(TAG, "Backup Manager not found!");
10718                        doRestore = false;
10719                    }
10720                }
10721
10722                if (!doRestore) {
10723                    // No restore possible, or the Backup Manager was mysteriously not
10724                    // available -- just fire the post-install work request directly.
10725                    if (DEBUG_INSTALL) Log.v(TAG, "No restore - queue post-install for " + token);
10726
10727                    Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "postInstall", token);
10728
10729                    Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0);
10730                    mHandler.sendMessage(msg);
10731                }
10732            }
10733        });
10734    }
10735
10736    private abstract class HandlerParams {
10737        private static final int MAX_RETRIES = 4;
10738
10739        /**
10740         * Number of times startCopy() has been attempted and had a non-fatal
10741         * error.
10742         */
10743        private int mRetries = 0;
10744
10745        /** User handle for the user requesting the information or installation. */
10746        private final UserHandle mUser;
10747        String traceMethod;
10748        int traceCookie;
10749
10750        HandlerParams(UserHandle user) {
10751            mUser = user;
10752        }
10753
10754        UserHandle getUser() {
10755            return mUser;
10756        }
10757
10758        HandlerParams setTraceMethod(String traceMethod) {
10759            this.traceMethod = traceMethod;
10760            return this;
10761        }
10762
10763        HandlerParams setTraceCookie(int traceCookie) {
10764            this.traceCookie = traceCookie;
10765            return this;
10766        }
10767
10768        final boolean startCopy() {
10769            boolean res;
10770            try {
10771                if (DEBUG_INSTALL) Slog.i(TAG, "startCopy " + mUser + ": " + this);
10772
10773                if (++mRetries > MAX_RETRIES) {
10774                    Slog.w(TAG, "Failed to invoke remote methods on default container service. Giving up");
10775                    mHandler.sendEmptyMessage(MCS_GIVE_UP);
10776                    handleServiceError();
10777                    return false;
10778                } else {
10779                    handleStartCopy();
10780                    res = true;
10781                }
10782            } catch (RemoteException e) {
10783                if (DEBUG_INSTALL) Slog.i(TAG, "Posting install MCS_RECONNECT");
10784                mHandler.sendEmptyMessage(MCS_RECONNECT);
10785                res = false;
10786            }
10787            handleReturnCode();
10788            return res;
10789        }
10790
10791        final void serviceError() {
10792            if (DEBUG_INSTALL) Slog.i(TAG, "serviceError");
10793            handleServiceError();
10794            handleReturnCode();
10795        }
10796
10797        abstract void handleStartCopy() throws RemoteException;
10798        abstract void handleServiceError();
10799        abstract void handleReturnCode();
10800    }
10801
10802    class MeasureParams extends HandlerParams {
10803        private final PackageStats mStats;
10804        private boolean mSuccess;
10805
10806        private final IPackageStatsObserver mObserver;
10807
10808        public MeasureParams(PackageStats stats, IPackageStatsObserver observer) {
10809            super(new UserHandle(stats.userHandle));
10810            mObserver = observer;
10811            mStats = stats;
10812        }
10813
10814        @Override
10815        public String toString() {
10816            return "MeasureParams{"
10817                + Integer.toHexString(System.identityHashCode(this))
10818                + " " + mStats.packageName + "}";
10819        }
10820
10821        @Override
10822        void handleStartCopy() throws RemoteException {
10823            synchronized (mInstallLock) {
10824                mSuccess = getPackageSizeInfoLI(mStats.packageName, mStats.userHandle, mStats);
10825            }
10826
10827            if (mSuccess) {
10828                final boolean mounted;
10829                if (Environment.isExternalStorageEmulated()) {
10830                    mounted = true;
10831                } else {
10832                    final String status = Environment.getExternalStorageState();
10833                    mounted = (Environment.MEDIA_MOUNTED.equals(status)
10834                            || Environment.MEDIA_MOUNTED_READ_ONLY.equals(status));
10835                }
10836
10837                if (mounted) {
10838                    final UserEnvironment userEnv = new UserEnvironment(mStats.userHandle);
10839
10840                    mStats.externalCacheSize = calculateDirectorySize(mContainerService,
10841                            userEnv.buildExternalStorageAppCacheDirs(mStats.packageName));
10842
10843                    mStats.externalDataSize = calculateDirectorySize(mContainerService,
10844                            userEnv.buildExternalStorageAppDataDirs(mStats.packageName));
10845
10846                    // Always subtract cache size, since it's a subdirectory
10847                    mStats.externalDataSize -= mStats.externalCacheSize;
10848
10849                    mStats.externalMediaSize = calculateDirectorySize(mContainerService,
10850                            userEnv.buildExternalStorageAppMediaDirs(mStats.packageName));
10851
10852                    mStats.externalObbSize = calculateDirectorySize(mContainerService,
10853                            userEnv.buildExternalStorageAppObbDirs(mStats.packageName));
10854                }
10855            }
10856        }
10857
10858        @Override
10859        void handleReturnCode() {
10860            if (mObserver != null) {
10861                try {
10862                    mObserver.onGetStatsCompleted(mStats, mSuccess);
10863                } catch (RemoteException e) {
10864                    Slog.i(TAG, "Observer no longer exists.");
10865                }
10866            }
10867        }
10868
10869        @Override
10870        void handleServiceError() {
10871            Slog.e(TAG, "Could not measure application " + mStats.packageName
10872                            + " external storage");
10873        }
10874    }
10875
10876    private static long calculateDirectorySize(IMediaContainerService mcs, File[] paths)
10877            throws RemoteException {
10878        long result = 0;
10879        for (File path : paths) {
10880            result += mcs.calculateDirectorySize(path.getAbsolutePath());
10881        }
10882        return result;
10883    }
10884
10885    private static void clearDirectory(IMediaContainerService mcs, File[] paths) {
10886        for (File path : paths) {
10887            try {
10888                mcs.clearDirectory(path.getAbsolutePath());
10889            } catch (RemoteException e) {
10890            }
10891        }
10892    }
10893
10894    static class OriginInfo {
10895        /**
10896         * Location where install is coming from, before it has been
10897         * copied/renamed into place. This could be a single monolithic APK
10898         * file, or a cluster directory. This location may be untrusted.
10899         */
10900        final File file;
10901        final String cid;
10902
10903        /**
10904         * Flag indicating that {@link #file} or {@link #cid} has already been
10905         * staged, meaning downstream users don't need to defensively copy the
10906         * contents.
10907         */
10908        final boolean staged;
10909
10910        /**
10911         * Flag indicating that {@link #file} or {@link #cid} is an already
10912         * installed app that is being moved.
10913         */
10914        final boolean existing;
10915
10916        final String resolvedPath;
10917        final File resolvedFile;
10918
10919        static OriginInfo fromNothing() {
10920            return new OriginInfo(null, null, false, false);
10921        }
10922
10923        static OriginInfo fromUntrustedFile(File file) {
10924            return new OriginInfo(file, null, false, false);
10925        }
10926
10927        static OriginInfo fromExistingFile(File file) {
10928            return new OriginInfo(file, null, false, true);
10929        }
10930
10931        static OriginInfo fromStagedFile(File file) {
10932            return new OriginInfo(file, null, true, false);
10933        }
10934
10935        static OriginInfo fromStagedContainer(String cid) {
10936            return new OriginInfo(null, cid, true, false);
10937        }
10938
10939        private OriginInfo(File file, String cid, boolean staged, boolean existing) {
10940            this.file = file;
10941            this.cid = cid;
10942            this.staged = staged;
10943            this.existing = existing;
10944
10945            if (cid != null) {
10946                resolvedPath = PackageHelper.getSdDir(cid);
10947                resolvedFile = new File(resolvedPath);
10948            } else if (file != null) {
10949                resolvedPath = file.getAbsolutePath();
10950                resolvedFile = file;
10951            } else {
10952                resolvedPath = null;
10953                resolvedFile = null;
10954            }
10955        }
10956    }
10957
10958    static class MoveInfo {
10959        final int moveId;
10960        final String fromUuid;
10961        final String toUuid;
10962        final String packageName;
10963        final String dataAppName;
10964        final int appId;
10965        final String seinfo;
10966        final int targetSdkVersion;
10967
10968        public MoveInfo(int moveId, String fromUuid, String toUuid, String packageName,
10969                String dataAppName, int appId, String seinfo, int targetSdkVersion) {
10970            this.moveId = moveId;
10971            this.fromUuid = fromUuid;
10972            this.toUuid = toUuid;
10973            this.packageName = packageName;
10974            this.dataAppName = dataAppName;
10975            this.appId = appId;
10976            this.seinfo = seinfo;
10977            this.targetSdkVersion = targetSdkVersion;
10978        }
10979    }
10980
10981    class InstallParams extends HandlerParams {
10982        final OriginInfo origin;
10983        final MoveInfo move;
10984        final IPackageInstallObserver2 observer;
10985        int installFlags;
10986        final String installerPackageName;
10987        final String volumeUuid;
10988        final VerificationParams verificationParams;
10989        private InstallArgs mArgs;
10990        private int mRet;
10991        final String packageAbiOverride;
10992        final String[] grantedRuntimePermissions;
10993
10994        InstallParams(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
10995                int installFlags, String installerPackageName, String volumeUuid,
10996                VerificationParams verificationParams, UserHandle user, String packageAbiOverride,
10997                String[] grantedPermissions) {
10998            super(user);
10999            this.origin = origin;
11000            this.move = move;
11001            this.observer = observer;
11002            this.installFlags = installFlags;
11003            this.installerPackageName = installerPackageName;
11004            this.volumeUuid = volumeUuid;
11005            this.verificationParams = verificationParams;
11006            this.packageAbiOverride = packageAbiOverride;
11007            this.grantedRuntimePermissions = grantedPermissions;
11008        }
11009
11010        @Override
11011        public String toString() {
11012            return "InstallParams{" + Integer.toHexString(System.identityHashCode(this))
11013                    + " file=" + origin.file + " cid=" + origin.cid + "}";
11014        }
11015
11016        private int installLocationPolicy(PackageInfoLite pkgLite) {
11017            String packageName = pkgLite.packageName;
11018            int installLocation = pkgLite.installLocation;
11019            boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
11020            // reader
11021            synchronized (mPackages) {
11022                PackageParser.Package pkg = mPackages.get(packageName);
11023                if (pkg != null) {
11024                    if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
11025                        // Check for downgrading.
11026                        if ((installFlags & PackageManager.INSTALL_ALLOW_DOWNGRADE) == 0) {
11027                            try {
11028                                checkDowngrade(pkg, pkgLite);
11029                            } catch (PackageManagerException e) {
11030                                Slog.w(TAG, "Downgrade detected: " + e.getMessage());
11031                                return PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE;
11032                            }
11033                        }
11034                        // Check for updated system application.
11035                        if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11036                            if (onSd) {
11037                                Slog.w(TAG, "Cannot install update to system app on sdcard");
11038                                return PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION;
11039                            }
11040                            return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
11041                        } else {
11042                            if (onSd) {
11043                                // Install flag overrides everything.
11044                                return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
11045                            }
11046                            // If current upgrade specifies particular preference
11047                            if (installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) {
11048                                // Application explicitly specified internal.
11049                                return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
11050                            } else if (installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) {
11051                                // App explictly prefers external. Let policy decide
11052                            } else {
11053                                // Prefer previous location
11054                                if (isExternal(pkg)) {
11055                                    return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
11056                                }
11057                                return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
11058                            }
11059                        }
11060                    } else {
11061                        // Invalid install. Return error code
11062                        return PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS;
11063                    }
11064                }
11065            }
11066            // All the special cases have been taken care of.
11067            // Return result based on recommended install location.
11068            if (onSd) {
11069                return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
11070            }
11071            return pkgLite.recommendedInstallLocation;
11072        }
11073
11074        /*
11075         * Invoke remote method to get package information and install
11076         * location values. Override install location based on default
11077         * policy if needed and then create install arguments based
11078         * on the install location.
11079         */
11080        public void handleStartCopy() throws RemoteException {
11081            int ret = PackageManager.INSTALL_SUCCEEDED;
11082
11083            // If we're already staged, we've firmly committed to an install location
11084            if (origin.staged) {
11085                if (origin.file != null) {
11086                    installFlags |= PackageManager.INSTALL_INTERNAL;
11087                    installFlags &= ~PackageManager.INSTALL_EXTERNAL;
11088                } else if (origin.cid != null) {
11089                    installFlags |= PackageManager.INSTALL_EXTERNAL;
11090                    installFlags &= ~PackageManager.INSTALL_INTERNAL;
11091                } else {
11092                    throw new IllegalStateException("Invalid stage location");
11093                }
11094            }
11095
11096            final boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
11097            final boolean onInt = (installFlags & PackageManager.INSTALL_INTERNAL) != 0;
11098            final boolean ephemeral = (installFlags & PackageManager.INSTALL_EPHEMERAL) != 0;
11099            PackageInfoLite pkgLite = null;
11100
11101            if (onInt && onSd) {
11102                // Check if both bits are set.
11103                Slog.w(TAG, "Conflicting flags specified for installing on both internal and external");
11104                ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
11105            } else if (onSd && ephemeral) {
11106                Slog.w(TAG,  "Conflicting flags specified for installing ephemeral on external");
11107                ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
11108            } else {
11109                pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, installFlags,
11110                        packageAbiOverride);
11111
11112                if (DEBUG_EPHEMERAL && ephemeral) {
11113                    Slog.v(TAG, "pkgLite for install: " + pkgLite);
11114                }
11115
11116                /*
11117                 * If we have too little free space, try to free cache
11118                 * before giving up.
11119                 */
11120                if (!origin.staged && pkgLite.recommendedInstallLocation
11121                        == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
11122                    // TODO: focus freeing disk space on the target device
11123                    final StorageManager storage = StorageManager.from(mContext);
11124                    final long lowThreshold = storage.getStorageLowBytes(
11125                            Environment.getDataDirectory());
11126
11127                    final long sizeBytes = mContainerService.calculateInstalledSize(
11128                            origin.resolvedPath, isForwardLocked(), packageAbiOverride);
11129
11130                    try {
11131                        mInstaller.freeCache(null, sizeBytes + lowThreshold);
11132                        pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath,
11133                                installFlags, packageAbiOverride);
11134                    } catch (InstallerException e) {
11135                        Slog.w(TAG, "Failed to free cache", e);
11136                    }
11137
11138                    /*
11139                     * The cache free must have deleted the file we
11140                     * downloaded to install.
11141                     *
11142                     * TODO: fix the "freeCache" call to not delete
11143                     *       the file we care about.
11144                     */
11145                    if (pkgLite.recommendedInstallLocation
11146                            == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
11147                        pkgLite.recommendedInstallLocation
11148                            = PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE;
11149                    }
11150                }
11151            }
11152
11153            if (ret == PackageManager.INSTALL_SUCCEEDED) {
11154                int loc = pkgLite.recommendedInstallLocation;
11155                if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION) {
11156                    ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
11157                } else if (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS) {
11158                    ret = PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
11159                } else if (loc == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
11160                    ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
11161                } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_APK) {
11162                    ret = PackageManager.INSTALL_FAILED_INVALID_APK;
11163                } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
11164                    ret = PackageManager.INSTALL_FAILED_INVALID_URI;
11165                } else if (loc == PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE) {
11166                    ret = PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE;
11167                } else {
11168                    // Override with defaults if needed.
11169                    loc = installLocationPolicy(pkgLite);
11170                    if (loc == PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE) {
11171                        ret = PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
11172                    } else if (!onSd && !onInt) {
11173                        // Override install location with flags
11174                        if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) {
11175                            // Set the flag to install on external media.
11176                            installFlags |= PackageManager.INSTALL_EXTERNAL;
11177                            installFlags &= ~PackageManager.INSTALL_INTERNAL;
11178                        } else if (loc == PackageHelper.RECOMMEND_INSTALL_EPHEMERAL) {
11179                            if (DEBUG_EPHEMERAL) {
11180                                Slog.v(TAG, "...setting INSTALL_EPHEMERAL install flag");
11181                            }
11182                            installFlags |= PackageManager.INSTALL_EPHEMERAL;
11183                            installFlags &= ~(PackageManager.INSTALL_EXTERNAL
11184                                    |PackageManager.INSTALL_INTERNAL);
11185                        } else {
11186                            // Make sure the flag for installing on external
11187                            // media is unset
11188                            installFlags |= PackageManager.INSTALL_INTERNAL;
11189                            installFlags &= ~PackageManager.INSTALL_EXTERNAL;
11190                        }
11191                    }
11192                }
11193            }
11194
11195            final InstallArgs args = createInstallArgs(this);
11196            mArgs = args;
11197
11198            if (ret == PackageManager.INSTALL_SUCCEEDED) {
11199                // TODO: http://b/22976637
11200                // Apps installed for "all" users use the device owner to verify the app
11201                UserHandle verifierUser = getUser();
11202                if (verifierUser == UserHandle.ALL) {
11203                    verifierUser = UserHandle.SYSTEM;
11204                }
11205
11206                /*
11207                 * Determine if we have any installed package verifiers. If we
11208                 * do, then we'll defer to them to verify the packages.
11209                 */
11210                final int requiredUid = mRequiredVerifierPackage == null ? -1
11211                        : getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
11212                                verifierUser.getIdentifier());
11213                if (!origin.existing && requiredUid != -1
11214                        && isVerificationEnabled(verifierUser.getIdentifier(), installFlags)) {
11215                    final Intent verification = new Intent(
11216                            Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
11217                    verification.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
11218                    verification.setDataAndType(Uri.fromFile(new File(origin.resolvedPath)),
11219                            PACKAGE_MIME_TYPE);
11220                    verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
11221
11222                    // Query all live verifiers based on current user state
11223                    final List<ResolveInfo> receivers = queryIntentReceivers(verification,
11224                            PACKAGE_MIME_TYPE, 0, verifierUser.getIdentifier());
11225
11226                    if (DEBUG_VERIFY) {
11227                        Slog.d(TAG, "Found " + receivers.size() + " verifiers for intent "
11228                                + verification.toString() + " with " + pkgLite.verifiers.length
11229                                + " optional verifiers");
11230                    }
11231
11232                    final int verificationId = mPendingVerificationToken++;
11233
11234                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
11235
11236                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_PACKAGE,
11237                            installerPackageName);
11238
11239                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALL_FLAGS,
11240                            installFlags);
11241
11242                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_PACKAGE_NAME,
11243                            pkgLite.packageName);
11244
11245                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_VERSION_CODE,
11246                            pkgLite.versionCode);
11247
11248                    if (verificationParams != null) {
11249                        if (verificationParams.getVerificationURI() != null) {
11250                           verification.putExtra(PackageManager.EXTRA_VERIFICATION_URI,
11251                                 verificationParams.getVerificationURI());
11252                        }
11253                        if (verificationParams.getOriginatingURI() != null) {
11254                            verification.putExtra(Intent.EXTRA_ORIGINATING_URI,
11255                                  verificationParams.getOriginatingURI());
11256                        }
11257                        if (verificationParams.getReferrer() != null) {
11258                            verification.putExtra(Intent.EXTRA_REFERRER,
11259                                  verificationParams.getReferrer());
11260                        }
11261                        if (verificationParams.getOriginatingUid() >= 0) {
11262                            verification.putExtra(Intent.EXTRA_ORIGINATING_UID,
11263                                  verificationParams.getOriginatingUid());
11264                        }
11265                        if (verificationParams.getInstallerUid() >= 0) {
11266                            verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_UID,
11267                                  verificationParams.getInstallerUid());
11268                        }
11269                    }
11270
11271                    final PackageVerificationState verificationState = new PackageVerificationState(
11272                            requiredUid, args);
11273
11274                    mPendingVerification.append(verificationId, verificationState);
11275
11276                    final List<ComponentName> sufficientVerifiers = matchVerifiers(pkgLite,
11277                            receivers, verificationState);
11278
11279                    /*
11280                     * If any sufficient verifiers were listed in the package
11281                     * manifest, attempt to ask them.
11282                     */
11283                    if (sufficientVerifiers != null) {
11284                        final int N = sufficientVerifiers.size();
11285                        if (N == 0) {
11286                            Slog.i(TAG, "Additional verifiers required, but none installed.");
11287                            ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
11288                        } else {
11289                            for (int i = 0; i < N; i++) {
11290                                final ComponentName verifierComponent = sufficientVerifiers.get(i);
11291
11292                                final Intent sufficientIntent = new Intent(verification);
11293                                sufficientIntent.setComponent(verifierComponent);
11294                                mContext.sendBroadcastAsUser(sufficientIntent, verifierUser);
11295                            }
11296                        }
11297                    }
11298
11299                    final ComponentName requiredVerifierComponent = matchComponentForVerifier(
11300                            mRequiredVerifierPackage, receivers);
11301                    if (ret == PackageManager.INSTALL_SUCCEEDED
11302                            && mRequiredVerifierPackage != null) {
11303                        Trace.asyncTraceBegin(
11304                                TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
11305                        /*
11306                         * Send the intent to the required verification agent,
11307                         * but only start the verification timeout after the
11308                         * target BroadcastReceivers have run.
11309                         */
11310                        verification.setComponent(requiredVerifierComponent);
11311                        mContext.sendOrderedBroadcastAsUser(verification, verifierUser,
11312                                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
11313                                new BroadcastReceiver() {
11314                                    @Override
11315                                    public void onReceive(Context context, Intent intent) {
11316                                        final Message msg = mHandler
11317                                                .obtainMessage(CHECK_PENDING_VERIFICATION);
11318                                        msg.arg1 = verificationId;
11319                                        mHandler.sendMessageDelayed(msg, getVerificationTimeout());
11320                                    }
11321                                }, null, 0, null, null);
11322
11323                        /*
11324                         * We don't want the copy to proceed until verification
11325                         * succeeds, so null out this field.
11326                         */
11327                        mArgs = null;
11328                    }
11329                } else {
11330                    /*
11331                     * No package verification is enabled, so immediately start
11332                     * the remote call to initiate copy using temporary file.
11333                     */
11334                    ret = args.copyApk(mContainerService, true);
11335                }
11336            }
11337
11338            mRet = ret;
11339        }
11340
11341        @Override
11342        void handleReturnCode() {
11343            // If mArgs is null, then MCS couldn't be reached. When it
11344            // reconnects, it will try again to install. At that point, this
11345            // will succeed.
11346            if (mArgs != null) {
11347                processPendingInstall(mArgs, mRet);
11348            }
11349        }
11350
11351        @Override
11352        void handleServiceError() {
11353            mArgs = createInstallArgs(this);
11354            mRet = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
11355        }
11356
11357        public boolean isForwardLocked() {
11358            return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
11359        }
11360    }
11361
11362    /**
11363     * Used during creation of InstallArgs
11364     *
11365     * @param installFlags package installation flags
11366     * @return true if should be installed on external storage
11367     */
11368    private static boolean installOnExternalAsec(int installFlags) {
11369        if ((installFlags & PackageManager.INSTALL_INTERNAL) != 0) {
11370            return false;
11371        }
11372        if ((installFlags & PackageManager.INSTALL_EXTERNAL) != 0) {
11373            return true;
11374        }
11375        return false;
11376    }
11377
11378    /**
11379     * Used during creation of InstallArgs
11380     *
11381     * @param installFlags package installation flags
11382     * @return true if should be installed as forward locked
11383     */
11384    private static boolean installForwardLocked(int installFlags) {
11385        return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
11386    }
11387
11388    private InstallArgs createInstallArgs(InstallParams params) {
11389        if (params.move != null) {
11390            return new MoveInstallArgs(params);
11391        } else if (installOnExternalAsec(params.installFlags) || params.isForwardLocked()) {
11392            return new AsecInstallArgs(params);
11393        } else {
11394            return new FileInstallArgs(params);
11395        }
11396    }
11397
11398    /**
11399     * Create args that describe an existing installed package. Typically used
11400     * when cleaning up old installs, or used as a move source.
11401     */
11402    private InstallArgs createInstallArgsForExisting(int installFlags, String codePath,
11403            String resourcePath, String[] instructionSets) {
11404        final boolean isInAsec;
11405        if (installOnExternalAsec(installFlags)) {
11406            /* Apps on SD card are always in ASEC containers. */
11407            isInAsec = true;
11408        } else if (installForwardLocked(installFlags)
11409                && !codePath.startsWith(mDrmAppPrivateInstallDir.getAbsolutePath())) {
11410            /*
11411             * Forward-locked apps are only in ASEC containers if they're the
11412             * new style
11413             */
11414            isInAsec = true;
11415        } else {
11416            isInAsec = false;
11417        }
11418
11419        if (isInAsec) {
11420            return new AsecInstallArgs(codePath, instructionSets,
11421                    installOnExternalAsec(installFlags), installForwardLocked(installFlags));
11422        } else {
11423            return new FileInstallArgs(codePath, resourcePath, instructionSets);
11424        }
11425    }
11426
11427    static abstract class InstallArgs {
11428        /** @see InstallParams#origin */
11429        final OriginInfo origin;
11430        /** @see InstallParams#move */
11431        final MoveInfo move;
11432
11433        final IPackageInstallObserver2 observer;
11434        // Always refers to PackageManager flags only
11435        final int installFlags;
11436        final String installerPackageName;
11437        final String volumeUuid;
11438        final UserHandle user;
11439        final String abiOverride;
11440        final String[] installGrantPermissions;
11441        /** If non-null, drop an async trace when the install completes */
11442        final String traceMethod;
11443        final int traceCookie;
11444
11445        // The list of instruction sets supported by this app. This is currently
11446        // only used during the rmdex() phase to clean up resources. We can get rid of this
11447        // if we move dex files under the common app path.
11448        /* nullable */ String[] instructionSets;
11449
11450        InstallArgs(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
11451                int installFlags, String installerPackageName, String volumeUuid,
11452                UserHandle user, String[] instructionSets,
11453                String abiOverride, String[] installGrantPermissions,
11454                String traceMethod, int traceCookie) {
11455            this.origin = origin;
11456            this.move = move;
11457            this.installFlags = installFlags;
11458            this.observer = observer;
11459            this.installerPackageName = installerPackageName;
11460            this.volumeUuid = volumeUuid;
11461            this.user = user;
11462            this.instructionSets = instructionSets;
11463            this.abiOverride = abiOverride;
11464            this.installGrantPermissions = installGrantPermissions;
11465            this.traceMethod = traceMethod;
11466            this.traceCookie = traceCookie;
11467        }
11468
11469        abstract int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException;
11470        abstract int doPreInstall(int status);
11471
11472        /**
11473         * Rename package into final resting place. All paths on the given
11474         * scanned package should be updated to reflect the rename.
11475         */
11476        abstract boolean doRename(int status, PackageParser.Package pkg, String oldCodePath);
11477        abstract int doPostInstall(int status, int uid);
11478
11479        /** @see PackageSettingBase#codePathString */
11480        abstract String getCodePath();
11481        /** @see PackageSettingBase#resourcePathString */
11482        abstract String getResourcePath();
11483
11484        // Need installer lock especially for dex file removal.
11485        abstract void cleanUpResourcesLI();
11486        abstract boolean doPostDeleteLI(boolean delete);
11487
11488        /**
11489         * Called before the source arguments are copied. This is used mostly
11490         * for MoveParams when it needs to read the source file to put it in the
11491         * destination.
11492         */
11493        int doPreCopy() {
11494            return PackageManager.INSTALL_SUCCEEDED;
11495        }
11496
11497        /**
11498         * Called after the source arguments are copied. This is used mostly for
11499         * MoveParams when it needs to read the source file to put it in the
11500         * destination.
11501         *
11502         * @return
11503         */
11504        int doPostCopy(int uid) {
11505            return PackageManager.INSTALL_SUCCEEDED;
11506        }
11507
11508        protected boolean isFwdLocked() {
11509            return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
11510        }
11511
11512        protected boolean isExternalAsec() {
11513            return (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
11514        }
11515
11516        protected boolean isEphemeral() {
11517            return (installFlags & PackageManager.INSTALL_EPHEMERAL) != 0;
11518        }
11519
11520        UserHandle getUser() {
11521            return user;
11522        }
11523    }
11524
11525    private void removeDexFiles(List<String> allCodePaths, String[] instructionSets) {
11526        if (!allCodePaths.isEmpty()) {
11527            if (instructionSets == null) {
11528                throw new IllegalStateException("instructionSet == null");
11529            }
11530            String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
11531            for (String codePath : allCodePaths) {
11532                for (String dexCodeInstructionSet : dexCodeInstructionSets) {
11533                    try {
11534                        mInstaller.rmdex(codePath, dexCodeInstructionSet);
11535                    } catch (InstallerException ignored) {
11536                    }
11537                }
11538            }
11539        }
11540    }
11541
11542    /**
11543     * Logic to handle installation of non-ASEC applications, including copying
11544     * and renaming logic.
11545     */
11546    class FileInstallArgs extends InstallArgs {
11547        private File codeFile;
11548        private File resourceFile;
11549
11550        // Example topology:
11551        // /data/app/com.example/base.apk
11552        // /data/app/com.example/split_foo.apk
11553        // /data/app/com.example/lib/arm/libfoo.so
11554        // /data/app/com.example/lib/arm64/libfoo.so
11555        // /data/app/com.example/dalvik/arm/base.apk@classes.dex
11556
11557        /** New install */
11558        FileInstallArgs(InstallParams params) {
11559            super(params.origin, params.move, params.observer, params.installFlags,
11560                    params.installerPackageName, params.volumeUuid,
11561                    params.getUser(), null /* instruction sets */, params.packageAbiOverride,
11562                    params.grantedRuntimePermissions,
11563                    params.traceMethod, params.traceCookie);
11564            if (isFwdLocked()) {
11565                throw new IllegalArgumentException("Forward locking only supported in ASEC");
11566            }
11567        }
11568
11569        /** Existing install */
11570        FileInstallArgs(String codePath, String resourcePath, String[] instructionSets) {
11571            super(OriginInfo.fromNothing(), null, null, 0, null, null, null, instructionSets,
11572                    null, null, null, 0);
11573            this.codeFile = (codePath != null) ? new File(codePath) : null;
11574            this.resourceFile = (resourcePath != null) ? new File(resourcePath) : null;
11575        }
11576
11577        int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
11578            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyApk");
11579            try {
11580                return doCopyApk(imcs, temp);
11581            } finally {
11582                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
11583            }
11584        }
11585
11586        private int doCopyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
11587            if (origin.staged) {
11588                if (DEBUG_INSTALL) Slog.d(TAG, origin.file + " already staged; skipping copy");
11589                codeFile = origin.file;
11590                resourceFile = origin.file;
11591                return PackageManager.INSTALL_SUCCEEDED;
11592            }
11593
11594            try {
11595                final boolean isEphemeral = (installFlags & PackageManager.INSTALL_EPHEMERAL) != 0;
11596                final File tempDir =
11597                        mInstallerService.allocateStageDirLegacy(volumeUuid, isEphemeral);
11598                codeFile = tempDir;
11599                resourceFile = tempDir;
11600            } catch (IOException e) {
11601                Slog.w(TAG, "Failed to create copy file: " + e);
11602                return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
11603            }
11604
11605            final IParcelFileDescriptorFactory target = new IParcelFileDescriptorFactory.Stub() {
11606                @Override
11607                public ParcelFileDescriptor open(String name, int mode) throws RemoteException {
11608                    if (!FileUtils.isValidExtFilename(name)) {
11609                        throw new IllegalArgumentException("Invalid filename: " + name);
11610                    }
11611                    try {
11612                        final File file = new File(codeFile, name);
11613                        final FileDescriptor fd = Os.open(file.getAbsolutePath(),
11614                                O_RDWR | O_CREAT, 0644);
11615                        Os.chmod(file.getAbsolutePath(), 0644);
11616                        return new ParcelFileDescriptor(fd);
11617                    } catch (ErrnoException e) {
11618                        throw new RemoteException("Failed to open: " + e.getMessage());
11619                    }
11620                }
11621            };
11622
11623            int ret = PackageManager.INSTALL_SUCCEEDED;
11624            ret = imcs.copyPackage(origin.file.getAbsolutePath(), target);
11625            if (ret != PackageManager.INSTALL_SUCCEEDED) {
11626                Slog.e(TAG, "Failed to copy package");
11627                return ret;
11628            }
11629
11630            final File libraryRoot = new File(codeFile, LIB_DIR_NAME);
11631            NativeLibraryHelper.Handle handle = null;
11632            try {
11633                handle = NativeLibraryHelper.Handle.create(codeFile);
11634                ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot,
11635                        abiOverride);
11636            } catch (IOException e) {
11637                Slog.e(TAG, "Copying native libraries failed", e);
11638                ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
11639            } finally {
11640                IoUtils.closeQuietly(handle);
11641            }
11642
11643            return ret;
11644        }
11645
11646        int doPreInstall(int status) {
11647            if (status != PackageManager.INSTALL_SUCCEEDED) {
11648                cleanUp();
11649            }
11650            return status;
11651        }
11652
11653        boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
11654            if (status != PackageManager.INSTALL_SUCCEEDED) {
11655                cleanUp();
11656                return false;
11657            }
11658
11659            final File targetDir = codeFile.getParentFile();
11660            final File beforeCodeFile = codeFile;
11661            final File afterCodeFile = getNextCodePath(targetDir, pkg.packageName);
11662
11663            if (DEBUG_INSTALL) Slog.d(TAG, "Renaming " + beforeCodeFile + " to " + afterCodeFile);
11664            try {
11665                Os.rename(beforeCodeFile.getAbsolutePath(), afterCodeFile.getAbsolutePath());
11666            } catch (ErrnoException e) {
11667                Slog.w(TAG, "Failed to rename", e);
11668                return false;
11669            }
11670
11671            if (!SELinux.restoreconRecursive(afterCodeFile)) {
11672                Slog.w(TAG, "Failed to restorecon");
11673                return false;
11674            }
11675
11676            // Reflect the rename internally
11677            codeFile = afterCodeFile;
11678            resourceFile = afterCodeFile;
11679
11680            // Reflect the rename in scanned details
11681            pkg.codePath = afterCodeFile.getAbsolutePath();
11682            pkg.baseCodePath = FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile,
11683                    pkg.baseCodePath);
11684            pkg.splitCodePaths = FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile,
11685                    pkg.splitCodePaths);
11686
11687            // Reflect the rename in app info
11688            pkg.applicationInfo.volumeUuid = pkg.volumeUuid;
11689            pkg.applicationInfo.setCodePath(pkg.codePath);
11690            pkg.applicationInfo.setBaseCodePath(pkg.baseCodePath);
11691            pkg.applicationInfo.setSplitCodePaths(pkg.splitCodePaths);
11692            pkg.applicationInfo.setResourcePath(pkg.codePath);
11693            pkg.applicationInfo.setBaseResourcePath(pkg.baseCodePath);
11694            pkg.applicationInfo.setSplitResourcePaths(pkg.splitCodePaths);
11695
11696            return true;
11697        }
11698
11699        int doPostInstall(int status, int uid) {
11700            if (status != PackageManager.INSTALL_SUCCEEDED) {
11701                cleanUp();
11702            }
11703            return status;
11704        }
11705
11706        @Override
11707        String getCodePath() {
11708            return (codeFile != null) ? codeFile.getAbsolutePath() : null;
11709        }
11710
11711        @Override
11712        String getResourcePath() {
11713            return (resourceFile != null) ? resourceFile.getAbsolutePath() : null;
11714        }
11715
11716        private boolean cleanUp() {
11717            if (codeFile == null || !codeFile.exists()) {
11718                return false;
11719            }
11720
11721            removeCodePathLI(codeFile);
11722
11723            if (resourceFile != null && !FileUtils.contains(codeFile, resourceFile)) {
11724                resourceFile.delete();
11725            }
11726
11727            return true;
11728        }
11729
11730        void cleanUpResourcesLI() {
11731            // Try enumerating all code paths before deleting
11732            List<String> allCodePaths = Collections.EMPTY_LIST;
11733            if (codeFile != null && codeFile.exists()) {
11734                try {
11735                    final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0);
11736                    allCodePaths = pkg.getAllCodePaths();
11737                } catch (PackageParserException e) {
11738                    // Ignored; we tried our best
11739                }
11740            }
11741
11742            cleanUp();
11743            removeDexFiles(allCodePaths, instructionSets);
11744        }
11745
11746        boolean doPostDeleteLI(boolean delete) {
11747            // XXX err, shouldn't we respect the delete flag?
11748            cleanUpResourcesLI();
11749            return true;
11750        }
11751    }
11752
11753    private boolean isAsecExternal(String cid) {
11754        final String asecPath = PackageHelper.getSdFilesystem(cid);
11755        return !asecPath.startsWith(mAsecInternalPath);
11756    }
11757
11758    private static void maybeThrowExceptionForMultiArchCopy(String message, int copyRet) throws
11759            PackageManagerException {
11760        if (copyRet < 0) {
11761            if (copyRet != PackageManager.NO_NATIVE_LIBRARIES &&
11762                    copyRet != PackageManager.INSTALL_FAILED_NO_MATCHING_ABIS) {
11763                throw new PackageManagerException(copyRet, message);
11764            }
11765        }
11766    }
11767
11768    /**
11769     * Extract the MountService "container ID" from the full code path of an
11770     * .apk.
11771     */
11772    static String cidFromCodePath(String fullCodePath) {
11773        int eidx = fullCodePath.lastIndexOf("/");
11774        String subStr1 = fullCodePath.substring(0, eidx);
11775        int sidx = subStr1.lastIndexOf("/");
11776        return subStr1.substring(sidx+1, eidx);
11777    }
11778
11779    /**
11780     * Logic to handle installation of ASEC applications, including copying and
11781     * renaming logic.
11782     */
11783    class AsecInstallArgs extends InstallArgs {
11784        static final String RES_FILE_NAME = "pkg.apk";
11785        static final String PUBLIC_RES_FILE_NAME = "res.zip";
11786
11787        String cid;
11788        String packagePath;
11789        String resourcePath;
11790
11791        /** New install */
11792        AsecInstallArgs(InstallParams params) {
11793            super(params.origin, params.move, params.observer, params.installFlags,
11794                    params.installerPackageName, params.volumeUuid,
11795                    params.getUser(), null /* instruction sets */, params.packageAbiOverride,
11796                    params.grantedRuntimePermissions,
11797                    params.traceMethod, params.traceCookie);
11798        }
11799
11800        /** Existing install */
11801        AsecInstallArgs(String fullCodePath, String[] instructionSets,
11802                        boolean isExternal, boolean isForwardLocked) {
11803            super(OriginInfo.fromNothing(), null, null, (isExternal ? INSTALL_EXTERNAL : 0)
11804                    | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null,
11805                    instructionSets, null, null, null, 0);
11806            // Hackily pretend we're still looking at a full code path
11807            if (!fullCodePath.endsWith(RES_FILE_NAME)) {
11808                fullCodePath = new File(fullCodePath, RES_FILE_NAME).getAbsolutePath();
11809            }
11810
11811            // Extract cid from fullCodePath
11812            int eidx = fullCodePath.lastIndexOf("/");
11813            String subStr1 = fullCodePath.substring(0, eidx);
11814            int sidx = subStr1.lastIndexOf("/");
11815            cid = subStr1.substring(sidx+1, eidx);
11816            setMountPath(subStr1);
11817        }
11818
11819        AsecInstallArgs(String cid, String[] instructionSets, boolean isForwardLocked) {
11820            super(OriginInfo.fromNothing(), null, null, (isAsecExternal(cid) ? INSTALL_EXTERNAL : 0)
11821                    | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null,
11822                    instructionSets, null, null, null, 0);
11823            this.cid = cid;
11824            setMountPath(PackageHelper.getSdDir(cid));
11825        }
11826
11827        void createCopyFile() {
11828            cid = mInstallerService.allocateExternalStageCidLegacy();
11829        }
11830
11831        int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
11832            if (origin.staged && origin.cid != null) {
11833                if (DEBUG_INSTALL) Slog.d(TAG, origin.cid + " already staged; skipping copy");
11834                cid = origin.cid;
11835                setMountPath(PackageHelper.getSdDir(cid));
11836                return PackageManager.INSTALL_SUCCEEDED;
11837            }
11838
11839            if (temp) {
11840                createCopyFile();
11841            } else {
11842                /*
11843                 * Pre-emptively destroy the container since it's destroyed if
11844                 * copying fails due to it existing anyway.
11845                 */
11846                PackageHelper.destroySdDir(cid);
11847            }
11848
11849            final String newMountPath = imcs.copyPackageToContainer(
11850                    origin.file.getAbsolutePath(), cid, getEncryptKey(), isExternalAsec(),
11851                    isFwdLocked(), deriveAbiOverride(abiOverride, null /* settings */));
11852
11853            if (newMountPath != null) {
11854                setMountPath(newMountPath);
11855                return PackageManager.INSTALL_SUCCEEDED;
11856            } else {
11857                return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
11858            }
11859        }
11860
11861        @Override
11862        String getCodePath() {
11863            return packagePath;
11864        }
11865
11866        @Override
11867        String getResourcePath() {
11868            return resourcePath;
11869        }
11870
11871        int doPreInstall(int status) {
11872            if (status != PackageManager.INSTALL_SUCCEEDED) {
11873                // Destroy container
11874                PackageHelper.destroySdDir(cid);
11875            } else {
11876                boolean mounted = PackageHelper.isContainerMounted(cid);
11877                if (!mounted) {
11878                    String newMountPath = PackageHelper.mountSdDir(cid, getEncryptKey(),
11879                            Process.SYSTEM_UID);
11880                    if (newMountPath != null) {
11881                        setMountPath(newMountPath);
11882                    } else {
11883                        return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
11884                    }
11885                }
11886            }
11887            return status;
11888        }
11889
11890        boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
11891            String newCacheId = getNextCodePath(oldCodePath, pkg.packageName, "/" + RES_FILE_NAME);
11892            String newMountPath = null;
11893            if (PackageHelper.isContainerMounted(cid)) {
11894                // Unmount the container
11895                if (!PackageHelper.unMountSdDir(cid)) {
11896                    Slog.i(TAG, "Failed to unmount " + cid + " before renaming");
11897                    return false;
11898                }
11899            }
11900            if (!PackageHelper.renameSdDir(cid, newCacheId)) {
11901                Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId +
11902                        " which might be stale. Will try to clean up.");
11903                // Clean up the stale container and proceed to recreate.
11904                if (!PackageHelper.destroySdDir(newCacheId)) {
11905                    Slog.e(TAG, "Very strange. Cannot clean up stale container " + newCacheId);
11906                    return false;
11907                }
11908                // Successfully cleaned up stale container. Try to rename again.
11909                if (!PackageHelper.renameSdDir(cid, newCacheId)) {
11910                    Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId
11911                            + " inspite of cleaning it up.");
11912                    return false;
11913                }
11914            }
11915            if (!PackageHelper.isContainerMounted(newCacheId)) {
11916                Slog.w(TAG, "Mounting container " + newCacheId);
11917                newMountPath = PackageHelper.mountSdDir(newCacheId,
11918                        getEncryptKey(), Process.SYSTEM_UID);
11919            } else {
11920                newMountPath = PackageHelper.getSdDir(newCacheId);
11921            }
11922            if (newMountPath == null) {
11923                Slog.w(TAG, "Failed to get cache path for  " + newCacheId);
11924                return false;
11925            }
11926            Log.i(TAG, "Succesfully renamed " + cid +
11927                    " to " + newCacheId +
11928                    " at new path: " + newMountPath);
11929            cid = newCacheId;
11930
11931            final File beforeCodeFile = new File(packagePath);
11932            setMountPath(newMountPath);
11933            final File afterCodeFile = new File(packagePath);
11934
11935            // Reflect the rename in scanned details
11936            pkg.codePath = afterCodeFile.getAbsolutePath();
11937            pkg.baseCodePath = FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile,
11938                    pkg.baseCodePath);
11939            pkg.splitCodePaths = FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile,
11940                    pkg.splitCodePaths);
11941
11942            // Reflect the rename in app info
11943            pkg.applicationInfo.volumeUuid = pkg.volumeUuid;
11944            pkg.applicationInfo.setCodePath(pkg.codePath);
11945            pkg.applicationInfo.setBaseCodePath(pkg.baseCodePath);
11946            pkg.applicationInfo.setSplitCodePaths(pkg.splitCodePaths);
11947            pkg.applicationInfo.setResourcePath(pkg.codePath);
11948            pkg.applicationInfo.setBaseResourcePath(pkg.baseCodePath);
11949            pkg.applicationInfo.setSplitResourcePaths(pkg.splitCodePaths);
11950
11951            return true;
11952        }
11953
11954        private void setMountPath(String mountPath) {
11955            final File mountFile = new File(mountPath);
11956
11957            final File monolithicFile = new File(mountFile, RES_FILE_NAME);
11958            if (monolithicFile.exists()) {
11959                packagePath = monolithicFile.getAbsolutePath();
11960                if (isFwdLocked()) {
11961                    resourcePath = new File(mountFile, PUBLIC_RES_FILE_NAME).getAbsolutePath();
11962                } else {
11963                    resourcePath = packagePath;
11964                }
11965            } else {
11966                packagePath = mountFile.getAbsolutePath();
11967                resourcePath = packagePath;
11968            }
11969        }
11970
11971        int doPostInstall(int status, int uid) {
11972            if (status != PackageManager.INSTALL_SUCCEEDED) {
11973                cleanUp();
11974            } else {
11975                final int groupOwner;
11976                final String protectedFile;
11977                if (isFwdLocked()) {
11978                    groupOwner = UserHandle.getSharedAppGid(uid);
11979                    protectedFile = RES_FILE_NAME;
11980                } else {
11981                    groupOwner = -1;
11982                    protectedFile = null;
11983                }
11984
11985                if (uid < Process.FIRST_APPLICATION_UID
11986                        || !PackageHelper.fixSdPermissions(cid, groupOwner, protectedFile)) {
11987                    Slog.e(TAG, "Failed to finalize " + cid);
11988                    PackageHelper.destroySdDir(cid);
11989                    return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
11990                }
11991
11992                boolean mounted = PackageHelper.isContainerMounted(cid);
11993                if (!mounted) {
11994                    PackageHelper.mountSdDir(cid, getEncryptKey(), Process.myUid());
11995                }
11996            }
11997            return status;
11998        }
11999
12000        private void cleanUp() {
12001            if (DEBUG_SD_INSTALL) Slog.i(TAG, "cleanUp");
12002
12003            // Destroy secure container
12004            PackageHelper.destroySdDir(cid);
12005        }
12006
12007        private List<String> getAllCodePaths() {
12008            final File codeFile = new File(getCodePath());
12009            if (codeFile != null && codeFile.exists()) {
12010                try {
12011                    final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0);
12012                    return pkg.getAllCodePaths();
12013                } catch (PackageParserException e) {
12014                    // Ignored; we tried our best
12015                }
12016            }
12017            return Collections.EMPTY_LIST;
12018        }
12019
12020        void cleanUpResourcesLI() {
12021            // Enumerate all code paths before deleting
12022            cleanUpResourcesLI(getAllCodePaths());
12023        }
12024
12025        private void cleanUpResourcesLI(List<String> allCodePaths) {
12026            cleanUp();
12027            removeDexFiles(allCodePaths, instructionSets);
12028        }
12029
12030        String getPackageName() {
12031            return getAsecPackageName(cid);
12032        }
12033
12034        boolean doPostDeleteLI(boolean delete) {
12035            if (DEBUG_SD_INSTALL) Slog.i(TAG, "doPostDeleteLI() del=" + delete);
12036            final List<String> allCodePaths = getAllCodePaths();
12037            boolean mounted = PackageHelper.isContainerMounted(cid);
12038            if (mounted) {
12039                // Unmount first
12040                if (PackageHelper.unMountSdDir(cid)) {
12041                    mounted = false;
12042                }
12043            }
12044            if (!mounted && delete) {
12045                cleanUpResourcesLI(allCodePaths);
12046            }
12047            return !mounted;
12048        }
12049
12050        @Override
12051        int doPreCopy() {
12052            if (isFwdLocked()) {
12053                if (!PackageHelper.fixSdPermissions(cid, getPackageUid(DEFAULT_CONTAINER_PACKAGE,
12054                        MATCH_SYSTEM_ONLY, UserHandle.USER_SYSTEM), RES_FILE_NAME)) {
12055                    return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
12056                }
12057            }
12058
12059            return PackageManager.INSTALL_SUCCEEDED;
12060        }
12061
12062        @Override
12063        int doPostCopy(int uid) {
12064            if (isFwdLocked()) {
12065                if (uid < Process.FIRST_APPLICATION_UID
12066                        || !PackageHelper.fixSdPermissions(cid, UserHandle.getSharedAppGid(uid),
12067                                RES_FILE_NAME)) {
12068                    Slog.e(TAG, "Failed to finalize " + cid);
12069                    PackageHelper.destroySdDir(cid);
12070                    return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
12071                }
12072            }
12073
12074            return PackageManager.INSTALL_SUCCEEDED;
12075        }
12076    }
12077
12078    /**
12079     * Logic to handle movement of existing installed applications.
12080     */
12081    class MoveInstallArgs extends InstallArgs {
12082        private File codeFile;
12083        private File resourceFile;
12084
12085        /** New install */
12086        MoveInstallArgs(InstallParams params) {
12087            super(params.origin, params.move, params.observer, params.installFlags,
12088                    params.installerPackageName, params.volumeUuid,
12089                    params.getUser(), null /* instruction sets */, params.packageAbiOverride,
12090                    params.grantedRuntimePermissions,
12091                    params.traceMethod, params.traceCookie);
12092        }
12093
12094        int copyApk(IMediaContainerService imcs, boolean temp) {
12095            if (DEBUG_INSTALL) Slog.d(TAG, "Moving " + move.packageName + " from "
12096                    + move.fromUuid + " to " + move.toUuid);
12097            synchronized (mInstaller) {
12098                try {
12099                    mInstaller.moveCompleteApp(move.fromUuid, move.toUuid, move.packageName,
12100                            move.dataAppName, move.appId, move.seinfo, move.targetSdkVersion);
12101                } catch (InstallerException e) {
12102                    Slog.w(TAG, "Failed to move app", e);
12103                    return PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
12104                }
12105            }
12106
12107            codeFile = new File(Environment.getDataAppDirectory(move.toUuid), move.dataAppName);
12108            resourceFile = codeFile;
12109            if (DEBUG_INSTALL) Slog.d(TAG, "codeFile after move is " + codeFile);
12110
12111            return PackageManager.INSTALL_SUCCEEDED;
12112        }
12113
12114        int doPreInstall(int status) {
12115            if (status != PackageManager.INSTALL_SUCCEEDED) {
12116                cleanUp(move.toUuid);
12117            }
12118            return status;
12119        }
12120
12121        boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
12122            if (status != PackageManager.INSTALL_SUCCEEDED) {
12123                cleanUp(move.toUuid);
12124                return false;
12125            }
12126
12127            // Reflect the move in app info
12128            pkg.applicationInfo.volumeUuid = pkg.volumeUuid;
12129            pkg.applicationInfo.setCodePath(pkg.codePath);
12130            pkg.applicationInfo.setBaseCodePath(pkg.baseCodePath);
12131            pkg.applicationInfo.setSplitCodePaths(pkg.splitCodePaths);
12132            pkg.applicationInfo.setResourcePath(pkg.codePath);
12133            pkg.applicationInfo.setBaseResourcePath(pkg.baseCodePath);
12134            pkg.applicationInfo.setSplitResourcePaths(pkg.splitCodePaths);
12135
12136            return true;
12137        }
12138
12139        int doPostInstall(int status, int uid) {
12140            if (status == PackageManager.INSTALL_SUCCEEDED) {
12141                cleanUp(move.fromUuid);
12142            } else {
12143                cleanUp(move.toUuid);
12144            }
12145            return status;
12146        }
12147
12148        @Override
12149        String getCodePath() {
12150            return (codeFile != null) ? codeFile.getAbsolutePath() : null;
12151        }
12152
12153        @Override
12154        String getResourcePath() {
12155            return (resourceFile != null) ? resourceFile.getAbsolutePath() : null;
12156        }
12157
12158        private boolean cleanUp(String volumeUuid) {
12159            final File codeFile = new File(Environment.getDataAppDirectory(volumeUuid),
12160                    move.dataAppName);
12161            Slog.d(TAG, "Cleaning up " + move.packageName + " on " + volumeUuid);
12162            synchronized (mInstallLock) {
12163                // Clean up both app data and code
12164                removeDataDirsLI(volumeUuid, move.packageName);
12165                removeCodePathLI(codeFile);
12166            }
12167            return true;
12168        }
12169
12170        void cleanUpResourcesLI() {
12171            throw new UnsupportedOperationException();
12172        }
12173
12174        boolean doPostDeleteLI(boolean delete) {
12175            throw new UnsupportedOperationException();
12176        }
12177    }
12178
12179    static String getAsecPackageName(String packageCid) {
12180        int idx = packageCid.lastIndexOf("-");
12181        if (idx == -1) {
12182            return packageCid;
12183        }
12184        return packageCid.substring(0, idx);
12185    }
12186
12187    // Utility method used to create code paths based on package name and available index.
12188    private static String getNextCodePath(String oldCodePath, String prefix, String suffix) {
12189        String idxStr = "";
12190        int idx = 1;
12191        // Fall back to default value of idx=1 if prefix is not
12192        // part of oldCodePath
12193        if (oldCodePath != null) {
12194            String subStr = oldCodePath;
12195            // Drop the suffix right away
12196            if (suffix != null && subStr.endsWith(suffix)) {
12197                subStr = subStr.substring(0, subStr.length() - suffix.length());
12198            }
12199            // If oldCodePath already contains prefix find out the
12200            // ending index to either increment or decrement.
12201            int sidx = subStr.lastIndexOf(prefix);
12202            if (sidx != -1) {
12203                subStr = subStr.substring(sidx + prefix.length());
12204                if (subStr != null) {
12205                    if (subStr.startsWith(INSTALL_PACKAGE_SUFFIX)) {
12206                        subStr = subStr.substring(INSTALL_PACKAGE_SUFFIX.length());
12207                    }
12208                    try {
12209                        idx = Integer.parseInt(subStr);
12210                        if (idx <= 1) {
12211                            idx++;
12212                        } else {
12213                            idx--;
12214                        }
12215                    } catch(NumberFormatException e) {
12216                    }
12217                }
12218            }
12219        }
12220        idxStr = INSTALL_PACKAGE_SUFFIX + Integer.toString(idx);
12221        return prefix + idxStr;
12222    }
12223
12224    private File getNextCodePath(File targetDir, String packageName) {
12225        int suffix = 1;
12226        File result;
12227        do {
12228            result = new File(targetDir, packageName + "-" + suffix);
12229            suffix++;
12230        } while (result.exists());
12231        return result;
12232    }
12233
12234    // Utility method that returns the relative package path with respect
12235    // to the installation directory. Like say for /data/data/com.test-1.apk
12236    // string com.test-1 is returned.
12237    static String deriveCodePathName(String codePath) {
12238        if (codePath == null) {
12239            return null;
12240        }
12241        final File codeFile = new File(codePath);
12242        final String name = codeFile.getName();
12243        if (codeFile.isDirectory()) {
12244            return name;
12245        } else if (name.endsWith(".apk") || name.endsWith(".tmp")) {
12246            final int lastDot = name.lastIndexOf('.');
12247            return name.substring(0, lastDot);
12248        } else {
12249            Slog.w(TAG, "Odd, " + codePath + " doesn't look like an APK");
12250            return null;
12251        }
12252    }
12253
12254    static class PackageInstalledInfo {
12255        String name;
12256        int uid;
12257        // The set of users that originally had this package installed.
12258        int[] origUsers;
12259        // The set of users that now have this package installed.
12260        int[] newUsers;
12261        PackageParser.Package pkg;
12262        int returnCode;
12263        String returnMsg;
12264        PackageRemovedInfo removedInfo;
12265
12266        public void setError(int code, String msg) {
12267            returnCode = code;
12268            returnMsg = msg;
12269            Slog.w(TAG, msg);
12270        }
12271
12272        public void setError(String msg, PackageParserException e) {
12273            returnCode = e.error;
12274            returnMsg = ExceptionUtils.getCompleteMessage(msg, e);
12275            Slog.w(TAG, msg, e);
12276        }
12277
12278        public void setError(String msg, PackageManagerException e) {
12279            returnCode = e.error;
12280            returnMsg = ExceptionUtils.getCompleteMessage(msg, e);
12281            Slog.w(TAG, msg, e);
12282        }
12283
12284        // In some error cases we want to convey more info back to the observer
12285        String origPackage;
12286        String origPermission;
12287    }
12288
12289    /*
12290     * Install a non-existing package.
12291     */
12292    private void installNewPackageLI(PackageParser.Package pkg, int parseFlags, int scanFlags,
12293            UserHandle user, String installerPackageName, String volumeUuid,
12294            PackageInstalledInfo res) {
12295        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installNewPackage");
12296
12297        // Remember this for later, in case we need to rollback this install
12298        String pkgName = pkg.packageName;
12299
12300        if (DEBUG_INSTALL) Slog.d(TAG, "installNewPackageLI: " + pkg);
12301        // TODO: b/23350563
12302        final boolean dataDirExists = Environment
12303                .getDataUserPackageDirectory(volumeUuid, UserHandle.USER_SYSTEM, pkgName).exists();
12304
12305        synchronized(mPackages) {
12306            if (mSettings.mRenamedPackages.containsKey(pkgName)) {
12307                // A package with the same name is already installed, though
12308                // it has been renamed to an older name.  The package we
12309                // are trying to install should be installed as an update to
12310                // the existing one, but that has not been requested, so bail.
12311                res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName
12312                        + " without first uninstalling package running as "
12313                        + mSettings.mRenamedPackages.get(pkgName));
12314                return;
12315            }
12316            if (mPackages.containsKey(pkgName)) {
12317                // Don't allow installation over an existing package with the same name.
12318                res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName
12319                        + " without first uninstalling.");
12320                return;
12321            }
12322        }
12323
12324        try {
12325            PackageParser.Package newPackage = scanPackageTracedLI(pkg, parseFlags, scanFlags,
12326                    System.currentTimeMillis(), user);
12327
12328            updateSettingsLI(newPackage, installerPackageName, volumeUuid, null, null, res, user);
12329            prepareAppDataAfterInstall(newPackage);
12330
12331            // delete the partially installed application. the data directory will have to be
12332            // restored if it was already existing
12333            if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
12334                // remove package from internal structures.  Note that we want deletePackageX to
12335                // delete the package data and cache directories that it created in
12336                // scanPackageLocked, unless those directories existed before we even tried to
12337                // install.
12338                deletePackageLI(pkgName, UserHandle.ALL, false, null, null,
12339                        dataDirExists ? PackageManager.DELETE_KEEP_DATA : 0,
12340                                res.removedInfo, true);
12341            }
12342
12343        } catch (PackageManagerException e) {
12344            res.setError("Package couldn't be installed in " + pkg.codePath, e);
12345        }
12346
12347        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
12348    }
12349
12350    private boolean shouldCheckUpgradeKeySetLP(PackageSetting oldPs, int scanFlags) {
12351        // Can't rotate keys during boot or if sharedUser.
12352        if (oldPs == null || (scanFlags&SCAN_INITIAL) != 0 || oldPs.sharedUser != null
12353                || !oldPs.keySetData.isUsingUpgradeKeySets()) {
12354            return false;
12355        }
12356        // app is using upgradeKeySets; make sure all are valid
12357        KeySetManagerService ksms = mSettings.mKeySetManagerService;
12358        long[] upgradeKeySets = oldPs.keySetData.getUpgradeKeySets();
12359        for (int i = 0; i < upgradeKeySets.length; i++) {
12360            if (!ksms.isIdValidKeySetId(upgradeKeySets[i])) {
12361                Slog.wtf(TAG, "Package "
12362                         + (oldPs.name != null ? oldPs.name : "<null>")
12363                         + " contains upgrade-key-set reference to unknown key-set: "
12364                         + upgradeKeySets[i]
12365                         + " reverting to signatures check.");
12366                return false;
12367            }
12368        }
12369        return true;
12370    }
12371
12372    private boolean checkUpgradeKeySetLP(PackageSetting oldPS, PackageParser.Package newPkg) {
12373        // Upgrade keysets are being used.  Determine if new package has a superset of the
12374        // required keys.
12375        long[] upgradeKeySets = oldPS.keySetData.getUpgradeKeySets();
12376        KeySetManagerService ksms = mSettings.mKeySetManagerService;
12377        for (int i = 0; i < upgradeKeySets.length; i++) {
12378            Set<PublicKey> upgradeSet = ksms.getPublicKeysFromKeySetLPr(upgradeKeySets[i]);
12379            if (upgradeSet != null && newPkg.mSigningKeys.containsAll(upgradeSet)) {
12380                return true;
12381            }
12382        }
12383        return false;
12384    }
12385
12386    private void replacePackageLI(PackageParser.Package pkg, int parseFlags, int scanFlags,
12387            UserHandle user, String installerPackageName, String volumeUuid,
12388            PackageInstalledInfo res) {
12389        final boolean isEphemeral = (parseFlags & PackageParser.PARSE_IS_EPHEMERAL) != 0;
12390
12391        final PackageParser.Package oldPackage;
12392        final String pkgName = pkg.packageName;
12393        final int[] allUsers;
12394        final boolean[] perUserInstalled;
12395
12396        // First find the old package info and check signatures
12397        synchronized(mPackages) {
12398            oldPackage = mPackages.get(pkgName);
12399            final boolean oldIsEphemeral = oldPackage.applicationInfo.isEphemeralApp();
12400            if (isEphemeral && !oldIsEphemeral) {
12401                // can't downgrade from full to ephemeral
12402                Slog.w(TAG, "Can't replace app with ephemeral: " + pkgName);
12403                res.returnCode = PackageManager.INSTALL_FAILED_EPHEMERAL_INVALID;
12404                return;
12405            }
12406            if (DEBUG_INSTALL) Slog.d(TAG, "replacePackageLI: new=" + pkg + ", old=" + oldPackage);
12407            final PackageSetting ps = mSettings.mPackages.get(pkgName);
12408            if (shouldCheckUpgradeKeySetLP(ps, scanFlags)) {
12409                if(!checkUpgradeKeySetLP(ps, pkg)) {
12410                    res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
12411                            "New package not signed by keys specified by upgrade-keysets: "
12412                            + pkgName);
12413                    return;
12414                }
12415            } else {
12416                // default to original signature matching
12417                if (compareSignatures(oldPackage.mSignatures, pkg.mSignatures)
12418                    != PackageManager.SIGNATURE_MATCH) {
12419                    res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
12420                            "New package has a different signature: " + pkgName);
12421                    return;
12422                }
12423            }
12424
12425            // In case of rollback, remember per-user/profile install state
12426            allUsers = sUserManager.getUserIds();
12427            perUserInstalled = new boolean[allUsers.length];
12428            for (int i = 0; i < allUsers.length; i++) {
12429                perUserInstalled[i] = ps != null ? ps.getInstalled(allUsers[i]) : false;
12430            }
12431        }
12432
12433        boolean sysPkg = (isSystemApp(oldPackage));
12434        if (sysPkg) {
12435            replaceSystemPackageLI(oldPackage, pkg, parseFlags, scanFlags,
12436                    user, allUsers, perUserInstalled, installerPackageName, volumeUuid, res);
12437        } else {
12438            replaceNonSystemPackageLI(oldPackage, pkg, parseFlags, scanFlags,
12439                    user, allUsers, perUserInstalled, installerPackageName, volumeUuid, res);
12440        }
12441    }
12442
12443    private void replaceNonSystemPackageLI(PackageParser.Package deletedPackage,
12444            PackageParser.Package pkg, int parseFlags, int scanFlags, UserHandle user,
12445            int[] allUsers, boolean[] perUserInstalled, String installerPackageName,
12446            String volumeUuid, PackageInstalledInfo res) {
12447        String pkgName = deletedPackage.packageName;
12448        boolean deletedPkg = true;
12449        boolean updatedSettings = false;
12450
12451        if (DEBUG_INSTALL) Slog.d(TAG, "replaceNonSystemPackageLI: new=" + pkg + ", old="
12452                + deletedPackage);
12453        long origUpdateTime;
12454        if (pkg.mExtras != null) {
12455            origUpdateTime = ((PackageSetting)pkg.mExtras).lastUpdateTime;
12456        } else {
12457            origUpdateTime = 0;
12458        }
12459
12460        // First delete the existing package while retaining the data directory
12461        if (!deletePackageLI(pkgName, null, true, null, null, PackageManager.DELETE_KEEP_DATA,
12462                res.removedInfo, true)) {
12463            // If the existing package wasn't successfully deleted
12464            res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE, "replaceNonSystemPackageLI");
12465            deletedPkg = false;
12466        } else {
12467            // Successfully deleted the old package; proceed with replace.
12468
12469            // If deleted package lived in a container, give users a chance to
12470            // relinquish resources before killing.
12471            if (deletedPackage.isForwardLocked() || isExternal(deletedPackage)) {
12472                if (DEBUG_INSTALL) {
12473                    Slog.i(TAG, "upgrading pkg " + deletedPackage + " is ASEC-hosted -> UNAVAILABLE");
12474                }
12475                final int[] uidArray = new int[] { deletedPackage.applicationInfo.uid };
12476                final ArrayList<String> pkgList = new ArrayList<String>(1);
12477                pkgList.add(deletedPackage.applicationInfo.packageName);
12478                sendResourcesChangedBroadcast(false, true, pkgList, uidArray, null);
12479            }
12480
12481            deleteCodeCacheDirsLI(pkg.volumeUuid, pkgName);
12482            try {
12483                final PackageParser.Package newPackage = scanPackageTracedLI(pkg, parseFlags,
12484                        scanFlags | SCAN_UPDATE_TIME, System.currentTimeMillis(), user);
12485                updateSettingsLI(newPackage, installerPackageName, volumeUuid, allUsers,
12486                        perUserInstalled, res, user);
12487                prepareAppDataAfterInstall(newPackage);
12488                updatedSettings = true;
12489            } catch (PackageManagerException e) {
12490                res.setError("Package couldn't be installed in " + pkg.codePath, e);
12491            }
12492        }
12493
12494        if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
12495            // remove package from internal structures.  Note that we want deletePackageX to
12496            // delete the package data and cache directories that it created in
12497            // scanPackageLocked, unless those directories existed before we even tried to
12498            // install.
12499            if(updatedSettings) {
12500                if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, rolling pack: " + pkgName);
12501                deletePackageLI(
12502                        pkgName, null, true, allUsers, perUserInstalled,
12503                        PackageManager.DELETE_KEEP_DATA,
12504                                res.removedInfo, true);
12505            }
12506            // Since we failed to install the new package we need to restore the old
12507            // package that we deleted.
12508            if (deletedPkg) {
12509                if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, reinstalling: " + deletedPackage);
12510                File restoreFile = new File(deletedPackage.codePath);
12511                // Parse old package
12512                boolean oldExternal = isExternal(deletedPackage);
12513                int oldParseFlags  = mDefParseFlags | PackageParser.PARSE_CHATTY |
12514                        (deletedPackage.isForwardLocked() ? PackageParser.PARSE_FORWARD_LOCK : 0) |
12515                        (oldExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0);
12516                int oldScanFlags = SCAN_UPDATE_SIGNATURE | SCAN_UPDATE_TIME;
12517                try {
12518                    scanPackageTracedLI(restoreFile, oldParseFlags, oldScanFlags, origUpdateTime,
12519                            null);
12520                } catch (PackageManagerException e) {
12521                    Slog.e(TAG, "Failed to restore package : " + pkgName + " after failed upgrade: "
12522                            + e.getMessage());
12523                    return;
12524                }
12525                // Restore of old package succeeded. Update permissions.
12526                // writer
12527                synchronized (mPackages) {
12528                    updatePermissionsLPw(deletedPackage.packageName, deletedPackage,
12529                            UPDATE_PERMISSIONS_ALL);
12530                    // can downgrade to reader
12531                    mSettings.writeLPr();
12532                }
12533                Slog.i(TAG, "Successfully restored package : " + pkgName + " after failed upgrade");
12534            }
12535        }
12536    }
12537
12538    private void replaceSystemPackageLI(PackageParser.Package deletedPackage,
12539            PackageParser.Package pkg, int parseFlags, int scanFlags, UserHandle user,
12540            int[] allUsers, boolean[] perUserInstalled, String installerPackageName,
12541            String volumeUuid, PackageInstalledInfo res) {
12542        if (DEBUG_INSTALL) Slog.d(TAG, "replaceSystemPackageLI: new=" + pkg
12543                + ", old=" + deletedPackage);
12544        boolean disabledSystem = false;
12545        boolean updatedSettings = false;
12546        parseFlags |= PackageParser.PARSE_IS_SYSTEM;
12547        if ((deletedPackage.applicationInfo.privateFlags&ApplicationInfo.PRIVATE_FLAG_PRIVILEGED)
12548                != 0) {
12549            parseFlags |= PackageParser.PARSE_IS_PRIVILEGED;
12550        }
12551        String packageName = deletedPackage.packageName;
12552        if (packageName == null) {
12553            res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE,
12554                    "Attempt to delete null packageName.");
12555            return;
12556        }
12557        PackageParser.Package oldPkg;
12558        PackageSetting oldPkgSetting;
12559        // reader
12560        synchronized (mPackages) {
12561            oldPkg = mPackages.get(packageName);
12562            oldPkgSetting = mSettings.mPackages.get(packageName);
12563            if((oldPkg == null) || (oldPkg.applicationInfo == null) ||
12564                    (oldPkgSetting == null)) {
12565                res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE,
12566                        "Couldn't find package " + packageName + " information");
12567                return;
12568            }
12569        }
12570
12571        killApplication(packageName, oldPkg.applicationInfo.uid, "replace sys pkg");
12572
12573        res.removedInfo.uid = oldPkg.applicationInfo.uid;
12574        res.removedInfo.removedPackage = packageName;
12575        // Remove existing system package
12576        removePackageLI(oldPkgSetting, true);
12577        // writer
12578        synchronized (mPackages) {
12579            disabledSystem = mSettings.disableSystemPackageLPw(packageName);
12580            if (!disabledSystem && deletedPackage != null) {
12581                // We didn't need to disable the .apk as a current system package,
12582                // which means we are replacing another update that is already
12583                // installed.  We need to make sure to delete the older one's .apk.
12584                res.removedInfo.args = createInstallArgsForExisting(0,
12585                        deletedPackage.applicationInfo.getCodePath(),
12586                        deletedPackage.applicationInfo.getResourcePath(),
12587                        getAppDexInstructionSets(deletedPackage.applicationInfo));
12588            } else {
12589                res.removedInfo.args = null;
12590            }
12591        }
12592
12593        // Successfully disabled the old package. Now proceed with re-installation
12594        deleteCodeCacheDirsLI(pkg.volumeUuid, packageName);
12595
12596        res.returnCode = PackageManager.INSTALL_SUCCEEDED;
12597        pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
12598
12599        PackageParser.Package newPackage = null;
12600        try {
12601            newPackage = scanPackageTracedLI(pkg, parseFlags, scanFlags, 0, user);
12602            if (newPackage.mExtras != null) {
12603                final PackageSetting newPkgSetting = (PackageSetting) newPackage.mExtras;
12604                newPkgSetting.firstInstallTime = oldPkgSetting.firstInstallTime;
12605                newPkgSetting.lastUpdateTime = System.currentTimeMillis();
12606
12607                // is the update attempting to change shared user? that isn't going to work...
12608                if (oldPkgSetting.sharedUser != newPkgSetting.sharedUser) {
12609                    res.setError(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
12610                            "Forbidding shared user change from " + oldPkgSetting.sharedUser
12611                            + " to " + newPkgSetting.sharedUser);
12612                    updatedSettings = true;
12613                }
12614            }
12615
12616            if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
12617                updateSettingsLI(newPackage, installerPackageName, volumeUuid, allUsers,
12618                        perUserInstalled, res, user);
12619                prepareAppDataAfterInstall(newPackage);
12620                updatedSettings = true;
12621            }
12622
12623        } catch (PackageManagerException e) {
12624            res.setError("Package couldn't be installed in " + pkg.codePath, e);
12625        }
12626
12627        if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
12628            // Re installation failed. Restore old information
12629            // Remove new pkg information
12630            if (newPackage != null) {
12631                removeInstalledPackageLI(newPackage, true);
12632            }
12633            // Add back the old system package
12634            try {
12635                scanPackageTracedLI(oldPkg, parseFlags, SCAN_UPDATE_SIGNATURE, 0, user);
12636            } catch (PackageManagerException e) {
12637                Slog.e(TAG, "Failed to restore original package: " + e.getMessage());
12638            }
12639            // Restore the old system information in Settings
12640            synchronized (mPackages) {
12641                if (disabledSystem) {
12642                    mSettings.enableSystemPackageLPw(packageName);
12643                }
12644                if (updatedSettings) {
12645                    mSettings.setInstallerPackageName(packageName,
12646                            oldPkgSetting.installerPackageName);
12647                }
12648                mSettings.writeLPr();
12649            }
12650        }
12651    }
12652
12653    private int[] revokeUnusedSharedUserPermissionsLPw(SharedUserSetting su, int[] allUserIds) {
12654        // Collect all used permissions in the UID
12655        ArraySet<String> usedPermissions = new ArraySet<>();
12656        final int packageCount = su.packages.size();
12657        for (int i = 0; i < packageCount; i++) {
12658            PackageSetting ps = su.packages.valueAt(i);
12659            if (ps.pkg == null) {
12660                continue;
12661            }
12662            final int requestedPermCount = ps.pkg.requestedPermissions.size();
12663            for (int j = 0; j < requestedPermCount; j++) {
12664                String permission = ps.pkg.requestedPermissions.get(j);
12665                BasePermission bp = mSettings.mPermissions.get(permission);
12666                if (bp != null) {
12667                    usedPermissions.add(permission);
12668                }
12669            }
12670        }
12671
12672        PermissionsState permissionsState = su.getPermissionsState();
12673        // Prune install permissions
12674        List<PermissionState> installPermStates = permissionsState.getInstallPermissionStates();
12675        final int installPermCount = installPermStates.size();
12676        for (int i = installPermCount - 1; i >= 0;  i--) {
12677            PermissionState permissionState = installPermStates.get(i);
12678            if (!usedPermissions.contains(permissionState.getName())) {
12679                BasePermission bp = mSettings.mPermissions.get(permissionState.getName());
12680                if (bp != null) {
12681                    permissionsState.revokeInstallPermission(bp);
12682                    permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
12683                            PackageManager.MASK_PERMISSION_FLAGS, 0);
12684                }
12685            }
12686        }
12687
12688        int[] runtimePermissionChangedUserIds = EmptyArray.INT;
12689
12690        // Prune runtime permissions
12691        for (int userId : allUserIds) {
12692            List<PermissionState> runtimePermStates = permissionsState
12693                    .getRuntimePermissionStates(userId);
12694            final int runtimePermCount = runtimePermStates.size();
12695            for (int i = runtimePermCount - 1; i >= 0; i--) {
12696                PermissionState permissionState = runtimePermStates.get(i);
12697                if (!usedPermissions.contains(permissionState.getName())) {
12698                    BasePermission bp = mSettings.mPermissions.get(permissionState.getName());
12699                    if (bp != null) {
12700                        permissionsState.revokeRuntimePermission(bp, userId);
12701                        permissionsState.updatePermissionFlags(bp, userId,
12702                                PackageManager.MASK_PERMISSION_FLAGS, 0);
12703                        runtimePermissionChangedUserIds = ArrayUtils.appendInt(
12704                                runtimePermissionChangedUserIds, userId);
12705                    }
12706                }
12707            }
12708        }
12709
12710        return runtimePermissionChangedUserIds;
12711    }
12712
12713    private void updateSettingsLI(PackageParser.Package newPackage, String installerPackageName,
12714            String volumeUuid, int[] allUsers, boolean[] perUserInstalled, PackageInstalledInfo res,
12715            UserHandle user) {
12716        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");
12717
12718        String pkgName = newPackage.packageName;
12719        synchronized (mPackages) {
12720            //write settings. the installStatus will be incomplete at this stage.
12721            //note that the new package setting would have already been
12722            //added to mPackages. It hasn't been persisted yet.
12723            mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_INCOMPLETE);
12724            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings");
12725            mSettings.writeLPr();
12726            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
12727        }
12728
12729        if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + newPackage.codePath);
12730        synchronized (mPackages) {
12731            updatePermissionsLPw(newPackage.packageName, newPackage,
12732                    UPDATE_PERMISSIONS_REPLACE_PKG | (newPackage.permissions.size() > 0
12733                            ? UPDATE_PERMISSIONS_ALL : 0));
12734            // For system-bundled packages, we assume that installing an upgraded version
12735            // of the package implies that the user actually wants to run that new code,
12736            // so we enable the package.
12737            PackageSetting ps = mSettings.mPackages.get(pkgName);
12738            if (ps != null) {
12739                if (isSystemApp(newPackage)) {
12740                    // NB: implicit assumption that system package upgrades apply to all users
12741                    if (DEBUG_INSTALL) {
12742                        Slog.d(TAG, "Implicitly enabling system package on upgrade: " + pkgName);
12743                    }
12744                    if (res.origUsers != null) {
12745                        for (int userHandle : res.origUsers) {
12746                            ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT,
12747                                    userHandle, installerPackageName);
12748                        }
12749                    }
12750                    // Also convey the prior install/uninstall state
12751                    if (allUsers != null && perUserInstalled != null) {
12752                        for (int i = 0; i < allUsers.length; i++) {
12753                            if (DEBUG_INSTALL) {
12754                                Slog.d(TAG, "    user " + allUsers[i]
12755                                        + " => " + perUserInstalled[i]);
12756                            }
12757                            ps.setInstalled(perUserInstalled[i], allUsers[i]);
12758                        }
12759                        // these install state changes will be persisted in the
12760                        // upcoming call to mSettings.writeLPr().
12761                    }
12762                }
12763                // It's implied that when a user requests installation, they want the app to be
12764                // installed and enabled.
12765                int userId = user.getIdentifier();
12766                if (userId != UserHandle.USER_ALL) {
12767                    ps.setInstalled(true, userId);
12768                    ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, userId, installerPackageName);
12769                }
12770            }
12771            res.name = pkgName;
12772            res.uid = newPackage.applicationInfo.uid;
12773            res.pkg = newPackage;
12774            mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_COMPLETE);
12775            mSettings.setInstallerPackageName(pkgName, installerPackageName);
12776            res.returnCode = PackageManager.INSTALL_SUCCEEDED;
12777            //to update install status
12778            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings");
12779            mSettings.writeLPr();
12780            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
12781        }
12782
12783        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
12784    }
12785
12786    private void installPackageTracedLI(InstallArgs args, PackageInstalledInfo res) {
12787        try {
12788            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installPackage");
12789            installPackageLI(args, res);
12790        } finally {
12791            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
12792        }
12793    }
12794
12795    private void installPackageLI(InstallArgs args, PackageInstalledInfo res) {
12796        final int installFlags = args.installFlags;
12797        final String installerPackageName = args.installerPackageName;
12798        final String volumeUuid = args.volumeUuid;
12799        final File tmpPackageFile = new File(args.getCodePath());
12800        final boolean forwardLocked = ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0);
12801        final boolean onExternal = (((installFlags & PackageManager.INSTALL_EXTERNAL) != 0)
12802                || (args.volumeUuid != null));
12803        final boolean ephemeral = ((installFlags & PackageManager.INSTALL_EPHEMERAL) != 0);
12804        boolean replace = false;
12805        int scanFlags = SCAN_NEW_INSTALL | SCAN_UPDATE_SIGNATURE;
12806        if (args.move != null) {
12807            // moving a complete application; perfom an initial scan on the new install location
12808            scanFlags |= SCAN_INITIAL;
12809        }
12810        // Result object to be returned
12811        res.returnCode = PackageManager.INSTALL_SUCCEEDED;
12812
12813        if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile);
12814
12815        // Sanity check
12816        if (ephemeral && (forwardLocked || onExternal)) {
12817            Slog.i(TAG, "Incompatible ephemeral install; fwdLocked=" + forwardLocked
12818                    + " external=" + onExternal);
12819            res.returnCode = PackageManager.INSTALL_FAILED_EPHEMERAL_INVALID;
12820            return;
12821        }
12822
12823        // Retrieve PackageSettings and parse package
12824        final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY
12825                | PackageParser.PARSE_ENFORCE_CODE
12826                | (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0)
12827                | (onExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0)
12828                | (ephemeral ? PackageParser.PARSE_IS_EPHEMERAL : 0);
12829        PackageParser pp = new PackageParser();
12830        pp.setSeparateProcesses(mSeparateProcesses);
12831        pp.setDisplayMetrics(mMetrics);
12832
12833        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
12834        final PackageParser.Package pkg;
12835        try {
12836            pkg = pp.parsePackage(tmpPackageFile, parseFlags);
12837        } catch (PackageParserException e) {
12838            res.setError("Failed parse during installPackageLI", e);
12839            return;
12840        } finally {
12841            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
12842        }
12843
12844        // Mark that we have an install time CPU ABI override.
12845        pkg.cpuAbiOverride = args.abiOverride;
12846
12847        String pkgName = res.name = pkg.packageName;
12848        if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_TEST_ONLY) != 0) {
12849            if ((installFlags & PackageManager.INSTALL_ALLOW_TEST) == 0) {
12850                res.setError(INSTALL_FAILED_TEST_ONLY, "installPackageLI");
12851                return;
12852            }
12853        }
12854
12855        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "collectCertificates");
12856        try {
12857            pp.collectCertificates(pkg, parseFlags);
12858        } catch (PackageParserException e) {
12859            res.setError("Failed collect during installPackageLI", e);
12860            return;
12861        } finally {
12862            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
12863        }
12864
12865        // Get rid of all references to package scan path via parser.
12866        pp = null;
12867        String oldCodePath = null;
12868        boolean systemApp = false;
12869        synchronized (mPackages) {
12870            // Check if installing already existing package
12871            if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
12872                String oldName = mSettings.mRenamedPackages.get(pkgName);
12873                if (pkg.mOriginalPackages != null
12874                        && pkg.mOriginalPackages.contains(oldName)
12875                        && mPackages.containsKey(oldName)) {
12876                    // This package is derived from an original package,
12877                    // and this device has been updating from that original
12878                    // name.  We must continue using the original name, so
12879                    // rename the new package here.
12880                    pkg.setPackageName(oldName);
12881                    pkgName = pkg.packageName;
12882                    replace = true;
12883                    if (DEBUG_INSTALL) Slog.d(TAG, "Replacing existing renamed package: oldName="
12884                            + oldName + " pkgName=" + pkgName);
12885                } else if (mPackages.containsKey(pkgName)) {
12886                    // This package, under its official name, already exists
12887                    // on the device; we should replace it.
12888                    replace = true;
12889                    if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing pacakge: " + pkgName);
12890                }
12891
12892                // Prevent apps opting out from runtime permissions
12893                if (replace) {
12894                    PackageParser.Package oldPackage = mPackages.get(pkgName);
12895                    final int oldTargetSdk = oldPackage.applicationInfo.targetSdkVersion;
12896                    final int newTargetSdk = pkg.applicationInfo.targetSdkVersion;
12897                    if (oldTargetSdk > Build.VERSION_CODES.LOLLIPOP_MR1
12898                            && newTargetSdk <= Build.VERSION_CODES.LOLLIPOP_MR1) {
12899                        res.setError(PackageManager.INSTALL_FAILED_PERMISSION_MODEL_DOWNGRADE,
12900                                "Package " + pkg.packageName + " new target SDK " + newTargetSdk
12901                                        + " doesn't support runtime permissions but the old"
12902                                        + " target SDK " + oldTargetSdk + " does.");
12903                        return;
12904                    }
12905                }
12906            }
12907
12908            PackageSetting ps = mSettings.mPackages.get(pkgName);
12909            if (ps != null) {
12910                if (DEBUG_INSTALL) Slog.d(TAG, "Existing package: " + ps);
12911
12912                // Quick sanity check that we're signed correctly if updating;
12913                // we'll check this again later when scanning, but we want to
12914                // bail early here before tripping over redefined permissions.
12915                if (shouldCheckUpgradeKeySetLP(ps, scanFlags)) {
12916                    if (!checkUpgradeKeySetLP(ps, pkg)) {
12917                        res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
12918                                + pkg.packageName + " upgrade keys do not match the "
12919                                + "previously installed version");
12920                        return;
12921                    }
12922                } else {
12923                    try {
12924                        verifySignaturesLP(ps, pkg);
12925                    } catch (PackageManagerException e) {
12926                        res.setError(e.error, e.getMessage());
12927                        return;
12928                    }
12929                }
12930
12931                oldCodePath = mSettings.mPackages.get(pkgName).codePathString;
12932                if (ps.pkg != null && ps.pkg.applicationInfo != null) {
12933                    systemApp = (ps.pkg.applicationInfo.flags &
12934                            ApplicationInfo.FLAG_SYSTEM) != 0;
12935                }
12936                res.origUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
12937            }
12938
12939            // Check whether the newly-scanned package wants to define an already-defined perm
12940            int N = pkg.permissions.size();
12941            for (int i = N-1; i >= 0; i--) {
12942                PackageParser.Permission perm = pkg.permissions.get(i);
12943                BasePermission bp = mSettings.mPermissions.get(perm.info.name);
12944                if (bp != null) {
12945                    // If the defining package is signed with our cert, it's okay.  This
12946                    // also includes the "updating the same package" case, of course.
12947                    // "updating same package" could also involve key-rotation.
12948                    final boolean sigsOk;
12949                    if (bp.sourcePackage.equals(pkg.packageName)
12950                            && (bp.packageSetting instanceof PackageSetting)
12951                            && (shouldCheckUpgradeKeySetLP((PackageSetting) bp.packageSetting,
12952                                    scanFlags))) {
12953                        sigsOk = checkUpgradeKeySetLP((PackageSetting) bp.packageSetting, pkg);
12954                    } else {
12955                        sigsOk = compareSignatures(bp.packageSetting.signatures.mSignatures,
12956                                pkg.mSignatures) == PackageManager.SIGNATURE_MATCH;
12957                    }
12958                    if (!sigsOk) {
12959                        // If the owning package is the system itself, we log but allow
12960                        // install to proceed; we fail the install on all other permission
12961                        // redefinitions.
12962                        if (!bp.sourcePackage.equals("android")) {
12963                            res.setError(INSTALL_FAILED_DUPLICATE_PERMISSION, "Package "
12964                                    + pkg.packageName + " attempting to redeclare permission "
12965                                    + perm.info.name + " already owned by " + bp.sourcePackage);
12966                            res.origPermission = perm.info.name;
12967                            res.origPackage = bp.sourcePackage;
12968                            return;
12969                        } else {
12970                            Slog.w(TAG, "Package " + pkg.packageName
12971                                    + " attempting to redeclare system permission "
12972                                    + perm.info.name + "; ignoring new declaration");
12973                            pkg.permissions.remove(i);
12974                        }
12975                    }
12976                }
12977            }
12978
12979        }
12980
12981        if (systemApp) {
12982            if (onExternal) {
12983                // Abort update; system app can't be replaced with app on sdcard
12984                res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
12985                        "Cannot install updates to system apps on sdcard");
12986                return;
12987            } else if (ephemeral) {
12988                // Abort update; system app can't be replaced with an ephemeral app
12989                res.setError(INSTALL_FAILED_EPHEMERAL_INVALID,
12990                        "Cannot update a system app with an ephemeral app");
12991                return;
12992            }
12993        }
12994
12995        if (args.move != null) {
12996            // We did an in-place move, so dex is ready to roll
12997            scanFlags |= SCAN_NO_DEX;
12998            scanFlags |= SCAN_MOVE;
12999
13000            synchronized (mPackages) {
13001                final PackageSetting ps = mSettings.mPackages.get(pkgName);
13002                if (ps == null) {
13003                    res.setError(INSTALL_FAILED_INTERNAL_ERROR,
13004                            "Missing settings for moved package " + pkgName);
13005                }
13006
13007                // We moved the entire application as-is, so bring over the
13008                // previously derived ABI information.
13009                pkg.applicationInfo.primaryCpuAbi = ps.primaryCpuAbiString;
13010                pkg.applicationInfo.secondaryCpuAbi = ps.secondaryCpuAbiString;
13011            }
13012
13013        } else if (!forwardLocked && !pkg.applicationInfo.isExternalAsec()) {
13014            // Enable SCAN_NO_DEX flag to skip dexopt at a later stage
13015            scanFlags |= SCAN_NO_DEX;
13016
13017            try {
13018                derivePackageAbi(pkg, new File(pkg.codePath), args.abiOverride,
13019                        true /* extract libs */);
13020            } catch (PackageManagerException pme) {
13021                Slog.e(TAG, "Error deriving application ABI", pme);
13022                res.setError(INSTALL_FAILED_INTERNAL_ERROR, "Error deriving application ABI");
13023                return;
13024            }
13025
13026            // Extract package to save the VM unzipping the APK in memory during
13027            // launch. Only do this if profile-guided compilation is enabled because
13028            // otherwise BackgroundDexOptService will not dexopt the package later.
13029            if (mUseJitProfiles) {
13030                Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
13031                // Do not run PackageDexOptimizer through the local performDexOpt
13032                // method because `pkg` is not in `mPackages` yet.
13033                int result = mPackageDexOptimizer.performDexOpt(pkg, null /* instructionSets */,
13034                        false /* inclDependencies */, false /* useProfiles */,
13035                        true /* extractOnly */);
13036                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
13037                if (result == PackageDexOptimizer.DEX_OPT_FAILED) {
13038                    String msg = "Extracking package failed for " + pkgName;
13039                    res.setError(INSTALL_FAILED_DEXOPT, msg);
13040                    return;
13041                }
13042            }
13043        }
13044
13045        if (!args.doRename(res.returnCode, pkg, oldCodePath)) {
13046            res.setError(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename");
13047            return;
13048        }
13049
13050        startIntentFilterVerifications(args.user.getIdentifier(), replace, pkg);
13051
13052        if (replace) {
13053            replacePackageLI(pkg, parseFlags, scanFlags | SCAN_REPLACING, args.user,
13054                    installerPackageName, volumeUuid, res);
13055        } else {
13056            installNewPackageLI(pkg, parseFlags, scanFlags | SCAN_DELETE_DATA_ON_FAILURES,
13057                    args.user, installerPackageName, volumeUuid, res);
13058        }
13059        synchronized (mPackages) {
13060            final PackageSetting ps = mSettings.mPackages.get(pkgName);
13061            if (ps != null) {
13062                res.newUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
13063            }
13064        }
13065    }
13066
13067    private void startIntentFilterVerifications(int userId, boolean replacing,
13068            PackageParser.Package pkg) {
13069        if (mIntentFilterVerifierComponent == null) {
13070            Slog.w(TAG, "No IntentFilter verification will not be done as "
13071                    + "there is no IntentFilterVerifier available!");
13072            return;
13073        }
13074
13075        final int verifierUid = getPackageUid(
13076                mIntentFilterVerifierComponent.getPackageName(),
13077                MATCH_DEBUG_TRIAGED_MISSING,
13078                (userId == UserHandle.USER_ALL) ? UserHandle.USER_SYSTEM : userId);
13079
13080        mHandler.removeMessages(START_INTENT_FILTER_VERIFICATIONS);
13081        final Message msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS);
13082        msg.obj = new IFVerificationParams(pkg, replacing, userId, verifierUid);
13083        mHandler.sendMessage(msg);
13084    }
13085
13086    private void verifyIntentFiltersIfNeeded(int userId, int verifierUid, boolean replacing,
13087            PackageParser.Package pkg) {
13088        int size = pkg.activities.size();
13089        if (size == 0) {
13090            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
13091                    "No activity, so no need to verify any IntentFilter!");
13092            return;
13093        }
13094
13095        final boolean hasDomainURLs = hasDomainURLs(pkg);
13096        if (!hasDomainURLs) {
13097            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
13098                    "No domain URLs, so no need to verify any IntentFilter!");
13099            return;
13100        }
13101
13102        if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Checking for userId:" + userId
13103                + " if any IntentFilter from the " + size
13104                + " Activities needs verification ...");
13105
13106        int count = 0;
13107        final String packageName = pkg.packageName;
13108
13109        synchronized (mPackages) {
13110            // If this is a new install and we see that we've already run verification for this
13111            // package, we have nothing to do: it means the state was restored from backup.
13112            if (!replacing) {
13113                IntentFilterVerificationInfo ivi =
13114                        mSettings.getIntentFilterVerificationLPr(packageName);
13115                if (ivi != null) {
13116                    if (DEBUG_DOMAIN_VERIFICATION) {
13117                        Slog.i(TAG, "Package " + packageName+ " already verified: status="
13118                                + ivi.getStatusString());
13119                    }
13120                    return;
13121                }
13122            }
13123
13124            // If any filters need to be verified, then all need to be.
13125            boolean needToVerify = false;
13126            for (PackageParser.Activity a : pkg.activities) {
13127                for (ActivityIntentInfo filter : a.intents) {
13128                    if (filter.needsVerification() && needsNetworkVerificationLPr(filter)) {
13129                        if (DEBUG_DOMAIN_VERIFICATION) {
13130                            Slog.d(TAG, "Intent filter needs verification, so processing all filters");
13131                        }
13132                        needToVerify = true;
13133                        break;
13134                    }
13135                }
13136            }
13137
13138            if (needToVerify) {
13139                final int verificationId = mIntentFilterVerificationToken++;
13140                for (PackageParser.Activity a : pkg.activities) {
13141                    for (ActivityIntentInfo filter : a.intents) {
13142                        if (filter.handlesWebUris(true) && needsNetworkVerificationLPr(filter)) {
13143                            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
13144                                    "Verification needed for IntentFilter:" + filter.toString());
13145                            mIntentFilterVerifier.addOneIntentFilterVerification(
13146                                    verifierUid, userId, verificationId, filter, packageName);
13147                            count++;
13148                        }
13149                    }
13150                }
13151            }
13152        }
13153
13154        if (count > 0) {
13155            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Starting " + count
13156                    + " IntentFilter verification" + (count > 1 ? "s" : "")
13157                    +  " for userId:" + userId);
13158            mIntentFilterVerifier.startVerifications(userId);
13159        } else {
13160            if (DEBUG_DOMAIN_VERIFICATION) {
13161                Slog.d(TAG, "No filters or not all autoVerify for " + packageName);
13162            }
13163        }
13164    }
13165
13166    private boolean needsNetworkVerificationLPr(ActivityIntentInfo filter) {
13167        final ComponentName cn  = filter.activity.getComponentName();
13168        final String packageName = cn.getPackageName();
13169
13170        IntentFilterVerificationInfo ivi = mSettings.getIntentFilterVerificationLPr(
13171                packageName);
13172        if (ivi == null) {
13173            return true;
13174        }
13175        int status = ivi.getStatus();
13176        switch (status) {
13177            case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED:
13178            case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK:
13179                return true;
13180
13181            default:
13182                // Nothing to do
13183                return false;
13184        }
13185    }
13186
13187    private static boolean isMultiArch(ApplicationInfo info) {
13188        return (info.flags & ApplicationInfo.FLAG_MULTIARCH) != 0;
13189    }
13190
13191    private static boolean isExternal(PackageParser.Package pkg) {
13192        return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
13193    }
13194
13195    private static boolean isExternal(PackageSetting ps) {
13196        return (ps.pkgFlags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
13197    }
13198
13199    private static boolean isEphemeral(PackageParser.Package pkg) {
13200        return pkg.applicationInfo.isEphemeralApp();
13201    }
13202
13203    private static boolean isEphemeral(PackageSetting ps) {
13204        return ps.pkg != null && isEphemeral(ps.pkg);
13205    }
13206
13207    private static boolean isSystemApp(PackageParser.Package pkg) {
13208        return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
13209    }
13210
13211    private static boolean isPrivilegedApp(PackageParser.Package pkg) {
13212        return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0;
13213    }
13214
13215    private static boolean hasDomainURLs(PackageParser.Package pkg) {
13216        return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) != 0;
13217    }
13218
13219    private static boolean isSystemApp(PackageSetting ps) {
13220        return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0;
13221    }
13222
13223    private static boolean isUpdatedSystemApp(PackageSetting ps) {
13224        return (ps.pkgFlags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
13225    }
13226
13227    private int packageFlagsToInstallFlags(PackageSetting ps) {
13228        int installFlags = 0;
13229        if (isEphemeral(ps)) {
13230            installFlags |= PackageManager.INSTALL_EPHEMERAL;
13231        }
13232        if (isExternal(ps) && TextUtils.isEmpty(ps.volumeUuid)) {
13233            // This existing package was an external ASEC install when we have
13234            // the external flag without a UUID
13235            installFlags |= PackageManager.INSTALL_EXTERNAL;
13236        }
13237        if (ps.isForwardLocked()) {
13238            installFlags |= PackageManager.INSTALL_FORWARD_LOCK;
13239        }
13240        return installFlags;
13241    }
13242
13243    private String getVolumeUuidForPackage(PackageParser.Package pkg) {
13244        if (isExternal(pkg)) {
13245            if (TextUtils.isEmpty(pkg.volumeUuid)) {
13246                return StorageManager.UUID_PRIMARY_PHYSICAL;
13247            } else {
13248                return pkg.volumeUuid;
13249            }
13250        } else {
13251            return StorageManager.UUID_PRIVATE_INTERNAL;
13252        }
13253    }
13254
13255    private VersionInfo getSettingsVersionForPackage(PackageParser.Package pkg) {
13256        if (isExternal(pkg)) {
13257            if (TextUtils.isEmpty(pkg.volumeUuid)) {
13258                return mSettings.getExternalVersion();
13259            } else {
13260                return mSettings.findOrCreateVersion(pkg.volumeUuid);
13261            }
13262        } else {
13263            return mSettings.getInternalVersion();
13264        }
13265    }
13266
13267    private void deleteTempPackageFiles() {
13268        final FilenameFilter filter = new FilenameFilter() {
13269            public boolean accept(File dir, String name) {
13270                return name.startsWith("vmdl") && name.endsWith(".tmp");
13271            }
13272        };
13273        for (File file : mDrmAppPrivateInstallDir.listFiles(filter)) {
13274            file.delete();
13275        }
13276    }
13277
13278    @Override
13279    public void deletePackageAsUser(String packageName, IPackageDeleteObserver observer, int userId,
13280            int flags) {
13281        deletePackage(packageName, new LegacyPackageDeleteObserver(observer).getBinder(), userId,
13282                flags);
13283    }
13284
13285    @Override
13286    public void deletePackage(final String packageName,
13287            final IPackageDeleteObserver2 observer, final int userId, final int flags) {
13288        mContext.enforceCallingOrSelfPermission(
13289                android.Manifest.permission.DELETE_PACKAGES, null);
13290        Preconditions.checkNotNull(packageName);
13291        Preconditions.checkNotNull(observer);
13292        final int uid = Binder.getCallingUid();
13293        final boolean deleteAllUsers = (flags & PackageManager.DELETE_ALL_USERS) != 0;
13294        final int[] users = deleteAllUsers ? sUserManager.getUserIds() : new int[]{ userId };
13295        if (UserHandle.getUserId(uid) != userId || (deleteAllUsers && users.length > 1)) {
13296            mContext.enforceCallingOrSelfPermission(
13297                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
13298                    "deletePackage for user " + userId);
13299        }
13300
13301        if (isUserRestricted(userId, UserManager.DISALLOW_UNINSTALL_APPS)) {
13302            try {
13303                observer.onPackageDeleted(packageName,
13304                        PackageManager.DELETE_FAILED_USER_RESTRICTED, null);
13305            } catch (RemoteException re) {
13306            }
13307            return;
13308        }
13309
13310        for (int currentUserId : users) {
13311            if (getBlockUninstallForUser(packageName, currentUserId)) {
13312                try {
13313                    observer.onPackageDeleted(packageName,
13314                            PackageManager.DELETE_FAILED_OWNER_BLOCKED, null);
13315                } catch (RemoteException re) {
13316                }
13317                return;
13318            }
13319        }
13320
13321        if (DEBUG_REMOVE) {
13322            Slog.d(TAG, "deletePackageAsUser: pkg=" + packageName + " user=" + userId);
13323        }
13324        // Queue up an async operation since the package deletion may take a little while.
13325        mHandler.post(new Runnable() {
13326            public void run() {
13327                mHandler.removeCallbacks(this);
13328                final int returnCode = deletePackageX(packageName, userId, flags);
13329                try {
13330                    observer.onPackageDeleted(packageName, returnCode, null);
13331                } catch (RemoteException e) {
13332                    Log.i(TAG, "Observer no longer exists.");
13333                } //end catch
13334            } //end run
13335        });
13336    }
13337
13338    private boolean isPackageDeviceAdmin(String packageName, int userId) {
13339        IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
13340                ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
13341        try {
13342            if (dpm != null) {
13343                final ComponentName deviceOwnerComponentName = dpm.getDeviceOwnerComponent(
13344                        /* callingUserOnly =*/ false);
13345                final String deviceOwnerPackageName = deviceOwnerComponentName == null ? null
13346                        : deviceOwnerComponentName.getPackageName();
13347                // Does the package contains the device owner?
13348                // TODO Do we have to do it even if userId != UserHandle.USER_ALL?  Otherwise,
13349                // this check is probably not needed, since DO should be registered as a device
13350                // admin on some user too. (Original bug for this: b/17657954)
13351                if (packageName.equals(deviceOwnerPackageName)) {
13352                    return true;
13353                }
13354                // Does it contain a device admin for any user?
13355                int[] users;
13356                if (userId == UserHandle.USER_ALL) {
13357                    users = sUserManager.getUserIds();
13358                } else {
13359                    users = new int[]{userId};
13360                }
13361                for (int i = 0; i < users.length; ++i) {
13362                    if (dpm.packageHasActiveAdmins(packageName, users[i])) {
13363                        return true;
13364                    }
13365                }
13366            }
13367        } catch (RemoteException e) {
13368        }
13369        return false;
13370    }
13371
13372    private boolean shouldKeepUninstalledPackageLPr(String packageName) {
13373        return mKeepUninstalledPackages != null && mKeepUninstalledPackages.contains(packageName);
13374    }
13375
13376    /**
13377     *  This method is an internal method that could be get invoked either
13378     *  to delete an installed package or to clean up a failed installation.
13379     *  After deleting an installed package, a broadcast is sent to notify any
13380     *  listeners that the package has been installed. For cleaning up a failed
13381     *  installation, the broadcast is not necessary since the package's
13382     *  installation wouldn't have sent the initial broadcast either
13383     *  The key steps in deleting a package are
13384     *  deleting the package information in internal structures like mPackages,
13385     *  deleting the packages base directories through installd
13386     *  updating mSettings to reflect current status
13387     *  persisting settings for later use
13388     *  sending a broadcast if necessary
13389     */
13390    private int deletePackageX(String packageName, int userId, int flags) {
13391        final PackageRemovedInfo info = new PackageRemovedInfo();
13392        final boolean res;
13393
13394        final UserHandle removeForUser = (flags & PackageManager.DELETE_ALL_USERS) != 0
13395                ? UserHandle.ALL : new UserHandle(userId);
13396
13397        if (isPackageDeviceAdmin(packageName, removeForUser.getIdentifier())) {
13398            Slog.w(TAG, "Not removing package " + packageName + ": has active device admin");
13399            return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER;
13400        }
13401
13402        boolean removedForAllUsers = false;
13403        boolean systemUpdate = false;
13404
13405        PackageParser.Package uninstalledPkg;
13406
13407        // for the uninstall-updates case and restricted profiles, remember the per-
13408        // userhandle installed state
13409        int[] allUsers;
13410        boolean[] perUserInstalled;
13411        synchronized (mPackages) {
13412            uninstalledPkg = mPackages.get(packageName);
13413            PackageSetting ps = mSettings.mPackages.get(packageName);
13414            allUsers = sUserManager.getUserIds();
13415            perUserInstalled = new boolean[allUsers.length];
13416            for (int i = 0; i < allUsers.length; i++) {
13417                perUserInstalled[i] = ps != null ? ps.getInstalled(allUsers[i]) : false;
13418            }
13419        }
13420
13421        synchronized (mInstallLock) {
13422            if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageX: pkg=" + packageName + " user=" + userId);
13423            res = deletePackageLI(packageName, removeForUser,
13424                    true, allUsers, perUserInstalled,
13425                    flags | REMOVE_CHATTY, info, true);
13426            systemUpdate = info.isRemovedPackageSystemUpdate;
13427            synchronized (mPackages) {
13428                if (res) {
13429                    if (!systemUpdate && mPackages.get(packageName) == null) {
13430                        removedForAllUsers = true;
13431                    }
13432                    mEphemeralApplicationRegistry.onPackageUninstalledLPw(uninstalledPkg);
13433                }
13434            }
13435            if (DEBUG_REMOVE) Slog.d(TAG, "delete res: systemUpdate=" + systemUpdate
13436                    + " removedForAllUsers=" + removedForAllUsers);
13437        }
13438
13439        if (res) {
13440            info.sendBroadcast(true, systemUpdate, removedForAllUsers);
13441
13442            // If the removed package was a system update, the old system package
13443            // was re-enabled; we need to broadcast this information
13444            if (systemUpdate) {
13445                Bundle extras = new Bundle(1);
13446                extras.putInt(Intent.EXTRA_UID, info.removedAppId >= 0
13447                        ? info.removedAppId : info.uid);
13448                extras.putBoolean(Intent.EXTRA_REPLACING, true);
13449
13450                sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
13451                        extras, 0, null, null, null);
13452                sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, packageName,
13453                        extras, 0, null, null, null);
13454                sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, null,
13455                        null, 0, packageName, null, null);
13456            }
13457        }
13458        // Force a gc here.
13459        Runtime.getRuntime().gc();
13460        // Delete the resources here after sending the broadcast to let
13461        // other processes clean up before deleting resources.
13462        if (info.args != null) {
13463            synchronized (mInstallLock) {
13464                info.args.doPostDeleteLI(true);
13465            }
13466        }
13467
13468        return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR;
13469    }
13470
13471    class PackageRemovedInfo {
13472        String removedPackage;
13473        int uid = -1;
13474        int removedAppId = -1;
13475        int[] removedUsers = null;
13476        boolean isRemovedPackageSystemUpdate = false;
13477        // Clean up resources deleted packages.
13478        InstallArgs args = null;
13479
13480        void sendBroadcast(boolean fullRemove, boolean replacing, boolean removedForAllUsers) {
13481            Bundle extras = new Bundle(1);
13482            extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid);
13483            extras.putBoolean(Intent.EXTRA_DATA_REMOVED, fullRemove);
13484            if (replacing) {
13485                extras.putBoolean(Intent.EXTRA_REPLACING, true);
13486            }
13487            extras.putBoolean(Intent.EXTRA_REMOVED_FOR_ALL_USERS, removedForAllUsers);
13488            if (removedPackage != null) {
13489                sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED, removedPackage,
13490                        extras, 0, null, null, removedUsers);
13491                if (fullRemove && !replacing) {
13492                    sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED, removedPackage,
13493                            extras, 0, null, null, removedUsers);
13494                }
13495            }
13496            if (removedAppId >= 0) {
13497                sendPackageBroadcast(Intent.ACTION_UID_REMOVED, null, extras, 0, null, null,
13498                        removedUsers);
13499            }
13500        }
13501    }
13502
13503    /*
13504     * This method deletes the package from internal data structures. If the DONT_DELETE_DATA
13505     * flag is not set, the data directory is removed as well.
13506     * make sure this flag is set for partially installed apps. If not its meaningless to
13507     * delete a partially installed application.
13508     */
13509    private void removePackageDataLI(PackageSetting ps,
13510            int[] allUserHandles, boolean[] perUserInstalled,
13511            PackageRemovedInfo outInfo, int flags, boolean writeSettings) {
13512        String packageName = ps.name;
13513        if (DEBUG_REMOVE) Slog.d(TAG, "removePackageDataLI: " + ps);
13514        removePackageLI(ps, (flags&REMOVE_CHATTY) != 0);
13515        // Retrieve object to delete permissions for shared user later on
13516        final PackageSetting deletedPs;
13517        // reader
13518        synchronized (mPackages) {
13519            deletedPs = mSettings.mPackages.get(packageName);
13520            if (outInfo != null) {
13521                outInfo.removedPackage = packageName;
13522                outInfo.removedUsers = deletedPs != null
13523                        ? deletedPs.queryInstalledUsers(sUserManager.getUserIds(), true)
13524                        : null;
13525            }
13526        }
13527        if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) {
13528            removeDataDirsLI(ps.volumeUuid, packageName);
13529            schedulePackageCleaning(packageName, UserHandle.USER_ALL, true);
13530        }
13531        // writer
13532        synchronized (mPackages) {
13533            if (deletedPs != null) {
13534                if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) {
13535                    clearIntentFilterVerificationsLPw(deletedPs.name, UserHandle.USER_ALL);
13536                    clearDefaultBrowserIfNeeded(packageName);
13537                    if (outInfo != null) {
13538                        mSettings.mKeySetManagerService.removeAppKeySetDataLPw(packageName);
13539                        outInfo.removedAppId = mSettings.removePackageLPw(packageName);
13540                    }
13541                    updatePermissionsLPw(deletedPs.name, null, 0);
13542                    if (deletedPs.sharedUser != null) {
13543                        // Remove permissions associated with package. Since runtime
13544                        // permissions are per user we have to kill the removed package
13545                        // or packages running under the shared user of the removed
13546                        // package if revoking the permissions requested only by the removed
13547                        // package is successful and this causes a change in gids.
13548                        for (int userId : UserManagerService.getInstance().getUserIds()) {
13549                            final int userIdToKill = mSettings.updateSharedUserPermsLPw(deletedPs,
13550                                    userId);
13551                            if (userIdToKill == UserHandle.USER_ALL
13552                                    || userIdToKill >= UserHandle.USER_SYSTEM) {
13553                                // If gids changed for this user, kill all affected packages.
13554                                mHandler.post(new Runnable() {
13555                                    @Override
13556                                    public void run() {
13557                                        // This has to happen with no lock held.
13558                                        killApplication(deletedPs.name, deletedPs.appId,
13559                                                KILL_APP_REASON_GIDS_CHANGED);
13560                                    }
13561                                });
13562                                break;
13563                            }
13564                        }
13565                    }
13566                    clearPackagePreferredActivitiesLPw(deletedPs.name, UserHandle.USER_ALL);
13567                }
13568                // make sure to preserve per-user disabled state if this removal was just
13569                // a downgrade of a system app to the factory package
13570                if (allUserHandles != null && perUserInstalled != null) {
13571                    if (DEBUG_REMOVE) {
13572                        Slog.d(TAG, "Propagating install state across downgrade");
13573                    }
13574                    for (int i = 0; i < allUserHandles.length; i++) {
13575                        if (DEBUG_REMOVE) {
13576                            Slog.d(TAG, "    user " + allUserHandles[i]
13577                                    + " => " + perUserInstalled[i]);
13578                        }
13579                        ps.setInstalled(perUserInstalled[i], allUserHandles[i]);
13580                    }
13581                }
13582            }
13583            // can downgrade to reader
13584            if (writeSettings) {
13585                // Save settings now
13586                mSettings.writeLPr();
13587            }
13588        }
13589        if (outInfo != null) {
13590            // A user ID was deleted here. Go through all users and remove it
13591            // from KeyStore.
13592            removeKeystoreDataIfNeeded(UserHandle.USER_ALL, outInfo.removedAppId);
13593        }
13594    }
13595
13596    static boolean locationIsPrivileged(File path) {
13597        try {
13598            final String privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app")
13599                    .getCanonicalPath();
13600            return path.getCanonicalPath().startsWith(privilegedAppDir);
13601        } catch (IOException e) {
13602            Slog.e(TAG, "Unable to access code path " + path);
13603        }
13604        return false;
13605    }
13606
13607    /*
13608     * Tries to delete system package.
13609     */
13610    private boolean deleteSystemPackageLI(PackageSetting newPs,
13611            int[] allUserHandles, boolean[] perUserInstalled,
13612            int flags, PackageRemovedInfo outInfo, boolean writeSettings) {
13613        final boolean applyUserRestrictions
13614                = (allUserHandles != null) && (perUserInstalled != null);
13615        PackageSetting disabledPs = null;
13616        // Confirm if the system package has been updated
13617        // An updated system app can be deleted. This will also have to restore
13618        // the system pkg from system partition
13619        // reader
13620        synchronized (mPackages) {
13621            disabledPs = mSettings.getDisabledSystemPkgLPr(newPs.name);
13622        }
13623        if (DEBUG_REMOVE) Slog.d(TAG, "deleteSystemPackageLI: newPs=" + newPs
13624                + " disabledPs=" + disabledPs);
13625        if (disabledPs == null) {
13626            Slog.w(TAG, "Attempt to delete unknown system package "+ newPs.name);
13627            return false;
13628        } else if (DEBUG_REMOVE) {
13629            Slog.d(TAG, "Deleting system pkg from data partition");
13630        }
13631        if (DEBUG_REMOVE) {
13632            if (applyUserRestrictions) {
13633                Slog.d(TAG, "Remembering install states:");
13634                for (int i = 0; i < allUserHandles.length; i++) {
13635                    Slog.d(TAG, "   u=" + allUserHandles[i] + " inst=" + perUserInstalled[i]);
13636                }
13637            }
13638        }
13639        // Delete the updated package
13640        outInfo.isRemovedPackageSystemUpdate = true;
13641        if (disabledPs.versionCode < newPs.versionCode) {
13642            // Delete data for downgrades
13643            flags &= ~PackageManager.DELETE_KEEP_DATA;
13644        } else {
13645            // Preserve data by setting flag
13646            flags |= PackageManager.DELETE_KEEP_DATA;
13647        }
13648        boolean ret = deleteInstalledPackageLI(newPs, true, flags,
13649                allUserHandles, perUserInstalled, outInfo, writeSettings);
13650        if (!ret) {
13651            return false;
13652        }
13653        // writer
13654        synchronized (mPackages) {
13655            // Reinstate the old system package
13656            mSettings.enableSystemPackageLPw(newPs.name);
13657            // Remove any native libraries from the upgraded package.
13658            NativeLibraryHelper.removeNativeBinariesLI(newPs.legacyNativeLibraryPathString);
13659        }
13660        // Install the system package
13661        if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs);
13662        int parseFlags = PackageParser.PARSE_MUST_BE_APK | PackageParser.PARSE_IS_SYSTEM;
13663        if (locationIsPrivileged(disabledPs.codePath)) {
13664            parseFlags |= PackageParser.PARSE_IS_PRIVILEGED;
13665        }
13666
13667        final PackageParser.Package newPkg;
13668        try {
13669            newPkg = scanPackageTracedLI(disabledPs.codePath, parseFlags, SCAN_NO_PATHS, 0, null);
13670        } catch (PackageManagerException e) {
13671            Slog.w(TAG, "Failed to restore system package " + newPs.name + ": " + e.getMessage());
13672            return false;
13673        }
13674
13675        prepareAppDataAfterInstall(newPkg);
13676
13677        // writer
13678        synchronized (mPackages) {
13679            PackageSetting ps = mSettings.mPackages.get(newPkg.packageName);
13680
13681            // Propagate the permissions state as we do not want to drop on the floor
13682            // runtime permissions. The update permissions method below will take
13683            // care of removing obsolete permissions and grant install permissions.
13684            ps.getPermissionsState().copyFrom(newPs.getPermissionsState());
13685            updatePermissionsLPw(newPkg.packageName, newPkg,
13686                    UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG);
13687
13688            if (applyUserRestrictions) {
13689                if (DEBUG_REMOVE) {
13690                    Slog.d(TAG, "Propagating install state across reinstall");
13691                }
13692                for (int i = 0; i < allUserHandles.length; i++) {
13693                    if (DEBUG_REMOVE) {
13694                        Slog.d(TAG, "    user " + allUserHandles[i]
13695                                + " => " + perUserInstalled[i]);
13696                    }
13697                    ps.setInstalled(perUserInstalled[i], allUserHandles[i]);
13698
13699                    mSettings.writeRuntimePermissionsForUserLPr(allUserHandles[i], false);
13700                }
13701                // Regardless of writeSettings we need to ensure that this restriction
13702                // state propagation is persisted
13703                mSettings.writeAllUsersPackageRestrictionsLPr();
13704            }
13705            // can downgrade to reader here
13706            if (writeSettings) {
13707                mSettings.writeLPr();
13708            }
13709        }
13710        return true;
13711    }
13712
13713    private boolean deleteInstalledPackageLI(PackageSetting ps,
13714            boolean deleteCodeAndResources, int flags,
13715            int[] allUserHandles, boolean[] perUserInstalled,
13716            PackageRemovedInfo outInfo, boolean writeSettings) {
13717        if (outInfo != null) {
13718            outInfo.uid = ps.appId;
13719        }
13720
13721        // Delete package data from internal structures and also remove data if flag is set
13722        removePackageDataLI(ps, allUserHandles, perUserInstalled, outInfo, flags, writeSettings);
13723
13724        // Delete application code and resources
13725        if (deleteCodeAndResources && (outInfo != null)) {
13726            outInfo.args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
13727                    ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
13728            if (DEBUG_SD_INSTALL) Slog.i(TAG, "args=" + outInfo.args);
13729        }
13730        return true;
13731    }
13732
13733    @Override
13734    public boolean setBlockUninstallForUser(String packageName, boolean blockUninstall,
13735            int userId) {
13736        mContext.enforceCallingOrSelfPermission(
13737                android.Manifest.permission.DELETE_PACKAGES, null);
13738        synchronized (mPackages) {
13739            PackageSetting ps = mSettings.mPackages.get(packageName);
13740            if (ps == null) {
13741                Log.i(TAG, "Package doesn't exist in set block uninstall " + packageName);
13742                return false;
13743            }
13744            if (!ps.getInstalled(userId)) {
13745                // Can't block uninstall for an app that is not installed or enabled.
13746                Log.i(TAG, "Package not installed in set block uninstall " + packageName);
13747                return false;
13748            }
13749            ps.setBlockUninstall(blockUninstall, userId);
13750            mSettings.writePackageRestrictionsLPr(userId);
13751        }
13752        return true;
13753    }
13754
13755    @Override
13756    public boolean getBlockUninstallForUser(String packageName, int userId) {
13757        synchronized (mPackages) {
13758            PackageSetting ps = mSettings.mPackages.get(packageName);
13759            if (ps == null) {
13760                Log.i(TAG, "Package doesn't exist in get block uninstall " + packageName);
13761                return false;
13762            }
13763            return ps.getBlockUninstall(userId);
13764        }
13765    }
13766
13767    @Override
13768    public boolean setRequiredForSystemUser(String packageName, boolean systemUserApp) {
13769        int callingUid = Binder.getCallingUid();
13770        if (callingUid != Process.SYSTEM_UID && callingUid != Process.ROOT_UID) {
13771            throw new SecurityException(
13772                    "setRequiredForSystemUser can only be run by the system or root");
13773        }
13774        synchronized (mPackages) {
13775            PackageSetting ps = mSettings.mPackages.get(packageName);
13776            if (ps == null) {
13777                Log.w(TAG, "Package doesn't exist: " + packageName);
13778                return false;
13779            }
13780            if (systemUserApp) {
13781                ps.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER;
13782            } else {
13783                ps.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER;
13784            }
13785            mSettings.writeLPr();
13786        }
13787        return true;
13788    }
13789
13790    /*
13791     * This method handles package deletion in general
13792     */
13793    private boolean deletePackageLI(String packageName, UserHandle user,
13794            boolean deleteCodeAndResources, int[] allUserHandles, boolean[] perUserInstalled,
13795            int flags, PackageRemovedInfo outInfo,
13796            boolean writeSettings) {
13797        if (packageName == null) {
13798            Slog.w(TAG, "Attempt to delete null packageName.");
13799            return false;
13800        }
13801        if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: " + packageName + " user " + user);
13802        PackageSetting ps;
13803        boolean dataOnly = false;
13804        int removeUser = -1;
13805        int appId = -1;
13806        synchronized (mPackages) {
13807            ps = mSettings.mPackages.get(packageName);
13808            if (ps == null) {
13809                Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
13810                return false;
13811            }
13812            if ((!isSystemApp(ps) || (flags&PackageManager.DELETE_SYSTEM_APP) != 0) && user != null
13813                    && user.getIdentifier() != UserHandle.USER_ALL) {
13814                // The caller is asking that the package only be deleted for a single
13815                // user.  To do this, we just mark its uninstalled state and delete
13816                // its data.  If this is a system app, we only allow this to happen if
13817                // they have set the special DELETE_SYSTEM_APP which requests different
13818                // semantics than normal for uninstalling system apps.
13819                if (DEBUG_REMOVE) Slog.d(TAG, "Only deleting for single user");
13820                final int userId = user.getIdentifier();
13821                ps.setUserState(userId,
13822                        COMPONENT_ENABLED_STATE_DEFAULT,
13823                        false, //installed
13824                        true,  //stopped
13825                        true,  //notLaunched
13826                        false, //hidden
13827                        false, //suspended
13828                        null, null, null,
13829                        false, // blockUninstall
13830                        ps.readUserState(userId).domainVerificationStatus, 0);
13831                if (!isSystemApp(ps)) {
13832                    // Do not uninstall the APK if an app should be cached
13833                    boolean keepUninstalledPackage = shouldKeepUninstalledPackageLPr(packageName);
13834                    if (ps.isAnyInstalled(sUserManager.getUserIds()) || keepUninstalledPackage) {
13835                        // Other user still have this package installed, so all
13836                        // we need to do is clear this user's data and save that
13837                        // it is uninstalled.
13838                        if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users");
13839                        removeUser = user.getIdentifier();
13840                        appId = ps.appId;
13841                        scheduleWritePackageRestrictionsLocked(removeUser);
13842                    } else {
13843                        // We need to set it back to 'installed' so the uninstall
13844                        // broadcasts will be sent correctly.
13845                        if (DEBUG_REMOVE) Slog.d(TAG, "Not installed by other users, full delete");
13846                        ps.setInstalled(true, user.getIdentifier());
13847                    }
13848                } else {
13849                    // This is a system app, so we assume that the
13850                    // other users still have this package installed, so all
13851                    // we need to do is clear this user's data and save that
13852                    // it is uninstalled.
13853                    if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app");
13854                    removeUser = user.getIdentifier();
13855                    appId = ps.appId;
13856                    scheduleWritePackageRestrictionsLocked(removeUser);
13857                }
13858            }
13859        }
13860
13861        if (removeUser >= 0) {
13862            // From above, we determined that we are deleting this only
13863            // for a single user.  Continue the work here.
13864            if (DEBUG_REMOVE) Slog.d(TAG, "Updating install state for user: " + removeUser);
13865            if (outInfo != null) {
13866                outInfo.removedPackage = packageName;
13867                outInfo.removedAppId = appId;
13868                outInfo.removedUsers = new int[] {removeUser};
13869            }
13870            // TODO: triage flags as part of 26466827
13871            final int installerFlags = Installer.FLAG_CE_STORAGE | Installer.FLAG_DE_STORAGE;
13872            try {
13873                mInstaller.destroyAppData(ps.volumeUuid, packageName, removeUser, installerFlags);
13874            } catch (InstallerException e) {
13875                Slog.w(TAG, "Failed to delete app data", e);
13876            }
13877            removeKeystoreDataIfNeeded(removeUser, appId);
13878            schedulePackageCleaning(packageName, removeUser, false);
13879            synchronized (mPackages) {
13880                if (clearPackagePreferredActivitiesLPw(packageName, removeUser)) {
13881                    scheduleWritePackageRestrictionsLocked(removeUser);
13882                }
13883                resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, removeUser);
13884            }
13885            return true;
13886        }
13887
13888        if (dataOnly) {
13889            // Delete application data first
13890            if (DEBUG_REMOVE) Slog.d(TAG, "Removing package data only");
13891            removePackageDataLI(ps, null, null, outInfo, flags, writeSettings);
13892            return true;
13893        }
13894
13895        boolean ret = false;
13896        if (isSystemApp(ps)) {
13897            if (DEBUG_REMOVE) Slog.d(TAG, "Removing system package: " + ps.name);
13898            // When an updated system application is deleted we delete the existing resources as well and
13899            // fall back to existing code in system partition
13900            ret = deleteSystemPackageLI(ps, allUserHandles, perUserInstalled,
13901                    flags, outInfo, writeSettings);
13902        } else {
13903            if (DEBUG_REMOVE) Slog.d(TAG, "Removing non-system package: " + ps.name);
13904            // Kill application pre-emptively especially for apps on sd.
13905            killApplication(packageName, ps.appId, "uninstall pkg");
13906            ret = deleteInstalledPackageLI(ps, deleteCodeAndResources, flags,
13907                    allUserHandles, perUserInstalled,
13908                    outInfo, writeSettings);
13909        }
13910
13911        return ret;
13912    }
13913
13914    private final static class ClearStorageConnection implements ServiceConnection {
13915        IMediaContainerService mContainerService;
13916
13917        @Override
13918        public void onServiceConnected(ComponentName name, IBinder service) {
13919            synchronized (this) {
13920                mContainerService = IMediaContainerService.Stub.asInterface(service);
13921                notifyAll();
13922            }
13923        }
13924
13925        @Override
13926        public void onServiceDisconnected(ComponentName name) {
13927        }
13928    }
13929
13930    private void clearExternalStorageDataSync(String packageName, int userId, boolean allData) {
13931        final boolean mounted;
13932        if (Environment.isExternalStorageEmulated()) {
13933            mounted = true;
13934        } else {
13935            final String status = Environment.getExternalStorageState();
13936
13937            mounted = status.equals(Environment.MEDIA_MOUNTED)
13938                    || status.equals(Environment.MEDIA_MOUNTED_READ_ONLY);
13939        }
13940
13941        if (!mounted) {
13942            return;
13943        }
13944
13945        final Intent containerIntent = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
13946        int[] users;
13947        if (userId == UserHandle.USER_ALL) {
13948            users = sUserManager.getUserIds();
13949        } else {
13950            users = new int[] { userId };
13951        }
13952        final ClearStorageConnection conn = new ClearStorageConnection();
13953        if (mContext.bindServiceAsUser(
13954                containerIntent, conn, Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) {
13955            try {
13956                for (int curUser : users) {
13957                    long timeout = SystemClock.uptimeMillis() + 5000;
13958                    synchronized (conn) {
13959                        long now = SystemClock.uptimeMillis();
13960                        while (conn.mContainerService == null && now < timeout) {
13961                            try {
13962                                conn.wait(timeout - now);
13963                            } catch (InterruptedException e) {
13964                            }
13965                        }
13966                    }
13967                    if (conn.mContainerService == null) {
13968                        return;
13969                    }
13970
13971                    final UserEnvironment userEnv = new UserEnvironment(curUser);
13972                    clearDirectory(conn.mContainerService,
13973                            userEnv.buildExternalStorageAppCacheDirs(packageName));
13974                    if (allData) {
13975                        clearDirectory(conn.mContainerService,
13976                                userEnv.buildExternalStorageAppDataDirs(packageName));
13977                        clearDirectory(conn.mContainerService,
13978                                userEnv.buildExternalStorageAppMediaDirs(packageName));
13979                    }
13980                }
13981            } finally {
13982                mContext.unbindService(conn);
13983            }
13984        }
13985    }
13986
13987    @Override
13988    public void clearApplicationUserData(final String packageName,
13989            final IPackageDataObserver observer, final int userId) {
13990        mContext.enforceCallingOrSelfPermission(
13991                android.Manifest.permission.CLEAR_APP_USER_DATA, null);
13992        enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, "clear application data");
13993        // Queue up an async operation since the package deletion may take a little while.
13994        mHandler.post(new Runnable() {
13995            public void run() {
13996                mHandler.removeCallbacks(this);
13997                final boolean succeeded;
13998                synchronized (mInstallLock) {
13999                    succeeded = clearApplicationUserDataLI(packageName, userId);
14000                }
14001                clearExternalStorageDataSync(packageName, userId, true);
14002                if (succeeded) {
14003                    // invoke DeviceStorageMonitor's update method to clear any notifications
14004                    DeviceStorageMonitorInternal
14005                            dsm = LocalServices.getService(DeviceStorageMonitorInternal.class);
14006                    if (dsm != null) {
14007                        dsm.checkMemory();
14008                    }
14009                }
14010                if(observer != null) {
14011                    try {
14012                        observer.onRemoveCompleted(packageName, succeeded);
14013                    } catch (RemoteException e) {
14014                        Log.i(TAG, "Observer no longer exists.");
14015                    }
14016                } //end if observer
14017            } //end run
14018        });
14019    }
14020
14021    private boolean clearApplicationUserDataLI(String packageName, int userId) {
14022        if (packageName == null) {
14023            Slog.w(TAG, "Attempt to delete null packageName.");
14024            return false;
14025        }
14026
14027        // Try finding details about the requested package
14028        PackageParser.Package pkg;
14029        synchronized (mPackages) {
14030            pkg = mPackages.get(packageName);
14031            if (pkg == null) {
14032                final PackageSetting ps = mSettings.mPackages.get(packageName);
14033                if (ps != null) {
14034                    pkg = ps.pkg;
14035                }
14036            }
14037
14038            if (pkg == null) {
14039                Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
14040                return false;
14041            }
14042
14043            PackageSetting ps = (PackageSetting) pkg.mExtras;
14044            resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
14045        }
14046
14047        // Always delete data directories for package, even if we found no other
14048        // record of app. This helps users recover from UID mismatches without
14049        // resorting to a full data wipe.
14050        // TODO: triage flags as part of 26466827
14051        final int flags = Installer.FLAG_CE_STORAGE | Installer.FLAG_DE_STORAGE;
14052        try {
14053            mInstaller.clearAppData(pkg.volumeUuid, packageName, userId, flags);
14054        } catch (InstallerException e) {
14055            Slog.w(TAG, "Couldn't remove cache files for package " + packageName, e);
14056            return false;
14057        }
14058
14059        final int appId = UserHandle.getAppId(pkg.applicationInfo.uid);
14060        removeKeystoreDataIfNeeded(userId, appId);
14061
14062        // Create a native library symlink only if we have native libraries
14063        // and if the native libraries are 32 bit libraries. We do not provide
14064        // this symlink for 64 bit libraries.
14065        if (pkg.applicationInfo.primaryCpuAbi != null &&
14066                !VMRuntime.is64BitAbi(pkg.applicationInfo.primaryCpuAbi)) {
14067            final String nativeLibPath = pkg.applicationInfo.nativeLibraryDir;
14068            try {
14069                mInstaller.linkNativeLibraryDirectory(pkg.volumeUuid, pkg.packageName,
14070                        nativeLibPath, userId);
14071            } catch (InstallerException e) {
14072                Slog.w(TAG, "Failed linking native library dir", e);
14073                return false;
14074            }
14075        }
14076
14077        return true;
14078    }
14079
14080    /**
14081     * Reverts user permission state changes (permissions and flags) in
14082     * all packages for a given user.
14083     *
14084     * @param userId The device user for which to do a reset.
14085     */
14086    private void resetUserChangesToRuntimePermissionsAndFlagsLPw(int userId) {
14087        final int packageCount = mPackages.size();
14088        for (int i = 0; i < packageCount; i++) {
14089            PackageParser.Package pkg = mPackages.valueAt(i);
14090            PackageSetting ps = (PackageSetting) pkg.mExtras;
14091            resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
14092        }
14093    }
14094
14095    /**
14096     * Reverts user permission state changes (permissions and flags).
14097     *
14098     * @param ps The package for which to reset.
14099     * @param userId The device user for which to do a reset.
14100     */
14101    private void resetUserChangesToRuntimePermissionsAndFlagsLPw(
14102            final PackageSetting ps, final int userId) {
14103        if (ps.pkg == null) {
14104            return;
14105        }
14106
14107        // These are flags that can change base on user actions.
14108        final int userSettableMask = FLAG_PERMISSION_USER_SET
14109                | FLAG_PERMISSION_USER_FIXED
14110                | FLAG_PERMISSION_REVOKE_ON_UPGRADE
14111                | FLAG_PERMISSION_REVIEW_REQUIRED;
14112
14113        final int policyOrSystemFlags = FLAG_PERMISSION_SYSTEM_FIXED
14114                | FLAG_PERMISSION_POLICY_FIXED;
14115
14116        boolean writeInstallPermissions = false;
14117        boolean writeRuntimePermissions = false;
14118
14119        final int permissionCount = ps.pkg.requestedPermissions.size();
14120        for (int i = 0; i < permissionCount; i++) {
14121            String permission = ps.pkg.requestedPermissions.get(i);
14122
14123            BasePermission bp = mSettings.mPermissions.get(permission);
14124            if (bp == null) {
14125                continue;
14126            }
14127
14128            // If shared user we just reset the state to which only this app contributed.
14129            if (ps.sharedUser != null) {
14130                boolean used = false;
14131                final int packageCount = ps.sharedUser.packages.size();
14132                for (int j = 0; j < packageCount; j++) {
14133                    PackageSetting pkg = ps.sharedUser.packages.valueAt(j);
14134                    if (pkg.pkg != null && !pkg.pkg.packageName.equals(ps.pkg.packageName)
14135                            && pkg.pkg.requestedPermissions.contains(permission)) {
14136                        used = true;
14137                        break;
14138                    }
14139                }
14140                if (used) {
14141                    continue;
14142                }
14143            }
14144
14145            PermissionsState permissionsState = ps.getPermissionsState();
14146
14147            final int oldFlags = permissionsState.getPermissionFlags(bp.name, userId);
14148
14149            // Always clear the user settable flags.
14150            final boolean hasInstallState = permissionsState.getInstallPermissionState(
14151                    bp.name) != null;
14152            // If permission review is enabled and this is a legacy app, mark the
14153            // permission as requiring a review as this is the initial state.
14154            int flags = 0;
14155            if (Build.PERMISSIONS_REVIEW_REQUIRED
14156                    && ps.pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
14157                flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
14158            }
14159            if (permissionsState.updatePermissionFlags(bp, userId, userSettableMask, flags)) {
14160                if (hasInstallState) {
14161                    writeInstallPermissions = true;
14162                } else {
14163                    writeRuntimePermissions = true;
14164                }
14165            }
14166
14167            // Below is only runtime permission handling.
14168            if (!bp.isRuntime()) {
14169                continue;
14170            }
14171
14172            // Never clobber system or policy.
14173            if ((oldFlags & policyOrSystemFlags) != 0) {
14174                continue;
14175            }
14176
14177            // If this permission was granted by default, make sure it is.
14178            if ((oldFlags & FLAG_PERMISSION_GRANTED_BY_DEFAULT) != 0) {
14179                if (permissionsState.grantRuntimePermission(bp, userId)
14180                        != PERMISSION_OPERATION_FAILURE) {
14181                    writeRuntimePermissions = true;
14182                }
14183            // If permission review is enabled the permissions for a legacy apps
14184            // are represented as constantly granted runtime ones, so don't revoke.
14185            } else if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) {
14186                // Otherwise, reset the permission.
14187                final int revokeResult = permissionsState.revokeRuntimePermission(bp, userId);
14188                switch (revokeResult) {
14189                    case PERMISSION_OPERATION_SUCCESS: {
14190                        writeRuntimePermissions = true;
14191                    } break;
14192
14193                    case PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
14194                        writeRuntimePermissions = true;
14195                        final int appId = ps.appId;
14196                        mHandler.post(new Runnable() {
14197                            @Override
14198                            public void run() {
14199                                killUid(appId, userId, KILL_APP_REASON_GIDS_CHANGED);
14200                            }
14201                        });
14202                    } break;
14203                }
14204            }
14205        }
14206
14207        // Synchronously write as we are taking permissions away.
14208        if (writeRuntimePermissions) {
14209            mSettings.writeRuntimePermissionsForUserLPr(userId, true);
14210        }
14211
14212        // Synchronously write as we are taking permissions away.
14213        if (writeInstallPermissions) {
14214            mSettings.writeLPr();
14215        }
14216    }
14217
14218    /**
14219     * Remove entries from the keystore daemon. Will only remove it if the
14220     * {@code appId} is valid.
14221     */
14222    private static void removeKeystoreDataIfNeeded(int userId, int appId) {
14223        if (appId < 0) {
14224            return;
14225        }
14226
14227        final KeyStore keyStore = KeyStore.getInstance();
14228        if (keyStore != null) {
14229            if (userId == UserHandle.USER_ALL) {
14230                for (final int individual : sUserManager.getUserIds()) {
14231                    keyStore.clearUid(UserHandle.getUid(individual, appId));
14232                }
14233            } else {
14234                keyStore.clearUid(UserHandle.getUid(userId, appId));
14235            }
14236        } else {
14237            Slog.w(TAG, "Could not contact keystore to clear entries for app id " + appId);
14238        }
14239    }
14240
14241    @Override
14242    public void deleteApplicationCacheFiles(final String packageName,
14243            final IPackageDataObserver observer) {
14244        mContext.enforceCallingOrSelfPermission(
14245                android.Manifest.permission.DELETE_CACHE_FILES, null);
14246        // Queue up an async operation since the package deletion may take a little while.
14247        final int userId = UserHandle.getCallingUserId();
14248        mHandler.post(new Runnable() {
14249            public void run() {
14250                mHandler.removeCallbacks(this);
14251                final boolean succeded;
14252                synchronized (mInstallLock) {
14253                    succeded = deleteApplicationCacheFilesLI(packageName, userId);
14254                }
14255                clearExternalStorageDataSync(packageName, userId, false);
14256                if (observer != null) {
14257                    try {
14258                        observer.onRemoveCompleted(packageName, succeded);
14259                    } catch (RemoteException e) {
14260                        Log.i(TAG, "Observer no longer exists.");
14261                    }
14262                } //end if observer
14263            } //end run
14264        });
14265    }
14266
14267    private boolean deleteApplicationCacheFilesLI(String packageName, int userId) {
14268        if (packageName == null) {
14269            Slog.w(TAG, "Attempt to delete null packageName.");
14270            return false;
14271        }
14272        PackageParser.Package p;
14273        synchronized (mPackages) {
14274            p = mPackages.get(packageName);
14275        }
14276        if (p == null) {
14277            Slog.w(TAG, "Package named '" + packageName +"' doesn't exist.");
14278            return false;
14279        }
14280        final ApplicationInfo applicationInfo = p.applicationInfo;
14281        if (applicationInfo == null) {
14282            Slog.w(TAG, "Package " + packageName + " has no applicationInfo.");
14283            return false;
14284        }
14285        // TODO: triage flags as part of 26466827
14286        final int flags = Installer.FLAG_CE_STORAGE | Installer.FLAG_DE_STORAGE;
14287        try {
14288            mInstaller.clearAppData(p.volumeUuid, packageName, userId,
14289                    flags | Installer.FLAG_CLEAR_CACHE_ONLY);
14290        } catch (InstallerException e) {
14291            Slog.w(TAG, "Couldn't remove cache files for package "
14292                    + packageName + " u" + userId, e);
14293            return false;
14294        }
14295        return true;
14296    }
14297
14298    @Override
14299    public void getPackageSizeInfo(final String packageName, int userHandle,
14300            final IPackageStatsObserver observer) {
14301        mContext.enforceCallingOrSelfPermission(
14302                android.Manifest.permission.GET_PACKAGE_SIZE, null);
14303        if (packageName == null) {
14304            throw new IllegalArgumentException("Attempt to get size of null packageName");
14305        }
14306
14307        PackageStats stats = new PackageStats(packageName, userHandle);
14308
14309        /*
14310         * Queue up an async operation since the package measurement may take a
14311         * little while.
14312         */
14313        Message msg = mHandler.obtainMessage(INIT_COPY);
14314        msg.obj = new MeasureParams(stats, observer);
14315        mHandler.sendMessage(msg);
14316    }
14317
14318    private boolean getPackageSizeInfoLI(String packageName, int userHandle,
14319            PackageStats pStats) {
14320        if (packageName == null) {
14321            Slog.w(TAG, "Attempt to get size of null packageName.");
14322            return false;
14323        }
14324        PackageParser.Package p;
14325        boolean dataOnly = false;
14326        String libDirRoot = null;
14327        String asecPath = null;
14328        PackageSetting ps = null;
14329        synchronized (mPackages) {
14330            p = mPackages.get(packageName);
14331            ps = mSettings.mPackages.get(packageName);
14332            if(p == null) {
14333                dataOnly = true;
14334                if((ps == null) || (ps.pkg == null)) {
14335                    Slog.w(TAG, "Package named '" + packageName +"' doesn't exist.");
14336                    return false;
14337                }
14338                p = ps.pkg;
14339            }
14340            if (ps != null) {
14341                libDirRoot = ps.legacyNativeLibraryPathString;
14342            }
14343            if (p != null && (p.isForwardLocked() || p.applicationInfo.isExternalAsec())) {
14344                final long token = Binder.clearCallingIdentity();
14345                try {
14346                    String secureContainerId = cidFromCodePath(p.applicationInfo.getBaseCodePath());
14347                    if (secureContainerId != null) {
14348                        asecPath = PackageHelper.getSdFilesystem(secureContainerId);
14349                    }
14350                } finally {
14351                    Binder.restoreCallingIdentity(token);
14352                }
14353            }
14354        }
14355        String publicSrcDir = null;
14356        if(!dataOnly) {
14357            final ApplicationInfo applicationInfo = p.applicationInfo;
14358            if (applicationInfo == null) {
14359                Slog.w(TAG, "Package " + packageName + " has no applicationInfo.");
14360                return false;
14361            }
14362            if (p.isForwardLocked()) {
14363                publicSrcDir = applicationInfo.getBaseResourcePath();
14364            }
14365        }
14366        // TODO: extend to measure size of split APKs
14367        // TODO(multiArch): Extend getSizeInfo to look at the full subdirectory tree,
14368        // not just the first level.
14369        // TODO(multiArch): Extend getSizeInfo to look at *all* instruction sets, not
14370        // just the primary.
14371        String[] dexCodeInstructionSets = getDexCodeInstructionSets(getAppDexInstructionSets(ps));
14372
14373        String apkPath;
14374        File packageDir = new File(p.codePath);
14375
14376        if (packageDir.isDirectory() && p.canHaveOatDir()) {
14377            apkPath = packageDir.getAbsolutePath();
14378            // If libDirRoot is inside a package dir, set it to null to avoid it being counted twice
14379            if (libDirRoot != null && libDirRoot.startsWith(apkPath)) {
14380                libDirRoot = null;
14381            }
14382        } else {
14383            apkPath = p.baseCodePath;
14384        }
14385
14386        // TODO: triage flags as part of 26466827
14387        final int flags = Installer.FLAG_CE_STORAGE | Installer.FLAG_DE_STORAGE;
14388        try {
14389            mInstaller.getAppSize(p.volumeUuid, packageName, userHandle, flags, apkPath,
14390                    libDirRoot, publicSrcDir, asecPath, dexCodeInstructionSets, pStats);
14391        } catch (InstallerException e) {
14392            return false;
14393        }
14394
14395        // Fix-up for forward-locked applications in ASEC containers.
14396        if (!isExternal(p)) {
14397            pStats.codeSize += pStats.externalCodeSize;
14398            pStats.externalCodeSize = 0L;
14399        }
14400
14401        return true;
14402    }
14403
14404
14405    @Override
14406    public void addPackageToPreferred(String packageName) {
14407        Slog.w(TAG, "addPackageToPreferred: this is now a no-op");
14408    }
14409
14410    @Override
14411    public void removePackageFromPreferred(String packageName) {
14412        Slog.w(TAG, "removePackageFromPreferred: this is now a no-op");
14413    }
14414
14415    @Override
14416    public List<PackageInfo> getPreferredPackages(int flags) {
14417        return new ArrayList<PackageInfo>();
14418    }
14419
14420    private int getUidTargetSdkVersionLockedLPr(int uid) {
14421        Object obj = mSettings.getUserIdLPr(uid);
14422        if (obj instanceof SharedUserSetting) {
14423            final SharedUserSetting sus = (SharedUserSetting) obj;
14424            int vers = Build.VERSION_CODES.CUR_DEVELOPMENT;
14425            final Iterator<PackageSetting> it = sus.packages.iterator();
14426            while (it.hasNext()) {
14427                final PackageSetting ps = it.next();
14428                if (ps.pkg != null) {
14429                    int v = ps.pkg.applicationInfo.targetSdkVersion;
14430                    if (v < vers) vers = v;
14431                }
14432            }
14433            return vers;
14434        } else if (obj instanceof PackageSetting) {
14435            final PackageSetting ps = (PackageSetting) obj;
14436            if (ps.pkg != null) {
14437                return ps.pkg.applicationInfo.targetSdkVersion;
14438            }
14439        }
14440        return Build.VERSION_CODES.CUR_DEVELOPMENT;
14441    }
14442
14443    @Override
14444    public void addPreferredActivity(IntentFilter filter, int match,
14445            ComponentName[] set, ComponentName activity, int userId) {
14446        addPreferredActivityInternal(filter, match, set, activity, true, userId,
14447                "Adding preferred");
14448    }
14449
14450    private void addPreferredActivityInternal(IntentFilter filter, int match,
14451            ComponentName[] set, ComponentName activity, boolean always, int userId,
14452            String opname) {
14453        // writer
14454        int callingUid = Binder.getCallingUid();
14455        enforceCrossUserPermission(callingUid, userId, true, false, "add preferred activity");
14456        if (filter.countActions() == 0) {
14457            Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
14458            return;
14459        }
14460        synchronized (mPackages) {
14461            if (mContext.checkCallingOrSelfPermission(
14462                    android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
14463                    != PackageManager.PERMISSION_GRANTED) {
14464                if (getUidTargetSdkVersionLockedLPr(callingUid)
14465                        < Build.VERSION_CODES.FROYO) {
14466                    Slog.w(TAG, "Ignoring addPreferredActivity() from uid "
14467                            + callingUid);
14468                    return;
14469                }
14470                mContext.enforceCallingOrSelfPermission(
14471                        android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
14472            }
14473
14474            PreferredIntentResolver pir = mSettings.editPreferredActivitiesLPw(userId);
14475            Slog.i(TAG, opname + " activity " + activity.flattenToShortString() + " for user "
14476                    + userId + ":");
14477            filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
14478            pir.addFilter(new PreferredActivity(filter, match, set, activity, always));
14479            scheduleWritePackageRestrictionsLocked(userId);
14480        }
14481    }
14482
14483    @Override
14484    public void replacePreferredActivity(IntentFilter filter, int match,
14485            ComponentName[] set, ComponentName activity, int userId) {
14486        if (filter.countActions() != 1) {
14487            throw new IllegalArgumentException(
14488                    "replacePreferredActivity expects filter to have only 1 action.");
14489        }
14490        if (filter.countDataAuthorities() != 0
14491                || filter.countDataPaths() != 0
14492                || filter.countDataSchemes() > 1
14493                || filter.countDataTypes() != 0) {
14494            throw new IllegalArgumentException(
14495                    "replacePreferredActivity expects filter to have no data authorities, " +
14496                    "paths, or types; and at most one scheme.");
14497        }
14498
14499        final int callingUid = Binder.getCallingUid();
14500        enforceCrossUserPermission(callingUid, userId, true, false, "replace preferred activity");
14501        synchronized (mPackages) {
14502            if (mContext.checkCallingOrSelfPermission(
14503                    android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
14504                    != PackageManager.PERMISSION_GRANTED) {
14505                if (getUidTargetSdkVersionLockedLPr(callingUid)
14506                        < Build.VERSION_CODES.FROYO) {
14507                    Slog.w(TAG, "Ignoring replacePreferredActivity() from uid "
14508                            + Binder.getCallingUid());
14509                    return;
14510                }
14511                mContext.enforceCallingOrSelfPermission(
14512                        android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
14513            }
14514
14515            PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
14516            if (pir != null) {
14517                // Get all of the existing entries that exactly match this filter.
14518                ArrayList<PreferredActivity> existing = pir.findFilters(filter);
14519                if (existing != null && existing.size() == 1) {
14520                    PreferredActivity cur = existing.get(0);
14521                    if (DEBUG_PREFERRED) {
14522                        Slog.i(TAG, "Checking replace of preferred:");
14523                        filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
14524                        if (!cur.mPref.mAlways) {
14525                            Slog.i(TAG, "  -- CUR; not mAlways!");
14526                        } else {
14527                            Slog.i(TAG, "  -- CUR: mMatch=" + cur.mPref.mMatch);
14528                            Slog.i(TAG, "  -- CUR: mSet="
14529                                    + Arrays.toString(cur.mPref.mSetComponents));
14530                            Slog.i(TAG, "  -- CUR: mComponent=" + cur.mPref.mShortComponent);
14531                            Slog.i(TAG, "  -- NEW: mMatch="
14532                                    + (match&IntentFilter.MATCH_CATEGORY_MASK));
14533                            Slog.i(TAG, "  -- CUR: mSet=" + Arrays.toString(set));
14534                            Slog.i(TAG, "  -- CUR: mComponent=" + activity.flattenToShortString());
14535                        }
14536                    }
14537                    if (cur.mPref.mAlways && cur.mPref.mComponent.equals(activity)
14538                            && cur.mPref.mMatch == (match&IntentFilter.MATCH_CATEGORY_MASK)
14539                            && cur.mPref.sameSet(set)) {
14540                        // Setting the preferred activity to what it happens to be already
14541                        if (DEBUG_PREFERRED) {
14542                            Slog.i(TAG, "Replacing with same preferred activity "
14543                                    + cur.mPref.mShortComponent + " for user "
14544                                    + userId + ":");
14545                            filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
14546                        }
14547                        return;
14548                    }
14549                }
14550
14551                if (existing != null) {
14552                    if (DEBUG_PREFERRED) {
14553                        Slog.i(TAG, existing.size() + " existing preferred matches for:");
14554                        filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
14555                    }
14556                    for (int i = 0; i < existing.size(); i++) {
14557                        PreferredActivity pa = existing.get(i);
14558                        if (DEBUG_PREFERRED) {
14559                            Slog.i(TAG, "Removing existing preferred activity "
14560                                    + pa.mPref.mComponent + ":");
14561                            pa.dump(new LogPrinter(Log.INFO, TAG), "  ");
14562                        }
14563                        pir.removeFilter(pa);
14564                    }
14565                }
14566            }
14567            addPreferredActivityInternal(filter, match, set, activity, true, userId,
14568                    "Replacing preferred");
14569        }
14570    }
14571
14572    @Override
14573    public void clearPackagePreferredActivities(String packageName) {
14574        final int uid = Binder.getCallingUid();
14575        // writer
14576        synchronized (mPackages) {
14577            PackageParser.Package pkg = mPackages.get(packageName);
14578            if (pkg == null || pkg.applicationInfo.uid != uid) {
14579                if (mContext.checkCallingOrSelfPermission(
14580                        android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
14581                        != PackageManager.PERMISSION_GRANTED) {
14582                    if (getUidTargetSdkVersionLockedLPr(Binder.getCallingUid())
14583                            < Build.VERSION_CODES.FROYO) {
14584                        Slog.w(TAG, "Ignoring clearPackagePreferredActivities() from uid "
14585                                + Binder.getCallingUid());
14586                        return;
14587                    }
14588                    mContext.enforceCallingOrSelfPermission(
14589                            android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
14590                }
14591            }
14592
14593            int user = UserHandle.getCallingUserId();
14594            if (clearPackagePreferredActivitiesLPw(packageName, user)) {
14595                scheduleWritePackageRestrictionsLocked(user);
14596            }
14597        }
14598    }
14599
14600    /** This method takes a specific user id as well as UserHandle.USER_ALL. */
14601    boolean clearPackagePreferredActivitiesLPw(String packageName, int userId) {
14602        ArrayList<PreferredActivity> removed = null;
14603        boolean changed = false;
14604        for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
14605            final int thisUserId = mSettings.mPreferredActivities.keyAt(i);
14606            PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
14607            if (userId != UserHandle.USER_ALL && userId != thisUserId) {
14608                continue;
14609            }
14610            Iterator<PreferredActivity> it = pir.filterIterator();
14611            while (it.hasNext()) {
14612                PreferredActivity pa = it.next();
14613                // Mark entry for removal only if it matches the package name
14614                // and the entry is of type "always".
14615                if (packageName == null ||
14616                        (pa.mPref.mComponent.getPackageName().equals(packageName)
14617                                && pa.mPref.mAlways)) {
14618                    if (removed == null) {
14619                        removed = new ArrayList<PreferredActivity>();
14620                    }
14621                    removed.add(pa);
14622                }
14623            }
14624            if (removed != null) {
14625                for (int j=0; j<removed.size(); j++) {
14626                    PreferredActivity pa = removed.get(j);
14627                    pir.removeFilter(pa);
14628                }
14629                changed = true;
14630            }
14631        }
14632        return changed;
14633    }
14634
14635    /** This method takes a specific user id as well as UserHandle.USER_ALL. */
14636    private void clearIntentFilterVerificationsLPw(int userId) {
14637        final int packageCount = mPackages.size();
14638        for (int i = 0; i < packageCount; i++) {
14639            PackageParser.Package pkg = mPackages.valueAt(i);
14640            clearIntentFilterVerificationsLPw(pkg.packageName, userId);
14641        }
14642    }
14643
14644    /** This method takes a specific user id as well as UserHandle.USER_ALL. */
14645    void clearIntentFilterVerificationsLPw(String packageName, int userId) {
14646        if (userId == UserHandle.USER_ALL) {
14647            if (mSettings.removeIntentFilterVerificationLPw(packageName,
14648                    sUserManager.getUserIds())) {
14649                for (int oneUserId : sUserManager.getUserIds()) {
14650                    scheduleWritePackageRestrictionsLocked(oneUserId);
14651                }
14652            }
14653        } else {
14654            if (mSettings.removeIntentFilterVerificationLPw(packageName, userId)) {
14655                scheduleWritePackageRestrictionsLocked(userId);
14656            }
14657        }
14658    }
14659
14660    void clearDefaultBrowserIfNeeded(String packageName) {
14661        for (int oneUserId : sUserManager.getUserIds()) {
14662            String defaultBrowserPackageName = getDefaultBrowserPackageName(oneUserId);
14663            if (TextUtils.isEmpty(defaultBrowserPackageName)) continue;
14664            if (packageName.equals(defaultBrowserPackageName)) {
14665                setDefaultBrowserPackageName(null, oneUserId);
14666            }
14667        }
14668    }
14669
14670    @Override
14671    public void resetApplicationPreferences(int userId) {
14672        mContext.enforceCallingOrSelfPermission(
14673                android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
14674        // writer
14675        synchronized (mPackages) {
14676            final long identity = Binder.clearCallingIdentity();
14677            try {
14678                clearPackagePreferredActivitiesLPw(null, userId);
14679                mSettings.applyDefaultPreferredAppsLPw(this, userId);
14680                // TODO: We have to reset the default SMS and Phone. This requires
14681                // significant refactoring to keep all default apps in the package
14682                // manager (cleaner but more work) or have the services provide
14683                // callbacks to the package manager to request a default app reset.
14684                applyFactoryDefaultBrowserLPw(userId);
14685                clearIntentFilterVerificationsLPw(userId);
14686                primeDomainVerificationsLPw(userId);
14687                resetUserChangesToRuntimePermissionsAndFlagsLPw(userId);
14688                scheduleWritePackageRestrictionsLocked(userId);
14689            } finally {
14690                Binder.restoreCallingIdentity(identity);
14691            }
14692        }
14693    }
14694
14695    @Override
14696    public int getPreferredActivities(List<IntentFilter> outFilters,
14697            List<ComponentName> outActivities, String packageName) {
14698
14699        int num = 0;
14700        final int userId = UserHandle.getCallingUserId();
14701        // reader
14702        synchronized (mPackages) {
14703            PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
14704            if (pir != null) {
14705                final Iterator<PreferredActivity> it = pir.filterIterator();
14706                while (it.hasNext()) {
14707                    final PreferredActivity pa = it.next();
14708                    if (packageName == null
14709                            || (pa.mPref.mComponent.getPackageName().equals(packageName)
14710                                    && pa.mPref.mAlways)) {
14711                        if (outFilters != null) {
14712                            outFilters.add(new IntentFilter(pa));
14713                        }
14714                        if (outActivities != null) {
14715                            outActivities.add(pa.mPref.mComponent);
14716                        }
14717                    }
14718                }
14719            }
14720        }
14721
14722        return num;
14723    }
14724
14725    @Override
14726    public void addPersistentPreferredActivity(IntentFilter filter, ComponentName activity,
14727            int userId) {
14728        int callingUid = Binder.getCallingUid();
14729        if (callingUid != Process.SYSTEM_UID) {
14730            throw new SecurityException(
14731                    "addPersistentPreferredActivity can only be run by the system");
14732        }
14733        if (filter.countActions() == 0) {
14734            Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
14735            return;
14736        }
14737        synchronized (mPackages) {
14738            Slog.i(TAG, "Adding persistent preferred activity " + activity + " for user " + userId +
14739                    ":");
14740            filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
14741            mSettings.editPersistentPreferredActivitiesLPw(userId).addFilter(
14742                    new PersistentPreferredActivity(filter, activity));
14743            scheduleWritePackageRestrictionsLocked(userId);
14744        }
14745    }
14746
14747    @Override
14748    public void clearPackagePersistentPreferredActivities(String packageName, int userId) {
14749        int callingUid = Binder.getCallingUid();
14750        if (callingUid != Process.SYSTEM_UID) {
14751            throw new SecurityException(
14752                    "clearPackagePersistentPreferredActivities can only be run by the system");
14753        }
14754        ArrayList<PersistentPreferredActivity> removed = null;
14755        boolean changed = false;
14756        synchronized (mPackages) {
14757            for (int i=0; i<mSettings.mPersistentPreferredActivities.size(); i++) {
14758                final int thisUserId = mSettings.mPersistentPreferredActivities.keyAt(i);
14759                PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
14760                        .valueAt(i);
14761                if (userId != thisUserId) {
14762                    continue;
14763                }
14764                Iterator<PersistentPreferredActivity> it = ppir.filterIterator();
14765                while (it.hasNext()) {
14766                    PersistentPreferredActivity ppa = it.next();
14767                    // Mark entry for removal only if it matches the package name.
14768                    if (ppa.mComponent.getPackageName().equals(packageName)) {
14769                        if (removed == null) {
14770                            removed = new ArrayList<PersistentPreferredActivity>();
14771                        }
14772                        removed.add(ppa);
14773                    }
14774                }
14775                if (removed != null) {
14776                    for (int j=0; j<removed.size(); j++) {
14777                        PersistentPreferredActivity ppa = removed.get(j);
14778                        ppir.removeFilter(ppa);
14779                    }
14780                    changed = true;
14781                }
14782            }
14783
14784            if (changed) {
14785                scheduleWritePackageRestrictionsLocked(userId);
14786            }
14787        }
14788    }
14789
14790    /**
14791     * Common machinery for picking apart a restored XML blob and passing
14792     * it to a caller-supplied functor to be applied to the running system.
14793     */
14794    private void restoreFromXml(XmlPullParser parser, int userId,
14795            String expectedStartTag, BlobXmlRestorer functor)
14796            throws IOException, XmlPullParserException {
14797        int type;
14798        while ((type = parser.next()) != XmlPullParser.START_TAG
14799                && type != XmlPullParser.END_DOCUMENT) {
14800        }
14801        if (type != XmlPullParser.START_TAG) {
14802            // oops didn't find a start tag?!
14803            if (DEBUG_BACKUP) {
14804                Slog.e(TAG, "Didn't find start tag during restore");
14805            }
14806            return;
14807        }
14808Slog.v(TAG, ":: restoreFromXml() : got to tag " + parser.getName());
14809        // this is supposed to be TAG_PREFERRED_BACKUP
14810        if (!expectedStartTag.equals(parser.getName())) {
14811            if (DEBUG_BACKUP) {
14812                Slog.e(TAG, "Found unexpected tag " + parser.getName());
14813            }
14814            return;
14815        }
14816
14817        // skip interfering stuff, then we're aligned with the backing implementation
14818        while ((type = parser.next()) == XmlPullParser.TEXT) { }
14819Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName());
14820        functor.apply(parser, userId);
14821    }
14822
14823    private interface BlobXmlRestorer {
14824        public void apply(XmlPullParser parser, int userId) throws IOException, XmlPullParserException;
14825    }
14826
14827    /**
14828     * Non-Binder method, support for the backup/restore mechanism: write the
14829     * full set of preferred activities in its canonical XML format.  Returns the
14830     * XML output as a byte array, or null if there is none.
14831     */
14832    @Override
14833    public byte[] getPreferredActivityBackup(int userId) {
14834        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
14835            throw new SecurityException("Only the system may call getPreferredActivityBackup()");
14836        }
14837
14838        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
14839        try {
14840            final XmlSerializer serializer = new FastXmlSerializer();
14841            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
14842            serializer.startDocument(null, true);
14843            serializer.startTag(null, TAG_PREFERRED_BACKUP);
14844
14845            synchronized (mPackages) {
14846                mSettings.writePreferredActivitiesLPr(serializer, userId, true);
14847            }
14848
14849            serializer.endTag(null, TAG_PREFERRED_BACKUP);
14850            serializer.endDocument();
14851            serializer.flush();
14852        } catch (Exception e) {
14853            if (DEBUG_BACKUP) {
14854                Slog.e(TAG, "Unable to write preferred activities for backup", e);
14855            }
14856            return null;
14857        }
14858
14859        return dataStream.toByteArray();
14860    }
14861
14862    @Override
14863    public void restorePreferredActivities(byte[] backup, int userId) {
14864        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
14865            throw new SecurityException("Only the system may call restorePreferredActivities()");
14866        }
14867
14868        try {
14869            final XmlPullParser parser = Xml.newPullParser();
14870            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
14871            restoreFromXml(parser, userId, TAG_PREFERRED_BACKUP,
14872                    new BlobXmlRestorer() {
14873                        @Override
14874                        public void apply(XmlPullParser parser, int userId)
14875                                throws XmlPullParserException, IOException {
14876                            synchronized (mPackages) {
14877                                mSettings.readPreferredActivitiesLPw(parser, userId);
14878                            }
14879                        }
14880                    } );
14881        } catch (Exception e) {
14882            if (DEBUG_BACKUP) {
14883                Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
14884            }
14885        }
14886    }
14887
14888    /**
14889     * Non-Binder method, support for the backup/restore mechanism: write the
14890     * default browser (etc) settings in its canonical XML format.  Returns the default
14891     * browser XML representation as a byte array, or null if there is none.
14892     */
14893    @Override
14894    public byte[] getDefaultAppsBackup(int userId) {
14895        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
14896            throw new SecurityException("Only the system may call getDefaultAppsBackup()");
14897        }
14898
14899        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
14900        try {
14901            final XmlSerializer serializer = new FastXmlSerializer();
14902            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
14903            serializer.startDocument(null, true);
14904            serializer.startTag(null, TAG_DEFAULT_APPS);
14905
14906            synchronized (mPackages) {
14907                mSettings.writeDefaultAppsLPr(serializer, userId);
14908            }
14909
14910            serializer.endTag(null, TAG_DEFAULT_APPS);
14911            serializer.endDocument();
14912            serializer.flush();
14913        } catch (Exception e) {
14914            if (DEBUG_BACKUP) {
14915                Slog.e(TAG, "Unable to write default apps for backup", e);
14916            }
14917            return null;
14918        }
14919
14920        return dataStream.toByteArray();
14921    }
14922
14923    @Override
14924    public void restoreDefaultApps(byte[] backup, int userId) {
14925        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
14926            throw new SecurityException("Only the system may call restoreDefaultApps()");
14927        }
14928
14929        try {
14930            final XmlPullParser parser = Xml.newPullParser();
14931            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
14932            restoreFromXml(parser, userId, TAG_DEFAULT_APPS,
14933                    new BlobXmlRestorer() {
14934                        @Override
14935                        public void apply(XmlPullParser parser, int userId)
14936                                throws XmlPullParserException, IOException {
14937                            synchronized (mPackages) {
14938                                mSettings.readDefaultAppsLPw(parser, userId);
14939                            }
14940                        }
14941                    } );
14942        } catch (Exception e) {
14943            if (DEBUG_BACKUP) {
14944                Slog.e(TAG, "Exception restoring default apps: " + e.getMessage());
14945            }
14946        }
14947    }
14948
14949    @Override
14950    public byte[] getIntentFilterVerificationBackup(int userId) {
14951        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
14952            throw new SecurityException("Only the system may call getIntentFilterVerificationBackup()");
14953        }
14954
14955        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
14956        try {
14957            final XmlSerializer serializer = new FastXmlSerializer();
14958            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
14959            serializer.startDocument(null, true);
14960            serializer.startTag(null, TAG_INTENT_FILTER_VERIFICATION);
14961
14962            synchronized (mPackages) {
14963                mSettings.writeAllDomainVerificationsLPr(serializer, userId);
14964            }
14965
14966            serializer.endTag(null, TAG_INTENT_FILTER_VERIFICATION);
14967            serializer.endDocument();
14968            serializer.flush();
14969        } catch (Exception e) {
14970            if (DEBUG_BACKUP) {
14971                Slog.e(TAG, "Unable to write default apps for backup", e);
14972            }
14973            return null;
14974        }
14975
14976        return dataStream.toByteArray();
14977    }
14978
14979    @Override
14980    public void restoreIntentFilterVerification(byte[] backup, int userId) {
14981        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
14982            throw new SecurityException("Only the system may call restorePreferredActivities()");
14983        }
14984
14985        try {
14986            final XmlPullParser parser = Xml.newPullParser();
14987            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
14988            restoreFromXml(parser, userId, TAG_INTENT_FILTER_VERIFICATION,
14989                    new BlobXmlRestorer() {
14990                        @Override
14991                        public void apply(XmlPullParser parser, int userId)
14992                                throws XmlPullParserException, IOException {
14993                            synchronized (mPackages) {
14994                                mSettings.readAllDomainVerificationsLPr(parser, userId);
14995                                mSettings.writeLPr();
14996                            }
14997                        }
14998                    } );
14999        } catch (Exception e) {
15000            if (DEBUG_BACKUP) {
15001                Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
15002            }
15003        }
15004    }
15005
15006    @Override
15007    public byte[] getPermissionGrantBackup(int userId) {
15008        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
15009            throw new SecurityException("Only the system may call getPermissionGrantBackup()");
15010        }
15011
15012        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
15013        try {
15014            final XmlSerializer serializer = new FastXmlSerializer();
15015            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
15016            serializer.startDocument(null, true);
15017            serializer.startTag(null, TAG_PERMISSION_BACKUP);
15018
15019            synchronized (mPackages) {
15020                serializeRuntimePermissionGrantsLPr(serializer, userId);
15021            }
15022
15023            serializer.endTag(null, TAG_PERMISSION_BACKUP);
15024            serializer.endDocument();
15025            serializer.flush();
15026        } catch (Exception e) {
15027            if (DEBUG_BACKUP) {
15028                Slog.e(TAG, "Unable to write default apps for backup", e);
15029            }
15030            return null;
15031        }
15032
15033        return dataStream.toByteArray();
15034    }
15035
15036    @Override
15037    public void restorePermissionGrants(byte[] backup, int userId) {
15038        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
15039            throw new SecurityException("Only the system may call restorePermissionGrants()");
15040        }
15041
15042        try {
15043            final XmlPullParser parser = Xml.newPullParser();
15044            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
15045            restoreFromXml(parser, userId, TAG_PERMISSION_BACKUP,
15046                    new BlobXmlRestorer() {
15047                        @Override
15048                        public void apply(XmlPullParser parser, int userId)
15049                                throws XmlPullParserException, IOException {
15050                            synchronized (mPackages) {
15051                                processRestoredPermissionGrantsLPr(parser, userId);
15052                            }
15053                        }
15054                    } );
15055        } catch (Exception e) {
15056            if (DEBUG_BACKUP) {
15057                Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
15058            }
15059        }
15060    }
15061
15062    private void serializeRuntimePermissionGrantsLPr(XmlSerializer serializer, final int userId)
15063            throws IOException {
15064        serializer.startTag(null, TAG_ALL_GRANTS);
15065
15066        final int N = mSettings.mPackages.size();
15067        for (int i = 0; i < N; i++) {
15068            final PackageSetting ps = mSettings.mPackages.valueAt(i);
15069            boolean pkgGrantsKnown = false;
15070
15071            PermissionsState packagePerms = ps.getPermissionsState();
15072
15073            for (PermissionState state : packagePerms.getRuntimePermissionStates(userId)) {
15074                final int grantFlags = state.getFlags();
15075                // only look at grants that are not system/policy fixed
15076                if ((grantFlags & SYSTEM_RUNTIME_GRANT_MASK) == 0) {
15077                    final boolean isGranted = state.isGranted();
15078                    // And only back up the user-twiddled state bits
15079                    if (isGranted || (grantFlags & USER_RUNTIME_GRANT_MASK) != 0) {
15080                        final String packageName = mSettings.mPackages.keyAt(i);
15081                        if (!pkgGrantsKnown) {
15082                            serializer.startTag(null, TAG_GRANT);
15083                            serializer.attribute(null, ATTR_PACKAGE_NAME, packageName);
15084                            pkgGrantsKnown = true;
15085                        }
15086
15087                        final boolean userSet =
15088                                (grantFlags & FLAG_PERMISSION_USER_SET) != 0;
15089                        final boolean userFixed =
15090                                (grantFlags & FLAG_PERMISSION_USER_FIXED) != 0;
15091                        final boolean revoke =
15092                                (grantFlags & FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0;
15093
15094                        serializer.startTag(null, TAG_PERMISSION);
15095                        serializer.attribute(null, ATTR_PERMISSION_NAME, state.getName());
15096                        if (isGranted) {
15097                            serializer.attribute(null, ATTR_IS_GRANTED, "true");
15098                        }
15099                        if (userSet) {
15100                            serializer.attribute(null, ATTR_USER_SET, "true");
15101                        }
15102                        if (userFixed) {
15103                            serializer.attribute(null, ATTR_USER_FIXED, "true");
15104                        }
15105                        if (revoke) {
15106                            serializer.attribute(null, ATTR_REVOKE_ON_UPGRADE, "true");
15107                        }
15108                        serializer.endTag(null, TAG_PERMISSION);
15109                    }
15110                }
15111            }
15112
15113            if (pkgGrantsKnown) {
15114                serializer.endTag(null, TAG_GRANT);
15115            }
15116        }
15117
15118        serializer.endTag(null, TAG_ALL_GRANTS);
15119    }
15120
15121    private void processRestoredPermissionGrantsLPr(XmlPullParser parser, int userId)
15122            throws XmlPullParserException, IOException {
15123        String pkgName = null;
15124        int outerDepth = parser.getDepth();
15125        int type;
15126        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
15127                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
15128            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
15129                continue;
15130            }
15131
15132            final String tagName = parser.getName();
15133            if (tagName.equals(TAG_GRANT)) {
15134                pkgName = parser.getAttributeValue(null, ATTR_PACKAGE_NAME);
15135                if (DEBUG_BACKUP) {
15136                    Slog.v(TAG, "+++ Restoring grants for package " + pkgName);
15137                }
15138            } else if (tagName.equals(TAG_PERMISSION)) {
15139
15140                final boolean isGranted = "true".equals(parser.getAttributeValue(null, ATTR_IS_GRANTED));
15141                final String permName = parser.getAttributeValue(null, ATTR_PERMISSION_NAME);
15142
15143                int newFlagSet = 0;
15144                if ("true".equals(parser.getAttributeValue(null, ATTR_USER_SET))) {
15145                    newFlagSet |= FLAG_PERMISSION_USER_SET;
15146                }
15147                if ("true".equals(parser.getAttributeValue(null, ATTR_USER_FIXED))) {
15148                    newFlagSet |= FLAG_PERMISSION_USER_FIXED;
15149                }
15150                if ("true".equals(parser.getAttributeValue(null, ATTR_REVOKE_ON_UPGRADE))) {
15151                    newFlagSet |= FLAG_PERMISSION_REVOKE_ON_UPGRADE;
15152                }
15153                if (DEBUG_BACKUP) {
15154                    Slog.v(TAG, "  + Restoring grant: pkg=" + pkgName + " perm=" + permName
15155                            + " granted=" + isGranted + " bits=0x" + Integer.toHexString(newFlagSet));
15156                }
15157                final PackageSetting ps = mSettings.mPackages.get(pkgName);
15158                if (ps != null) {
15159                    // Already installed so we apply the grant immediately
15160                    if (DEBUG_BACKUP) {
15161                        Slog.v(TAG, "        + already installed; applying");
15162                    }
15163                    PermissionsState perms = ps.getPermissionsState();
15164                    BasePermission bp = mSettings.mPermissions.get(permName);
15165                    if (bp != null) {
15166                        if (isGranted) {
15167                            perms.grantRuntimePermission(bp, userId);
15168                        }
15169                        if (newFlagSet != 0) {
15170                            perms.updatePermissionFlags(bp, userId, USER_RUNTIME_GRANT_MASK, newFlagSet);
15171                        }
15172                    }
15173                } else {
15174                    // Need to wait for post-restore install to apply the grant
15175                    if (DEBUG_BACKUP) {
15176                        Slog.v(TAG, "        - not yet installed; saving for later");
15177                    }
15178                    mSettings.processRestoredPermissionGrantLPr(pkgName, permName,
15179                            isGranted, newFlagSet, userId);
15180                }
15181            } else {
15182                PackageManagerService.reportSettingsProblem(Log.WARN,
15183                        "Unknown element under <" + TAG_PERMISSION_BACKUP + ">: " + tagName);
15184                XmlUtils.skipCurrentTag(parser);
15185            }
15186        }
15187
15188        scheduleWriteSettingsLocked();
15189        mSettings.writeRuntimePermissionsForUserLPr(userId, false);
15190    }
15191
15192    @Override
15193    public void addCrossProfileIntentFilter(IntentFilter intentFilter, String ownerPackage,
15194            int sourceUserId, int targetUserId, int flags) {
15195        mContext.enforceCallingOrSelfPermission(
15196                        android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
15197        int callingUid = Binder.getCallingUid();
15198        enforceOwnerRights(ownerPackage, callingUid);
15199        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
15200        if (intentFilter.countActions() == 0) {
15201            Slog.w(TAG, "Cannot set a crossProfile intent filter with no filter actions");
15202            return;
15203        }
15204        synchronized (mPackages) {
15205            CrossProfileIntentFilter newFilter = new CrossProfileIntentFilter(intentFilter,
15206                    ownerPackage, targetUserId, flags);
15207            CrossProfileIntentResolver resolver =
15208                    mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
15209            ArrayList<CrossProfileIntentFilter> existing = resolver.findFilters(intentFilter);
15210            // We have all those whose filter is equal. Now checking if the rest is equal as well.
15211            if (existing != null) {
15212                int size = existing.size();
15213                for (int i = 0; i < size; i++) {
15214                    if (newFilter.equalsIgnoreFilter(existing.get(i))) {
15215                        return;
15216                    }
15217                }
15218            }
15219            resolver.addFilter(newFilter);
15220            scheduleWritePackageRestrictionsLocked(sourceUserId);
15221        }
15222    }
15223
15224    @Override
15225    public void clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage) {
15226        mContext.enforceCallingOrSelfPermission(
15227                        android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
15228        int callingUid = Binder.getCallingUid();
15229        enforceOwnerRights(ownerPackage, callingUid);
15230        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
15231        synchronized (mPackages) {
15232            CrossProfileIntentResolver resolver =
15233                    mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
15234            ArraySet<CrossProfileIntentFilter> set =
15235                    new ArraySet<CrossProfileIntentFilter>(resolver.filterSet());
15236            for (CrossProfileIntentFilter filter : set) {
15237                if (filter.getOwnerPackage().equals(ownerPackage)) {
15238                    resolver.removeFilter(filter);
15239                }
15240            }
15241            scheduleWritePackageRestrictionsLocked(sourceUserId);
15242        }
15243    }
15244
15245    // Enforcing that callingUid is owning pkg on userId
15246    private void enforceOwnerRights(String pkg, int callingUid) {
15247        // The system owns everything.
15248        if (UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) {
15249            return;
15250        }
15251        int callingUserId = UserHandle.getUserId(callingUid);
15252        PackageInfo pi = getPackageInfo(pkg, 0, callingUserId);
15253        if (pi == null) {
15254            throw new IllegalArgumentException("Unknown package " + pkg + " on user "
15255                    + callingUserId);
15256        }
15257        if (!UserHandle.isSameApp(pi.applicationInfo.uid, callingUid)) {
15258            throw new SecurityException("Calling uid " + callingUid
15259                    + " does not own package " + pkg);
15260        }
15261    }
15262
15263    @Override
15264    public ComponentName getHomeActivities(List<ResolveInfo> allHomeCandidates) {
15265        Intent intent = new Intent(Intent.ACTION_MAIN);
15266        intent.addCategory(Intent.CATEGORY_HOME);
15267
15268        final int callingUserId = UserHandle.getCallingUserId();
15269        List<ResolveInfo> list = queryIntentActivities(intent, null,
15270                PackageManager.GET_META_DATA, callingUserId);
15271        ResolveInfo preferred = findPreferredActivity(intent, null, 0, list, 0,
15272                true, false, false, callingUserId);
15273
15274        allHomeCandidates.clear();
15275        if (list != null) {
15276            for (ResolveInfo ri : list) {
15277                allHomeCandidates.add(ri);
15278            }
15279        }
15280        return (preferred == null || preferred.activityInfo == null)
15281                ? null
15282                : new ComponentName(preferred.activityInfo.packageName,
15283                        preferred.activityInfo.name);
15284    }
15285
15286    @Override
15287    public void setApplicationEnabledSetting(String appPackageName,
15288            int newState, int flags, int userId, String callingPackage) {
15289        if (!sUserManager.exists(userId)) return;
15290        if (callingPackage == null) {
15291            callingPackage = Integer.toString(Binder.getCallingUid());
15292        }
15293        setEnabledSetting(appPackageName, null, newState, flags, userId, callingPackage);
15294    }
15295
15296    @Override
15297    public void setComponentEnabledSetting(ComponentName componentName,
15298            int newState, int flags, int userId) {
15299        if (!sUserManager.exists(userId)) return;
15300        setEnabledSetting(componentName.getPackageName(),
15301                componentName.getClassName(), newState, flags, userId, null);
15302    }
15303
15304    private void setEnabledSetting(final String packageName, String className, int newState,
15305            final int flags, int userId, String callingPackage) {
15306        if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT
15307              || newState == COMPONENT_ENABLED_STATE_ENABLED
15308              || newState == COMPONENT_ENABLED_STATE_DISABLED
15309              || newState == COMPONENT_ENABLED_STATE_DISABLED_USER
15310              || newState == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED)) {
15311            throw new IllegalArgumentException("Invalid new component state: "
15312                    + newState);
15313        }
15314        PackageSetting pkgSetting;
15315        final int uid = Binder.getCallingUid();
15316        final int permission = mContext.checkCallingOrSelfPermission(
15317                android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
15318        enforceCrossUserPermission(uid, userId, false, true, "set enabled");
15319        final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
15320        boolean sendNow = false;
15321        boolean isApp = (className == null);
15322        String componentName = isApp ? packageName : className;
15323        int packageUid = -1;
15324        ArrayList<String> components;
15325
15326        // writer
15327        synchronized (mPackages) {
15328            pkgSetting = mSettings.mPackages.get(packageName);
15329            if (pkgSetting == null) {
15330                if (className == null) {
15331                    throw new IllegalArgumentException("Unknown package: " + packageName);
15332                }
15333                throw new IllegalArgumentException(
15334                        "Unknown component: " + packageName + "/" + className);
15335            }
15336            // Allow root and verify that userId is not being specified by a different user
15337            if (!allowedByPermission && !UserHandle.isSameApp(uid, pkgSetting.appId)) {
15338                throw new SecurityException(
15339                        "Permission Denial: attempt to change component state from pid="
15340                        + Binder.getCallingPid()
15341                        + ", uid=" + uid + ", package uid=" + pkgSetting.appId);
15342            }
15343            if (className == null) {
15344                // We're dealing with an application/package level state change
15345                if (pkgSetting.getEnabled(userId) == newState) {
15346                    // Nothing to do
15347                    return;
15348                }
15349                if (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
15350                    || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {
15351                    // Don't care about who enables an app.
15352                    callingPackage = null;
15353                }
15354                pkgSetting.setEnabled(newState, userId, callingPackage);
15355                // pkgSetting.pkg.mSetEnabled = newState;
15356            } else {
15357                // We're dealing with a component level state change
15358                // First, verify that this is a valid class name.
15359                PackageParser.Package pkg = pkgSetting.pkg;
15360                if (pkg == null || !pkg.hasComponentClassName(className)) {
15361                    if (pkg != null &&
15362                            pkg.applicationInfo.targetSdkVersion >=
15363                                    Build.VERSION_CODES.JELLY_BEAN) {
15364                        throw new IllegalArgumentException("Component class " + className
15365                                + " does not exist in " + packageName);
15366                    } else {
15367                        Slog.w(TAG, "Failed setComponentEnabledSetting: component class "
15368                                + className + " does not exist in " + packageName);
15369                    }
15370                }
15371                switch (newState) {
15372                case COMPONENT_ENABLED_STATE_ENABLED:
15373                    if (!pkgSetting.enableComponentLPw(className, userId)) {
15374                        return;
15375                    }
15376                    break;
15377                case COMPONENT_ENABLED_STATE_DISABLED:
15378                    if (!pkgSetting.disableComponentLPw(className, userId)) {
15379                        return;
15380                    }
15381                    break;
15382                case COMPONENT_ENABLED_STATE_DEFAULT:
15383                    if (!pkgSetting.restoreComponentLPw(className, userId)) {
15384                        return;
15385                    }
15386                    break;
15387                default:
15388                    Slog.e(TAG, "Invalid new component state: " + newState);
15389                    return;
15390                }
15391            }
15392            scheduleWritePackageRestrictionsLocked(userId);
15393            components = mPendingBroadcasts.get(userId, packageName);
15394            final boolean newPackage = components == null;
15395            if (newPackage) {
15396                components = new ArrayList<String>();
15397            }
15398            if (!components.contains(componentName)) {
15399                components.add(componentName);
15400            }
15401            if ((flags&PackageManager.DONT_KILL_APP) == 0) {
15402                sendNow = true;
15403                // Purge entry from pending broadcast list if another one exists already
15404                // since we are sending one right away.
15405                mPendingBroadcasts.remove(userId, packageName);
15406            } else {
15407                if (newPackage) {
15408                    mPendingBroadcasts.put(userId, packageName, components);
15409                }
15410                if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) {
15411                    // Schedule a message
15412                    mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, BROADCAST_DELAY);
15413                }
15414            }
15415        }
15416
15417        long callingId = Binder.clearCallingIdentity();
15418        try {
15419            if (sendNow) {
15420                packageUid = UserHandle.getUid(userId, pkgSetting.appId);
15421                sendPackageChangedBroadcast(packageName,
15422                        (flags&PackageManager.DONT_KILL_APP) != 0, components, packageUid);
15423            }
15424        } finally {
15425            Binder.restoreCallingIdentity(callingId);
15426        }
15427    }
15428
15429    private void sendPackageChangedBroadcast(String packageName,
15430            boolean killFlag, ArrayList<String> componentNames, int packageUid) {
15431        if (DEBUG_INSTALL)
15432            Log.v(TAG, "Sending package changed: package=" + packageName + " components="
15433                    + componentNames);
15434        Bundle extras = new Bundle(4);
15435        extras.putString(Intent.EXTRA_CHANGED_COMPONENT_NAME, componentNames.get(0));
15436        String nameList[] = new String[componentNames.size()];
15437        componentNames.toArray(nameList);
15438        extras.putStringArray(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST, nameList);
15439        extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, killFlag);
15440        extras.putInt(Intent.EXTRA_UID, packageUid);
15441        // If this is not reporting a change of the overall package, then only send it
15442        // to registered receivers.  We don't want to launch a swath of apps for every
15443        // little component state change.
15444        final int flags = !componentNames.contains(packageName)
15445                ? Intent.FLAG_RECEIVER_REGISTERED_ONLY : 0;
15446        sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED,  packageName, extras, flags, null, null,
15447                new int[] {UserHandle.getUserId(packageUid)});
15448    }
15449
15450    @Override
15451    public void setPackageStoppedState(String packageName, boolean stopped, int userId) {
15452        if (!sUserManager.exists(userId)) return;
15453        final int uid = Binder.getCallingUid();
15454        final int permission = mContext.checkCallingOrSelfPermission(
15455                android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
15456        final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
15457        enforceCrossUserPermission(uid, userId, true, true, "stop package");
15458        // writer
15459        synchronized (mPackages) {
15460            if (mSettings.setPackageStoppedStateLPw(this, packageName, stopped,
15461                    allowedByPermission, uid, userId)) {
15462                scheduleWritePackageRestrictionsLocked(userId);
15463            }
15464        }
15465    }
15466
15467    @Override
15468    public String getInstallerPackageName(String packageName) {
15469        // reader
15470        synchronized (mPackages) {
15471            return mSettings.getInstallerPackageNameLPr(packageName);
15472        }
15473    }
15474
15475    @Override
15476    public int getApplicationEnabledSetting(String packageName, int userId) {
15477        if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
15478        int uid = Binder.getCallingUid();
15479        enforceCrossUserPermission(uid, userId, false, false, "get enabled");
15480        // reader
15481        synchronized (mPackages) {
15482            return mSettings.getApplicationEnabledSettingLPr(packageName, userId);
15483        }
15484    }
15485
15486    @Override
15487    public int getComponentEnabledSetting(ComponentName componentName, int userId) {
15488        if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
15489        int uid = Binder.getCallingUid();
15490        enforceCrossUserPermission(uid, userId, false, false, "get component enabled");
15491        // reader
15492        synchronized (mPackages) {
15493            return mSettings.getComponentEnabledSettingLPr(componentName, userId);
15494        }
15495    }
15496
15497    @Override
15498    public void enterSafeMode() {
15499        enforceSystemOrRoot("Only the system can request entering safe mode");
15500
15501        if (!mSystemReady) {
15502            mSafeMode = true;
15503        }
15504    }
15505
15506    @Override
15507    public void systemReady() {
15508        mSystemReady = true;
15509
15510        // Read the compatibilty setting when the system is ready.
15511        boolean compatibilityModeEnabled = android.provider.Settings.Global.getInt(
15512                mContext.getContentResolver(),
15513                android.provider.Settings.Global.COMPATIBILITY_MODE, 1) == 1;
15514        PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled);
15515        if (DEBUG_SETTINGS) {
15516            Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled);
15517        }
15518
15519        int[] grantPermissionsUserIds = EMPTY_INT_ARRAY;
15520
15521        synchronized (mPackages) {
15522            // Verify that all of the preferred activity components actually
15523            // exist.  It is possible for applications to be updated and at
15524            // that point remove a previously declared activity component that
15525            // had been set as a preferred activity.  We try to clean this up
15526            // the next time we encounter that preferred activity, but it is
15527            // possible for the user flow to never be able to return to that
15528            // situation so here we do a sanity check to make sure we haven't
15529            // left any junk around.
15530            ArrayList<PreferredActivity> removed = new ArrayList<PreferredActivity>();
15531            for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
15532                PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
15533                removed.clear();
15534                for (PreferredActivity pa : pir.filterSet()) {
15535                    if (mActivities.mActivities.get(pa.mPref.mComponent) == null) {
15536                        removed.add(pa);
15537                    }
15538                }
15539                if (removed.size() > 0) {
15540                    for (int r=0; r<removed.size(); r++) {
15541                        PreferredActivity pa = removed.get(r);
15542                        Slog.w(TAG, "Removing dangling preferred activity: "
15543                                + pa.mPref.mComponent);
15544                        pir.removeFilter(pa);
15545                    }
15546                    mSettings.writePackageRestrictionsLPr(
15547                            mSettings.mPreferredActivities.keyAt(i));
15548                }
15549            }
15550
15551            for (int userId : UserManagerService.getInstance().getUserIds()) {
15552                if (!mSettings.areDefaultRuntimePermissionsGrantedLPr(userId)) {
15553                    grantPermissionsUserIds = ArrayUtils.appendInt(
15554                            grantPermissionsUserIds, userId);
15555                }
15556            }
15557        }
15558        sUserManager.systemReady();
15559
15560        // If we upgraded grant all default permissions before kicking off.
15561        for (int userId : grantPermissionsUserIds) {
15562            mDefaultPermissionPolicy.grantDefaultPermissions(userId);
15563        }
15564
15565        // Kick off any messages waiting for system ready
15566        if (mPostSystemReadyMessages != null) {
15567            for (Message msg : mPostSystemReadyMessages) {
15568                msg.sendToTarget();
15569            }
15570            mPostSystemReadyMessages = null;
15571        }
15572
15573        // Watch for external volumes that come and go over time
15574        final StorageManager storage = mContext.getSystemService(StorageManager.class);
15575        storage.registerListener(mStorageListener);
15576
15577        mInstallerService.systemReady();
15578        mPackageDexOptimizer.systemReady();
15579
15580        MountServiceInternal mountServiceInternal = LocalServices.getService(
15581                MountServiceInternal.class);
15582        mountServiceInternal.addExternalStoragePolicy(
15583                new MountServiceInternal.ExternalStorageMountPolicy() {
15584            @Override
15585            public int getMountMode(int uid, String packageName) {
15586                if (Process.isIsolated(uid)) {
15587                    return Zygote.MOUNT_EXTERNAL_NONE;
15588                }
15589                if (checkUidPermission(WRITE_MEDIA_STORAGE, uid) == PERMISSION_GRANTED) {
15590                    return Zygote.MOUNT_EXTERNAL_DEFAULT;
15591                }
15592                if (checkUidPermission(READ_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) {
15593                    return Zygote.MOUNT_EXTERNAL_DEFAULT;
15594                }
15595                if (checkUidPermission(WRITE_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) {
15596                    return Zygote.MOUNT_EXTERNAL_READ;
15597                }
15598                return Zygote.MOUNT_EXTERNAL_WRITE;
15599            }
15600
15601            @Override
15602            public boolean hasExternalStorage(int uid, String packageName) {
15603                return true;
15604            }
15605        });
15606    }
15607
15608    @Override
15609    public boolean isSafeMode() {
15610        return mSafeMode;
15611    }
15612
15613    @Override
15614    public boolean hasSystemUidErrors() {
15615        return mHasSystemUidErrors;
15616    }
15617
15618    static String arrayToString(int[] array) {
15619        StringBuffer buf = new StringBuffer(128);
15620        buf.append('[');
15621        if (array != null) {
15622            for (int i=0; i<array.length; i++) {
15623                if (i > 0) buf.append(", ");
15624                buf.append(array[i]);
15625            }
15626        }
15627        buf.append(']');
15628        return buf.toString();
15629    }
15630
15631    static class DumpState {
15632        public static final int DUMP_LIBS = 1 << 0;
15633        public static final int DUMP_FEATURES = 1 << 1;
15634        public static final int DUMP_ACTIVITY_RESOLVERS = 1 << 2;
15635        public static final int DUMP_SERVICE_RESOLVERS = 1 << 3;
15636        public static final int DUMP_RECEIVER_RESOLVERS = 1 << 4;
15637        public static final int DUMP_CONTENT_RESOLVERS = 1 << 5;
15638        public static final int DUMP_PERMISSIONS = 1 << 6;
15639        public static final int DUMP_PACKAGES = 1 << 7;
15640        public static final int DUMP_SHARED_USERS = 1 << 8;
15641        public static final int DUMP_MESSAGES = 1 << 9;
15642        public static final int DUMP_PROVIDERS = 1 << 10;
15643        public static final int DUMP_VERIFIERS = 1 << 11;
15644        public static final int DUMP_PREFERRED = 1 << 12;
15645        public static final int DUMP_PREFERRED_XML = 1 << 13;
15646        public static final int DUMP_KEYSETS = 1 << 14;
15647        public static final int DUMP_VERSION = 1 << 15;
15648        public static final int DUMP_INSTALLS = 1 << 16;
15649        public static final int DUMP_INTENT_FILTER_VERIFIERS = 1 << 17;
15650        public static final int DUMP_DOMAIN_PREFERRED = 1 << 18;
15651
15652        public static final int OPTION_SHOW_FILTERS = 1 << 0;
15653
15654        private int mTypes;
15655
15656        private int mOptions;
15657
15658        private boolean mTitlePrinted;
15659
15660        private SharedUserSetting mSharedUser;
15661
15662        public boolean isDumping(int type) {
15663            if (mTypes == 0 && type != DUMP_PREFERRED_XML) {
15664                return true;
15665            }
15666
15667            return (mTypes & type) != 0;
15668        }
15669
15670        public void setDump(int type) {
15671            mTypes |= type;
15672        }
15673
15674        public boolean isOptionEnabled(int option) {
15675            return (mOptions & option) != 0;
15676        }
15677
15678        public void setOptionEnabled(int option) {
15679            mOptions |= option;
15680        }
15681
15682        public boolean onTitlePrinted() {
15683            final boolean printed = mTitlePrinted;
15684            mTitlePrinted = true;
15685            return printed;
15686        }
15687
15688        public boolean getTitlePrinted() {
15689            return mTitlePrinted;
15690        }
15691
15692        public void setTitlePrinted(boolean enabled) {
15693            mTitlePrinted = enabled;
15694        }
15695
15696        public SharedUserSetting getSharedUser() {
15697            return mSharedUser;
15698        }
15699
15700        public void setSharedUser(SharedUserSetting user) {
15701            mSharedUser = user;
15702        }
15703    }
15704
15705    @Override
15706    public void onShellCommand(FileDescriptor in, FileDescriptor out,
15707            FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
15708        (new PackageManagerShellCommand(this)).exec(
15709                this, in, out, err, args, resultReceiver);
15710    }
15711
15712    @Override
15713    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
15714        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
15715                != PackageManager.PERMISSION_GRANTED) {
15716            pw.println("Permission Denial: can't dump ActivityManager from from pid="
15717                    + Binder.getCallingPid()
15718                    + ", uid=" + Binder.getCallingUid()
15719                    + " without permission "
15720                    + android.Manifest.permission.DUMP);
15721            return;
15722        }
15723
15724        DumpState dumpState = new DumpState();
15725        boolean fullPreferred = false;
15726        boolean checkin = false;
15727
15728        String packageName = null;
15729        ArraySet<String> permissionNames = null;
15730
15731        int opti = 0;
15732        while (opti < args.length) {
15733            String opt = args[opti];
15734            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15735                break;
15736            }
15737            opti++;
15738
15739            if ("-a".equals(opt)) {
15740                // Right now we only know how to print all.
15741            } else if ("-h".equals(opt)) {
15742                pw.println("Package manager dump options:");
15743                pw.println("  [-h] [-f] [--checkin] [cmd] ...");
15744                pw.println("    --checkin: dump for a checkin");
15745                pw.println("    -f: print details of intent filters");
15746                pw.println("    -h: print this help");
15747                pw.println("  cmd may be one of:");
15748                pw.println("    l[ibraries]: list known shared libraries");
15749                pw.println("    f[eatures]: list device features");
15750                pw.println("    k[eysets]: print known keysets");
15751                pw.println("    r[esolvers] [activity|service|receiver|content]: dump intent resolvers");
15752                pw.println("    perm[issions]: dump permissions");
15753                pw.println("    permission [name ...]: dump declaration and use of given permission");
15754                pw.println("    pref[erred]: print preferred package settings");
15755                pw.println("    preferred-xml [--full]: print preferred package settings as xml");
15756                pw.println("    prov[iders]: dump content providers");
15757                pw.println("    p[ackages]: dump installed packages");
15758                pw.println("    s[hared-users]: dump shared user IDs");
15759                pw.println("    m[essages]: print collected runtime messages");
15760                pw.println("    v[erifiers]: print package verifier info");
15761                pw.println("    d[omain-preferred-apps]: print domains preferred apps");
15762                pw.println("    i[ntent-filter-verifiers]|ifv: print intent filter verifier info");
15763                pw.println("    version: print database version info");
15764                pw.println("    write: write current settings now");
15765                pw.println("    installs: details about install sessions");
15766                pw.println("    check-permission <permission> <package> [<user>]: does pkg hold perm?");
15767                pw.println("    <package.name>: info about given package");
15768                return;
15769            } else if ("--checkin".equals(opt)) {
15770                checkin = true;
15771            } else if ("-f".equals(opt)) {
15772                dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
15773            } else {
15774                pw.println("Unknown argument: " + opt + "; use -h for help");
15775            }
15776        }
15777
15778        // Is the caller requesting to dump a particular piece of data?
15779        if (opti < args.length) {
15780            String cmd = args[opti];
15781            opti++;
15782            // Is this a package name?
15783            if ("android".equals(cmd) || cmd.contains(".")) {
15784                packageName = cmd;
15785                // When dumping a single package, we always dump all of its
15786                // filter information since the amount of data will be reasonable.
15787                dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
15788            } else if ("check-permission".equals(cmd)) {
15789                if (opti >= args.length) {
15790                    pw.println("Error: check-permission missing permission argument");
15791                    return;
15792                }
15793                String perm = args[opti];
15794                opti++;
15795                if (opti >= args.length) {
15796                    pw.println("Error: check-permission missing package argument");
15797                    return;
15798                }
15799                String pkg = args[opti];
15800                opti++;
15801                int user = UserHandle.getUserId(Binder.getCallingUid());
15802                if (opti < args.length) {
15803                    try {
15804                        user = Integer.parseInt(args[opti]);
15805                    } catch (NumberFormatException e) {
15806                        pw.println("Error: check-permission user argument is not a number: "
15807                                + args[opti]);
15808                        return;
15809                    }
15810                }
15811                pw.println(checkPermission(perm, pkg, user));
15812                return;
15813            } else if ("l".equals(cmd) || "libraries".equals(cmd)) {
15814                dumpState.setDump(DumpState.DUMP_LIBS);
15815            } else if ("f".equals(cmd) || "features".equals(cmd)) {
15816                dumpState.setDump(DumpState.DUMP_FEATURES);
15817            } else if ("r".equals(cmd) || "resolvers".equals(cmd)) {
15818                if (opti >= args.length) {
15819                    dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS
15820                            | DumpState.DUMP_SERVICE_RESOLVERS
15821                            | DumpState.DUMP_RECEIVER_RESOLVERS
15822                            | DumpState.DUMP_CONTENT_RESOLVERS);
15823                } else {
15824                    while (opti < args.length) {
15825                        String name = args[opti];
15826                        if ("a".equals(name) || "activity".equals(name)) {
15827                            dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS);
15828                        } else if ("s".equals(name) || "service".equals(name)) {
15829                            dumpState.setDump(DumpState.DUMP_SERVICE_RESOLVERS);
15830                        } else if ("r".equals(name) || "receiver".equals(name)) {
15831                            dumpState.setDump(DumpState.DUMP_RECEIVER_RESOLVERS);
15832                        } else if ("c".equals(name) || "content".equals(name)) {
15833                            dumpState.setDump(DumpState.DUMP_CONTENT_RESOLVERS);
15834                        } else {
15835                            pw.println("Error: unknown resolver table type: " + name);
15836                            return;
15837                        }
15838                        opti++;
15839                    }
15840                }
15841            } else if ("perm".equals(cmd) || "permissions".equals(cmd)) {
15842                dumpState.setDump(DumpState.DUMP_PERMISSIONS);
15843            } else if ("permission".equals(cmd)) {
15844                if (opti >= args.length) {
15845                    pw.println("Error: permission requires permission name");
15846                    return;
15847                }
15848                permissionNames = new ArraySet<>();
15849                while (opti < args.length) {
15850                    permissionNames.add(args[opti]);
15851                    opti++;
15852                }
15853                dumpState.setDump(DumpState.DUMP_PERMISSIONS
15854                        | DumpState.DUMP_PACKAGES | DumpState.DUMP_SHARED_USERS);
15855            } else if ("pref".equals(cmd) || "preferred".equals(cmd)) {
15856                dumpState.setDump(DumpState.DUMP_PREFERRED);
15857            } else if ("preferred-xml".equals(cmd)) {
15858                dumpState.setDump(DumpState.DUMP_PREFERRED_XML);
15859                if (opti < args.length && "--full".equals(args[opti])) {
15860                    fullPreferred = true;
15861                    opti++;
15862                }
15863            } else if ("d".equals(cmd) || "domain-preferred-apps".equals(cmd)) {
15864                dumpState.setDump(DumpState.DUMP_DOMAIN_PREFERRED);
15865            } else if ("p".equals(cmd) || "packages".equals(cmd)) {
15866                dumpState.setDump(DumpState.DUMP_PACKAGES);
15867            } else if ("s".equals(cmd) || "shared-users".equals(cmd)) {
15868                dumpState.setDump(DumpState.DUMP_SHARED_USERS);
15869            } else if ("prov".equals(cmd) || "providers".equals(cmd)) {
15870                dumpState.setDump(DumpState.DUMP_PROVIDERS);
15871            } else if ("m".equals(cmd) || "messages".equals(cmd)) {
15872                dumpState.setDump(DumpState.DUMP_MESSAGES);
15873            } else if ("v".equals(cmd) || "verifiers".equals(cmd)) {
15874                dumpState.setDump(DumpState.DUMP_VERIFIERS);
15875            } else if ("i".equals(cmd) || "ifv".equals(cmd)
15876                    || "intent-filter-verifiers".equals(cmd)) {
15877                dumpState.setDump(DumpState.DUMP_INTENT_FILTER_VERIFIERS);
15878            } else if ("version".equals(cmd)) {
15879                dumpState.setDump(DumpState.DUMP_VERSION);
15880            } else if ("k".equals(cmd) || "keysets".equals(cmd)) {
15881                dumpState.setDump(DumpState.DUMP_KEYSETS);
15882            } else if ("installs".equals(cmd)) {
15883                dumpState.setDump(DumpState.DUMP_INSTALLS);
15884            } else if ("write".equals(cmd)) {
15885                synchronized (mPackages) {
15886                    mSettings.writeLPr();
15887                    pw.println("Settings written.");
15888                    return;
15889                }
15890            }
15891        }
15892
15893        if (checkin) {
15894            pw.println("vers,1");
15895        }
15896
15897        // reader
15898        synchronized (mPackages) {
15899            if (dumpState.isDumping(DumpState.DUMP_VERSION) && packageName == null) {
15900                if (!checkin) {
15901                    if (dumpState.onTitlePrinted())
15902                        pw.println();
15903                    pw.println("Database versions:");
15904                    mSettings.dumpVersionLPr(new IndentingPrintWriter(pw, "  "));
15905                }
15906            }
15907
15908            if (dumpState.isDumping(DumpState.DUMP_VERIFIERS) && packageName == null) {
15909                if (!checkin) {
15910                    if (dumpState.onTitlePrinted())
15911                        pw.println();
15912                    pw.println("Verifiers:");
15913                    pw.print("  Required: ");
15914                    pw.print(mRequiredVerifierPackage);
15915                    pw.print(" (uid=");
15916                    pw.print(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
15917                            UserHandle.USER_SYSTEM));
15918                    pw.println(")");
15919                } else if (mRequiredVerifierPackage != null) {
15920                    pw.print("vrfy,"); pw.print(mRequiredVerifierPackage);
15921                    pw.print(",");
15922                    pw.println(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
15923                            UserHandle.USER_SYSTEM));
15924                }
15925            }
15926
15927            if (dumpState.isDumping(DumpState.DUMP_INTENT_FILTER_VERIFIERS) &&
15928                    packageName == null) {
15929                if (mIntentFilterVerifierComponent != null) {
15930                    String verifierPackageName = mIntentFilterVerifierComponent.getPackageName();
15931                    if (!checkin) {
15932                        if (dumpState.onTitlePrinted())
15933                            pw.println();
15934                        pw.println("Intent Filter Verifier:");
15935                        pw.print("  Using: ");
15936                        pw.print(verifierPackageName);
15937                        pw.print(" (uid=");
15938                        pw.print(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING,
15939                                UserHandle.USER_SYSTEM));
15940                        pw.println(")");
15941                    } else if (verifierPackageName != null) {
15942                        pw.print("ifv,"); pw.print(verifierPackageName);
15943                        pw.print(",");
15944                        pw.println(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING,
15945                                UserHandle.USER_SYSTEM));
15946                    }
15947                } else {
15948                    pw.println();
15949                    pw.println("No Intent Filter Verifier available!");
15950                }
15951            }
15952
15953            if (dumpState.isDumping(DumpState.DUMP_LIBS) && packageName == null) {
15954                boolean printedHeader = false;
15955                final Iterator<String> it = mSharedLibraries.keySet().iterator();
15956                while (it.hasNext()) {
15957                    String name = it.next();
15958                    SharedLibraryEntry ent = mSharedLibraries.get(name);
15959                    if (!checkin) {
15960                        if (!printedHeader) {
15961                            if (dumpState.onTitlePrinted())
15962                                pw.println();
15963                            pw.println("Libraries:");
15964                            printedHeader = true;
15965                        }
15966                        pw.print("  ");
15967                    } else {
15968                        pw.print("lib,");
15969                    }
15970                    pw.print(name);
15971                    if (!checkin) {
15972                        pw.print(" -> ");
15973                    }
15974                    if (ent.path != null) {
15975                        if (!checkin) {
15976                            pw.print("(jar) ");
15977                            pw.print(ent.path);
15978                        } else {
15979                            pw.print(",jar,");
15980                            pw.print(ent.path);
15981                        }
15982                    } else {
15983                        if (!checkin) {
15984                            pw.print("(apk) ");
15985                            pw.print(ent.apk);
15986                        } else {
15987                            pw.print(",apk,");
15988                            pw.print(ent.apk);
15989                        }
15990                    }
15991                    pw.println();
15992                }
15993            }
15994
15995            if (dumpState.isDumping(DumpState.DUMP_FEATURES) && packageName == null) {
15996                if (dumpState.onTitlePrinted())
15997                    pw.println();
15998                if (!checkin) {
15999                    pw.println("Features:");
16000                }
16001                Iterator<String> it = mAvailableFeatures.keySet().iterator();
16002                while (it.hasNext()) {
16003                    String name = it.next();
16004                    if (!checkin) {
16005                        pw.print("  ");
16006                    } else {
16007                        pw.print("feat,");
16008                    }
16009                    pw.println(name);
16010                }
16011            }
16012
16013            if (!checkin && dumpState.isDumping(DumpState.DUMP_ACTIVITY_RESOLVERS)) {
16014                if (mActivities.dump(pw, dumpState.getTitlePrinted() ? "\nActivity Resolver Table:"
16015                        : "Activity Resolver Table:", "  ", packageName,
16016                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
16017                    dumpState.setTitlePrinted(true);
16018                }
16019            }
16020            if (!checkin && dumpState.isDumping(DumpState.DUMP_RECEIVER_RESOLVERS)) {
16021                if (mReceivers.dump(pw, dumpState.getTitlePrinted() ? "\nReceiver Resolver Table:"
16022                        : "Receiver Resolver Table:", "  ", packageName,
16023                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
16024                    dumpState.setTitlePrinted(true);
16025                }
16026            }
16027            if (!checkin && dumpState.isDumping(DumpState.DUMP_SERVICE_RESOLVERS)) {
16028                if (mServices.dump(pw, dumpState.getTitlePrinted() ? "\nService Resolver Table:"
16029                        : "Service Resolver Table:", "  ", packageName,
16030                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
16031                    dumpState.setTitlePrinted(true);
16032                }
16033            }
16034            if (!checkin && dumpState.isDumping(DumpState.DUMP_CONTENT_RESOLVERS)) {
16035                if (mProviders.dump(pw, dumpState.getTitlePrinted() ? "\nProvider Resolver Table:"
16036                        : "Provider Resolver Table:", "  ", packageName,
16037                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
16038                    dumpState.setTitlePrinted(true);
16039                }
16040            }
16041
16042            if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED)) {
16043                for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
16044                    PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
16045                    int user = mSettings.mPreferredActivities.keyAt(i);
16046                    if (pir.dump(pw,
16047                            dumpState.getTitlePrinted()
16048                                ? "\nPreferred Activities User " + user + ":"
16049                                : "Preferred Activities User " + user + ":", "  ",
16050                            packageName, true, false)) {
16051                        dumpState.setTitlePrinted(true);
16052                    }
16053                }
16054            }
16055
16056            if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED_XML)) {
16057                pw.flush();
16058                FileOutputStream fout = new FileOutputStream(fd);
16059                BufferedOutputStream str = new BufferedOutputStream(fout);
16060                XmlSerializer serializer = new FastXmlSerializer();
16061                try {
16062                    serializer.setOutput(str, StandardCharsets.UTF_8.name());
16063                    serializer.startDocument(null, true);
16064                    serializer.setFeature(
16065                            "http://xmlpull.org/v1/doc/features.html#indent-output", true);
16066                    mSettings.writePreferredActivitiesLPr(serializer, 0, fullPreferred);
16067                    serializer.endDocument();
16068                    serializer.flush();
16069                } catch (IllegalArgumentException e) {
16070                    pw.println("Failed writing: " + e);
16071                } catch (IllegalStateException e) {
16072                    pw.println("Failed writing: " + e);
16073                } catch (IOException e) {
16074                    pw.println("Failed writing: " + e);
16075                }
16076            }
16077
16078            if (!checkin
16079                    && dumpState.isDumping(DumpState.DUMP_DOMAIN_PREFERRED)
16080                    && packageName == null) {
16081                pw.println();
16082                int count = mSettings.mPackages.size();
16083                if (count == 0) {
16084                    pw.println("No applications!");
16085                    pw.println();
16086                } else {
16087                    final String prefix = "  ";
16088                    Collection<PackageSetting> allPackageSettings = mSettings.mPackages.values();
16089                    if (allPackageSettings.size() == 0) {
16090                        pw.println("No domain preferred apps!");
16091                        pw.println();
16092                    } else {
16093                        pw.println("App verification status:");
16094                        pw.println();
16095                        count = 0;
16096                        for (PackageSetting ps : allPackageSettings) {
16097                            IntentFilterVerificationInfo ivi = ps.getIntentFilterVerificationInfo();
16098                            if (ivi == null || ivi.getPackageName() == null) continue;
16099                            pw.println(prefix + "Package: " + ivi.getPackageName());
16100                            pw.println(prefix + "Domains: " + ivi.getDomainsString());
16101                            pw.println(prefix + "Status:  " + ivi.getStatusString());
16102                            pw.println();
16103                            count++;
16104                        }
16105                        if (count == 0) {
16106                            pw.println(prefix + "No app verification established.");
16107                            pw.println();
16108                        }
16109                        for (int userId : sUserManager.getUserIds()) {
16110                            pw.println("App linkages for user " + userId + ":");
16111                            pw.println();
16112                            count = 0;
16113                            for (PackageSetting ps : allPackageSettings) {
16114                                final long status = ps.getDomainVerificationStatusForUser(userId);
16115                                if (status >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) {
16116                                    continue;
16117                                }
16118                                pw.println(prefix + "Package: " + ps.name);
16119                                pw.println(prefix + "Domains: " + dumpDomainString(ps.name));
16120                                String statusStr = IntentFilterVerificationInfo.
16121                                        getStatusStringFromValue(status);
16122                                pw.println(prefix + "Status:  " + statusStr);
16123                                pw.println();
16124                                count++;
16125                            }
16126                            if (count == 0) {
16127                                pw.println(prefix + "No configured app linkages.");
16128                                pw.println();
16129                            }
16130                        }
16131                    }
16132                }
16133            }
16134
16135            if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) {
16136                mSettings.dumpPermissionsLPr(pw, packageName, permissionNames, dumpState);
16137                if (packageName == null && permissionNames == null) {
16138                    for (int iperm=0; iperm<mAppOpPermissionPackages.size(); iperm++) {
16139                        if (iperm == 0) {
16140                            if (dumpState.onTitlePrinted())
16141                                pw.println();
16142                            pw.println("AppOp Permissions:");
16143                        }
16144                        pw.print("  AppOp Permission ");
16145                        pw.print(mAppOpPermissionPackages.keyAt(iperm));
16146                        pw.println(":");
16147                        ArraySet<String> pkgs = mAppOpPermissionPackages.valueAt(iperm);
16148                        for (int ipkg=0; ipkg<pkgs.size(); ipkg++) {
16149                            pw.print("    "); pw.println(pkgs.valueAt(ipkg));
16150                        }
16151                    }
16152                }
16153            }
16154
16155            if (!checkin && dumpState.isDumping(DumpState.DUMP_PROVIDERS)) {
16156                boolean printedSomething = false;
16157                for (PackageParser.Provider p : mProviders.mProviders.values()) {
16158                    if (packageName != null && !packageName.equals(p.info.packageName)) {
16159                        continue;
16160                    }
16161                    if (!printedSomething) {
16162                        if (dumpState.onTitlePrinted())
16163                            pw.println();
16164                        pw.println("Registered ContentProviders:");
16165                        printedSomething = true;
16166                    }
16167                    pw.print("  "); p.printComponentShortName(pw); pw.println(":");
16168                    pw.print("    "); pw.println(p.toString());
16169                }
16170                printedSomething = false;
16171                for (Map.Entry<String, PackageParser.Provider> entry :
16172                        mProvidersByAuthority.entrySet()) {
16173                    PackageParser.Provider p = entry.getValue();
16174                    if (packageName != null && !packageName.equals(p.info.packageName)) {
16175                        continue;
16176                    }
16177                    if (!printedSomething) {
16178                        if (dumpState.onTitlePrinted())
16179                            pw.println();
16180                        pw.println("ContentProvider Authorities:");
16181                        printedSomething = true;
16182                    }
16183                    pw.print("  ["); pw.print(entry.getKey()); pw.println("]:");
16184                    pw.print("    "); pw.println(p.toString());
16185                    if (p.info != null && p.info.applicationInfo != null) {
16186                        final String appInfo = p.info.applicationInfo.toString();
16187                        pw.print("      applicationInfo="); pw.println(appInfo);
16188                    }
16189                }
16190            }
16191
16192            if (!checkin && dumpState.isDumping(DumpState.DUMP_KEYSETS)) {
16193                mSettings.mKeySetManagerService.dumpLPr(pw, packageName, dumpState);
16194            }
16195
16196            if (dumpState.isDumping(DumpState.DUMP_PACKAGES)) {
16197                mSettings.dumpPackagesLPr(pw, packageName, permissionNames, dumpState, checkin);
16198            }
16199
16200            if (dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) {
16201                mSettings.dumpSharedUsersLPr(pw, packageName, permissionNames, dumpState, checkin);
16202            }
16203
16204            if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS) && packageName == null) {
16205                mSettings.dumpRestoredPermissionGrantsLPr(pw, dumpState);
16206            }
16207
16208            if (!checkin && dumpState.isDumping(DumpState.DUMP_INSTALLS) && packageName == null) {
16209                // XXX should handle packageName != null by dumping only install data that
16210                // the given package is involved with.
16211                if (dumpState.onTitlePrinted()) pw.println();
16212                mInstallerService.dump(new IndentingPrintWriter(pw, "  ", 120));
16213            }
16214
16215            if (!checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES) && packageName == null) {
16216                if (dumpState.onTitlePrinted()) pw.println();
16217                mSettings.dumpReadMessagesLPr(pw, dumpState);
16218
16219                pw.println();
16220                pw.println("Package warning messages:");
16221                BufferedReader in = null;
16222                String line = null;
16223                try {
16224                    in = new BufferedReader(new FileReader(getSettingsProblemFile()));
16225                    while ((line = in.readLine()) != null) {
16226                        if (line.contains("ignored: updated version")) continue;
16227                        pw.println(line);
16228                    }
16229                } catch (IOException ignored) {
16230                } finally {
16231                    IoUtils.closeQuietly(in);
16232                }
16233            }
16234
16235            if (checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES)) {
16236                BufferedReader in = null;
16237                String line = null;
16238                try {
16239                    in = new BufferedReader(new FileReader(getSettingsProblemFile()));
16240                    while ((line = in.readLine()) != null) {
16241                        if (line.contains("ignored: updated version")) continue;
16242                        pw.print("msg,");
16243                        pw.println(line);
16244                    }
16245                } catch (IOException ignored) {
16246                } finally {
16247                    IoUtils.closeQuietly(in);
16248                }
16249            }
16250        }
16251    }
16252
16253    private String dumpDomainString(String packageName) {
16254        List<IntentFilterVerificationInfo> iviList = getIntentFilterVerifications(packageName);
16255        List<IntentFilter> filters = getAllIntentFilters(packageName);
16256
16257        ArraySet<String> result = new ArraySet<>();
16258        if (iviList.size() > 0) {
16259            for (IntentFilterVerificationInfo ivi : iviList) {
16260                for (String host : ivi.getDomains()) {
16261                    result.add(host);
16262                }
16263            }
16264        }
16265        if (filters != null && filters.size() > 0) {
16266            for (IntentFilter filter : filters) {
16267                if (filter.hasCategory(Intent.CATEGORY_BROWSABLE)
16268                        && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) ||
16269                                filter.hasDataScheme(IntentFilter.SCHEME_HTTPS))) {
16270                    result.addAll(filter.getHostsList());
16271                }
16272            }
16273        }
16274
16275        StringBuilder sb = new StringBuilder(result.size() * 16);
16276        for (String domain : result) {
16277            if (sb.length() > 0) sb.append(" ");
16278            sb.append(domain);
16279        }
16280        return sb.toString();
16281    }
16282
16283    // ------- apps on sdcard specific code -------
16284    static final boolean DEBUG_SD_INSTALL = false;
16285
16286    private static final String SD_ENCRYPTION_KEYSTORE_NAME = "AppsOnSD";
16287
16288    private static final String SD_ENCRYPTION_ALGORITHM = "AES";
16289
16290    private boolean mMediaMounted = false;
16291
16292    static String getEncryptKey() {
16293        try {
16294            String sdEncKey = SystemKeyStore.getInstance().retrieveKeyHexString(
16295                    SD_ENCRYPTION_KEYSTORE_NAME);
16296            if (sdEncKey == null) {
16297                sdEncKey = SystemKeyStore.getInstance().generateNewKeyHexString(128,
16298                        SD_ENCRYPTION_ALGORITHM, SD_ENCRYPTION_KEYSTORE_NAME);
16299                if (sdEncKey == null) {
16300                    Slog.e(TAG, "Failed to create encryption keys");
16301                    return null;
16302                }
16303            }
16304            return sdEncKey;
16305        } catch (NoSuchAlgorithmException nsae) {
16306            Slog.e(TAG, "Failed to create encryption keys with exception: " + nsae);
16307            return null;
16308        } catch (IOException ioe) {
16309            Slog.e(TAG, "Failed to retrieve encryption keys with exception: " + ioe);
16310            return null;
16311        }
16312    }
16313
16314    /*
16315     * Update media status on PackageManager.
16316     */
16317    @Override
16318    public void updateExternalMediaStatus(final boolean mediaStatus, final boolean reportStatus) {
16319        int callingUid = Binder.getCallingUid();
16320        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
16321            throw new SecurityException("Media status can only be updated by the system");
16322        }
16323        // reader; this apparently protects mMediaMounted, but should probably
16324        // be a different lock in that case.
16325        synchronized (mPackages) {
16326            Log.i(TAG, "Updating external media status from "
16327                    + (mMediaMounted ? "mounted" : "unmounted") + " to "
16328                    + (mediaStatus ? "mounted" : "unmounted"));
16329            if (DEBUG_SD_INSTALL)
16330                Log.i(TAG, "updateExternalMediaStatus:: mediaStatus=" + mediaStatus
16331                        + ", mMediaMounted=" + mMediaMounted);
16332            if (mediaStatus == mMediaMounted) {
16333                final Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1
16334                        : 0, -1);
16335                mHandler.sendMessage(msg);
16336                return;
16337            }
16338            mMediaMounted = mediaStatus;
16339        }
16340        // Queue up an async operation since the package installation may take a
16341        // little while.
16342        mHandler.post(new Runnable() {
16343            public void run() {
16344                updateExternalMediaStatusInner(mediaStatus, reportStatus, true);
16345            }
16346        });
16347    }
16348
16349    /**
16350     * Called by MountService when the initial ASECs to scan are available.
16351     * Should block until all the ASEC containers are finished being scanned.
16352     */
16353    public void scanAvailableAsecs() {
16354        updateExternalMediaStatusInner(true, false, false);
16355    }
16356
16357    /*
16358     * Collect information of applications on external media, map them against
16359     * existing containers and update information based on current mount status.
16360     * Please note that we always have to report status if reportStatus has been
16361     * set to true especially when unloading packages.
16362     */
16363    private void updateExternalMediaStatusInner(boolean isMounted, boolean reportStatus,
16364            boolean externalStorage) {
16365        ArrayMap<AsecInstallArgs, String> processCids = new ArrayMap<>();
16366        int[] uidArr = EmptyArray.INT;
16367
16368        final String[] list = PackageHelper.getSecureContainerList();
16369        if (ArrayUtils.isEmpty(list)) {
16370            Log.i(TAG, "No secure containers found");
16371        } else {
16372            // Process list of secure containers and categorize them
16373            // as active or stale based on their package internal state.
16374
16375            // reader
16376            synchronized (mPackages) {
16377                for (String cid : list) {
16378                    // Leave stages untouched for now; installer service owns them
16379                    if (PackageInstallerService.isStageName(cid)) continue;
16380
16381                    if (DEBUG_SD_INSTALL)
16382                        Log.i(TAG, "Processing container " + cid);
16383                    String pkgName = getAsecPackageName(cid);
16384                    if (pkgName == null) {
16385                        Slog.i(TAG, "Found stale container " + cid + " with no package name");
16386                        continue;
16387                    }
16388                    if (DEBUG_SD_INSTALL)
16389                        Log.i(TAG, "Looking for pkg : " + pkgName);
16390
16391                    final PackageSetting ps = mSettings.mPackages.get(pkgName);
16392                    if (ps == null) {
16393                        Slog.i(TAG, "Found stale container " + cid + " with no matching settings");
16394                        continue;
16395                    }
16396
16397                    /*
16398                     * Skip packages that are not external if we're unmounting
16399                     * external storage.
16400                     */
16401                    if (externalStorage && !isMounted && !isExternal(ps)) {
16402                        continue;
16403                    }
16404
16405                    final AsecInstallArgs args = new AsecInstallArgs(cid,
16406                            getAppDexInstructionSets(ps), ps.isForwardLocked());
16407                    // The package status is changed only if the code path
16408                    // matches between settings and the container id.
16409                    if (ps.codePathString != null
16410                            && ps.codePathString.startsWith(args.getCodePath())) {
16411                        if (DEBUG_SD_INSTALL) {
16412                            Log.i(TAG, "Container : " + cid + " corresponds to pkg : " + pkgName
16413                                    + " at code path: " + ps.codePathString);
16414                        }
16415
16416                        // We do have a valid package installed on sdcard
16417                        processCids.put(args, ps.codePathString);
16418                        final int uid = ps.appId;
16419                        if (uid != -1) {
16420                            uidArr = ArrayUtils.appendInt(uidArr, uid);
16421                        }
16422                    } else {
16423                        Slog.i(TAG, "Found stale container " + cid + ": expected codePath="
16424                                + ps.codePathString);
16425                    }
16426                }
16427            }
16428
16429            Arrays.sort(uidArr);
16430        }
16431
16432        // Process packages with valid entries.
16433        if (isMounted) {
16434            if (DEBUG_SD_INSTALL)
16435                Log.i(TAG, "Loading packages");
16436            loadMediaPackages(processCids, uidArr, externalStorage);
16437            startCleaningPackages();
16438            mInstallerService.onSecureContainersAvailable();
16439        } else {
16440            if (DEBUG_SD_INSTALL)
16441                Log.i(TAG, "Unloading packages");
16442            unloadMediaPackages(processCids, uidArr, reportStatus);
16443        }
16444    }
16445
16446    private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
16447            ArrayList<ApplicationInfo> infos, IIntentReceiver finishedReceiver) {
16448        final int size = infos.size();
16449        final String[] packageNames = new String[size];
16450        final int[] packageUids = new int[size];
16451        for (int i = 0; i < size; i++) {
16452            final ApplicationInfo info = infos.get(i);
16453            packageNames[i] = info.packageName;
16454            packageUids[i] = info.uid;
16455        }
16456        sendResourcesChangedBroadcast(mediaStatus, replacing, packageNames, packageUids,
16457                finishedReceiver);
16458    }
16459
16460    private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
16461            ArrayList<String> pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
16462        sendResourcesChangedBroadcast(mediaStatus, replacing,
16463                pkgList.toArray(new String[pkgList.size()]), uidArr, finishedReceiver);
16464    }
16465
16466    private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
16467            String[] pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
16468        int size = pkgList.length;
16469        if (size > 0) {
16470            // Send broadcasts here
16471            Bundle extras = new Bundle();
16472            extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
16473            if (uidArr != null) {
16474                extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidArr);
16475            }
16476            if (replacing) {
16477                extras.putBoolean(Intent.EXTRA_REPLACING, replacing);
16478            }
16479            String action = mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE
16480                    : Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE;
16481            sendPackageBroadcast(action, null, extras, 0, null, finishedReceiver, null);
16482        }
16483    }
16484
16485   /*
16486     * Look at potentially valid container ids from processCids If package
16487     * information doesn't match the one on record or package scanning fails,
16488     * the cid is added to list of removeCids. We currently don't delete stale
16489     * containers.
16490     */
16491    private void loadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int[] uidArr,
16492            boolean externalStorage) {
16493        ArrayList<String> pkgList = new ArrayList<String>();
16494        Set<AsecInstallArgs> keys = processCids.keySet();
16495
16496        for (AsecInstallArgs args : keys) {
16497            String codePath = processCids.get(args);
16498            if (DEBUG_SD_INSTALL)
16499                Log.i(TAG, "Loading container : " + args.cid);
16500            int retCode = PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
16501            try {
16502                // Make sure there are no container errors first.
16503                if (args.doPreInstall(PackageManager.INSTALL_SUCCEEDED) != PackageManager.INSTALL_SUCCEEDED) {
16504                    Slog.e(TAG, "Failed to mount cid : " + args.cid
16505                            + " when installing from sdcard");
16506                    continue;
16507                }
16508                // Check code path here.
16509                if (codePath == null || !codePath.startsWith(args.getCodePath())) {
16510                    Slog.e(TAG, "Container " + args.cid + " cachepath " + args.getCodePath()
16511                            + " does not match one in settings " + codePath);
16512                    continue;
16513                }
16514                // Parse package
16515                int parseFlags = mDefParseFlags;
16516                if (args.isExternalAsec()) {
16517                    parseFlags |= PackageParser.PARSE_EXTERNAL_STORAGE;
16518                }
16519                if (args.isFwdLocked()) {
16520                    parseFlags |= PackageParser.PARSE_FORWARD_LOCK;
16521                }
16522
16523                synchronized (mInstallLock) {
16524                    PackageParser.Package pkg = null;
16525                    try {
16526                        pkg = scanPackageTracedLI(new File(codePath), parseFlags, 0, 0, null);
16527                    } catch (PackageManagerException e) {
16528                        Slog.w(TAG, "Failed to scan " + codePath + ": " + e.getMessage());
16529                    }
16530                    // Scan the package
16531                    if (pkg != null) {
16532                        /*
16533                         * TODO why is the lock being held? doPostInstall is
16534                         * called in other places without the lock. This needs
16535                         * to be straightened out.
16536                         */
16537                        // writer
16538                        synchronized (mPackages) {
16539                            retCode = PackageManager.INSTALL_SUCCEEDED;
16540                            pkgList.add(pkg.packageName);
16541                            // Post process args
16542                            args.doPostInstall(PackageManager.INSTALL_SUCCEEDED,
16543                                    pkg.applicationInfo.uid);
16544                        }
16545                    } else {
16546                        Slog.i(TAG, "Failed to install pkg from  " + codePath + " from sdcard");
16547                    }
16548                }
16549
16550            } finally {
16551                if (retCode != PackageManager.INSTALL_SUCCEEDED) {
16552                    Log.w(TAG, "Container " + args.cid + " is stale, retCode=" + retCode);
16553                }
16554            }
16555        }
16556        // writer
16557        synchronized (mPackages) {
16558            // If the platform SDK has changed since the last time we booted,
16559            // we need to re-grant app permission to catch any new ones that
16560            // appear. This is really a hack, and means that apps can in some
16561            // cases get permissions that the user didn't initially explicitly
16562            // allow... it would be nice to have some better way to handle
16563            // this situation.
16564            final VersionInfo ver = externalStorage ? mSettings.getExternalVersion()
16565                    : mSettings.getInternalVersion();
16566            final String volumeUuid = externalStorage ? StorageManager.UUID_PRIMARY_PHYSICAL
16567                    : StorageManager.UUID_PRIVATE_INTERNAL;
16568
16569            int updateFlags = UPDATE_PERMISSIONS_ALL;
16570            if (ver.sdkVersion != mSdkVersion) {
16571                logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to "
16572                        + mSdkVersion + "; regranting permissions for external");
16573                updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
16574            }
16575            updatePermissionsLPw(null, null, volumeUuid, updateFlags);
16576
16577            // Yay, everything is now upgraded
16578            ver.forceCurrent();
16579
16580            // can downgrade to reader
16581            // Persist settings
16582            mSettings.writeLPr();
16583        }
16584        // Send a broadcast to let everyone know we are done processing
16585        if (pkgList.size() > 0) {
16586            sendResourcesChangedBroadcast(true, false, pkgList, uidArr, null);
16587        }
16588    }
16589
16590   /*
16591     * Utility method to unload a list of specified containers
16592     */
16593    private void unloadAllContainers(Set<AsecInstallArgs> cidArgs) {
16594        // Just unmount all valid containers.
16595        for (AsecInstallArgs arg : cidArgs) {
16596            synchronized (mInstallLock) {
16597                arg.doPostDeleteLI(false);
16598           }
16599       }
16600   }
16601
16602    /*
16603     * Unload packages mounted on external media. This involves deleting package
16604     * data from internal structures, sending broadcasts about diabled packages,
16605     * gc'ing to free up references, unmounting all secure containers
16606     * corresponding to packages on external media, and posting a
16607     * UPDATED_MEDIA_STATUS message if status has been requested. Please note
16608     * that we always have to post this message if status has been requested no
16609     * matter what.
16610     */
16611    private void unloadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int uidArr[],
16612            final boolean reportStatus) {
16613        if (DEBUG_SD_INSTALL)
16614            Log.i(TAG, "unloading media packages");
16615        ArrayList<String> pkgList = new ArrayList<String>();
16616        ArrayList<AsecInstallArgs> failedList = new ArrayList<AsecInstallArgs>();
16617        final Set<AsecInstallArgs> keys = processCids.keySet();
16618        for (AsecInstallArgs args : keys) {
16619            String pkgName = args.getPackageName();
16620            if (DEBUG_SD_INSTALL)
16621                Log.i(TAG, "Trying to unload pkg : " + pkgName);
16622            // Delete package internally
16623            PackageRemovedInfo outInfo = new PackageRemovedInfo();
16624            synchronized (mInstallLock) {
16625                boolean res = deletePackageLI(pkgName, null, false, null, null,
16626                        PackageManager.DELETE_KEEP_DATA, outInfo, false);
16627                if (res) {
16628                    pkgList.add(pkgName);
16629                } else {
16630                    Slog.e(TAG, "Failed to delete pkg from sdcard : " + pkgName);
16631                    failedList.add(args);
16632                }
16633            }
16634        }
16635
16636        // reader
16637        synchronized (mPackages) {
16638            // We didn't update the settings after removing each package;
16639            // write them now for all packages.
16640            mSettings.writeLPr();
16641        }
16642
16643        // We have to absolutely send UPDATED_MEDIA_STATUS only
16644        // after confirming that all the receivers processed the ordered
16645        // broadcast when packages get disabled, force a gc to clean things up.
16646        // and unload all the containers.
16647        if (pkgList.size() > 0) {
16648            sendResourcesChangedBroadcast(false, false, pkgList, uidArr,
16649                    new IIntentReceiver.Stub() {
16650                public void performReceive(Intent intent, int resultCode, String data,
16651                        Bundle extras, boolean ordered, boolean sticky,
16652                        int sendingUser) throws RemoteException {
16653                    Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS,
16654                            reportStatus ? 1 : 0, 1, keys);
16655                    mHandler.sendMessage(msg);
16656                }
16657            });
16658        } else {
16659            Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1 : 0, -1,
16660                    keys);
16661            mHandler.sendMessage(msg);
16662        }
16663    }
16664
16665    private void loadPrivatePackages(final VolumeInfo vol) {
16666        mHandler.post(new Runnable() {
16667            @Override
16668            public void run() {
16669                loadPrivatePackagesInner(vol);
16670            }
16671        });
16672    }
16673
16674    private void loadPrivatePackagesInner(VolumeInfo vol) {
16675        final String volumeUuid = vol.fsUuid;
16676        if (TextUtils.isEmpty(volumeUuid)) {
16677            Slog.e(TAG, "Loading internal storage is probably a mistake; ignoring");
16678            return;
16679        }
16680
16681        final ArrayList<ApplicationInfo> loaded = new ArrayList<>();
16682        final int parseFlags = mDefParseFlags | PackageParser.PARSE_EXTERNAL_STORAGE;
16683
16684        final VersionInfo ver;
16685        final List<PackageSetting> packages;
16686        synchronized (mPackages) {
16687            ver = mSettings.findOrCreateVersion(volumeUuid);
16688            packages = mSettings.getVolumePackagesLPr(volumeUuid);
16689        }
16690
16691        // TODO: introduce a new concept similar to "frozen" to prevent these
16692        // apps from being launched until after data has been fully reconciled
16693        for (PackageSetting ps : packages) {
16694            synchronized (mInstallLock) {
16695                final PackageParser.Package pkg;
16696                try {
16697                    pkg = scanPackageTracedLI(ps.codePath, parseFlags, SCAN_INITIAL, 0, null);
16698                    loaded.add(pkg.applicationInfo);
16699
16700                } catch (PackageManagerException e) {
16701                    Slog.w(TAG, "Failed to scan " + ps.codePath + ": " + e.getMessage());
16702                }
16703
16704                if (!Build.FINGERPRINT.equals(ver.fingerprint)) {
16705                    deleteCodeCacheDirsLI(ps.volumeUuid, ps.name);
16706                }
16707            }
16708        }
16709
16710        // Reconcile app data for all started/unlocked users
16711        final UserManager um = mContext.getSystemService(UserManager.class);
16712        for (UserInfo user : um.getUsers()) {
16713            if (um.isUserUnlocked(user.id)) {
16714                reconcileAppsData(volumeUuid, user.id,
16715                        Installer.FLAG_DE_STORAGE | Installer.FLAG_CE_STORAGE);
16716            } else if (um.isUserRunning(user.id)) {
16717                reconcileAppsData(volumeUuid, user.id, Installer.FLAG_DE_STORAGE);
16718            } else {
16719                continue;
16720            }
16721        }
16722
16723        synchronized (mPackages) {
16724            int updateFlags = UPDATE_PERMISSIONS_ALL;
16725            if (ver.sdkVersion != mSdkVersion) {
16726                logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to "
16727                        + mSdkVersion + "; regranting permissions for " + volumeUuid);
16728                updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
16729            }
16730            updatePermissionsLPw(null, null, volumeUuid, updateFlags);
16731
16732            // Yay, everything is now upgraded
16733            ver.forceCurrent();
16734
16735            mSettings.writeLPr();
16736        }
16737
16738        if (DEBUG_INSTALL) Slog.d(TAG, "Loaded packages " + loaded);
16739        sendResourcesChangedBroadcast(true, false, loaded, null);
16740    }
16741
16742    private void unloadPrivatePackages(final VolumeInfo vol) {
16743        mHandler.post(new Runnable() {
16744            @Override
16745            public void run() {
16746                unloadPrivatePackagesInner(vol);
16747            }
16748        });
16749    }
16750
16751    private void unloadPrivatePackagesInner(VolumeInfo vol) {
16752        final String volumeUuid = vol.fsUuid;
16753        if (TextUtils.isEmpty(volumeUuid)) {
16754            Slog.e(TAG, "Unloading internal storage is probably a mistake; ignoring");
16755            return;
16756        }
16757
16758        final ArrayList<ApplicationInfo> unloaded = new ArrayList<>();
16759        synchronized (mInstallLock) {
16760        synchronized (mPackages) {
16761            final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(volumeUuid);
16762            for (PackageSetting ps : packages) {
16763                if (ps.pkg == null) continue;
16764
16765                final ApplicationInfo info = ps.pkg.applicationInfo;
16766                final PackageRemovedInfo outInfo = new PackageRemovedInfo();
16767                if (deletePackageLI(ps.name, null, false, null, null,
16768                        PackageManager.DELETE_KEEP_DATA, outInfo, false)) {
16769                    unloaded.add(info);
16770                } else {
16771                    Slog.w(TAG, "Failed to unload " + ps.codePath);
16772                }
16773            }
16774
16775            mSettings.writeLPr();
16776        }
16777        }
16778
16779        if (DEBUG_INSTALL) Slog.d(TAG, "Unloaded packages " + unloaded);
16780        sendResourcesChangedBroadcast(false, false, unloaded, null);
16781    }
16782
16783    /**
16784     * Examine all users present on given mounted volume, and destroy data
16785     * belonging to users that are no longer valid, or whose user ID has been
16786     * recycled.
16787     */
16788    private void reconcileUsers(String volumeUuid) {
16789        final File[] files = FileUtils
16790                .listFilesOrEmpty(Environment.getDataUserDirectory(volumeUuid));
16791        for (File file : files) {
16792            if (!file.isDirectory()) continue;
16793
16794            final int userId;
16795            final UserInfo info;
16796            try {
16797                userId = Integer.parseInt(file.getName());
16798                info = sUserManager.getUserInfo(userId);
16799            } catch (NumberFormatException e) {
16800                Slog.w(TAG, "Invalid user directory " + file);
16801                continue;
16802            }
16803
16804            boolean destroyUser = false;
16805            if (info == null) {
16806                logCriticalInfo(Log.WARN, "Destroying user directory " + file
16807                        + " because no matching user was found");
16808                destroyUser = true;
16809            } else {
16810                try {
16811                    UserManagerService.enforceSerialNumber(file, info.serialNumber);
16812                } catch (IOException e) {
16813                    logCriticalInfo(Log.WARN, "Destroying user directory " + file
16814                            + " because we failed to enforce serial number: " + e);
16815                    destroyUser = true;
16816                }
16817            }
16818
16819            if (destroyUser) {
16820                synchronized (mInstallLock) {
16821                    try {
16822                        mInstaller.removeUserDataDirs(volumeUuid, userId);
16823                    } catch (InstallerException e) {
16824                        Slog.w(TAG, "Failed to clean up user dirs", e);
16825                    }
16826                }
16827            }
16828        }
16829
16830        final StorageManager sm = mContext.getSystemService(StorageManager.class);
16831        final UserManager um = mContext.getSystemService(UserManager.class);
16832        for (UserInfo user : um.getUsers()) {
16833            final File userDir = Environment.getDataUserDirectory(volumeUuid, user.id);
16834            if (userDir.exists()) continue;
16835
16836            try {
16837                sm.prepareUserStorage(volumeUuid, user.id, user.serialNumber, user.isEphemeral());
16838                UserManagerService.enforceSerialNumber(userDir, user.serialNumber);
16839            } catch (IOException e) {
16840                Log.wtf(TAG, "Failed to create user directory on " + volumeUuid, e);
16841            }
16842        }
16843    }
16844
16845    private void assertPackageKnown(String volumeUuid, String packageName)
16846            throws PackageManagerException {
16847        synchronized (mPackages) {
16848            final PackageSetting ps = mSettings.mPackages.get(packageName);
16849            if (ps == null) {
16850                throw new PackageManagerException("Package " + packageName + " is unknown");
16851            } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) {
16852                throw new PackageManagerException(
16853                        "Package " + packageName + " found on unknown volume " + volumeUuid
16854                                + "; expected volume " + ps.volumeUuid);
16855            }
16856        }
16857    }
16858
16859    private void assertPackageKnownAndInstalled(String volumeUuid, String packageName, int userId)
16860            throws PackageManagerException {
16861        synchronized (mPackages) {
16862            final PackageSetting ps = mSettings.mPackages.get(packageName);
16863            if (ps == null) {
16864                throw new PackageManagerException("Package " + packageName + " is unknown");
16865            } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) {
16866                throw new PackageManagerException(
16867                        "Package " + packageName + " found on unknown volume " + volumeUuid
16868                                + "; expected volume " + ps.volumeUuid);
16869            } else if (!ps.getInstalled(userId)) {
16870                throw new PackageManagerException(
16871                        "Package " + packageName + " not installed for user " + userId);
16872            }
16873        }
16874    }
16875
16876    /**
16877     * Examine all apps present on given mounted volume, and destroy apps that
16878     * aren't expected, either due to uninstallation or reinstallation on
16879     * another volume.
16880     */
16881    private void reconcileApps(String volumeUuid) {
16882        final File[] files = FileUtils
16883                .listFilesOrEmpty(Environment.getDataAppDirectory(volumeUuid));
16884        for (File file : files) {
16885            final boolean isPackage = (isApkFile(file) || file.isDirectory())
16886                    && !PackageInstallerService.isStageName(file.getName());
16887            if (!isPackage) {
16888                // Ignore entries which are not packages
16889                continue;
16890            }
16891
16892            try {
16893                final PackageLite pkg = PackageParser.parsePackageLite(file,
16894                        PackageParser.PARSE_MUST_BE_APK);
16895                assertPackageKnown(volumeUuid, pkg.packageName);
16896
16897            } catch (PackageParserException | PackageManagerException e) {
16898                logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e);
16899                synchronized (mInstallLock) {
16900                    removeCodePathLI(file);
16901                }
16902            }
16903        }
16904    }
16905
16906    /**
16907     * Reconcile all app data for the given user.
16908     * <p>
16909     * Verifies that directories exist and that ownership and labeling is
16910     * correct for all installed apps on all mounted volumes.
16911     */
16912    void reconcileAppsData(int userId, @StorageFlags int flags) {
16913        final StorageManager storage = mContext.getSystemService(StorageManager.class);
16914        for (VolumeInfo vol : storage.getWritablePrivateVolumes()) {
16915            final String volumeUuid = vol.getFsUuid();
16916            reconcileAppsData(volumeUuid, userId, flags);
16917        }
16918    }
16919
16920    /**
16921     * Reconcile all app data on given mounted volume.
16922     * <p>
16923     * Destroys app data that isn't expected, either due to uninstallation or
16924     * reinstallation on another volume.
16925     * <p>
16926     * Verifies that directories exist and that ownership and labeling is
16927     * correct for all installed apps.
16928     */
16929    private void reconcileAppsData(String volumeUuid, int userId, @StorageFlags int flags) {
16930        Slog.v(TAG, "reconcileAppsData for " + volumeUuid + " u" + userId + " 0x"
16931                + Integer.toHexString(flags));
16932
16933        final File ceDir = Environment.getDataUserCredentialEncryptedDirectory(volumeUuid, userId);
16934        final File deDir = Environment.getDataUserDeviceEncryptedDirectory(volumeUuid, userId);
16935
16936        boolean restoreconNeeded = false;
16937
16938        // First look for stale data that doesn't belong, and check if things
16939        // have changed since we did our last restorecon
16940        if ((flags & Installer.FLAG_CE_STORAGE) != 0) {
16941            if (!isUserKeyUnlocked(userId)) {
16942                throw new RuntimeException(
16943                        "Yikes, someone asked us to reconcile CE storage while " + userId
16944                                + " was still locked; this would have caused massive data loss!");
16945            }
16946
16947            restoreconNeeded |= SELinuxMMAC.isRestoreconNeeded(ceDir);
16948
16949            final File[] files = FileUtils.listFilesOrEmpty(ceDir);
16950            for (File file : files) {
16951                final String packageName = file.getName();
16952                try {
16953                    assertPackageKnownAndInstalled(volumeUuid, packageName, userId);
16954                } catch (PackageManagerException e) {
16955                    logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e);
16956                    synchronized (mInstallLock) {
16957                        destroyAppDataLI(volumeUuid, packageName, userId,
16958                                Installer.FLAG_CE_STORAGE);
16959                    }
16960                }
16961            }
16962        }
16963        if ((flags & Installer.FLAG_DE_STORAGE) != 0) {
16964            restoreconNeeded |= SELinuxMMAC.isRestoreconNeeded(deDir);
16965
16966            final File[] files = FileUtils.listFilesOrEmpty(deDir);
16967            for (File file : files) {
16968                final String packageName = file.getName();
16969                try {
16970                    assertPackageKnownAndInstalled(volumeUuid, packageName, userId);
16971                } catch (PackageManagerException e) {
16972                    logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e);
16973                    synchronized (mInstallLock) {
16974                        destroyAppDataLI(volumeUuid, packageName, userId,
16975                                Installer.FLAG_DE_STORAGE);
16976                    }
16977                }
16978            }
16979        }
16980
16981        // Ensure that data directories are ready to roll for all packages
16982        // installed for this volume and user
16983        final List<PackageSetting> packages;
16984        synchronized (mPackages) {
16985            packages = mSettings.getVolumePackagesLPr(volumeUuid);
16986        }
16987        int preparedCount = 0;
16988        for (PackageSetting ps : packages) {
16989            final String packageName = ps.name;
16990            if (ps.pkg == null) {
16991                Slog.w(TAG, "Odd, missing scanned package " + packageName);
16992                // TODO: might be due to legacy ASEC apps; we should circle back
16993                // and reconcile again once they're scanned
16994                continue;
16995            }
16996
16997            if (ps.getInstalled(userId)) {
16998                prepareAppData(volumeUuid, userId, flags, ps.pkg, restoreconNeeded);
16999                preparedCount++;
17000            }
17001        }
17002
17003        if (restoreconNeeded) {
17004            if ((flags & Installer.FLAG_CE_STORAGE) != 0) {
17005                SELinuxMMAC.setRestoreconDone(ceDir);
17006            }
17007            if ((flags & Installer.FLAG_DE_STORAGE) != 0) {
17008                SELinuxMMAC.setRestoreconDone(deDir);
17009            }
17010        }
17011
17012        Slog.v(TAG, "reconcileAppsData finished " + preparedCount
17013                + " packages; restoreconNeeded was " + restoreconNeeded);
17014    }
17015
17016    /**
17017     * Prepare app data for the given app just after it was installed or
17018     * upgraded. This method carefully only touches users that it's installed
17019     * for, and it forces a restorecon to handle any seinfo changes.
17020     * <p>
17021     * Verifies that directories exist and that ownership and labeling is
17022     * correct for all installed apps. If there is an ownership mismatch, it
17023     * will try recovering system apps by wiping data; third-party app data is
17024     * left intact.
17025     */
17026    private void prepareAppDataAfterInstall(PackageParser.Package pkg) {
17027        final PackageSetting ps;
17028        synchronized (mPackages) {
17029            ps = mSettings.mPackages.get(pkg.packageName);
17030        }
17031
17032        final UserManager um = mContext.getSystemService(UserManager.class);
17033        for (UserInfo user : um.getUsers()) {
17034            final int flags;
17035            if (um.isUserUnlocked(user.id)) {
17036                flags = Installer.FLAG_DE_STORAGE | Installer.FLAG_CE_STORAGE;
17037            } else if (um.isUserRunning(user.id)) {
17038                flags = Installer.FLAG_DE_STORAGE;
17039            } else {
17040                continue;
17041            }
17042
17043            if (ps.getInstalled(user.id)) {
17044                // Whenever an app changes, force a restorecon of its data
17045                // TODO: when user data is locked, mark that we're still dirty
17046                prepareAppData(pkg.volumeUuid, user.id, flags, pkg, true);
17047            }
17048        }
17049    }
17050
17051    /**
17052     * Prepare app data for the given app.
17053     * <p>
17054     * Verifies that directories exist and that ownership and labeling is
17055     * correct for all installed apps. If there is an ownership mismatch, this
17056     * will try recovering system apps by wiping data; third-party app data is
17057     * left intact.
17058     */
17059    private void prepareAppData(String volumeUuid, int userId, @StorageFlags int flags,
17060            PackageParser.Package pkg, boolean restoreconNeeded) {
17061        if (DEBUG_APP_DATA) {
17062            Slog.v(TAG, "prepareAppData for " + pkg.packageName + " u" + userId + " 0x"
17063                    + Integer.toHexString(flags) + (restoreconNeeded ? " restoreconNeeded" : ""));
17064        }
17065
17066        final String packageName = pkg.packageName;
17067        final ApplicationInfo app = pkg.applicationInfo;
17068        final int appId = UserHandle.getAppId(app.uid);
17069
17070        Preconditions.checkNotNull(app.seinfo);
17071
17072        synchronized (mInstallLock) {
17073            try {
17074                mInstaller.createAppData(volumeUuid, packageName, userId, flags,
17075                        appId, app.seinfo, app.targetSdkVersion);
17076            } catch (InstallerException e) {
17077                if (app.isSystemApp()) {
17078                    logCriticalInfo(Log.ERROR, "Failed to create app data for " + packageName
17079                            + ", but trying to recover: " + e);
17080                    destroyAppDataLI(volumeUuid, packageName, userId, flags);
17081                    try {
17082                        mInstaller.createAppData(volumeUuid, packageName, userId, flags,
17083                                appId, app.seinfo, app.targetSdkVersion);
17084                        logCriticalInfo(Log.DEBUG, "Recovery succeeded!");
17085                    } catch (InstallerException e2) {
17086                        logCriticalInfo(Log.DEBUG, "Recovery failed!");
17087                    }
17088                } else {
17089                    Slog.e(TAG, "Failed to create app data for " + packageName + ": " + e);
17090                }
17091            }
17092
17093            if (restoreconNeeded) {
17094                restoreconAppDataLI(volumeUuid, packageName, userId, flags, appId, app.seinfo);
17095            }
17096
17097            if ((flags & Installer.FLAG_CE_STORAGE) != 0) {
17098                // Create a native library symlink only if we have native libraries
17099                // and if the native libraries are 32 bit libraries. We do not provide
17100                // this symlink for 64 bit libraries.
17101                if (app.primaryCpuAbi != null && !VMRuntime.is64BitAbi(app.primaryCpuAbi)) {
17102                    final String nativeLibPath = app.nativeLibraryDir;
17103                    try {
17104                        mInstaller.linkNativeLibraryDirectory(volumeUuid, packageName,
17105                                nativeLibPath, userId);
17106                    } catch (InstallerException e) {
17107                        Slog.e(TAG, "Failed to link native for " + packageName + ": " + e);
17108                    }
17109                }
17110            }
17111        }
17112    }
17113
17114    private void unfreezePackage(String packageName) {
17115        synchronized (mPackages) {
17116            final PackageSetting ps = mSettings.mPackages.get(packageName);
17117            if (ps != null) {
17118                ps.frozen = false;
17119            }
17120        }
17121    }
17122
17123    @Override
17124    public int movePackage(final String packageName, final String volumeUuid) {
17125        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
17126
17127        final int moveId = mNextMoveId.getAndIncrement();
17128        mHandler.post(new Runnable() {
17129            @Override
17130            public void run() {
17131                try {
17132                    movePackageInternal(packageName, volumeUuid, moveId);
17133                } catch (PackageManagerException e) {
17134                    Slog.w(TAG, "Failed to move " + packageName, e);
17135                    mMoveCallbacks.notifyStatusChanged(moveId,
17136                            PackageManager.MOVE_FAILED_INTERNAL_ERROR);
17137                }
17138            }
17139        });
17140        return moveId;
17141    }
17142
17143    private void movePackageInternal(final String packageName, final String volumeUuid,
17144            final int moveId) throws PackageManagerException {
17145        final UserHandle user = new UserHandle(UserHandle.getCallingUserId());
17146        final StorageManager storage = mContext.getSystemService(StorageManager.class);
17147        final PackageManager pm = mContext.getPackageManager();
17148
17149        final boolean currentAsec;
17150        final String currentVolumeUuid;
17151        final File codeFile;
17152        final String installerPackageName;
17153        final String packageAbiOverride;
17154        final int appId;
17155        final String seinfo;
17156        final String label;
17157        final int targetSdkVersion;
17158
17159        // reader
17160        synchronized (mPackages) {
17161            final PackageParser.Package pkg = mPackages.get(packageName);
17162            final PackageSetting ps = mSettings.mPackages.get(packageName);
17163            if (pkg == null || ps == null) {
17164                throw new PackageManagerException(MOVE_FAILED_DOESNT_EXIST, "Missing package");
17165            }
17166
17167            if (pkg.applicationInfo.isSystemApp()) {
17168                throw new PackageManagerException(MOVE_FAILED_SYSTEM_PACKAGE,
17169                        "Cannot move system application");
17170            }
17171
17172            if (pkg.applicationInfo.isExternalAsec()) {
17173                currentAsec = true;
17174                currentVolumeUuid = StorageManager.UUID_PRIMARY_PHYSICAL;
17175            } else if (pkg.applicationInfo.isForwardLocked()) {
17176                currentAsec = true;
17177                currentVolumeUuid = "forward_locked";
17178            } else {
17179                currentAsec = false;
17180                currentVolumeUuid = ps.volumeUuid;
17181
17182                final File probe = new File(pkg.codePath);
17183                final File probeOat = new File(probe, "oat");
17184                if (!probe.isDirectory() || !probeOat.isDirectory()) {
17185                    throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
17186                            "Move only supported for modern cluster style installs");
17187                }
17188            }
17189
17190            if (Objects.equals(currentVolumeUuid, volumeUuid)) {
17191                throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
17192                        "Package already moved to " + volumeUuid);
17193            }
17194
17195            if (ps.frozen) {
17196                throw new PackageManagerException(MOVE_FAILED_OPERATION_PENDING,
17197                        "Failed to move already frozen package");
17198            }
17199            ps.frozen = true;
17200
17201            codeFile = new File(pkg.codePath);
17202            installerPackageName = ps.installerPackageName;
17203            packageAbiOverride = ps.cpuAbiOverrideString;
17204            appId = UserHandle.getAppId(pkg.applicationInfo.uid);
17205            seinfo = pkg.applicationInfo.seinfo;
17206            label = String.valueOf(pm.getApplicationLabel(pkg.applicationInfo));
17207            targetSdkVersion = pkg.applicationInfo.targetSdkVersion;
17208        }
17209
17210        // Now that we're guarded by frozen state, kill app during move
17211        final long token = Binder.clearCallingIdentity();
17212        try {
17213            killApplication(packageName, appId, "move pkg");
17214        } finally {
17215            Binder.restoreCallingIdentity(token);
17216        }
17217
17218        final Bundle extras = new Bundle();
17219        extras.putString(Intent.EXTRA_PACKAGE_NAME, packageName);
17220        extras.putString(Intent.EXTRA_TITLE, label);
17221        mMoveCallbacks.notifyCreated(moveId, extras);
17222
17223        int installFlags;
17224        final boolean moveCompleteApp;
17225        final File measurePath;
17226
17227        if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, volumeUuid)) {
17228            installFlags = INSTALL_INTERNAL;
17229            moveCompleteApp = !currentAsec;
17230            measurePath = Environment.getDataAppDirectory(volumeUuid);
17231        } else if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, volumeUuid)) {
17232            installFlags = INSTALL_EXTERNAL;
17233            moveCompleteApp = false;
17234            measurePath = storage.getPrimaryPhysicalVolume().getPath();
17235        } else {
17236            final VolumeInfo volume = storage.findVolumeByUuid(volumeUuid);
17237            if (volume == null || volume.getType() != VolumeInfo.TYPE_PRIVATE
17238                    || !volume.isMountedWritable()) {
17239                unfreezePackage(packageName);
17240                throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
17241                        "Move location not mounted private volume");
17242            }
17243
17244            Preconditions.checkState(!currentAsec);
17245
17246            installFlags = INSTALL_INTERNAL;
17247            moveCompleteApp = true;
17248            measurePath = Environment.getDataAppDirectory(volumeUuid);
17249        }
17250
17251        final PackageStats stats = new PackageStats(null, -1);
17252        synchronized (mInstaller) {
17253            if (!getPackageSizeInfoLI(packageName, -1, stats)) {
17254                unfreezePackage(packageName);
17255                throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
17256                        "Failed to measure package size");
17257            }
17258        }
17259
17260        if (DEBUG_INSTALL) Slog.d(TAG, "Measured code size " + stats.codeSize + ", data size "
17261                + stats.dataSize);
17262
17263        final long startFreeBytes = measurePath.getFreeSpace();
17264        final long sizeBytes;
17265        if (moveCompleteApp) {
17266            sizeBytes = stats.codeSize + stats.dataSize;
17267        } else {
17268            sizeBytes = stats.codeSize;
17269        }
17270
17271        if (sizeBytes > storage.getStorageBytesUntilLow(measurePath)) {
17272            unfreezePackage(packageName);
17273            throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
17274                    "Not enough free space to move");
17275        }
17276
17277        mMoveCallbacks.notifyStatusChanged(moveId, 10);
17278
17279        final CountDownLatch installedLatch = new CountDownLatch(1);
17280        final IPackageInstallObserver2 installObserver = new IPackageInstallObserver2.Stub() {
17281            @Override
17282            public void onUserActionRequired(Intent intent) throws RemoteException {
17283                throw new IllegalStateException();
17284            }
17285
17286            @Override
17287            public void onPackageInstalled(String basePackageName, int returnCode, String msg,
17288                    Bundle extras) throws RemoteException {
17289                if (DEBUG_INSTALL) Slog.d(TAG, "Install result for move: "
17290                        + PackageManager.installStatusToString(returnCode, msg));
17291
17292                installedLatch.countDown();
17293
17294                // Regardless of success or failure of the move operation,
17295                // always unfreeze the package
17296                unfreezePackage(packageName);
17297
17298                final int status = PackageManager.installStatusToPublicStatus(returnCode);
17299                switch (status) {
17300                    case PackageInstaller.STATUS_SUCCESS:
17301                        mMoveCallbacks.notifyStatusChanged(moveId,
17302                                PackageManager.MOVE_SUCCEEDED);
17303                        break;
17304                    case PackageInstaller.STATUS_FAILURE_STORAGE:
17305                        mMoveCallbacks.notifyStatusChanged(moveId,
17306                                PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE);
17307                        break;
17308                    default:
17309                        mMoveCallbacks.notifyStatusChanged(moveId,
17310                                PackageManager.MOVE_FAILED_INTERNAL_ERROR);
17311                        break;
17312                }
17313            }
17314        };
17315
17316        final MoveInfo move;
17317        if (moveCompleteApp) {
17318            // Kick off a thread to report progress estimates
17319            new Thread() {
17320                @Override
17321                public void run() {
17322                    while (true) {
17323                        try {
17324                            if (installedLatch.await(1, TimeUnit.SECONDS)) {
17325                                break;
17326                            }
17327                        } catch (InterruptedException ignored) {
17328                        }
17329
17330                        final long deltaFreeBytes = startFreeBytes - measurePath.getFreeSpace();
17331                        final int progress = 10 + (int) MathUtils.constrain(
17332                                ((deltaFreeBytes * 80) / sizeBytes), 0, 80);
17333                        mMoveCallbacks.notifyStatusChanged(moveId, progress);
17334                    }
17335                }
17336            }.start();
17337
17338            final String dataAppName = codeFile.getName();
17339            move = new MoveInfo(moveId, currentVolumeUuid, volumeUuid, packageName,
17340                    dataAppName, appId, seinfo, targetSdkVersion);
17341        } else {
17342            move = null;
17343        }
17344
17345        installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
17346
17347        final Message msg = mHandler.obtainMessage(INIT_COPY);
17348        final OriginInfo origin = OriginInfo.fromExistingFile(codeFile);
17349        final InstallParams params = new InstallParams(origin, move, installObserver, installFlags,
17350                installerPackageName, volumeUuid, null, user, packageAbiOverride, null);
17351        params.setTraceMethod("movePackage").setTraceCookie(System.identityHashCode(params));
17352        msg.obj = params;
17353
17354        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "movePackage",
17355                System.identityHashCode(msg.obj));
17356        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
17357                System.identityHashCode(msg.obj));
17358
17359        mHandler.sendMessage(msg);
17360    }
17361
17362    @Override
17363    public int movePrimaryStorage(String volumeUuid) throws RemoteException {
17364        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
17365
17366        final int realMoveId = mNextMoveId.getAndIncrement();
17367        final Bundle extras = new Bundle();
17368        extras.putString(VolumeRecord.EXTRA_FS_UUID, volumeUuid);
17369        mMoveCallbacks.notifyCreated(realMoveId, extras);
17370
17371        final IPackageMoveObserver callback = new IPackageMoveObserver.Stub() {
17372            @Override
17373            public void onCreated(int moveId, Bundle extras) {
17374                // Ignored
17375            }
17376
17377            @Override
17378            public void onStatusChanged(int moveId, int status, long estMillis) {
17379                mMoveCallbacks.notifyStatusChanged(realMoveId, status, estMillis);
17380            }
17381        };
17382
17383        final StorageManager storage = mContext.getSystemService(StorageManager.class);
17384        storage.setPrimaryStorageUuid(volumeUuid, callback);
17385        return realMoveId;
17386    }
17387
17388    @Override
17389    public int getMoveStatus(int moveId) {
17390        mContext.enforceCallingOrSelfPermission(
17391                android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
17392        return mMoveCallbacks.mLastStatus.get(moveId);
17393    }
17394
17395    @Override
17396    public void registerMoveCallback(IPackageMoveObserver callback) {
17397        mContext.enforceCallingOrSelfPermission(
17398                android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
17399        mMoveCallbacks.register(callback);
17400    }
17401
17402    @Override
17403    public void unregisterMoveCallback(IPackageMoveObserver callback) {
17404        mContext.enforceCallingOrSelfPermission(
17405                android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
17406        mMoveCallbacks.unregister(callback);
17407    }
17408
17409    @Override
17410    public boolean setInstallLocation(int loc) {
17411        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS,
17412                null);
17413        if (getInstallLocation() == loc) {
17414            return true;
17415        }
17416        if (loc == PackageHelper.APP_INSTALL_AUTO || loc == PackageHelper.APP_INSTALL_INTERNAL
17417                || loc == PackageHelper.APP_INSTALL_EXTERNAL) {
17418            android.provider.Settings.Global.putInt(mContext.getContentResolver(),
17419                    android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, loc);
17420            return true;
17421        }
17422        return false;
17423   }
17424
17425    @Override
17426    public int getInstallLocation() {
17427        return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
17428                android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION,
17429                PackageHelper.APP_INSTALL_AUTO);
17430    }
17431
17432    /** Called by UserManagerService */
17433    void cleanUpUser(UserManagerService userManager, int userHandle) {
17434        synchronized (mPackages) {
17435            mDirtyUsers.remove(userHandle);
17436            mUserNeedsBadging.delete(userHandle);
17437            mSettings.removeUserLPw(userHandle);
17438            mPendingBroadcasts.remove(userHandle);
17439            mEphemeralApplicationRegistry.onUserRemovedLPw(userHandle);
17440        }
17441        synchronized (mInstallLock) {
17442            final StorageManager storage = mContext.getSystemService(StorageManager.class);
17443            for (VolumeInfo vol : storage.getWritablePrivateVolumes()) {
17444                final String volumeUuid = vol.getFsUuid();
17445                if (DEBUG_INSTALL) Slog.d(TAG, "Removing user data on volume " + volumeUuid);
17446                try {
17447                    mInstaller.removeUserDataDirs(volumeUuid, userHandle);
17448                } catch (InstallerException e) {
17449                    Slog.w(TAG, "Failed to remove user data", e);
17450                }
17451            }
17452            synchronized (mPackages) {
17453                removeUnusedPackagesLILPw(userManager, userHandle);
17454            }
17455        }
17456    }
17457
17458    /**
17459     * We're removing userHandle and would like to remove any downloaded packages
17460     * that are no longer in use by any other user.
17461     * @param userHandle the user being removed
17462     */
17463    private void removeUnusedPackagesLILPw(UserManagerService userManager, final int userHandle) {
17464        final boolean DEBUG_CLEAN_APKS = false;
17465        int [] users = userManager.getUserIds();
17466        Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
17467        while (psit.hasNext()) {
17468            PackageSetting ps = psit.next();
17469            if (ps.pkg == null) {
17470                continue;
17471            }
17472            final String packageName = ps.pkg.packageName;
17473            // Skip over if system app
17474            if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) {
17475                continue;
17476            }
17477            if (DEBUG_CLEAN_APKS) {
17478                Slog.i(TAG, "Checking package " + packageName);
17479            }
17480            boolean keep = shouldKeepUninstalledPackageLPr(packageName);
17481            if (keep) {
17482                if (DEBUG_CLEAN_APKS) {
17483                    Slog.i(TAG, "  Keeping package " + packageName + " - requested by DO");
17484                }
17485            } else {
17486                for (int i = 0; i < users.length; i++) {
17487                    if (users[i] != userHandle && ps.getInstalled(users[i])) {
17488                        keep = true;
17489                        if (DEBUG_CLEAN_APKS) {
17490                            Slog.i(TAG, "  Keeping package " + packageName + " for user "
17491                                    + users[i]);
17492                        }
17493                        break;
17494                    }
17495                }
17496            }
17497            if (!keep) {
17498                if (DEBUG_CLEAN_APKS) {
17499                    Slog.i(TAG, "  Removing package " + packageName);
17500                }
17501                mHandler.post(new Runnable() {
17502                    public void run() {
17503                        deletePackageX(packageName, userHandle, 0);
17504                    } //end run
17505                });
17506            }
17507        }
17508    }
17509
17510    /** Called by UserManagerService */
17511    void createNewUser(int userHandle) {
17512        synchronized (mInstallLock) {
17513            try {
17514                mInstaller.createUserConfig(userHandle);
17515            } catch (InstallerException e) {
17516                Slog.w(TAG, "Failed to create user config", e);
17517            }
17518            mSettings.createNewUserLI(this, mInstaller, userHandle);
17519        }
17520        synchronized (mPackages) {
17521            applyFactoryDefaultBrowserLPw(userHandle);
17522            primeDomainVerificationsLPw(userHandle);
17523        }
17524    }
17525
17526    void newUserCreated(final int userHandle) {
17527        mDefaultPermissionPolicy.grantDefaultPermissions(userHandle);
17528        // If permission review for legacy apps is required, we represent
17529        // dagerous permissions for such apps as always granted runtime
17530        // permissions to keep per user flag state whether review is needed.
17531        // Hence, if a new user is added we have to propagate dangerous
17532        // permission grants for these legacy apps.
17533        if (Build.PERMISSIONS_REVIEW_REQUIRED) {
17534            updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL
17535                    | UPDATE_PERMISSIONS_REPLACE_ALL);
17536        }
17537    }
17538
17539    @Override
17540    public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException {
17541        mContext.enforceCallingOrSelfPermission(
17542                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
17543                "Only package verification agents can read the verifier device identity");
17544
17545        synchronized (mPackages) {
17546            return mSettings.getVerifierDeviceIdentityLPw();
17547        }
17548    }
17549
17550    @Override
17551    public void setPermissionEnforced(String permission, boolean enforced) {
17552        // TODO: Now that we no longer change GID for storage, this should to away.
17553        mContext.enforceCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
17554                "setPermissionEnforced");
17555        if (READ_EXTERNAL_STORAGE.equals(permission)) {
17556            synchronized (mPackages) {
17557                if (mSettings.mReadExternalStorageEnforced == null
17558                        || mSettings.mReadExternalStorageEnforced != enforced) {
17559                    mSettings.mReadExternalStorageEnforced = enforced;
17560                    mSettings.writeLPr();
17561                }
17562            }
17563            // kill any non-foreground processes so we restart them and
17564            // grant/revoke the GID.
17565            final IActivityManager am = ActivityManagerNative.getDefault();
17566            if (am != null) {
17567                final long token = Binder.clearCallingIdentity();
17568                try {
17569                    am.killProcessesBelowForeground("setPermissionEnforcement");
17570                } catch (RemoteException e) {
17571                } finally {
17572                    Binder.restoreCallingIdentity(token);
17573                }
17574            }
17575        } else {
17576            throw new IllegalArgumentException("No selective enforcement for " + permission);
17577        }
17578    }
17579
17580    @Override
17581    @Deprecated
17582    public boolean isPermissionEnforced(String permission) {
17583        return true;
17584    }
17585
17586    @Override
17587    public boolean isStorageLow() {
17588        final long token = Binder.clearCallingIdentity();
17589        try {
17590            final DeviceStorageMonitorInternal
17591                    dsm = LocalServices.getService(DeviceStorageMonitorInternal.class);
17592            if (dsm != null) {
17593                return dsm.isMemoryLow();
17594            } else {
17595                return false;
17596            }
17597        } finally {
17598            Binder.restoreCallingIdentity(token);
17599        }
17600    }
17601
17602    @Override
17603    public IPackageInstaller getPackageInstaller() {
17604        return mInstallerService;
17605    }
17606
17607    private boolean userNeedsBadging(int userId) {
17608        int index = mUserNeedsBadging.indexOfKey(userId);
17609        if (index < 0) {
17610            final UserInfo userInfo;
17611            final long token = Binder.clearCallingIdentity();
17612            try {
17613                userInfo = sUserManager.getUserInfo(userId);
17614            } finally {
17615                Binder.restoreCallingIdentity(token);
17616            }
17617            final boolean b;
17618            if (userInfo != null && userInfo.isManagedProfile()) {
17619                b = true;
17620            } else {
17621                b = false;
17622            }
17623            mUserNeedsBadging.put(userId, b);
17624            return b;
17625        }
17626        return mUserNeedsBadging.valueAt(index);
17627    }
17628
17629    @Override
17630    public KeySet getKeySetByAlias(String packageName, String alias) {
17631        if (packageName == null || alias == null) {
17632            return null;
17633        }
17634        synchronized(mPackages) {
17635            final PackageParser.Package pkg = mPackages.get(packageName);
17636            if (pkg == null) {
17637                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
17638                throw new IllegalArgumentException("Unknown package: " + packageName);
17639            }
17640            KeySetManagerService ksms = mSettings.mKeySetManagerService;
17641            return new KeySet(ksms.getKeySetByAliasAndPackageNameLPr(packageName, alias));
17642        }
17643    }
17644
17645    @Override
17646    public KeySet getSigningKeySet(String packageName) {
17647        if (packageName == null) {
17648            return null;
17649        }
17650        synchronized(mPackages) {
17651            final PackageParser.Package pkg = mPackages.get(packageName);
17652            if (pkg == null) {
17653                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
17654                throw new IllegalArgumentException("Unknown package: " + packageName);
17655            }
17656            if (pkg.applicationInfo.uid != Binder.getCallingUid()
17657                    && Process.SYSTEM_UID != Binder.getCallingUid()) {
17658                throw new SecurityException("May not access signing KeySet of other apps.");
17659            }
17660            KeySetManagerService ksms = mSettings.mKeySetManagerService;
17661            return new KeySet(ksms.getSigningKeySetByPackageNameLPr(packageName));
17662        }
17663    }
17664
17665    @Override
17666    public boolean isPackageSignedByKeySet(String packageName, KeySet ks) {
17667        if (packageName == null || ks == null) {
17668            return false;
17669        }
17670        synchronized(mPackages) {
17671            final PackageParser.Package pkg = mPackages.get(packageName);
17672            if (pkg == null) {
17673                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
17674                throw new IllegalArgumentException("Unknown package: " + packageName);
17675            }
17676            IBinder ksh = ks.getToken();
17677            if (ksh instanceof KeySetHandle) {
17678                KeySetManagerService ksms = mSettings.mKeySetManagerService;
17679                return ksms.packageIsSignedByLPr(packageName, (KeySetHandle) ksh);
17680            }
17681            return false;
17682        }
17683    }
17684
17685    @Override
17686    public boolean isPackageSignedByKeySetExactly(String packageName, KeySet ks) {
17687        if (packageName == null || ks == null) {
17688            return false;
17689        }
17690        synchronized(mPackages) {
17691            final PackageParser.Package pkg = mPackages.get(packageName);
17692            if (pkg == null) {
17693                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
17694                throw new IllegalArgumentException("Unknown package: " + packageName);
17695            }
17696            IBinder ksh = ks.getToken();
17697            if (ksh instanceof KeySetHandle) {
17698                KeySetManagerService ksms = mSettings.mKeySetManagerService;
17699                return ksms.packageIsSignedByExactlyLPr(packageName, (KeySetHandle) ksh);
17700            }
17701            return false;
17702        }
17703    }
17704
17705    private void deletePackageIfUnusedLPr(final String packageName) {
17706        PackageSetting ps = mSettings.mPackages.get(packageName);
17707        if (ps == null) {
17708            return;
17709        }
17710        if (!ps.isAnyInstalled(sUserManager.getUserIds())) {
17711            // TODO Implement atomic delete if package is unused
17712            // It is currently possible that the package will be deleted even if it is installed
17713            // after this method returns.
17714            mHandler.post(new Runnable() {
17715                public void run() {
17716                    deletePackageX(packageName, 0, PackageManager.DELETE_ALL_USERS);
17717                }
17718            });
17719        }
17720    }
17721
17722    /**
17723     * Check and throw if the given before/after packages would be considered a
17724     * downgrade.
17725     */
17726    private static void checkDowngrade(PackageParser.Package before, PackageInfoLite after)
17727            throws PackageManagerException {
17728        if (after.versionCode < before.mVersionCode) {
17729            throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
17730                    "Update version code " + after.versionCode + " is older than current "
17731                    + before.mVersionCode);
17732        } else if (after.versionCode == before.mVersionCode) {
17733            if (after.baseRevisionCode < before.baseRevisionCode) {
17734                throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
17735                        "Update base revision code " + after.baseRevisionCode
17736                        + " is older than current " + before.baseRevisionCode);
17737            }
17738
17739            if (!ArrayUtils.isEmpty(after.splitNames)) {
17740                for (int i = 0; i < after.splitNames.length; i++) {
17741                    final String splitName = after.splitNames[i];
17742                    final int j = ArrayUtils.indexOf(before.splitNames, splitName);
17743                    if (j != -1) {
17744                        if (after.splitRevisionCodes[i] < before.splitRevisionCodes[j]) {
17745                            throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
17746                                    "Update split " + splitName + " revision code "
17747                                    + after.splitRevisionCodes[i] + " is older than current "
17748                                    + before.splitRevisionCodes[j]);
17749                        }
17750                    }
17751                }
17752            }
17753        }
17754    }
17755
17756    private static class MoveCallbacks extends Handler {
17757        private static final int MSG_CREATED = 1;
17758        private static final int MSG_STATUS_CHANGED = 2;
17759
17760        private final RemoteCallbackList<IPackageMoveObserver>
17761                mCallbacks = new RemoteCallbackList<>();
17762
17763        private final SparseIntArray mLastStatus = new SparseIntArray();
17764
17765        public MoveCallbacks(Looper looper) {
17766            super(looper);
17767        }
17768
17769        public void register(IPackageMoveObserver callback) {
17770            mCallbacks.register(callback);
17771        }
17772
17773        public void unregister(IPackageMoveObserver callback) {
17774            mCallbacks.unregister(callback);
17775        }
17776
17777        @Override
17778        public void handleMessage(Message msg) {
17779            final SomeArgs args = (SomeArgs) msg.obj;
17780            final int n = mCallbacks.beginBroadcast();
17781            for (int i = 0; i < n; i++) {
17782                final IPackageMoveObserver callback = mCallbacks.getBroadcastItem(i);
17783                try {
17784                    invokeCallback(callback, msg.what, args);
17785                } catch (RemoteException ignored) {
17786                }
17787            }
17788            mCallbacks.finishBroadcast();
17789            args.recycle();
17790        }
17791
17792        private void invokeCallback(IPackageMoveObserver callback, int what, SomeArgs args)
17793                throws RemoteException {
17794            switch (what) {
17795                case MSG_CREATED: {
17796                    callback.onCreated(args.argi1, (Bundle) args.arg2);
17797                    break;
17798                }
17799                case MSG_STATUS_CHANGED: {
17800                    callback.onStatusChanged(args.argi1, args.argi2, (long) args.arg3);
17801                    break;
17802                }
17803            }
17804        }
17805
17806        private void notifyCreated(int moveId, Bundle extras) {
17807            Slog.v(TAG, "Move " + moveId + " created " + extras.toString());
17808
17809            final SomeArgs args = SomeArgs.obtain();
17810            args.argi1 = moveId;
17811            args.arg2 = extras;
17812            obtainMessage(MSG_CREATED, args).sendToTarget();
17813        }
17814
17815        private void notifyStatusChanged(int moveId, int status) {
17816            notifyStatusChanged(moveId, status, -1);
17817        }
17818
17819        private void notifyStatusChanged(int moveId, int status, long estMillis) {
17820            Slog.v(TAG, "Move " + moveId + " status " + status);
17821
17822            final SomeArgs args = SomeArgs.obtain();
17823            args.argi1 = moveId;
17824            args.argi2 = status;
17825            args.arg3 = estMillis;
17826            obtainMessage(MSG_STATUS_CHANGED, args).sendToTarget();
17827
17828            synchronized (mLastStatus) {
17829                mLastStatus.put(moveId, status);
17830            }
17831        }
17832    }
17833
17834    private final static class OnPermissionChangeListeners extends Handler {
17835        private static final int MSG_ON_PERMISSIONS_CHANGED = 1;
17836
17837        private final RemoteCallbackList<IOnPermissionsChangeListener> mPermissionListeners =
17838                new RemoteCallbackList<>();
17839
17840        public OnPermissionChangeListeners(Looper looper) {
17841            super(looper);
17842        }
17843
17844        @Override
17845        public void handleMessage(Message msg) {
17846            switch (msg.what) {
17847                case MSG_ON_PERMISSIONS_CHANGED: {
17848                    final int uid = msg.arg1;
17849                    handleOnPermissionsChanged(uid);
17850                } break;
17851            }
17852        }
17853
17854        public void addListenerLocked(IOnPermissionsChangeListener listener) {
17855            mPermissionListeners.register(listener);
17856
17857        }
17858
17859        public void removeListenerLocked(IOnPermissionsChangeListener listener) {
17860            mPermissionListeners.unregister(listener);
17861        }
17862
17863        public void onPermissionsChanged(int uid) {
17864            if (mPermissionListeners.getRegisteredCallbackCount() > 0) {
17865                obtainMessage(MSG_ON_PERMISSIONS_CHANGED, uid, 0).sendToTarget();
17866            }
17867        }
17868
17869        private void handleOnPermissionsChanged(int uid) {
17870            final int count = mPermissionListeners.beginBroadcast();
17871            try {
17872                for (int i = 0; i < count; i++) {
17873                    IOnPermissionsChangeListener callback = mPermissionListeners
17874                            .getBroadcastItem(i);
17875                    try {
17876                        callback.onPermissionsChanged(uid);
17877                    } catch (RemoteException e) {
17878                        Log.e(TAG, "Permission listener is dead", e);
17879                    }
17880                }
17881            } finally {
17882                mPermissionListeners.finishBroadcast();
17883            }
17884        }
17885    }
17886
17887    private class PackageManagerInternalImpl extends PackageManagerInternal {
17888        @Override
17889        public void setLocationPackagesProvider(PackagesProvider provider) {
17890            synchronized (mPackages) {
17891                mDefaultPermissionPolicy.setLocationPackagesProviderLPw(provider);
17892            }
17893        }
17894
17895        @Override
17896        public void setImePackagesProvider(PackagesProvider provider) {
17897            synchronized (mPackages) {
17898                mDefaultPermissionPolicy.setImePackagesProviderLPr(provider);
17899            }
17900        }
17901
17902        @Override
17903        public void setVoiceInteractionPackagesProvider(PackagesProvider provider) {
17904            synchronized (mPackages) {
17905                mDefaultPermissionPolicy.setVoiceInteractionPackagesProviderLPw(provider);
17906            }
17907        }
17908
17909        @Override
17910        public void setSmsAppPackagesProvider(PackagesProvider provider) {
17911            synchronized (mPackages) {
17912                mDefaultPermissionPolicy.setSmsAppPackagesProviderLPw(provider);
17913            }
17914        }
17915
17916        @Override
17917        public void setDialerAppPackagesProvider(PackagesProvider provider) {
17918            synchronized (mPackages) {
17919                mDefaultPermissionPolicy.setDialerAppPackagesProviderLPw(provider);
17920            }
17921        }
17922
17923        @Override
17924        public void setSimCallManagerPackagesProvider(PackagesProvider provider) {
17925            synchronized (mPackages) {
17926                mDefaultPermissionPolicy.setSimCallManagerPackagesProviderLPw(provider);
17927            }
17928        }
17929
17930        @Override
17931        public void setSyncAdapterPackagesprovider(SyncAdapterPackagesProvider provider) {
17932            synchronized (mPackages) {
17933                mDefaultPermissionPolicy.setSyncAdapterPackagesProviderLPw(provider);
17934            }
17935        }
17936
17937        @Override
17938        public void grantDefaultPermissionsToDefaultSmsApp(String packageName, int userId) {
17939            synchronized (mPackages) {
17940                mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSmsAppLPr(
17941                        packageName, userId);
17942            }
17943        }
17944
17945        @Override
17946        public void grantDefaultPermissionsToDefaultDialerApp(String packageName, int userId) {
17947            synchronized (mPackages) {
17948                mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultDialerAppLPr(
17949                        packageName, userId);
17950            }
17951        }
17952
17953        @Override
17954        public void grantDefaultPermissionsToDefaultSimCallManager(String packageName, int userId) {
17955            synchronized (mPackages) {
17956                mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSimCallManagerLPr(
17957                        packageName, userId);
17958            }
17959        }
17960
17961        @Override
17962        public void setKeepUninstalledPackages(final List<String> packageList) {
17963            Preconditions.checkNotNull(packageList);
17964            List<String> removedFromList = null;
17965            synchronized (mPackages) {
17966                if (mKeepUninstalledPackages != null) {
17967                    final int packagesCount = mKeepUninstalledPackages.size();
17968                    for (int i = 0; i < packagesCount; i++) {
17969                        String oldPackage = mKeepUninstalledPackages.get(i);
17970                        if (packageList != null && packageList.contains(oldPackage)) {
17971                            continue;
17972                        }
17973                        if (removedFromList == null) {
17974                            removedFromList = new ArrayList<>();
17975                        }
17976                        removedFromList.add(oldPackage);
17977                    }
17978                }
17979                mKeepUninstalledPackages = new ArrayList<>(packageList);
17980                if (removedFromList != null) {
17981                    final int removedCount = removedFromList.size();
17982                    for (int i = 0; i < removedCount; i++) {
17983                        deletePackageIfUnusedLPr(removedFromList.get(i));
17984                    }
17985                }
17986            }
17987        }
17988
17989        @Override
17990        public boolean isPermissionsReviewRequired(String packageName, int userId) {
17991            synchronized (mPackages) {
17992                // If we do not support permission review, done.
17993                if (!Build.PERMISSIONS_REVIEW_REQUIRED) {
17994                    return false;
17995                }
17996
17997                PackageSetting packageSetting = mSettings.mPackages.get(packageName);
17998                if (packageSetting == null) {
17999                    return false;
18000                }
18001
18002                // Permission review applies only to apps not supporting the new permission model.
18003                if (packageSetting.pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.M) {
18004                    return false;
18005                }
18006
18007                // Legacy apps have the permission and get user consent on launch.
18008                PermissionsState permissionsState = packageSetting.getPermissionsState();
18009                return permissionsState.isPermissionReviewRequired(userId);
18010            }
18011        }
18012    }
18013
18014    @Override
18015    public void grantDefaultPermissionsToEnabledCarrierApps(String[] packageNames, int userId) {
18016        enforceSystemOrPhoneCaller("grantPermissionsToEnabledCarrierApps");
18017        synchronized (mPackages) {
18018            final long identity = Binder.clearCallingIdentity();
18019            try {
18020                mDefaultPermissionPolicy.grantDefaultPermissionsToEnabledCarrierAppsLPr(
18021                        packageNames, userId);
18022            } finally {
18023                Binder.restoreCallingIdentity(identity);
18024            }
18025        }
18026    }
18027
18028    private static void enforceSystemOrPhoneCaller(String tag) {
18029        int callingUid = Binder.getCallingUid();
18030        if (callingUid != Process.PHONE_UID && callingUid != Process.SYSTEM_UID) {
18031            throw new SecurityException(
18032                    "Cannot call " + tag + " from UID " + callingUid);
18033        }
18034    }
18035}
18036