PackageManagerService.java revision 0ab0bdde2b39c77175d9e0d69d6631e130e4b5ac
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_DUPLICATE_PACKAGE;
38import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION;
39import static android.content.pm.PackageManager.INSTALL_FAILED_EPHEMERAL_INVALID;
40import static android.content.pm.PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
41import static android.content.pm.PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
42import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_APK;
43import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
44import static android.content.pm.PackageManager.INSTALL_FAILED_MISSING_SHARED_LIBRARY;
45import static android.content.pm.PackageManager.INSTALL_FAILED_PACKAGE_CHANGED;
46import static android.content.pm.PackageManager.INSTALL_FAILED_REPLACE_COULDNT_DELETE;
47import static android.content.pm.PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE;
48import static android.content.pm.PackageManager.INSTALL_FAILED_TEST_ONLY;
49import static android.content.pm.PackageManager.INSTALL_FAILED_UID_CHANGED;
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_DISABLED_COMPONENTS;
63import static android.content.pm.PackageManager.MATCH_ENCRYPTION_AWARE_AND_UNAWARE;
64import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
65import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
66import static android.content.pm.PackageManager.MOVE_FAILED_DOESNT_EXIST;
67import static android.content.pm.PackageManager.MOVE_FAILED_INTERNAL_ERROR;
68import static android.content.pm.PackageManager.MOVE_FAILED_OPERATION_PENDING;
69import static android.content.pm.PackageManager.MOVE_FAILED_SYSTEM_PACKAGE;
70import static android.content.pm.PackageManager.PERMISSION_DENIED;
71import static android.content.pm.PackageManager.PERMISSION_GRANTED;
72import static android.content.pm.PackageParser.isApkFile;
73import static android.os.Process.PACKAGE_INFO_GID;
74import static android.os.Process.SYSTEM_UID;
75import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
76import static android.system.OsConstants.O_CREAT;
77import static android.system.OsConstants.O_RDWR;
78
79import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE;
80import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_PARENT;
81import static com.android.internal.content.NativeLibraryHelper.LIB64_DIR_NAME;
82import static com.android.internal.content.NativeLibraryHelper.LIB_DIR_NAME;
83import static com.android.internal.util.ArrayUtils.appendInt;
84import static com.android.server.pm.Installer.DEXOPT_PUBLIC;
85import static com.android.server.pm.InstructionSets.getAppDexInstructionSets;
86import static com.android.server.pm.InstructionSets.getDexCodeInstructionSet;
87import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets;
88import static com.android.server.pm.InstructionSets.getPreferredInstructionSet;
89import static com.android.server.pm.InstructionSets.getPrimaryInstructionSet;
90import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_FAILURE;
91import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_SUCCESS;
92import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED;
93
94import android.Manifest;
95import android.annotation.NonNull;
96import android.annotation.Nullable;
97import android.app.ActivityManager;
98import android.app.ActivityManagerNative;
99import android.app.AppGlobals;
100import android.app.IActivityManager;
101import android.app.admin.IDevicePolicyManager;
102import android.app.backup.IBackupManager;
103import android.content.BroadcastReceiver;
104import android.content.ComponentName;
105import android.content.Context;
106import android.content.IIntentReceiver;
107import android.content.Intent;
108import android.content.IntentFilter;
109import android.content.IntentSender;
110import android.content.IntentSender.SendIntentException;
111import android.content.ServiceConnection;
112import android.content.pm.ActivityInfo;
113import android.content.pm.ApplicationInfo;
114import android.content.pm.AppsQueryHelper;
115import android.content.pm.ComponentInfo;
116import android.content.pm.EphemeralApplicationInfo;
117import android.content.pm.EphemeralResolveInfo;
118import android.content.pm.EphemeralResolveInfo.EphemeralResolveIntentInfo;
119import android.content.pm.FeatureInfo;
120import android.content.pm.IOnPermissionsChangeListener;
121import android.content.pm.IPackageDataObserver;
122import android.content.pm.IPackageDeleteObserver;
123import android.content.pm.IPackageDeleteObserver2;
124import android.content.pm.IPackageInstallObserver2;
125import android.content.pm.IPackageInstaller;
126import android.content.pm.IPackageManager;
127import android.content.pm.IPackageMoveObserver;
128import android.content.pm.IPackageStatsObserver;
129import android.content.pm.InstrumentationInfo;
130import android.content.pm.IntentFilterVerificationInfo;
131import android.content.pm.KeySet;
132import android.content.pm.PackageCleanItem;
133import android.content.pm.PackageInfo;
134import android.content.pm.PackageInfoLite;
135import android.content.pm.PackageInstaller;
136import android.content.pm.PackageManager;
137import android.content.pm.PackageManager.LegacyPackageDeleteObserver;
138import android.content.pm.PackageManagerInternal;
139import android.content.pm.PackageParser;
140import android.content.pm.PackageParser.ActivityIntentInfo;
141import android.content.pm.PackageParser.PackageLite;
142import android.content.pm.PackageParser.PackageParserException;
143import android.content.pm.PackageStats;
144import android.content.pm.PackageUserState;
145import android.content.pm.ParceledListSlice;
146import android.content.pm.PermissionGroupInfo;
147import android.content.pm.PermissionInfo;
148import android.content.pm.ProviderInfo;
149import android.content.pm.ResolveInfo;
150import android.content.pm.ServiceInfo;
151import android.content.pm.Signature;
152import android.content.pm.UserInfo;
153import android.content.pm.VerificationParams;
154import android.content.pm.VerifierDeviceIdentity;
155import android.content.pm.VerifierInfo;
156import android.content.res.Resources;
157import android.graphics.Bitmap;
158import android.hardware.display.DisplayManager;
159import android.net.Uri;
160import android.os.Binder;
161import android.os.Build;
162import android.os.Bundle;
163import android.os.Debug;
164import android.os.Environment;
165import android.os.Environment.UserEnvironment;
166import android.os.FileUtils;
167import android.os.Handler;
168import android.os.IBinder;
169import android.os.Looper;
170import android.os.Message;
171import android.os.Parcel;
172import android.os.ParcelFileDescriptor;
173import android.os.Process;
174import android.os.RemoteCallbackList;
175import android.os.RemoteException;
176import android.os.ResultReceiver;
177import android.os.SELinux;
178import android.os.ServiceManager;
179import android.os.SystemClock;
180import android.os.SystemProperties;
181import android.os.Trace;
182import android.os.UserHandle;
183import android.os.UserManager;
184import android.os.storage.IMountService;
185import android.os.storage.MountServiceInternal;
186import android.os.storage.StorageEventListener;
187import android.os.storage.StorageManager;
188import android.os.storage.VolumeInfo;
189import android.os.storage.VolumeRecord;
190import android.security.KeyStore;
191import android.security.SystemKeyStore;
192import android.system.ErrnoException;
193import android.system.Os;
194import android.system.StructStat;
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.SomeArgs;
222import com.android.internal.os.Zygote;
223import com.android.internal.util.ArrayUtils;
224import com.android.internal.util.FastPrintWriter;
225import com.android.internal.util.FastXmlSerializer;
226import com.android.internal.util.IndentingPrintWriter;
227import com.android.internal.util.Preconditions;
228import com.android.server.EventLogTags;
229import com.android.server.FgThread;
230import com.android.server.IntentResolver;
231import com.android.server.LocalServices;
232import com.android.server.ServiceThread;
233import com.android.server.SystemConfig;
234import com.android.server.Watchdog;
235import com.android.server.pm.PermissionsState.PermissionState;
236import com.android.server.pm.Settings.DatabaseVersion;
237import com.android.server.pm.Settings.VersionInfo;
238import com.android.server.storage.DeviceStorageMonitorInternal;
239
240import dalvik.system.DexFile;
241import dalvik.system.VMRuntime;
242
243import libcore.io.IoUtils;
244import libcore.util.EmptyArray;
245
246import org.xmlpull.v1.XmlPullParser;
247import org.xmlpull.v1.XmlPullParserException;
248import org.xmlpull.v1.XmlSerializer;
249
250import java.io.BufferedInputStream;
251import java.io.BufferedOutputStream;
252import java.io.BufferedReader;
253import java.io.ByteArrayInputStream;
254import java.io.ByteArrayOutputStream;
255import java.io.File;
256import java.io.FileDescriptor;
257import java.io.FileNotFoundException;
258import java.io.FileOutputStream;
259import java.io.FileReader;
260import java.io.FilenameFilter;
261import java.io.IOException;
262import java.io.InputStream;
263import java.io.PrintWriter;
264import java.nio.charset.StandardCharsets;
265import java.security.MessageDigest;
266import java.security.NoSuchAlgorithmException;
267import java.security.PublicKey;
268import java.security.cert.CertificateEncodingException;
269import java.security.cert.CertificateException;
270import java.text.SimpleDateFormat;
271import java.util.ArrayList;
272import java.util.Arrays;
273import java.util.Collection;
274import java.util.Collections;
275import java.util.Comparator;
276import java.util.Date;
277import java.util.Iterator;
278import java.util.List;
279import java.util.Map;
280import java.util.Objects;
281import java.util.Set;
282import java.util.concurrent.CountDownLatch;
283import java.util.concurrent.TimeUnit;
284import java.util.concurrent.atomic.AtomicBoolean;
285import java.util.concurrent.atomic.AtomicInteger;
286import java.util.concurrent.atomic.AtomicLong;
287
288/**
289 * Keep track of all those .apks everywhere.
290 *
291 * This is very central to the platform's security; please run the unit
292 * tests whenever making modifications here:
293 *
294runtest -c android.content.pm.PackageManagerTests frameworks-core
295 *
296 * {@hide}
297 */
298public class PackageManagerService extends IPackageManager.Stub {
299    static final String TAG = "PackageManager";
300    static final boolean DEBUG_SETTINGS = false;
301    static final boolean DEBUG_PREFERRED = false;
302    static final boolean DEBUG_UPGRADE = false;
303    static final boolean DEBUG_DOMAIN_VERIFICATION = false;
304    private static final boolean DEBUG_BACKUP = false;
305    private static final boolean DEBUG_INSTALL = false;
306    private static final boolean DEBUG_REMOVE = false;
307    private static final boolean DEBUG_BROADCASTS = false;
308    private static final boolean DEBUG_SHOW_INFO = false;
309    private static final boolean DEBUG_PACKAGE_INFO = false;
310    private static final boolean DEBUG_INTENT_MATCHING = false;
311    private static final boolean DEBUG_PACKAGE_SCANNING = false;
312    private static final boolean DEBUG_VERIFY = false;
313    private static final boolean DEBUG_DEXOPT = false;
314    private static final boolean DEBUG_ABI_SELECTION = false;
315    private static final boolean DEBUG_EPHEMERAL = false;
316    private static final boolean DEBUG_TRIAGED_MISSING = false;
317
318    static final boolean CLEAR_RUNTIME_PERMISSIONS_ON_UPGRADE = false;
319
320    private static final int RADIO_UID = Process.PHONE_UID;
321    private static final int LOG_UID = Process.LOG_UID;
322    private static final int NFC_UID = Process.NFC_UID;
323    private static final int BLUETOOTH_UID = Process.BLUETOOTH_UID;
324    private static final int SHELL_UID = Process.SHELL_UID;
325
326    // Cap the size of permission trees that 3rd party apps can define
327    private static final int MAX_PERMISSION_TREE_FOOTPRINT = 32768;     // characters of text
328
329    // Suffix used during package installation when copying/moving
330    // package apks to install directory.
331    private static final String INSTALL_PACKAGE_SUFFIX = "-";
332
333    static final int SCAN_NO_DEX = 1<<1;
334    static final int SCAN_FORCE_DEX = 1<<2;
335    static final int SCAN_UPDATE_SIGNATURE = 1<<3;
336    static final int SCAN_NEW_INSTALL = 1<<4;
337    static final int SCAN_NO_PATHS = 1<<5;
338    static final int SCAN_UPDATE_TIME = 1<<6;
339    static final int SCAN_DEFER_DEX = 1<<7;
340    static final int SCAN_BOOTING = 1<<8;
341    static final int SCAN_TRUSTED_OVERLAY = 1<<9;
342    static final int SCAN_DELETE_DATA_ON_FAILURES = 1<<10;
343    static final int SCAN_REPLACING = 1<<11;
344    static final int SCAN_REQUIRE_KNOWN = 1<<12;
345    static final int SCAN_MOVE = 1<<13;
346    static final int SCAN_INITIAL = 1<<14;
347
348    static final int REMOVE_CHATTY = 1<<16;
349
350    private static final int[] EMPTY_INT_ARRAY = new int[0];
351
352    /**
353     * Timeout (in milliseconds) after which the watchdog should declare that
354     * our handler thread is wedged.  The usual default for such things is one
355     * minute but we sometimes do very lengthy I/O operations on this thread,
356     * such as installing multi-gigabyte applications, so ours needs to be longer.
357     */
358    private static final long WATCHDOG_TIMEOUT = 1000*60*10;     // ten minutes
359
360    /**
361     * Wall-clock timeout (in milliseconds) after which we *require* that an fstrim
362     * be run on this device.  We use the value in the Settings.Global.MANDATORY_FSTRIM_INTERVAL
363     * settings entry if available, otherwise we use the hardcoded default.  If it's been
364     * more than this long since the last fstrim, we force one during the boot sequence.
365     *
366     * This backstops other fstrim scheduling:  if the device is alive at midnight+idle,
367     * one gets run at the next available charging+idle time.  This final mandatory
368     * no-fstrim check kicks in only of the other scheduling criteria is never met.
369     */
370    private static final long DEFAULT_MANDATORY_FSTRIM_INTERVAL = 3 * DateUtils.DAY_IN_MILLIS;
371
372    /**
373     * Whether verification is enabled by default.
374     */
375    private static final boolean DEFAULT_VERIFY_ENABLE = true;
376
377    /**
378     * The default maximum time to wait for the verification agent to return in
379     * milliseconds.
380     */
381    private static final long DEFAULT_VERIFICATION_TIMEOUT = 10 * 1000;
382
383    /**
384     * The default response for package verification timeout.
385     *
386     * This can be either PackageManager.VERIFICATION_ALLOW or
387     * PackageManager.VERIFICATION_REJECT.
388     */
389    private static final int DEFAULT_VERIFICATION_RESPONSE = PackageManager.VERIFICATION_ALLOW;
390
391    static final String DEFAULT_CONTAINER_PACKAGE = "com.android.defcontainer";
392
393    static final ComponentName DEFAULT_CONTAINER_COMPONENT = new ComponentName(
394            DEFAULT_CONTAINER_PACKAGE,
395            "com.android.defcontainer.DefaultContainerService");
396
397    private static final String KILL_APP_REASON_GIDS_CHANGED =
398            "permission grant or revoke changed gids";
399
400    private static final String KILL_APP_REASON_PERMISSIONS_REVOKED =
401            "permissions revoked";
402
403    private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive";
404
405    private static final String VENDOR_OVERLAY_DIR = "/vendor/overlay";
406
407    /** Permission grant: not grant the permission. */
408    private static final int GRANT_DENIED = 1;
409
410    /** Permission grant: grant the permission as an install permission. */
411    private static final int GRANT_INSTALL = 2;
412
413    /** Permission grant: grant the permission as a runtime one. */
414    private static final int GRANT_RUNTIME = 3;
415
416    /** Permission grant: grant as runtime a permission that was granted as an install time one. */
417    private static final int GRANT_UPGRADE = 4;
418
419    /** Canonical intent used to identify what counts as a "web browser" app */
420    private static final Intent sBrowserIntent;
421    static {
422        sBrowserIntent = new Intent();
423        sBrowserIntent.setAction(Intent.ACTION_VIEW);
424        sBrowserIntent.addCategory(Intent.CATEGORY_BROWSABLE);
425        sBrowserIntent.setData(Uri.parse("http:"));
426    }
427
428    final ServiceThread mHandlerThread;
429
430    final PackageHandler mHandler;
431
432    /**
433     * Messages for {@link #mHandler} that need to wait for system ready before
434     * being dispatched.
435     */
436    private ArrayList<Message> mPostSystemReadyMessages;
437
438    final int mSdkVersion = Build.VERSION.SDK_INT;
439
440    final Context mContext;
441    final boolean mFactoryTest;
442    final boolean mOnlyCore;
443    final DisplayMetrics mMetrics;
444    final int mDefParseFlags;
445    final String[] mSeparateProcesses;
446    final boolean mIsUpgrade;
447
448    /** The location for ASEC container files on internal storage. */
449    final String mAsecInternalPath;
450
451    // Used for privilege escalation. MUST NOT BE CALLED WITH mPackages
452    // LOCK HELD.  Can be called with mInstallLock held.
453    @GuardedBy("mInstallLock")
454    final Installer mInstaller;
455
456    /** Directory where installed third-party apps stored */
457    final File mAppInstallDir;
458    final File mEphemeralInstallDir;
459
460    /**
461     * Directory to which applications installed internally have their
462     * 32 bit native libraries copied.
463     */
464    private File mAppLib32InstallDir;
465
466    // Directory containing the private parts (e.g. code and non-resource assets) of forward-locked
467    // apps.
468    final File mDrmAppPrivateInstallDir;
469
470    // ----------------------------------------------------------------
471
472    // Lock for state used when installing and doing other long running
473    // operations.  Methods that must be called with this lock held have
474    // the suffix "LI".
475    final Object mInstallLock = new Object();
476
477    // ----------------------------------------------------------------
478
479    // Keys are String (package name), values are Package.  This also serves
480    // as the lock for the global state.  Methods that must be called with
481    // this lock held have the prefix "LP".
482    @GuardedBy("mPackages")
483    final ArrayMap<String, PackageParser.Package> mPackages =
484            new ArrayMap<String, PackageParser.Package>();
485
486    // Tracks available target package names -> overlay package paths.
487    final ArrayMap<String, ArrayMap<String, PackageParser.Package>> mOverlays =
488        new ArrayMap<String, ArrayMap<String, PackageParser.Package>>();
489
490    /**
491     * Tracks new system packages [received in an OTA] that we expect to
492     * find updated user-installed versions. Keys are package name, values
493     * are package location.
494     */
495    final private ArrayMap<String, File> mExpectingBetter = new ArrayMap<>();
496
497    /**
498     * Tracks existing system packages prior to receiving an OTA. Keys are package name.
499     */
500    final private ArraySet<String> mExistingSystemPackages = new ArraySet<>();
501    /**
502     * Whether or not system app permissions should be promoted from install to runtime.
503     */
504    boolean mPromoteSystemApps;
505
506    final Settings mSettings;
507    boolean mRestoredSettings;
508
509    // System configuration read by SystemConfig.
510    final int[] mGlobalGids;
511    final SparseArray<ArraySet<String>> mSystemPermissions;
512    final ArrayMap<String, FeatureInfo> mAvailableFeatures;
513
514    // If mac_permissions.xml was found for seinfo labeling.
515    boolean mFoundPolicyFile;
516
517    // If a recursive restorecon of /data/data/<pkg> is needed.
518    private boolean mShouldRestoreconData = SELinuxMMAC.shouldRestorecon();
519
520    private final EphemeralApplicationRegistry mEphemeralApplicationRegistry;
521
522    public static final class SharedLibraryEntry {
523        public final String path;
524        public final String apk;
525
526        SharedLibraryEntry(String _path, String _apk) {
527            path = _path;
528            apk = _apk;
529        }
530    }
531
532    // Currently known shared libraries.
533    final ArrayMap<String, SharedLibraryEntry> mSharedLibraries =
534            new ArrayMap<String, SharedLibraryEntry>();
535
536    // All available activities, for your resolving pleasure.
537    final ActivityIntentResolver mActivities =
538            new ActivityIntentResolver();
539
540    // All available receivers, for your resolving pleasure.
541    final ActivityIntentResolver mReceivers =
542            new ActivityIntentResolver();
543
544    // All available services, for your resolving pleasure.
545    final ServiceIntentResolver mServices = new ServiceIntentResolver();
546
547    // All available providers, for your resolving pleasure.
548    final ProviderIntentResolver mProviders = new ProviderIntentResolver();
549
550    // Mapping from provider base names (first directory in content URI codePath)
551    // to the provider information.
552    final ArrayMap<String, PackageParser.Provider> mProvidersByAuthority =
553            new ArrayMap<String, PackageParser.Provider>();
554
555    // Mapping from instrumentation class names to info about them.
556    final ArrayMap<ComponentName, PackageParser.Instrumentation> mInstrumentation =
557            new ArrayMap<ComponentName, PackageParser.Instrumentation>();
558
559    // Mapping from permission names to info about them.
560    final ArrayMap<String, PackageParser.PermissionGroup> mPermissionGroups =
561            new ArrayMap<String, PackageParser.PermissionGroup>();
562
563    // Packages whose data we have transfered into another package, thus
564    // should no longer exist.
565    final ArraySet<String> mTransferedPackages = new ArraySet<String>();
566
567    // Broadcast actions that are only available to the system.
568    final ArraySet<String> mProtectedBroadcasts = new ArraySet<String>();
569
570    /** List of packages waiting for verification. */
571    final SparseArray<PackageVerificationState> mPendingVerification
572            = new SparseArray<PackageVerificationState>();
573
574    /** Set of packages associated with each app op permission. */
575    final ArrayMap<String, ArraySet<String>> mAppOpPermissionPackages = new ArrayMap<>();
576
577    final PackageInstallerService mInstallerService;
578
579    private final PackageDexOptimizer mPackageDexOptimizer;
580
581    private AtomicInteger mNextMoveId = new AtomicInteger();
582    private final MoveCallbacks mMoveCallbacks;
583
584    private final OnPermissionChangeListeners mOnPermissionChangeListeners;
585
586    // Cache of users who need badging.
587    SparseBooleanArray mUserNeedsBadging = new SparseBooleanArray();
588
589    /** Token for keys in mPendingVerification. */
590    private int mPendingVerificationToken = 0;
591
592    volatile boolean mSystemReady;
593    volatile boolean mSafeMode;
594    volatile boolean mHasSystemUidErrors;
595
596    ApplicationInfo mAndroidApplication;
597    final ActivityInfo mResolveActivity = new ActivityInfo();
598    final ResolveInfo mResolveInfo = new ResolveInfo();
599    ComponentName mResolveComponentName;
600    PackageParser.Package mPlatformPackage;
601    ComponentName mCustomResolverComponentName;
602
603    boolean mResolverReplaced = false;
604
605    private final @Nullable ComponentName mIntentFilterVerifierComponent;
606    private final @Nullable IntentFilterVerifier<ActivityIntentInfo> mIntentFilterVerifier;
607
608    private int mIntentFilterVerificationToken = 0;
609
610    /** Component that knows whether or not an ephemeral application exists */
611    final ComponentName mEphemeralResolverComponent;
612    /** The service connection to the ephemeral resolver */
613    final EphemeralResolverConnection mEphemeralResolverConnection;
614
615    /** Component used to install ephemeral applications */
616    final ComponentName mEphemeralInstallerComponent;
617    final ActivityInfo mEphemeralInstallerActivity = new ActivityInfo();
618    final ResolveInfo mEphemeralInstallerInfo = new ResolveInfo();
619
620    final SparseArray<IntentFilterVerificationState> mIntentFilterVerificationStates
621            = new SparseArray<IntentFilterVerificationState>();
622
623    final DefaultPermissionGrantPolicy mDefaultPermissionPolicy =
624            new DefaultPermissionGrantPolicy(this);
625
626    // List of packages names to keep cached, even if they are uninstalled for all users
627    private List<String> mKeepUninstalledPackages;
628
629    private static class IFVerificationParams {
630        PackageParser.Package pkg;
631        boolean replacing;
632        int userId;
633        int verifierUid;
634
635        public IFVerificationParams(PackageParser.Package _pkg, boolean _replacing,
636                int _userId, int _verifierUid) {
637            pkg = _pkg;
638            replacing = _replacing;
639            userId = _userId;
640            replacing = _replacing;
641            verifierUid = _verifierUid;
642        }
643    }
644
645    private interface IntentFilterVerifier<T extends IntentFilter> {
646        boolean addOneIntentFilterVerification(int verifierId, int userId, int verificationId,
647                                               T filter, String packageName);
648        void startVerifications(int userId);
649        void receiveVerificationResponse(int verificationId);
650    }
651
652    private class IntentVerifierProxy implements IntentFilterVerifier<ActivityIntentInfo> {
653        private Context mContext;
654        private ComponentName mIntentFilterVerifierComponent;
655        private ArrayList<Integer> mCurrentIntentFilterVerifications = new ArrayList<Integer>();
656
657        public IntentVerifierProxy(Context context, ComponentName verifierComponent) {
658            mContext = context;
659            mIntentFilterVerifierComponent = verifierComponent;
660        }
661
662        private String getDefaultScheme() {
663            return IntentFilter.SCHEME_HTTPS;
664        }
665
666        @Override
667        public void startVerifications(int userId) {
668            // Launch verifications requests
669            int count = mCurrentIntentFilterVerifications.size();
670            for (int n=0; n<count; n++) {
671                int verificationId = mCurrentIntentFilterVerifications.get(n);
672                final IntentFilterVerificationState ivs =
673                        mIntentFilterVerificationStates.get(verificationId);
674
675                String packageName = ivs.getPackageName();
676
677                ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters();
678                final int filterCount = filters.size();
679                ArraySet<String> domainsSet = new ArraySet<>();
680                for (int m=0; m<filterCount; m++) {
681                    PackageParser.ActivityIntentInfo filter = filters.get(m);
682                    domainsSet.addAll(filter.getHostsList());
683                }
684                ArrayList<String> domainsList = new ArrayList<>(domainsSet);
685                synchronized (mPackages) {
686                    if (mSettings.createIntentFilterVerificationIfNeededLPw(
687                            packageName, domainsList) != null) {
688                        scheduleWriteSettingsLocked();
689                    }
690                }
691                sendVerificationRequest(userId, verificationId, ivs);
692            }
693            mCurrentIntentFilterVerifications.clear();
694        }
695
696        private void sendVerificationRequest(int userId, int verificationId,
697                IntentFilterVerificationState ivs) {
698
699            Intent verificationIntent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION);
700            verificationIntent.putExtra(
701                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_ID,
702                    verificationId);
703            verificationIntent.putExtra(
704                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_URI_SCHEME,
705                    getDefaultScheme());
706            verificationIntent.putExtra(
707                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_HOSTS,
708                    ivs.getHostsString());
709            verificationIntent.putExtra(
710                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_PACKAGE_NAME,
711                    ivs.getPackageName());
712            verificationIntent.setComponent(mIntentFilterVerifierComponent);
713            verificationIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
714
715            UserHandle user = new UserHandle(userId);
716            mContext.sendBroadcastAsUser(verificationIntent, user);
717            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
718                    "Sending IntentFilter verification broadcast");
719        }
720
721        public void receiveVerificationResponse(int verificationId) {
722            IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId);
723
724            final boolean verified = ivs.isVerified();
725
726            ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters();
727            final int count = filters.size();
728            if (DEBUG_DOMAIN_VERIFICATION) {
729                Slog.i(TAG, "Received verification response " + verificationId
730                        + " for " + count + " filters, verified=" + verified);
731            }
732            for (int n=0; n<count; n++) {
733                PackageParser.ActivityIntentInfo filter = filters.get(n);
734                filter.setVerified(verified);
735
736                if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "IntentFilter " + filter.toString()
737                        + " verified with result:" + verified + " and hosts:"
738                        + ivs.getHostsString());
739            }
740
741            mIntentFilterVerificationStates.remove(verificationId);
742
743            final String packageName = ivs.getPackageName();
744            IntentFilterVerificationInfo ivi = null;
745
746            synchronized (mPackages) {
747                ivi = mSettings.getIntentFilterVerificationLPr(packageName);
748            }
749            if (ivi == null) {
750                Slog.w(TAG, "IntentFilterVerificationInfo not found for verificationId:"
751                        + verificationId + " packageName:" + packageName);
752                return;
753            }
754            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
755                    "Updating IntentFilterVerificationInfo for package " + packageName
756                            +" verificationId:" + verificationId);
757
758            synchronized (mPackages) {
759                if (verified) {
760                    ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS);
761                } else {
762                    ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK);
763                }
764                scheduleWriteSettingsLocked();
765
766                final int userId = ivs.getUserId();
767                if (userId != UserHandle.USER_ALL) {
768                    final int userStatus =
769                            mSettings.getIntentFilterVerificationStatusLPr(packageName, userId);
770
771                    int updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
772                    boolean needUpdate = false;
773
774                    // We cannot override the STATUS_ALWAYS / STATUS_NEVER states if they have
775                    // already been set by the User thru the Disambiguation dialog
776                    switch (userStatus) {
777                        case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED:
778                            if (verified) {
779                                updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
780                            } else {
781                                updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK;
782                            }
783                            needUpdate = true;
784                            break;
785
786                        case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK:
787                            if (verified) {
788                                updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
789                                needUpdate = true;
790                            }
791                            break;
792
793                        default:
794                            // Nothing to do
795                    }
796
797                    if (needUpdate) {
798                        mSettings.updateIntentFilterVerificationStatusLPw(
799                                packageName, updatedStatus, userId);
800                        scheduleWritePackageRestrictionsLocked(userId);
801                    }
802                }
803            }
804        }
805
806        @Override
807        public boolean addOneIntentFilterVerification(int verifierUid, int userId, int verificationId,
808                    ActivityIntentInfo filter, String packageName) {
809            if (!hasValidDomains(filter)) {
810                return false;
811            }
812            IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId);
813            if (ivs == null) {
814                ivs = createDomainVerificationState(verifierUid, userId, verificationId,
815                        packageName);
816            }
817            if (DEBUG_DOMAIN_VERIFICATION) {
818                Slog.d(TAG, "Adding verification filter for " + packageName + ": " + filter);
819            }
820            ivs.addFilter(filter);
821            return true;
822        }
823
824        private IntentFilterVerificationState createDomainVerificationState(int verifierUid,
825                int userId, int verificationId, String packageName) {
826            IntentFilterVerificationState ivs = new IntentFilterVerificationState(
827                    verifierUid, userId, packageName);
828            ivs.setPendingState();
829            synchronized (mPackages) {
830                mIntentFilterVerificationStates.append(verificationId, ivs);
831                mCurrentIntentFilterVerifications.add(verificationId);
832            }
833            return ivs;
834        }
835    }
836
837    private static boolean hasValidDomains(ActivityIntentInfo filter) {
838        return filter.hasCategory(Intent.CATEGORY_BROWSABLE)
839                && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) ||
840                        filter.hasDataScheme(IntentFilter.SCHEME_HTTPS));
841    }
842
843    // Set of pending broadcasts for aggregating enable/disable of components.
844    static class PendingPackageBroadcasts {
845        // for each user id, a map of <package name -> components within that package>
846        final SparseArray<ArrayMap<String, ArrayList<String>>> mUidMap;
847
848        public PendingPackageBroadcasts() {
849            mUidMap = new SparseArray<ArrayMap<String, ArrayList<String>>>(2);
850        }
851
852        public ArrayList<String> get(int userId, String packageName) {
853            ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId);
854            return packages.get(packageName);
855        }
856
857        public void put(int userId, String packageName, ArrayList<String> components) {
858            ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId);
859            packages.put(packageName, components);
860        }
861
862        public void remove(int userId, String packageName) {
863            ArrayMap<String, ArrayList<String>> packages = mUidMap.get(userId);
864            if (packages != null) {
865                packages.remove(packageName);
866            }
867        }
868
869        public void remove(int userId) {
870            mUidMap.remove(userId);
871        }
872
873        public int userIdCount() {
874            return mUidMap.size();
875        }
876
877        public int userIdAt(int n) {
878            return mUidMap.keyAt(n);
879        }
880
881        public ArrayMap<String, ArrayList<String>> packagesForUserId(int userId) {
882            return mUidMap.get(userId);
883        }
884
885        public int size() {
886            // total number of pending broadcast entries across all userIds
887            int num = 0;
888            for (int i = 0; i< mUidMap.size(); i++) {
889                num += mUidMap.valueAt(i).size();
890            }
891            return num;
892        }
893
894        public void clear() {
895            mUidMap.clear();
896        }
897
898        private ArrayMap<String, ArrayList<String>> getOrAllocate(int userId) {
899            ArrayMap<String, ArrayList<String>> map = mUidMap.get(userId);
900            if (map == null) {
901                map = new ArrayMap<String, ArrayList<String>>();
902                mUidMap.put(userId, map);
903            }
904            return map;
905        }
906    }
907    final PendingPackageBroadcasts mPendingBroadcasts = new PendingPackageBroadcasts();
908
909    // Service Connection to remote media container service to copy
910    // package uri's from external media onto secure containers
911    // or internal storage.
912    private IMediaContainerService mContainerService = null;
913
914    static final int SEND_PENDING_BROADCAST = 1;
915    static final int MCS_BOUND = 3;
916    static final int END_COPY = 4;
917    static final int INIT_COPY = 5;
918    static final int MCS_UNBIND = 6;
919    static final int START_CLEANING_PACKAGE = 7;
920    static final int FIND_INSTALL_LOC = 8;
921    static final int POST_INSTALL = 9;
922    static final int MCS_RECONNECT = 10;
923    static final int MCS_GIVE_UP = 11;
924    static final int UPDATED_MEDIA_STATUS = 12;
925    static final int WRITE_SETTINGS = 13;
926    static final int WRITE_PACKAGE_RESTRICTIONS = 14;
927    static final int PACKAGE_VERIFIED = 15;
928    static final int CHECK_PENDING_VERIFICATION = 16;
929    static final int START_INTENT_FILTER_VERIFICATIONS = 17;
930    static final int INTENT_FILTER_VERIFIED = 18;
931
932    static final int WRITE_SETTINGS_DELAY = 10*1000;  // 10 seconds
933
934    // Delay time in millisecs
935    static final int BROADCAST_DELAY = 10 * 1000;
936
937    static UserManagerService sUserManager;
938
939    // Stores a list of users whose package restrictions file needs to be updated
940    private ArraySet<Integer> mDirtyUsers = new ArraySet<Integer>();
941
942    final private DefaultContainerConnection mDefContainerConn =
943            new DefaultContainerConnection();
944    class DefaultContainerConnection implements ServiceConnection {
945        public void onServiceConnected(ComponentName name, IBinder service) {
946            if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceConnected");
947            IMediaContainerService imcs =
948                IMediaContainerService.Stub.asInterface(service);
949            mHandler.sendMessage(mHandler.obtainMessage(MCS_BOUND, imcs));
950        }
951
952        public void onServiceDisconnected(ComponentName name) {
953            if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceDisconnected");
954        }
955    }
956
957    // Recordkeeping of restore-after-install operations that are currently in flight
958    // between the Package Manager and the Backup Manager
959    static class PostInstallData {
960        public InstallArgs args;
961        public PackageInstalledInfo res;
962
963        PostInstallData(InstallArgs _a, PackageInstalledInfo _r) {
964            args = _a;
965            res = _r;
966        }
967    }
968
969    final SparseArray<PostInstallData> mRunningInstalls = new SparseArray<PostInstallData>();
970    int mNextInstallToken = 1;  // nonzero; will be wrapped back to 1 when ++ overflows
971
972    // XML tags for backup/restore of various bits of state
973    private static final String TAG_PREFERRED_BACKUP = "pa";
974    private static final String TAG_DEFAULT_APPS = "da";
975    private static final String TAG_INTENT_FILTER_VERIFICATION = "iv";
976
977    final @Nullable String mRequiredVerifierPackage;
978    final @Nullable String mRequiredInstallerPackage;
979
980    private final PackageUsage mPackageUsage = new PackageUsage();
981
982    private class PackageUsage {
983        private static final int WRITE_INTERVAL
984            = (DEBUG_DEXOPT) ? 0 : 30*60*1000; // 30m in ms
985
986        private final Object mFileLock = new Object();
987        private final AtomicLong mLastWritten = new AtomicLong(0);
988        private final AtomicBoolean mBackgroundWriteRunning = new AtomicBoolean(false);
989
990        private boolean mIsHistoricalPackageUsageAvailable = true;
991
992        boolean isHistoricalPackageUsageAvailable() {
993            return mIsHistoricalPackageUsageAvailable;
994        }
995
996        void write(boolean force) {
997            if (force) {
998                writeInternal();
999                return;
1000            }
1001            if (SystemClock.elapsedRealtime() - mLastWritten.get() < WRITE_INTERVAL
1002                && !DEBUG_DEXOPT) {
1003                return;
1004            }
1005            if (mBackgroundWriteRunning.compareAndSet(false, true)) {
1006                new Thread("PackageUsage_DiskWriter") {
1007                    @Override
1008                    public void run() {
1009                        try {
1010                            writeInternal();
1011                        } finally {
1012                            mBackgroundWriteRunning.set(false);
1013                        }
1014                    }
1015                }.start();
1016            }
1017        }
1018
1019        private void writeInternal() {
1020            synchronized (mPackages) {
1021                synchronized (mFileLock) {
1022                    AtomicFile file = getFile();
1023                    FileOutputStream f = null;
1024                    try {
1025                        f = file.startWrite();
1026                        BufferedOutputStream out = new BufferedOutputStream(f);
1027                        FileUtils.setPermissions(file.getBaseFile().getPath(), 0640, SYSTEM_UID, PACKAGE_INFO_GID);
1028                        StringBuilder sb = new StringBuilder();
1029                        for (PackageParser.Package pkg : mPackages.values()) {
1030                            if (pkg.mLastPackageUsageTimeInMills == 0) {
1031                                continue;
1032                            }
1033                            sb.setLength(0);
1034                            sb.append(pkg.packageName);
1035                            sb.append(' ');
1036                            sb.append((long)pkg.mLastPackageUsageTimeInMills);
1037                            sb.append('\n');
1038                            out.write(sb.toString().getBytes(StandardCharsets.US_ASCII));
1039                        }
1040                        out.flush();
1041                        file.finishWrite(f);
1042                    } catch (IOException e) {
1043                        if (f != null) {
1044                            file.failWrite(f);
1045                        }
1046                        Log.e(TAG, "Failed to write package usage times", e);
1047                    }
1048                }
1049            }
1050            mLastWritten.set(SystemClock.elapsedRealtime());
1051        }
1052
1053        void readLP() {
1054            synchronized (mFileLock) {
1055                AtomicFile file = getFile();
1056                BufferedInputStream in = null;
1057                try {
1058                    in = new BufferedInputStream(file.openRead());
1059                    StringBuffer sb = new StringBuffer();
1060                    while (true) {
1061                        String packageName = readToken(in, sb, ' ');
1062                        if (packageName == null) {
1063                            break;
1064                        }
1065                        String timeInMillisString = readToken(in, sb, '\n');
1066                        if (timeInMillisString == null) {
1067                            throw new IOException("Failed to find last usage time for package "
1068                                                  + packageName);
1069                        }
1070                        PackageParser.Package pkg = mPackages.get(packageName);
1071                        if (pkg == null) {
1072                            continue;
1073                        }
1074                        long timeInMillis;
1075                        try {
1076                            timeInMillis = Long.parseLong(timeInMillisString);
1077                        } catch (NumberFormatException e) {
1078                            throw new IOException("Failed to parse " + timeInMillisString
1079                                                  + " as a long.", e);
1080                        }
1081                        pkg.mLastPackageUsageTimeInMills = timeInMillis;
1082                    }
1083                } catch (FileNotFoundException expected) {
1084                    mIsHistoricalPackageUsageAvailable = false;
1085                } catch (IOException e) {
1086                    Log.w(TAG, "Failed to read package usage times", e);
1087                } finally {
1088                    IoUtils.closeQuietly(in);
1089                }
1090            }
1091            mLastWritten.set(SystemClock.elapsedRealtime());
1092        }
1093
1094        private String readToken(InputStream in, StringBuffer sb, char endOfToken)
1095                throws IOException {
1096            sb.setLength(0);
1097            while (true) {
1098                int ch = in.read();
1099                if (ch == -1) {
1100                    if (sb.length() == 0) {
1101                        return null;
1102                    }
1103                    throw new IOException("Unexpected EOF");
1104                }
1105                if (ch == endOfToken) {
1106                    return sb.toString();
1107                }
1108                sb.append((char)ch);
1109            }
1110        }
1111
1112        private AtomicFile getFile() {
1113            File dataDir = Environment.getDataDirectory();
1114            File systemDir = new File(dataDir, "system");
1115            File fname = new File(systemDir, "package-usage.list");
1116            return new AtomicFile(fname);
1117        }
1118    }
1119
1120    class PackageHandler extends Handler {
1121        private boolean mBound = false;
1122        final ArrayList<HandlerParams> mPendingInstalls =
1123            new ArrayList<HandlerParams>();
1124
1125        private boolean connectToService() {
1126            if (DEBUG_SD_INSTALL) Log.i(TAG, "Trying to bind to" +
1127                    " DefaultContainerService");
1128            Intent service = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
1129            Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1130            if (mContext.bindServiceAsUser(service, mDefContainerConn,
1131                    Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) {
1132                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1133                mBound = true;
1134                return true;
1135            }
1136            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1137            return false;
1138        }
1139
1140        private void disconnectService() {
1141            mContainerService = null;
1142            mBound = false;
1143            Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1144            mContext.unbindService(mDefContainerConn);
1145            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1146        }
1147
1148        PackageHandler(Looper looper) {
1149            super(looper);
1150        }
1151
1152        public void handleMessage(Message msg) {
1153            try {
1154                doHandleMessage(msg);
1155            } finally {
1156                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1157            }
1158        }
1159
1160        void doHandleMessage(Message msg) {
1161            switch (msg.what) {
1162                case INIT_COPY: {
1163                    HandlerParams params = (HandlerParams) msg.obj;
1164                    int idx = mPendingInstalls.size();
1165                    if (DEBUG_INSTALL) Slog.i(TAG, "init_copy idx=" + idx + ": " + params);
1166                    // If a bind was already initiated we dont really
1167                    // need to do anything. The pending install
1168                    // will be processed later on.
1169                    if (!mBound) {
1170                        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1171                                System.identityHashCode(mHandler));
1172                        // If this is the only one pending we might
1173                        // have to bind to the service again.
1174                        if (!connectToService()) {
1175                            Slog.e(TAG, "Failed to bind to media container service");
1176                            params.serviceError();
1177                            Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1178                                    System.identityHashCode(mHandler));
1179                            if (params.traceMethod != null) {
1180                                Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, params.traceMethod,
1181                                        params.traceCookie);
1182                            }
1183                            return;
1184                        } else {
1185                            // Once we bind to the service, the first
1186                            // pending request will be processed.
1187                            mPendingInstalls.add(idx, params);
1188                        }
1189                    } else {
1190                        mPendingInstalls.add(idx, params);
1191                        // Already bound to the service. Just make
1192                        // sure we trigger off processing the first request.
1193                        if (idx == 0) {
1194                            mHandler.sendEmptyMessage(MCS_BOUND);
1195                        }
1196                    }
1197                    break;
1198                }
1199                case MCS_BOUND: {
1200                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_bound");
1201                    if (msg.obj != null) {
1202                        mContainerService = (IMediaContainerService) msg.obj;
1203                        Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1204                                System.identityHashCode(mHandler));
1205                    }
1206                    if (mContainerService == null) {
1207                        if (!mBound) {
1208                            // Something seriously wrong since we are not bound and we are not
1209                            // waiting for connection. Bail out.
1210                            Slog.e(TAG, "Cannot bind to media container service");
1211                            for (HandlerParams params : mPendingInstalls) {
1212                                // Indicate service bind error
1213                                params.serviceError();
1214                                Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1215                                        System.identityHashCode(params));
1216                                if (params.traceMethod != null) {
1217                                    Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER,
1218                                            params.traceMethod, params.traceCookie);
1219                                }
1220                                return;
1221                            }
1222                            mPendingInstalls.clear();
1223                        } else {
1224                            Slog.w(TAG, "Waiting to connect to media container service");
1225                        }
1226                    } else if (mPendingInstalls.size() > 0) {
1227                        HandlerParams params = mPendingInstalls.get(0);
1228                        if (params != null) {
1229                            Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1230                                    System.identityHashCode(params));
1231                            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "startCopy");
1232                            if (params.startCopy()) {
1233                                // We are done...  look for more work or to
1234                                // go idle.
1235                                if (DEBUG_SD_INSTALL) Log.i(TAG,
1236                                        "Checking for more work or unbind...");
1237                                // Delete pending install
1238                                if (mPendingInstalls.size() > 0) {
1239                                    mPendingInstalls.remove(0);
1240                                }
1241                                if (mPendingInstalls.size() == 0) {
1242                                    if (mBound) {
1243                                        if (DEBUG_SD_INSTALL) Log.i(TAG,
1244                                                "Posting delayed MCS_UNBIND");
1245                                        removeMessages(MCS_UNBIND);
1246                                        Message ubmsg = obtainMessage(MCS_UNBIND);
1247                                        // Unbind after a little delay, to avoid
1248                                        // continual thrashing.
1249                                        sendMessageDelayed(ubmsg, 10000);
1250                                    }
1251                                } else {
1252                                    // There are more pending requests in queue.
1253                                    // Just post MCS_BOUND message to trigger processing
1254                                    // of next pending install.
1255                                    if (DEBUG_SD_INSTALL) Log.i(TAG,
1256                                            "Posting MCS_BOUND for next work");
1257                                    mHandler.sendEmptyMessage(MCS_BOUND);
1258                                }
1259                            }
1260                            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
1261                        }
1262                    } else {
1263                        // Should never happen ideally.
1264                        Slog.w(TAG, "Empty queue");
1265                    }
1266                    break;
1267                }
1268                case MCS_RECONNECT: {
1269                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_reconnect");
1270                    if (mPendingInstalls.size() > 0) {
1271                        if (mBound) {
1272                            disconnectService();
1273                        }
1274                        if (!connectToService()) {
1275                            Slog.e(TAG, "Failed to bind to media container service");
1276                            for (HandlerParams params : mPendingInstalls) {
1277                                // Indicate service bind error
1278                                params.serviceError();
1279                                Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1280                                        System.identityHashCode(params));
1281                            }
1282                            mPendingInstalls.clear();
1283                        }
1284                    }
1285                    break;
1286                }
1287                case MCS_UNBIND: {
1288                    // If there is no actual work left, then time to unbind.
1289                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_unbind");
1290
1291                    if (mPendingInstalls.size() == 0 && mPendingVerification.size() == 0) {
1292                        if (mBound) {
1293                            if (DEBUG_INSTALL) Slog.i(TAG, "calling disconnectService()");
1294
1295                            disconnectService();
1296                        }
1297                    } else if (mPendingInstalls.size() > 0) {
1298                        // There are more pending requests in queue.
1299                        // Just post MCS_BOUND message to trigger processing
1300                        // of next pending install.
1301                        mHandler.sendEmptyMessage(MCS_BOUND);
1302                    }
1303
1304                    break;
1305                }
1306                case MCS_GIVE_UP: {
1307                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_giveup too many retries");
1308                    HandlerParams params = mPendingInstalls.remove(0);
1309                    Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1310                            System.identityHashCode(params));
1311                    break;
1312                }
1313                case SEND_PENDING_BROADCAST: {
1314                    String packages[];
1315                    ArrayList<String> components[];
1316                    int size = 0;
1317                    int uids[];
1318                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1319                    synchronized (mPackages) {
1320                        if (mPendingBroadcasts == null) {
1321                            return;
1322                        }
1323                        size = mPendingBroadcasts.size();
1324                        if (size <= 0) {
1325                            // Nothing to be done. Just return
1326                            return;
1327                        }
1328                        packages = new String[size];
1329                        components = new ArrayList[size];
1330                        uids = new int[size];
1331                        int i = 0;  // filling out the above arrays
1332
1333                        for (int n = 0; n < mPendingBroadcasts.userIdCount(); n++) {
1334                            int packageUserId = mPendingBroadcasts.userIdAt(n);
1335                            Iterator<Map.Entry<String, ArrayList<String>>> it
1336                                    = mPendingBroadcasts.packagesForUserId(packageUserId)
1337                                            .entrySet().iterator();
1338                            while (it.hasNext() && i < size) {
1339                                Map.Entry<String, ArrayList<String>> ent = it.next();
1340                                packages[i] = ent.getKey();
1341                                components[i] = ent.getValue();
1342                                PackageSetting ps = mSettings.mPackages.get(ent.getKey());
1343                                uids[i] = (ps != null)
1344                                        ? UserHandle.getUid(packageUserId, ps.appId)
1345                                        : -1;
1346                                i++;
1347                            }
1348                        }
1349                        size = i;
1350                        mPendingBroadcasts.clear();
1351                    }
1352                    // Send broadcasts
1353                    for (int i = 0; i < size; i++) {
1354                        sendPackageChangedBroadcast(packages[i], true, components[i], uids[i]);
1355                    }
1356                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1357                    break;
1358                }
1359                case START_CLEANING_PACKAGE: {
1360                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1361                    final String packageName = (String)msg.obj;
1362                    final int userId = msg.arg1;
1363                    final boolean andCode = msg.arg2 != 0;
1364                    synchronized (mPackages) {
1365                        if (userId == UserHandle.USER_ALL) {
1366                            int[] users = sUserManager.getUserIds();
1367                            for (int user : users) {
1368                                mSettings.addPackageToCleanLPw(
1369                                        new PackageCleanItem(user, packageName, andCode));
1370                            }
1371                        } else {
1372                            mSettings.addPackageToCleanLPw(
1373                                    new PackageCleanItem(userId, packageName, andCode));
1374                        }
1375                    }
1376                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1377                    startCleaningPackages();
1378                } break;
1379                case POST_INSTALL: {
1380                    if (DEBUG_INSTALL) Log.v(TAG, "Handling post-install for " + msg.arg1);
1381
1382                    PostInstallData data = mRunningInstalls.get(msg.arg1);
1383                    mRunningInstalls.delete(msg.arg1);
1384                    boolean deleteOld = false;
1385
1386                    if (data != null) {
1387                        InstallArgs args = data.args;
1388                        PackageInstalledInfo res = data.res;
1389
1390                        if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
1391                            final String packageName = res.pkg.applicationInfo.packageName;
1392                            res.removedInfo.sendBroadcast(false, true, false);
1393                            Bundle extras = new Bundle(1);
1394                            extras.putInt(Intent.EXTRA_UID, res.uid);
1395
1396                            // Now that we successfully installed the package, grant runtime
1397                            // permissions if requested before broadcasting the install.
1398                            if ((args.installFlags
1399                                    & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0
1400                                    && res.pkg.applicationInfo.targetSdkVersion
1401                                            >= Build.VERSION_CODES.M) {
1402                                grantRequestedRuntimePermissions(res.pkg, args.user.getIdentifier(),
1403                                        args.installGrantPermissions);
1404                            }
1405
1406                            synchronized (mPackages) {
1407                                mEphemeralApplicationRegistry.onPackageInstalledLPw(res.pkg);
1408                            }
1409
1410                            // Determine the set of users who are adding this
1411                            // package for the first time vs. those who are seeing
1412                            // an update.
1413                            int[] firstUsers;
1414                            int[] updateUsers = new int[0];
1415                            if (res.origUsers == null || res.origUsers.length == 0) {
1416                                firstUsers = res.newUsers;
1417                            } else {
1418                                firstUsers = new int[0];
1419                                for (int i=0; i<res.newUsers.length; i++) {
1420                                    int user = res.newUsers[i];
1421                                    boolean isNew = true;
1422                                    for (int j=0; j<res.origUsers.length; j++) {
1423                                        if (res.origUsers[j] == user) {
1424                                            isNew = false;
1425                                            break;
1426                                        }
1427                                    }
1428                                    if (isNew) {
1429                                        int[] newFirst = new int[firstUsers.length+1];
1430                                        System.arraycopy(firstUsers, 0, newFirst, 0,
1431                                                firstUsers.length);
1432                                        newFirst[firstUsers.length] = user;
1433                                        firstUsers = newFirst;
1434                                    } else {
1435                                        int[] newUpdate = new int[updateUsers.length+1];
1436                                        System.arraycopy(updateUsers, 0, newUpdate, 0,
1437                                                updateUsers.length);
1438                                        newUpdate[updateUsers.length] = user;
1439                                        updateUsers = newUpdate;
1440                                    }
1441                                }
1442                            }
1443                            // don't broadcast for ephemeral installs/updates
1444                            final boolean isEphemeral = isEphemeral(res.pkg);
1445                            if (!isEphemeral) {
1446                                sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
1447                                        extras, 0 /*flags*/, null /*targetPackage*/,
1448                                        null /*finishedReceiver*/, firstUsers);
1449                            }
1450                            final boolean update = res.removedInfo.removedPackage != null;
1451                            if (update) {
1452                                extras.putBoolean(Intent.EXTRA_REPLACING, true);
1453                            }
1454                            if (!isEphemeral) {
1455                                sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
1456                                        extras, 0 /*flags*/, null /*targetPackage*/,
1457                                        null /*finishedReceiver*/, updateUsers);
1458                            }
1459                            if (update) {
1460                                if (!isEphemeral) {
1461                                    sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
1462                                            packageName, extras, 0 /*flags*/,
1463                                            null /*targetPackage*/, null /*finishedReceiver*/,
1464                                            updateUsers);
1465                                    sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
1466                                            null /*package*/, null /*extras*/, 0 /*flags*/,
1467                                            packageName /*targetPackage*/,
1468                                            null /*finishedReceiver*/, updateUsers);
1469                                }
1470
1471                                // treat asec-hosted packages like removable media on upgrade
1472                                if (res.pkg.isForwardLocked() || isExternal(res.pkg)) {
1473                                    if (DEBUG_INSTALL) {
1474                                        Slog.i(TAG, "upgrading pkg " + res.pkg
1475                                                + " is ASEC-hosted -> AVAILABLE");
1476                                    }
1477                                    int[] uidArray = new int[] { res.pkg.applicationInfo.uid };
1478                                    ArrayList<String> pkgList = new ArrayList<String>(1);
1479                                    pkgList.add(packageName);
1480                                    sendResourcesChangedBroadcast(true, true,
1481                                            pkgList,uidArray, null);
1482                                }
1483                            }
1484                            if (res.removedInfo.args != null) {
1485                                // Remove the replaced package's older resources safely now
1486                                deleteOld = true;
1487                            }
1488
1489                            // If this app is a browser and it's newly-installed for some
1490                            // users, clear any default-browser state in those users
1491                            if (firstUsers.length > 0) {
1492                                // the app's nature doesn't depend on the user, so we can just
1493                                // check its browser nature in any user and generalize.
1494                                if (packageIsBrowser(packageName, firstUsers[0])) {
1495                                    synchronized (mPackages) {
1496                                        for (int userId : firstUsers) {
1497                                            mSettings.setDefaultBrowserPackageNameLPw(null, userId);
1498                                        }
1499                                    }
1500                                }
1501                            }
1502                            // Log current value of "unknown sources" setting
1503                            EventLog.writeEvent(EventLogTags.UNKNOWN_SOURCES_ENABLED,
1504                                getUnknownSourcesSettings());
1505                        }
1506                        // Force a gc to clear up things
1507                        Runtime.getRuntime().gc();
1508                        // We delete after a gc for applications  on sdcard.
1509                        if (deleteOld) {
1510                            synchronized (mInstallLock) {
1511                                res.removedInfo.args.doPostDeleteLI(true);
1512                            }
1513                        }
1514                        if (args.observer != null) {
1515                            try {
1516                                Bundle extras = extrasForInstallResult(res);
1517                                args.observer.onPackageInstalled(res.name, res.returnCode,
1518                                        res.returnMsg, extras);
1519                            } catch (RemoteException e) {
1520                                Slog.i(TAG, "Observer no longer exists.");
1521                            }
1522                        }
1523                        if (args.traceMethod != null) {
1524                            Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, args.traceMethod,
1525                                    args.traceCookie);
1526                        }
1527                        return;
1528                    } else {
1529                        Slog.e(TAG, "Bogus post-install token " + msg.arg1);
1530                    }
1531
1532                    Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "postInstall", msg.arg1);
1533                } break;
1534                case UPDATED_MEDIA_STATUS: {
1535                    if (DEBUG_SD_INSTALL) Log.i(TAG, "Got message UPDATED_MEDIA_STATUS");
1536                    boolean reportStatus = msg.arg1 == 1;
1537                    boolean doGc = msg.arg2 == 1;
1538                    if (DEBUG_SD_INSTALL) Log.i(TAG, "reportStatus=" + reportStatus + ", doGc = " + doGc);
1539                    if (doGc) {
1540                        // Force a gc to clear up stale containers.
1541                        Runtime.getRuntime().gc();
1542                    }
1543                    if (msg.obj != null) {
1544                        @SuppressWarnings("unchecked")
1545                        Set<AsecInstallArgs> args = (Set<AsecInstallArgs>) msg.obj;
1546                        if (DEBUG_SD_INSTALL) Log.i(TAG, "Unloading all containers");
1547                        // Unload containers
1548                        unloadAllContainers(args);
1549                    }
1550                    if (reportStatus) {
1551                        try {
1552                            if (DEBUG_SD_INSTALL) Log.i(TAG, "Invoking MountService call back");
1553                            PackageHelper.getMountService().finishMediaUpdate();
1554                        } catch (RemoteException e) {
1555                            Log.e(TAG, "MountService not running?");
1556                        }
1557                    }
1558                } break;
1559                case WRITE_SETTINGS: {
1560                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1561                    synchronized (mPackages) {
1562                        removeMessages(WRITE_SETTINGS);
1563                        removeMessages(WRITE_PACKAGE_RESTRICTIONS);
1564                        mSettings.writeLPr();
1565                        mDirtyUsers.clear();
1566                    }
1567                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1568                } break;
1569                case WRITE_PACKAGE_RESTRICTIONS: {
1570                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1571                    synchronized (mPackages) {
1572                        removeMessages(WRITE_PACKAGE_RESTRICTIONS);
1573                        for (int userId : mDirtyUsers) {
1574                            mSettings.writePackageRestrictionsLPr(userId);
1575                        }
1576                        mDirtyUsers.clear();
1577                    }
1578                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1579                } break;
1580                case CHECK_PENDING_VERIFICATION: {
1581                    final int verificationId = msg.arg1;
1582                    final PackageVerificationState state = mPendingVerification.get(verificationId);
1583
1584                    if ((state != null) && !state.timeoutExtended()) {
1585                        final InstallArgs args = state.getInstallArgs();
1586                        final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
1587
1588                        Slog.i(TAG, "Verification timed out for " + originUri);
1589                        mPendingVerification.remove(verificationId);
1590
1591                        int ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
1592
1593                        if (getDefaultVerificationResponse() == PackageManager.VERIFICATION_ALLOW) {
1594                            Slog.i(TAG, "Continuing with installation of " + originUri);
1595                            state.setVerifierResponse(Binder.getCallingUid(),
1596                                    PackageManager.VERIFICATION_ALLOW_WITHOUT_SUFFICIENT);
1597                            broadcastPackageVerified(verificationId, originUri,
1598                                    PackageManager.VERIFICATION_ALLOW,
1599                                    state.getInstallArgs().getUser());
1600                            try {
1601                                ret = args.copyApk(mContainerService, true);
1602                            } catch (RemoteException e) {
1603                                Slog.e(TAG, "Could not contact the ContainerService");
1604                            }
1605                        } else {
1606                            broadcastPackageVerified(verificationId, originUri,
1607                                    PackageManager.VERIFICATION_REJECT,
1608                                    state.getInstallArgs().getUser());
1609                        }
1610
1611                        Trace.asyncTraceEnd(
1612                                TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
1613
1614                        processPendingInstall(args, ret);
1615                        mHandler.sendEmptyMessage(MCS_UNBIND);
1616                    }
1617                    break;
1618                }
1619                case PACKAGE_VERIFIED: {
1620                    final int verificationId = msg.arg1;
1621
1622                    final PackageVerificationState state = mPendingVerification.get(verificationId);
1623                    if (state == null) {
1624                        Slog.w(TAG, "Invalid verification token " + verificationId + " received");
1625                        break;
1626                    }
1627
1628                    final PackageVerificationResponse response = (PackageVerificationResponse) msg.obj;
1629
1630                    state.setVerifierResponse(response.callerUid, response.code);
1631
1632                    if (state.isVerificationComplete()) {
1633                        mPendingVerification.remove(verificationId);
1634
1635                        final InstallArgs args = state.getInstallArgs();
1636                        final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
1637
1638                        int ret;
1639                        if (state.isInstallAllowed()) {
1640                            ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
1641                            broadcastPackageVerified(verificationId, originUri,
1642                                    response.code, state.getInstallArgs().getUser());
1643                            try {
1644                                ret = args.copyApk(mContainerService, true);
1645                            } catch (RemoteException e) {
1646                                Slog.e(TAG, "Could not contact the ContainerService");
1647                            }
1648                        } else {
1649                            ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
1650                        }
1651
1652                        Trace.asyncTraceEnd(
1653                                TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
1654
1655                        processPendingInstall(args, ret);
1656                        mHandler.sendEmptyMessage(MCS_UNBIND);
1657                    }
1658
1659                    break;
1660                }
1661                case START_INTENT_FILTER_VERIFICATIONS: {
1662                    IFVerificationParams params = (IFVerificationParams) msg.obj;
1663                    verifyIntentFiltersIfNeeded(params.userId, params.verifierUid,
1664                            params.replacing, params.pkg);
1665                    break;
1666                }
1667                case INTENT_FILTER_VERIFIED: {
1668                    final int verificationId = msg.arg1;
1669
1670                    final IntentFilterVerificationState state = mIntentFilterVerificationStates.get(
1671                            verificationId);
1672                    if (state == null) {
1673                        Slog.w(TAG, "Invalid IntentFilter verification token "
1674                                + verificationId + " received");
1675                        break;
1676                    }
1677
1678                    final int userId = state.getUserId();
1679
1680                    if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1681                            "Processing IntentFilter verification with token:"
1682                            + verificationId + " and userId:" + userId);
1683
1684                    final IntentFilterVerificationResponse response =
1685                            (IntentFilterVerificationResponse) msg.obj;
1686
1687                    state.setVerifierResponse(response.callerUid, response.code);
1688
1689                    if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1690                            "IntentFilter verification with token:" + verificationId
1691                            + " and userId:" + userId
1692                            + " is settings verifier response with response code:"
1693                            + response.code);
1694
1695                    if (response.code == PackageManager.INTENT_FILTER_VERIFICATION_FAILURE) {
1696                        if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Domains failing verification: "
1697                                + response.getFailedDomainsString());
1698                    }
1699
1700                    if (state.isVerificationComplete()) {
1701                        mIntentFilterVerifier.receiveVerificationResponse(verificationId);
1702                    } else {
1703                        if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1704                                "IntentFilter verification with token:" + verificationId
1705                                + " was not said to be complete");
1706                    }
1707
1708                    break;
1709                }
1710            }
1711        }
1712    }
1713
1714    private StorageEventListener mStorageListener = new StorageEventListener() {
1715        @Override
1716        public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState) {
1717            if (vol.type == VolumeInfo.TYPE_PRIVATE) {
1718                if (vol.state == VolumeInfo.STATE_MOUNTED) {
1719                    final String volumeUuid = vol.getFsUuid();
1720
1721                    // Clean up any users or apps that were removed or recreated
1722                    // while this volume was missing
1723                    reconcileUsers(volumeUuid);
1724                    reconcileApps(volumeUuid);
1725
1726                    // Clean up any install sessions that expired or were
1727                    // cancelled while this volume was missing
1728                    mInstallerService.onPrivateVolumeMounted(volumeUuid);
1729
1730                    loadPrivatePackages(vol);
1731
1732                } else if (vol.state == VolumeInfo.STATE_EJECTING) {
1733                    unloadPrivatePackages(vol);
1734                }
1735            }
1736
1737            if (vol.type == VolumeInfo.TYPE_PUBLIC && vol.isPrimary()) {
1738                if (vol.state == VolumeInfo.STATE_MOUNTED) {
1739                    updateExternalMediaStatus(true, false);
1740                } else if (vol.state == VolumeInfo.STATE_EJECTING) {
1741                    updateExternalMediaStatus(false, false);
1742                }
1743            }
1744        }
1745
1746        @Override
1747        public void onVolumeForgotten(String fsUuid) {
1748            if (TextUtils.isEmpty(fsUuid)) {
1749                Slog.w(TAG, "Forgetting internal storage is probably a mistake; ignoring");
1750                return;
1751            }
1752
1753            // Remove any apps installed on the forgotten volume
1754            synchronized (mPackages) {
1755                final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(fsUuid);
1756                for (PackageSetting ps : packages) {
1757                    Slog.d(TAG, "Destroying " + ps.name + " because volume was forgotten");
1758                    deletePackage(ps.name, new LegacyPackageDeleteObserver(null).getBinder(),
1759                            UserHandle.USER_SYSTEM, PackageManager.DELETE_ALL_USERS);
1760                }
1761
1762                mSettings.onVolumeForgotten(fsUuid);
1763                mSettings.writeLPr();
1764            }
1765        }
1766    };
1767
1768    private void grantRequestedRuntimePermissions(PackageParser.Package pkg, int userId,
1769            String[] grantedPermissions) {
1770        if (userId >= UserHandle.USER_SYSTEM) {
1771            grantRequestedRuntimePermissionsForUser(pkg, userId, grantedPermissions);
1772        } else if (userId == UserHandle.USER_ALL) {
1773            final int[] userIds;
1774            synchronized (mPackages) {
1775                userIds = UserManagerService.getInstance().getUserIds();
1776            }
1777            for (int someUserId : userIds) {
1778                grantRequestedRuntimePermissionsForUser(pkg, someUserId, grantedPermissions);
1779            }
1780        }
1781
1782        // We could have touched GID membership, so flush out packages.list
1783        synchronized (mPackages) {
1784            mSettings.writePackageListLPr();
1785        }
1786    }
1787
1788    private void grantRequestedRuntimePermissionsForUser(PackageParser.Package pkg, int userId,
1789            String[] grantedPermissions) {
1790        SettingBase sb = (SettingBase) pkg.mExtras;
1791        if (sb == null) {
1792            return;
1793        }
1794
1795        PermissionsState permissionsState = sb.getPermissionsState();
1796
1797        final int immutableFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
1798                | PackageManager.FLAG_PERMISSION_POLICY_FIXED;
1799
1800        synchronized (mPackages) {
1801            for (String permission : pkg.requestedPermissions) {
1802                BasePermission bp = mSettings.mPermissions.get(permission);
1803                if (bp != null && (bp.isRuntime() || bp.isDevelopment())
1804                        && (grantedPermissions == null
1805                               || ArrayUtils.contains(grantedPermissions, permission))) {
1806                    final int flags = permissionsState.getPermissionFlags(permission, userId);
1807                    // Installer cannot change immutable permissions.
1808                    if ((flags & immutableFlags) == 0) {
1809                        grantRuntimePermission(pkg.packageName, permission, userId);
1810                    }
1811                }
1812            }
1813        }
1814    }
1815
1816    Bundle extrasForInstallResult(PackageInstalledInfo res) {
1817        Bundle extras = null;
1818        switch (res.returnCode) {
1819            case PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION: {
1820                extras = new Bundle();
1821                extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PERMISSION,
1822                        res.origPermission);
1823                extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PACKAGE,
1824                        res.origPackage);
1825                break;
1826            }
1827            case PackageManager.INSTALL_SUCCEEDED: {
1828                extras = new Bundle();
1829                extras.putBoolean(Intent.EXTRA_REPLACING,
1830                        res.removedInfo != null && res.removedInfo.removedPackage != null);
1831                break;
1832            }
1833        }
1834        return extras;
1835    }
1836
1837    void scheduleWriteSettingsLocked() {
1838        if (!mHandler.hasMessages(WRITE_SETTINGS)) {
1839            mHandler.sendEmptyMessageDelayed(WRITE_SETTINGS, WRITE_SETTINGS_DELAY);
1840        }
1841    }
1842
1843    void scheduleWritePackageRestrictionsLocked(int userId) {
1844        if (!sUserManager.exists(userId)) return;
1845        mDirtyUsers.add(userId);
1846        if (!mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) {
1847            mHandler.sendEmptyMessageDelayed(WRITE_PACKAGE_RESTRICTIONS, WRITE_SETTINGS_DELAY);
1848        }
1849    }
1850
1851    public static PackageManagerService main(Context context, Installer installer,
1852            boolean factoryTest, boolean onlyCore) {
1853        PackageManagerService m = new PackageManagerService(context, installer,
1854                factoryTest, onlyCore);
1855        m.enableSystemUserPackages();
1856        ServiceManager.addService("package", m);
1857        return m;
1858    }
1859
1860    private void enableSystemUserPackages() {
1861        if (!UserManager.isSplitSystemUser()) {
1862            return;
1863        }
1864        // For system user, enable apps based on the following conditions:
1865        // - app is whitelisted or belong to one of these groups:
1866        //   -- system app which has no launcher icons
1867        //   -- system app which has INTERACT_ACROSS_USERS permission
1868        //   -- system IME app
1869        // - app is not in the blacklist
1870        AppsQueryHelper queryHelper = new AppsQueryHelper(this);
1871        Set<String> enableApps = new ArraySet<>();
1872        enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_NON_LAUNCHABLE_APPS
1873                | AppsQueryHelper.GET_APPS_WITH_INTERACT_ACROSS_USERS_PERM
1874                | AppsQueryHelper.GET_IMES, /* systemAppsOnly */ true, UserHandle.SYSTEM));
1875        ArraySet<String> wlApps = SystemConfig.getInstance().getSystemUserWhitelistedApps();
1876        enableApps.addAll(wlApps);
1877        enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_REQUIRED_FOR_SYSTEM_USER,
1878                /* systemAppsOnly */ false, UserHandle.SYSTEM));
1879        ArraySet<String> blApps = SystemConfig.getInstance().getSystemUserBlacklistedApps();
1880        enableApps.removeAll(blApps);
1881        Log.i(TAG, "Applications installed for system user: " + enableApps);
1882        List<String> allAps = queryHelper.queryApps(0, /* systemAppsOnly */ false,
1883                UserHandle.SYSTEM);
1884        final int allAppsSize = allAps.size();
1885        synchronized (mPackages) {
1886            for (int i = 0; i < allAppsSize; i++) {
1887                String pName = allAps.get(i);
1888                PackageSetting pkgSetting = mSettings.mPackages.get(pName);
1889                // Should not happen, but we shouldn't be failing if it does
1890                if (pkgSetting == null) {
1891                    continue;
1892                }
1893                boolean install = enableApps.contains(pName);
1894                if (pkgSetting.getInstalled(UserHandle.USER_SYSTEM) != install) {
1895                    Log.i(TAG, (install ? "Installing " : "Uninstalling ") + pName
1896                            + " for system user");
1897                    pkgSetting.setInstalled(install, UserHandle.USER_SYSTEM);
1898                }
1899            }
1900        }
1901    }
1902
1903    private static void getDefaultDisplayMetrics(Context context, DisplayMetrics metrics) {
1904        DisplayManager displayManager = (DisplayManager) context.getSystemService(
1905                Context.DISPLAY_SERVICE);
1906        displayManager.getDisplay(Display.DEFAULT_DISPLAY).getMetrics(metrics);
1907    }
1908
1909    public PackageManagerService(Context context, Installer installer,
1910            boolean factoryTest, boolean onlyCore) {
1911        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START,
1912                SystemClock.uptimeMillis());
1913
1914        if (mSdkVersion <= 0) {
1915            Slog.w(TAG, "**** ro.build.version.sdk not set!");
1916        }
1917
1918        mContext = context;
1919        mFactoryTest = factoryTest;
1920        mOnlyCore = onlyCore;
1921        mMetrics = new DisplayMetrics();
1922        mSettings = new Settings(mPackages);
1923        mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID,
1924                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
1925        mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID,
1926                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
1927        mSettings.addSharedUserLPw("android.uid.log", LOG_UID,
1928                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
1929        mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID,
1930                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
1931        mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID,
1932                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
1933        mSettings.addSharedUserLPw("android.uid.shell", SHELL_UID,
1934                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
1935
1936        String separateProcesses = SystemProperties.get("debug.separate_processes");
1937        if (separateProcesses != null && separateProcesses.length() > 0) {
1938            if ("*".equals(separateProcesses)) {
1939                mDefParseFlags = PackageParser.PARSE_IGNORE_PROCESSES;
1940                mSeparateProcesses = null;
1941                Slog.w(TAG, "Running with debug.separate_processes: * (ALL)");
1942            } else {
1943                mDefParseFlags = 0;
1944                mSeparateProcesses = separateProcesses.split(",");
1945                Slog.w(TAG, "Running with debug.separate_processes: "
1946                        + separateProcesses);
1947            }
1948        } else {
1949            mDefParseFlags = 0;
1950            mSeparateProcesses = null;
1951        }
1952
1953        mInstaller = installer;
1954        mPackageDexOptimizer = new PackageDexOptimizer(this);
1955        mMoveCallbacks = new MoveCallbacks(FgThread.get().getLooper());
1956
1957        mOnPermissionChangeListeners = new OnPermissionChangeListeners(
1958                FgThread.get().getLooper());
1959
1960        getDefaultDisplayMetrics(context, mMetrics);
1961
1962        SystemConfig systemConfig = SystemConfig.getInstance();
1963        mGlobalGids = systemConfig.getGlobalGids();
1964        mSystemPermissions = systemConfig.getSystemPermissions();
1965        mAvailableFeatures = systemConfig.getAvailableFeatures();
1966
1967        synchronized (mInstallLock) {
1968        // writer
1969        synchronized (mPackages) {
1970            mHandlerThread = new ServiceThread(TAG,
1971                    Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
1972            mHandlerThread.start();
1973            mHandler = new PackageHandler(mHandlerThread.getLooper());
1974            Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT);
1975
1976            File dataDir = Environment.getDataDirectory();
1977            mAppInstallDir = new File(dataDir, "app");
1978            mAppLib32InstallDir = new File(dataDir, "app-lib");
1979            mEphemeralInstallDir = new File(dataDir, "app-ephemeral");
1980            mAsecInternalPath = new File(dataDir, "app-asec").getPath();
1981            mDrmAppPrivateInstallDir = new File(dataDir, "app-private");
1982
1983            sUserManager = new UserManagerService(context, this, mPackages);
1984
1985            // Propagate permission configuration in to package manager.
1986            ArrayMap<String, SystemConfig.PermissionEntry> permConfig
1987                    = systemConfig.getPermissions();
1988            for (int i=0; i<permConfig.size(); i++) {
1989                SystemConfig.PermissionEntry perm = permConfig.valueAt(i);
1990                BasePermission bp = mSettings.mPermissions.get(perm.name);
1991                if (bp == null) {
1992                    bp = new BasePermission(perm.name, "android", BasePermission.TYPE_BUILTIN);
1993                    mSettings.mPermissions.put(perm.name, bp);
1994                }
1995                if (perm.gids != null) {
1996                    bp.setGids(perm.gids, perm.perUser);
1997                }
1998            }
1999
2000            ArrayMap<String, String> libConfig = systemConfig.getSharedLibraries();
2001            for (int i=0; i<libConfig.size(); i++) {
2002                mSharedLibraries.put(libConfig.keyAt(i),
2003                        new SharedLibraryEntry(libConfig.valueAt(i), null));
2004            }
2005
2006            mFoundPolicyFile = SELinuxMMAC.readInstallPolicy();
2007
2008            mRestoredSettings = mSettings.readLPw(sUserManager.getUsers(false));
2009
2010            String customResolverActivity = Resources.getSystem().getString(
2011                    R.string.config_customResolverActivity);
2012            if (TextUtils.isEmpty(customResolverActivity)) {
2013                customResolverActivity = null;
2014            } else {
2015                mCustomResolverComponentName = ComponentName.unflattenFromString(
2016                        customResolverActivity);
2017            }
2018
2019            long startTime = SystemClock.uptimeMillis();
2020
2021            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START,
2022                    startTime);
2023
2024            // Set flag to monitor and not change apk file paths when
2025            // scanning install directories.
2026            final int scanFlags = SCAN_NO_PATHS | SCAN_DEFER_DEX | SCAN_BOOTING | SCAN_INITIAL;
2027
2028            final String bootClassPath = System.getenv("BOOTCLASSPATH");
2029            final String systemServerClassPath = System.getenv("SYSTEMSERVERCLASSPATH");
2030
2031            if (bootClassPath == null) {
2032                Slog.w(TAG, "No BOOTCLASSPATH found!");
2033            }
2034
2035            if (systemServerClassPath == null) {
2036                Slog.w(TAG, "No SYSTEMSERVERCLASSPATH found!");
2037            }
2038
2039            final List<String> allInstructionSets = InstructionSets.getAllInstructionSets();
2040            final String[] dexCodeInstructionSets =
2041                    getDexCodeInstructionSets(
2042                            allInstructionSets.toArray(new String[allInstructionSets.size()]));
2043
2044            /**
2045             * Ensure all external libraries have had dexopt run on them.
2046             */
2047            if (mSharedLibraries.size() > 0) {
2048                // NOTE: For now, we're compiling these system "shared libraries"
2049                // (and framework jars) into all available architectures. It's possible
2050                // to compile them only when we come across an app that uses them (there's
2051                // already logic for that in scanPackageLI) but that adds some complexity.
2052                for (String dexCodeInstructionSet : dexCodeInstructionSets) {
2053                    for (SharedLibraryEntry libEntry : mSharedLibraries.values()) {
2054                        final String lib = libEntry.path;
2055                        if (lib == null) {
2056                            continue;
2057                        }
2058
2059                        try {
2060                            int dexoptNeeded = DexFile.getDexOptNeeded(lib, null, dexCodeInstructionSet, false);
2061                            if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) {
2062                                mInstaller.dexopt(lib, Process.SYSTEM_UID, dexCodeInstructionSet,
2063                                        dexoptNeeded, DEXOPT_PUBLIC /*dexFlags*/);
2064                            }
2065                        } catch (FileNotFoundException e) {
2066                            Slog.w(TAG, "Library not found: " + lib);
2067                        } catch (IOException e) {
2068                            Slog.w(TAG, "Cannot dexopt " + lib + "; is it an APK or JAR? "
2069                                    + e.getMessage());
2070                        }
2071                    }
2072                }
2073            }
2074
2075            File frameworkDir = new File(Environment.getRootDirectory(), "framework");
2076
2077            final VersionInfo ver = mSettings.getInternalVersion();
2078            mIsUpgrade = !Build.FINGERPRINT.equals(ver.fingerprint);
2079            // when upgrading from pre-M, promote system app permissions from install to runtime
2080            mPromoteSystemApps =
2081                    mIsUpgrade && ver.sdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1;
2082
2083            // save off the names of pre-existing system packages prior to scanning; we don't
2084            // want to automatically grant runtime permissions for new system apps
2085            if (mPromoteSystemApps) {
2086                Iterator<PackageSetting> pkgSettingIter = mSettings.mPackages.values().iterator();
2087                while (pkgSettingIter.hasNext()) {
2088                    PackageSetting ps = pkgSettingIter.next();
2089                    if (isSystemApp(ps)) {
2090                        mExistingSystemPackages.add(ps.name);
2091                    }
2092                }
2093            }
2094
2095            // Collect vendor overlay packages.
2096            // (Do this before scanning any apps.)
2097            // For security and version matching reason, only consider
2098            // overlay packages if they reside in VENDOR_OVERLAY_DIR.
2099            File vendorOverlayDir = new File(VENDOR_OVERLAY_DIR);
2100            scanDirTracedLI(vendorOverlayDir, PackageParser.PARSE_IS_SYSTEM
2101                    | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags | SCAN_TRUSTED_OVERLAY, 0);
2102
2103            // Find base frameworks (resource packages without code).
2104            scanDirTracedLI(frameworkDir, PackageParser.PARSE_IS_SYSTEM
2105                    | PackageParser.PARSE_IS_SYSTEM_DIR
2106                    | PackageParser.PARSE_IS_PRIVILEGED,
2107                    scanFlags | SCAN_NO_DEX, 0);
2108
2109            // Collected privileged system packages.
2110            final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app");
2111            scanDirTracedLI(privilegedAppDir, PackageParser.PARSE_IS_SYSTEM
2112                    | PackageParser.PARSE_IS_SYSTEM_DIR
2113                    | PackageParser.PARSE_IS_PRIVILEGED, scanFlags, 0);
2114
2115            // Collect ordinary system packages.
2116            final File systemAppDir = new File(Environment.getRootDirectory(), "app");
2117            scanDirTracedLI(systemAppDir, PackageParser.PARSE_IS_SYSTEM
2118                    | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
2119
2120            // Collect all vendor packages.
2121            File vendorAppDir = new File("/vendor/app");
2122            try {
2123                vendorAppDir = vendorAppDir.getCanonicalFile();
2124            } catch (IOException e) {
2125                // failed to look up canonical path, continue with original one
2126            }
2127            scanDirTracedLI(vendorAppDir, PackageParser.PARSE_IS_SYSTEM
2128                    | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
2129
2130            // Collect all OEM packages.
2131            final File oemAppDir = new File(Environment.getOemDirectory(), "app");
2132            scanDirTracedLI(oemAppDir, PackageParser.PARSE_IS_SYSTEM
2133                    | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
2134
2135            if (DEBUG_UPGRADE) Log.v(TAG, "Running installd update commands");
2136            mInstaller.moveFiles();
2137
2138            // Prune any system packages that no longer exist.
2139            final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<String>();
2140            if (!mOnlyCore) {
2141                Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
2142                while (psit.hasNext()) {
2143                    PackageSetting ps = psit.next();
2144
2145                    /*
2146                     * If this is not a system app, it can't be a
2147                     * disable system app.
2148                     */
2149                    if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
2150                        continue;
2151                    }
2152
2153                    /*
2154                     * If the package is scanned, it's not erased.
2155                     */
2156                    final PackageParser.Package scannedPkg = mPackages.get(ps.name);
2157                    if (scannedPkg != null) {
2158                        /*
2159                         * If the system app is both scanned and in the
2160                         * disabled packages list, then it must have been
2161                         * added via OTA. Remove it from the currently
2162                         * scanned package so the previously user-installed
2163                         * application can be scanned.
2164                         */
2165                        if (mSettings.isDisabledSystemPackageLPr(ps.name)) {
2166                            logCriticalInfo(Log.WARN, "Expecting better updated system app for "
2167                                    + ps.name + "; removing system app.  Last known codePath="
2168                                    + ps.codePathString + ", installStatus=" + ps.installStatus
2169                                    + ", versionCode=" + ps.versionCode + "; scanned versionCode="
2170                                    + scannedPkg.mVersionCode);
2171                            removePackageLI(ps, true);
2172                            mExpectingBetter.put(ps.name, ps.codePath);
2173                        }
2174
2175                        continue;
2176                    }
2177
2178                    if (!mSettings.isDisabledSystemPackageLPr(ps.name)) {
2179                        psit.remove();
2180                        logCriticalInfo(Log.WARN, "System package " + ps.name
2181                                + " no longer exists; wiping its data");
2182                        removeDataDirsLI(null, ps.name);
2183                    } else {
2184                        final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(ps.name);
2185                        if (disabledPs.codePath == null || !disabledPs.codePath.exists()) {
2186                            possiblyDeletedUpdatedSystemApps.add(ps.name);
2187                        }
2188                    }
2189                }
2190            }
2191
2192            //look for any incomplete package installations
2193            ArrayList<PackageSetting> deletePkgsList = mSettings.getListOfIncompleteInstallPackagesLPr();
2194            //clean up list
2195            for(int i = 0; i < deletePkgsList.size(); i++) {
2196                //clean up here
2197                cleanupInstallFailedPackage(deletePkgsList.get(i));
2198            }
2199            //delete tmp files
2200            deleteTempPackageFiles();
2201
2202            // Remove any shared userIDs that have no associated packages
2203            mSettings.pruneSharedUsersLPw();
2204
2205            if (!mOnlyCore) {
2206                EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,
2207                        SystemClock.uptimeMillis());
2208                scanDirTracedLI(mAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0);
2209
2210                scanDirTracedLI(mDrmAppPrivateInstallDir, PackageParser.PARSE_FORWARD_LOCK,
2211                        scanFlags | SCAN_REQUIRE_KNOWN, 0);
2212
2213                scanDirLI(mEphemeralInstallDir, PackageParser.PARSE_IS_EPHEMERAL,
2214                        scanFlags | SCAN_REQUIRE_KNOWN, 0);
2215
2216                /**
2217                 * Remove disable package settings for any updated system
2218                 * apps that were removed via an OTA. If they're not a
2219                 * previously-updated app, remove them completely.
2220                 * Otherwise, just revoke their system-level permissions.
2221                 */
2222                for (String deletedAppName : possiblyDeletedUpdatedSystemApps) {
2223                    PackageParser.Package deletedPkg = mPackages.get(deletedAppName);
2224                    mSettings.removeDisabledSystemPackageLPw(deletedAppName);
2225
2226                    String msg;
2227                    if (deletedPkg == null) {
2228                        msg = "Updated system package " + deletedAppName
2229                                + " no longer exists; wiping its data";
2230                        removeDataDirsLI(null, deletedAppName);
2231                    } else {
2232                        msg = "Updated system app + " + deletedAppName
2233                                + " no longer present; removing system privileges for "
2234                                + deletedAppName;
2235
2236                        deletedPkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM;
2237
2238                        PackageSetting deletedPs = mSettings.mPackages.get(deletedAppName);
2239                        deletedPs.pkgFlags &= ~ApplicationInfo.FLAG_SYSTEM;
2240                    }
2241                    logCriticalInfo(Log.WARN, msg);
2242                }
2243
2244                /**
2245                 * Make sure all system apps that we expected to appear on
2246                 * the userdata partition actually showed up. If they never
2247                 * appeared, crawl back and revive the system version.
2248                 */
2249                for (int i = 0; i < mExpectingBetter.size(); i++) {
2250                    final String packageName = mExpectingBetter.keyAt(i);
2251                    if (!mPackages.containsKey(packageName)) {
2252                        final File scanFile = mExpectingBetter.valueAt(i);
2253
2254                        logCriticalInfo(Log.WARN, "Expected better " + packageName
2255                                + " but never showed up; reverting to system");
2256
2257                        final int reparseFlags;
2258                        if (FileUtils.contains(privilegedAppDir, scanFile)) {
2259                            reparseFlags = PackageParser.PARSE_IS_SYSTEM
2260                                    | PackageParser.PARSE_IS_SYSTEM_DIR
2261                                    | PackageParser.PARSE_IS_PRIVILEGED;
2262                        } else if (FileUtils.contains(systemAppDir, scanFile)) {
2263                            reparseFlags = PackageParser.PARSE_IS_SYSTEM
2264                                    | PackageParser.PARSE_IS_SYSTEM_DIR;
2265                        } else if (FileUtils.contains(vendorAppDir, scanFile)) {
2266                            reparseFlags = PackageParser.PARSE_IS_SYSTEM
2267                                    | PackageParser.PARSE_IS_SYSTEM_DIR;
2268                        } else if (FileUtils.contains(oemAppDir, scanFile)) {
2269                            reparseFlags = PackageParser.PARSE_IS_SYSTEM
2270                                    | PackageParser.PARSE_IS_SYSTEM_DIR;
2271                        } else {
2272                            Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile);
2273                            continue;
2274                        }
2275
2276                        mSettings.enableSystemPackageLPw(packageName);
2277
2278                        try {
2279                            scanPackageTracedLI(scanFile, reparseFlags, scanFlags, 0, null);
2280                        } catch (PackageManagerException e) {
2281                            Slog.e(TAG, "Failed to parse original system package: "
2282                                    + e.getMessage());
2283                        }
2284                    }
2285                }
2286            }
2287            mExpectingBetter.clear();
2288
2289            // Now that we know all of the shared libraries, update all clients to have
2290            // the correct library paths.
2291            updateAllSharedLibrariesLPw();
2292
2293            for (SharedUserSetting setting : mSettings.getAllSharedUsersLPw()) {
2294                // NOTE: We ignore potential failures here during a system scan (like
2295                // the rest of the commands above) because there's precious little we
2296                // can do about it. A settings error is reported, though.
2297                adjustCpuAbisForSharedUserLPw(setting.packages, null /* scanned package */,
2298                        false /* boot complete */);
2299            }
2300
2301            // Now that we know all the packages we are keeping,
2302            // read and update their last usage times.
2303            mPackageUsage.readLP();
2304
2305            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END,
2306                    SystemClock.uptimeMillis());
2307            Slog.i(TAG, "Time to scan packages: "
2308                    + ((SystemClock.uptimeMillis()-startTime)/1000f)
2309                    + " seconds");
2310
2311            // If the platform SDK has changed since the last time we booted,
2312            // we need to re-grant app permission to catch any new ones that
2313            // appear.  This is really a hack, and means that apps can in some
2314            // cases get permissions that the user didn't initially explicitly
2315            // allow...  it would be nice to have some better way to handle
2316            // this situation.
2317            int updateFlags = UPDATE_PERMISSIONS_ALL;
2318            if (ver.sdkVersion != mSdkVersion) {
2319                Slog.i(TAG, "Platform changed from " + ver.sdkVersion + " to "
2320                        + mSdkVersion + "; regranting permissions for internal storage");
2321                updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
2322            }
2323            updatePermissionsLPw(null, null, StorageManager.UUID_PRIVATE_INTERNAL, updateFlags);
2324            ver.sdkVersion = mSdkVersion;
2325
2326            // If this is the first boot or an update from pre-M, and it is a normal
2327            // boot, then we need to initialize the default preferred apps across
2328            // all defined users.
2329            if (!onlyCore && (mPromoteSystemApps || !mRestoredSettings)) {
2330                for (UserInfo user : sUserManager.getUsers(true)) {
2331                    mSettings.applyDefaultPreferredAppsLPw(this, user.id);
2332                    applyFactoryDefaultBrowserLPw(user.id);
2333                    primeDomainVerificationsLPw(user.id);
2334                }
2335            }
2336
2337            // If this is first boot after an OTA, and a normal boot, then
2338            // we need to clear code cache directories.
2339            if (mIsUpgrade && !onlyCore) {
2340                Slog.i(TAG, "Build fingerprint changed; clearing code caches");
2341                for (int i = 0; i < mSettings.mPackages.size(); i++) {
2342                    final PackageSetting ps = mSettings.mPackages.valueAt(i);
2343                    if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, ps.volumeUuid)) {
2344                        deleteCodeCacheDirsLI(ps.volumeUuid, ps.name);
2345                    }
2346                }
2347                ver.fingerprint = Build.FINGERPRINT;
2348            }
2349
2350            checkDefaultBrowser();
2351
2352            // clear only after permissions and other defaults have been updated
2353            mExistingSystemPackages.clear();
2354            mPromoteSystemApps = false;
2355
2356            // All the changes are done during package scanning.
2357            ver.databaseVersion = Settings.CURRENT_DATABASE_VERSION;
2358
2359            // can downgrade to reader
2360            mSettings.writeLPr();
2361
2362            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY,
2363                    SystemClock.uptimeMillis());
2364
2365            if (!mOnlyCore) {
2366                mRequiredVerifierPackage = getRequiredButNotReallyRequiredVerifierLPr();
2367                mRequiredInstallerPackage = getRequiredInstallerLPr();
2368                mIntentFilterVerifierComponent = getIntentFilterVerifierComponentNameLPr();
2369                mIntentFilterVerifier = new IntentVerifierProxy(mContext,
2370                        mIntentFilterVerifierComponent);
2371            } else {
2372                mRequiredVerifierPackage = null;
2373                mRequiredInstallerPackage = null;
2374                mIntentFilterVerifierComponent = null;
2375                mIntentFilterVerifier = null;
2376            }
2377
2378            mInstallerService = new PackageInstallerService(context, this);
2379
2380            final ComponentName ephemeralResolverComponent = getEphemeralResolverLPr();
2381            final ComponentName ephemeralInstallerComponent = getEphemeralInstallerLPr();
2382            // both the installer and resolver must be present to enable ephemeral
2383            if (ephemeralInstallerComponent != null && ephemeralResolverComponent != null) {
2384                if (DEBUG_EPHEMERAL) {
2385                    Slog.i(TAG, "Ephemeral activated; resolver: " + ephemeralResolverComponent
2386                            + " installer:" + ephemeralInstallerComponent);
2387                }
2388                mEphemeralResolverComponent = ephemeralResolverComponent;
2389                mEphemeralInstallerComponent = ephemeralInstallerComponent;
2390                setUpEphemeralInstallerActivityLP(mEphemeralInstallerComponent);
2391                mEphemeralResolverConnection =
2392                        new EphemeralResolverConnection(mContext, mEphemeralResolverComponent);
2393            } else {
2394                if (DEBUG_EPHEMERAL) {
2395                    final String missingComponent =
2396                            (ephemeralResolverComponent == null)
2397                            ? (ephemeralInstallerComponent == null)
2398                                    ? "resolver and installer"
2399                                    : "resolver"
2400                            : "installer";
2401                    Slog.i(TAG, "Ephemeral deactivated; missing " + missingComponent);
2402                }
2403                mEphemeralResolverComponent = null;
2404                mEphemeralInstallerComponent = null;
2405                mEphemeralResolverConnection = null;
2406            }
2407
2408            mEphemeralApplicationRegistry = new EphemeralApplicationRegistry(this);
2409        } // synchronized (mPackages)
2410        } // synchronized (mInstallLock)
2411
2412        // Now after opening every single application zip, make sure they
2413        // are all flushed.  Not really needed, but keeps things nice and
2414        // tidy.
2415        Runtime.getRuntime().gc();
2416
2417        // The initial scanning above does many calls into installd while
2418        // holding the mPackages lock, but we're mostly interested in yelling
2419        // once we have a booted system.
2420        mInstaller.setWarnIfHeld(mPackages);
2421
2422        // Expose private service for system components to use.
2423        LocalServices.addService(PackageManagerInternal.class, new PackageManagerInternalImpl());
2424    }
2425
2426    @Override
2427    public boolean isFirstBoot() {
2428        return !mRestoredSettings;
2429    }
2430
2431    @Override
2432    public boolean isOnlyCoreApps() {
2433        return mOnlyCore;
2434    }
2435
2436    @Override
2437    public boolean isUpgrade() {
2438        return mIsUpgrade;
2439    }
2440
2441    private @Nullable String getRequiredButNotReallyRequiredVerifierLPr() {
2442        final Intent intent = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
2443
2444        final List<ResolveInfo> matches = queryIntentReceivers(intent, PACKAGE_MIME_TYPE,
2445                MATCH_SYSTEM_ONLY | MATCH_ENCRYPTION_AWARE_AND_UNAWARE, UserHandle.USER_SYSTEM);
2446        if (matches.size() == 1) {
2447            return matches.get(0).getComponentInfo().packageName;
2448        } else {
2449            Log.e(TAG, "There should probably be exactly one verifier; found " + matches);
2450            return null;
2451        }
2452    }
2453
2454    private @NonNull String getRequiredInstallerLPr() {
2455        final Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
2456        intent.addCategory(Intent.CATEGORY_DEFAULT);
2457        intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE);
2458
2459        final List<ResolveInfo> matches = queryIntentActivities(intent, PACKAGE_MIME_TYPE,
2460                MATCH_SYSTEM_ONLY | MATCH_ENCRYPTION_AWARE_AND_UNAWARE, UserHandle.USER_SYSTEM);
2461        if (matches.size() == 1) {
2462            return matches.get(0).getComponentInfo().packageName;
2463        } else {
2464            throw new RuntimeException("There must be exactly one installer; found " + matches);
2465        }
2466    }
2467
2468    private @NonNull ComponentName getIntentFilterVerifierComponentNameLPr() {
2469        final Intent intent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION);
2470
2471        final List<ResolveInfo> matches = queryIntentReceivers(intent, PACKAGE_MIME_TYPE,
2472                MATCH_SYSTEM_ONLY | MATCH_ENCRYPTION_AWARE_AND_UNAWARE, UserHandle.USER_SYSTEM);
2473        ResolveInfo best = null;
2474        final int N = matches.size();
2475        for (int i = 0; i < N; i++) {
2476            final ResolveInfo cur = matches.get(i);
2477            final String packageName = cur.getComponentInfo().packageName;
2478            if (checkPermission(android.Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT,
2479                    packageName, UserHandle.USER_SYSTEM) != PackageManager.PERMISSION_GRANTED) {
2480                continue;
2481            }
2482
2483            if (best == null || cur.priority > best.priority) {
2484                best = cur;
2485            }
2486        }
2487
2488        if (best != null) {
2489            return best.getComponentInfo().getComponentName();
2490        } else {
2491            throw new RuntimeException("There must be at least one intent filter verifier");
2492        }
2493    }
2494
2495    private @Nullable ComponentName getEphemeralResolverLPr() {
2496        final String[] packageArray =
2497                mContext.getResources().getStringArray(R.array.config_ephemeralResolverPackage);
2498        if (packageArray.length == 0) {
2499            if (DEBUG_EPHEMERAL) {
2500                Slog.d(TAG, "Ephemeral resolver NOT found; empty package list");
2501            }
2502            return null;
2503        }
2504
2505        final Intent resolverIntent = new Intent(Intent.ACTION_RESOLVE_EPHEMERAL_PACKAGE);
2506        final List<ResolveInfo> resolvers = queryIntentServices(resolverIntent, null,
2507                MATCH_SYSTEM_ONLY | MATCH_ENCRYPTION_AWARE_AND_UNAWARE, UserHandle.USER_SYSTEM);
2508
2509        final int N = resolvers.size();
2510        if (N == 0) {
2511            if (DEBUG_EPHEMERAL) {
2512                Slog.d(TAG, "Ephemeral resolver NOT found; no matching intent filters");
2513            }
2514            return null;
2515        }
2516
2517        final Set<String> possiblePackages = new ArraySet<>(Arrays.asList(packageArray));
2518        for (int i = 0; i < N; i++) {
2519            final ResolveInfo info = resolvers.get(i);
2520
2521            if (info.serviceInfo == null) {
2522                continue;
2523            }
2524
2525            final String packageName = info.serviceInfo.packageName;
2526            if (!possiblePackages.contains(packageName)) {
2527                if (DEBUG_EPHEMERAL) {
2528                    Slog.d(TAG, "Ephemeral resolver not in allowed package list;"
2529                            + " pkg: " + packageName + ", info:" + info);
2530                }
2531                continue;
2532            }
2533
2534            if (DEBUG_EPHEMERAL) {
2535                Slog.v(TAG, "Ephemeral resolver found;"
2536                        + " pkg: " + packageName + ", info:" + info);
2537            }
2538            return new ComponentName(packageName, info.serviceInfo.name);
2539        }
2540        if (DEBUG_EPHEMERAL) {
2541            Slog.v(TAG, "Ephemeral resolver NOT found");
2542        }
2543        return null;
2544    }
2545
2546    private @Nullable ComponentName getEphemeralInstallerLPr() {
2547        final Intent intent = new Intent(Intent.ACTION_INSTALL_EPHEMERAL_PACKAGE);
2548        intent.addCategory(Intent.CATEGORY_DEFAULT);
2549        intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE);
2550
2551        final List<ResolveInfo> matches = queryIntentActivities(intent, PACKAGE_MIME_TYPE,
2552                MATCH_SYSTEM_ONLY | MATCH_ENCRYPTION_AWARE_AND_UNAWARE, UserHandle.USER_SYSTEM);
2553        if (matches.size() == 0) {
2554            return null;
2555        } else if (matches.size() == 1) {
2556            return matches.get(0).getComponentInfo().getComponentName();
2557        } else {
2558            throw new RuntimeException(
2559                    "There must be at most one ephemeral installer; found " + matches);
2560        }
2561    }
2562
2563    private void primeDomainVerificationsLPw(int userId) {
2564        if (DEBUG_DOMAIN_VERIFICATION) {
2565            Slog.d(TAG, "Priming domain verifications in user " + userId);
2566        }
2567
2568        SystemConfig systemConfig = SystemConfig.getInstance();
2569        ArraySet<String> packages = systemConfig.getLinkedApps();
2570        ArraySet<String> domains = new ArraySet<String>();
2571
2572        for (String packageName : packages) {
2573            PackageParser.Package pkg = mPackages.get(packageName);
2574            if (pkg != null) {
2575                if (!pkg.isSystemApp()) {
2576                    Slog.w(TAG, "Non-system app '" + packageName + "' in sysconfig <app-link>");
2577                    continue;
2578                }
2579
2580                domains.clear();
2581                for (PackageParser.Activity a : pkg.activities) {
2582                    for (ActivityIntentInfo filter : a.intents) {
2583                        if (hasValidDomains(filter)) {
2584                            domains.addAll(filter.getHostsList());
2585                        }
2586                    }
2587                }
2588
2589                if (domains.size() > 0) {
2590                    if (DEBUG_DOMAIN_VERIFICATION) {
2591                        Slog.v(TAG, "      + " + packageName);
2592                    }
2593                    // 'Undefined' in the global IntentFilterVerificationInfo, i.e. the usual
2594                    // state w.r.t. the formal app-linkage "no verification attempted" state;
2595                    // and then 'always' in the per-user state actually used for intent resolution.
2596                    final IntentFilterVerificationInfo ivi;
2597                    ivi = mSettings.createIntentFilterVerificationIfNeededLPw(packageName,
2598                            new ArrayList<String>(domains));
2599                    ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED);
2600                    mSettings.updateIntentFilterVerificationStatusLPw(packageName,
2601                            INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS, userId);
2602                } else {
2603                    Slog.w(TAG, "Sysconfig <app-link> package '" + packageName
2604                            + "' does not handle web links");
2605                }
2606            } else {
2607                Slog.w(TAG, "Unknown package " + packageName + " in sysconfig <app-link>");
2608            }
2609        }
2610
2611        scheduleWritePackageRestrictionsLocked(userId);
2612        scheduleWriteSettingsLocked();
2613    }
2614
2615    private void applyFactoryDefaultBrowserLPw(int userId) {
2616        // The default browser app's package name is stored in a string resource,
2617        // with a product-specific overlay used for vendor customization.
2618        String browserPkg = mContext.getResources().getString(
2619                com.android.internal.R.string.default_browser);
2620        if (!TextUtils.isEmpty(browserPkg)) {
2621            // non-empty string => required to be a known package
2622            PackageSetting ps = mSettings.mPackages.get(browserPkg);
2623            if (ps == null) {
2624                Slog.e(TAG, "Product default browser app does not exist: " + browserPkg);
2625                browserPkg = null;
2626            } else {
2627                mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId);
2628            }
2629        }
2630
2631        // Nothing valid explicitly set? Make the factory-installed browser the explicit
2632        // default.  If there's more than one, just leave everything alone.
2633        if (browserPkg == null) {
2634            calculateDefaultBrowserLPw(userId);
2635        }
2636    }
2637
2638    private void calculateDefaultBrowserLPw(int userId) {
2639        List<String> allBrowsers = resolveAllBrowserApps(userId);
2640        final String browserPkg = (allBrowsers.size() == 1) ? allBrowsers.get(0) : null;
2641        mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId);
2642    }
2643
2644    private List<String> resolveAllBrowserApps(int userId) {
2645        // Resolve the canonical browser intent and check that the handleAllWebDataURI boolean is set
2646        List<ResolveInfo> list = queryIntentActivities(sBrowserIntent, null,
2647                PackageManager.MATCH_ALL, userId);
2648
2649        final int count = list.size();
2650        List<String> result = new ArrayList<String>(count);
2651        for (int i=0; i<count; i++) {
2652            ResolveInfo info = list.get(i);
2653            if (info.activityInfo == null
2654                    || !info.handleAllWebDataURI
2655                    || (info.activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0
2656                    || result.contains(info.activityInfo.packageName)) {
2657                continue;
2658            }
2659            result.add(info.activityInfo.packageName);
2660        }
2661
2662        return result;
2663    }
2664
2665    private boolean packageIsBrowser(String packageName, int userId) {
2666        List<ResolveInfo> list = queryIntentActivities(sBrowserIntent, null,
2667                PackageManager.MATCH_ALL, userId);
2668        final int N = list.size();
2669        for (int i = 0; i < N; i++) {
2670            ResolveInfo info = list.get(i);
2671            if (packageName.equals(info.activityInfo.packageName)) {
2672                return true;
2673            }
2674        }
2675        return false;
2676    }
2677
2678    private void checkDefaultBrowser() {
2679        final int myUserId = UserHandle.myUserId();
2680        final String packageName = getDefaultBrowserPackageName(myUserId);
2681        if (packageName != null) {
2682            PackageInfo info = getPackageInfo(packageName, 0, myUserId);
2683            if (info == null) {
2684                Slog.w(TAG, "Default browser no longer installed: " + packageName);
2685                synchronized (mPackages) {
2686                    applyFactoryDefaultBrowserLPw(myUserId);    // leaves ambiguous when > 1
2687                }
2688            }
2689        }
2690    }
2691
2692    @Override
2693    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2694            throws RemoteException {
2695        try {
2696            return super.onTransact(code, data, reply, flags);
2697        } catch (RuntimeException e) {
2698            if (!(e instanceof SecurityException) && !(e instanceof IllegalArgumentException)) {
2699                Slog.wtf(TAG, "Package Manager Crash", e);
2700            }
2701            throw e;
2702        }
2703    }
2704
2705    void cleanupInstallFailedPackage(PackageSetting ps) {
2706        logCriticalInfo(Log.WARN, "Cleaning up incompletely installed app: " + ps.name);
2707
2708        removeDataDirsLI(ps.volumeUuid, ps.name);
2709        if (ps.codePath != null) {
2710            if (ps.codePath.isDirectory()) {
2711                mInstaller.rmPackageDir(ps.codePath.getAbsolutePath());
2712            } else {
2713                ps.codePath.delete();
2714            }
2715        }
2716        if (ps.resourcePath != null && !ps.resourcePath.equals(ps.codePath)) {
2717            if (ps.resourcePath.isDirectory()) {
2718                FileUtils.deleteContents(ps.resourcePath);
2719            }
2720            ps.resourcePath.delete();
2721        }
2722        mSettings.removePackageLPw(ps.name);
2723    }
2724
2725    static int[] appendInts(int[] cur, int[] add) {
2726        if (add == null) return cur;
2727        if (cur == null) return add;
2728        final int N = add.length;
2729        for (int i=0; i<N; i++) {
2730            cur = appendInt(cur, add[i]);
2731        }
2732        return cur;
2733    }
2734
2735    PackageInfo generatePackageInfo(PackageParser.Package p, int flags, int userId) {
2736        if (!sUserManager.exists(userId)) return null;
2737        final PackageSetting ps = (PackageSetting) p.mExtras;
2738        if (ps == null) {
2739            return null;
2740        }
2741
2742        final PermissionsState permissionsState = ps.getPermissionsState();
2743
2744        final int[] gids = permissionsState.computeGids(userId);
2745        final Set<String> permissions = permissionsState.getPermissions(userId);
2746        final PackageUserState state = ps.readUserState(userId);
2747
2748        return PackageParser.generatePackageInfo(p, gids, flags,
2749                ps.firstInstallTime, ps.lastUpdateTime, permissions, state, userId);
2750    }
2751
2752    @Override
2753    public void checkPackageStartable(String packageName, int userId) {
2754        final boolean userKeyUnlocked = isUserKeyUnlocked(userId);
2755
2756        synchronized (mPackages) {
2757            final PackageSetting ps = mSettings.mPackages.get(packageName);
2758            if (ps == null) {
2759                throw new SecurityException("Package " + packageName + " was not found!");
2760            }
2761
2762            if (ps.frozen) {
2763                throw new SecurityException("Package " + packageName + " is currently frozen!");
2764            }
2765
2766            if (!userKeyUnlocked && !(ps.pkg.applicationInfo.isEncryptionAware()
2767                    || ps.pkg.applicationInfo.isPartiallyEncryptionAware())) {
2768                throw new SecurityException("Package " + packageName + " is not encryption aware!");
2769            }
2770        }
2771    }
2772
2773    @Override
2774    public boolean isPackageAvailable(String packageName, int userId) {
2775        if (!sUserManager.exists(userId)) return false;
2776        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "is package available");
2777        synchronized (mPackages) {
2778            PackageParser.Package p = mPackages.get(packageName);
2779            if (p != null) {
2780                final PackageSetting ps = (PackageSetting) p.mExtras;
2781                if (ps != null) {
2782                    final PackageUserState state = ps.readUserState(userId);
2783                    if (state != null) {
2784                        return PackageParser.isAvailable(state);
2785                    }
2786                }
2787            }
2788        }
2789        return false;
2790    }
2791
2792    @Override
2793    public PackageInfo getPackageInfo(String packageName, int flags, int userId) {
2794        if (!sUserManager.exists(userId)) return null;
2795        flags = updateFlagsForPackage(flags, userId, packageName);
2796        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get package info");
2797        // reader
2798        synchronized (mPackages) {
2799            PackageParser.Package p = mPackages.get(packageName);
2800            if (DEBUG_PACKAGE_INFO)
2801                Log.v(TAG, "getPackageInfo " + packageName + ": " + p);
2802            if (p != null) {
2803                return generatePackageInfo(p, flags, userId);
2804            }
2805            if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0) {
2806                return generatePackageInfoFromSettingsLPw(packageName, flags, userId);
2807            }
2808        }
2809        return null;
2810    }
2811
2812    @Override
2813    public String[] currentToCanonicalPackageNames(String[] names) {
2814        String[] out = new String[names.length];
2815        // reader
2816        synchronized (mPackages) {
2817            for (int i=names.length-1; i>=0; i--) {
2818                PackageSetting ps = mSettings.mPackages.get(names[i]);
2819                out[i] = ps != null && ps.realName != null ? ps.realName : names[i];
2820            }
2821        }
2822        return out;
2823    }
2824
2825    @Override
2826    public String[] canonicalToCurrentPackageNames(String[] names) {
2827        String[] out = new String[names.length];
2828        // reader
2829        synchronized (mPackages) {
2830            for (int i=names.length-1; i>=0; i--) {
2831                String cur = mSettings.mRenamedPackages.get(names[i]);
2832                out[i] = cur != null ? cur : names[i];
2833            }
2834        }
2835        return out;
2836    }
2837
2838    @Override
2839    public int getPackageUid(String packageName, int userId) {
2840        return getPackageUidEtc(packageName, 0, userId);
2841    }
2842
2843    @Override
2844    public int getPackageUidEtc(String packageName, int flags, int userId) {
2845        if (!sUserManager.exists(userId)) return -1;
2846        flags = updateFlagsForPackage(flags, userId, packageName);
2847        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get package uid");
2848
2849        // reader
2850        synchronized (mPackages) {
2851            final PackageParser.Package p = mPackages.get(packageName);
2852            if (p != null && p.isMatch(flags)) {
2853                return UserHandle.getUid(userId, p.applicationInfo.uid);
2854            }
2855            if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0) {
2856                final PackageSetting ps = mSettings.mPackages.get(packageName);
2857                if (ps != null && ps.isMatch(flags)) {
2858                    return UserHandle.getUid(userId, ps.appId);
2859                }
2860            }
2861        }
2862
2863        return -1;
2864    }
2865
2866    @Override
2867    public int[] getPackageGids(String packageName, int userId) {
2868        return getPackageGidsEtc(packageName, 0, userId);
2869    }
2870
2871    @Override
2872    public int[] getPackageGidsEtc(String packageName, int flags, int userId) {
2873        if (!sUserManager.exists(userId)) return null;
2874        flags = updateFlagsForPackage(flags, userId, packageName);
2875        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false,
2876                "getPackageGids");
2877
2878        // reader
2879        synchronized (mPackages) {
2880            final PackageParser.Package p = mPackages.get(packageName);
2881            if (p != null && p.isMatch(flags)) {
2882                PackageSetting ps = (PackageSetting) p.mExtras;
2883                return ps.getPermissionsState().computeGids(userId);
2884            }
2885            if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0) {
2886                final PackageSetting ps = mSettings.mPackages.get(packageName);
2887                if (ps != null && ps.isMatch(flags)) {
2888                    return ps.getPermissionsState().computeGids(userId);
2889                }
2890            }
2891        }
2892
2893        return null;
2894    }
2895
2896    static PermissionInfo generatePermissionInfo(BasePermission bp, int flags) {
2897        if (bp.perm != null) {
2898            return PackageParser.generatePermissionInfo(bp.perm, flags);
2899        }
2900        PermissionInfo pi = new PermissionInfo();
2901        pi.name = bp.name;
2902        pi.packageName = bp.sourcePackage;
2903        pi.nonLocalizedLabel = bp.name;
2904        pi.protectionLevel = bp.protectionLevel;
2905        return pi;
2906    }
2907
2908    @Override
2909    public PermissionInfo getPermissionInfo(String name, int flags) {
2910        // reader
2911        synchronized (mPackages) {
2912            final BasePermission p = mSettings.mPermissions.get(name);
2913            if (p != null) {
2914                return generatePermissionInfo(p, flags);
2915            }
2916            return null;
2917        }
2918    }
2919
2920    @Override
2921    public List<PermissionInfo> queryPermissionsByGroup(String group, int flags) {
2922        // reader
2923        synchronized (mPackages) {
2924            ArrayList<PermissionInfo> out = new ArrayList<PermissionInfo>(10);
2925            for (BasePermission p : mSettings.mPermissions.values()) {
2926                if (group == null) {
2927                    if (p.perm == null || p.perm.info.group == null) {
2928                        out.add(generatePermissionInfo(p, flags));
2929                    }
2930                } else {
2931                    if (p.perm != null && group.equals(p.perm.info.group)) {
2932                        out.add(PackageParser.generatePermissionInfo(p.perm, flags));
2933                    }
2934                }
2935            }
2936
2937            if (out.size() > 0) {
2938                return out;
2939            }
2940            return mPermissionGroups.containsKey(group) ? out : null;
2941        }
2942    }
2943
2944    @Override
2945    public PermissionGroupInfo getPermissionGroupInfo(String name, int flags) {
2946        // reader
2947        synchronized (mPackages) {
2948            return PackageParser.generatePermissionGroupInfo(
2949                    mPermissionGroups.get(name), flags);
2950        }
2951    }
2952
2953    @Override
2954    public List<PermissionGroupInfo> getAllPermissionGroups(int flags) {
2955        // reader
2956        synchronized (mPackages) {
2957            final int N = mPermissionGroups.size();
2958            ArrayList<PermissionGroupInfo> out
2959                    = new ArrayList<PermissionGroupInfo>(N);
2960            for (PackageParser.PermissionGroup pg : mPermissionGroups.values()) {
2961                out.add(PackageParser.generatePermissionGroupInfo(pg, flags));
2962            }
2963            return out;
2964        }
2965    }
2966
2967    private ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName, int flags,
2968            int userId) {
2969        if (!sUserManager.exists(userId)) return null;
2970        PackageSetting ps = mSettings.mPackages.get(packageName);
2971        if (ps != null) {
2972            if (ps.pkg == null) {
2973                PackageInfo pInfo = generatePackageInfoFromSettingsLPw(packageName,
2974                        flags, userId);
2975                if (pInfo != null) {
2976                    return pInfo.applicationInfo;
2977                }
2978                return null;
2979            }
2980            return PackageParser.generateApplicationInfo(ps.pkg, flags,
2981                    ps.readUserState(userId), userId);
2982        }
2983        return null;
2984    }
2985
2986    private PackageInfo generatePackageInfoFromSettingsLPw(String packageName, int flags,
2987            int userId) {
2988        if (!sUserManager.exists(userId)) return null;
2989        PackageSetting ps = mSettings.mPackages.get(packageName);
2990        if (ps != null) {
2991            PackageParser.Package pkg = ps.pkg;
2992            if (pkg == null) {
2993                if ((flags & MATCH_UNINSTALLED_PACKAGES) == 0) {
2994                    return null;
2995                }
2996                // Only data remains, so we aren't worried about code paths
2997                pkg = new PackageParser.Package(packageName);
2998                pkg.applicationInfo.packageName = packageName;
2999                pkg.applicationInfo.flags = ps.pkgFlags | ApplicationInfo.FLAG_IS_DATA_ONLY;
3000                pkg.applicationInfo.privateFlags = ps.pkgPrivateFlags;
3001                pkg.applicationInfo.uid = ps.appId;
3002                pkg.applicationInfo.initForUser(userId);
3003                pkg.applicationInfo.primaryCpuAbi = ps.primaryCpuAbiString;
3004                pkg.applicationInfo.secondaryCpuAbi = ps.secondaryCpuAbiString;
3005            }
3006            return generatePackageInfo(pkg, flags, userId);
3007        }
3008        return null;
3009    }
3010
3011    @Override
3012    public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) {
3013        if (!sUserManager.exists(userId)) return null;
3014        flags = updateFlagsForApplication(flags, userId, packageName);
3015        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get application info");
3016        // writer
3017        synchronized (mPackages) {
3018            PackageParser.Package p = mPackages.get(packageName);
3019            if (DEBUG_PACKAGE_INFO) Log.v(
3020                    TAG, "getApplicationInfo " + packageName
3021                    + ": " + p);
3022            if (p != null) {
3023                PackageSetting ps = mSettings.mPackages.get(packageName);
3024                if (ps == null) return null;
3025                // Note: isEnabledLP() does not apply here - always return info
3026                return PackageParser.generateApplicationInfo(
3027                        p, flags, ps.readUserState(userId), userId);
3028            }
3029            if ("android".equals(packageName)||"system".equals(packageName)) {
3030                return mAndroidApplication;
3031            }
3032            if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0) {
3033                return generateApplicationInfoFromSettingsLPw(packageName, flags, userId);
3034            }
3035        }
3036        return null;
3037    }
3038
3039    @Override
3040    public void freeStorageAndNotify(final String volumeUuid, final long freeStorageSize,
3041            final IPackageDataObserver observer) {
3042        mContext.enforceCallingOrSelfPermission(
3043                android.Manifest.permission.CLEAR_APP_CACHE, null);
3044        // Queue up an async operation since clearing cache may take a little while.
3045        mHandler.post(new Runnable() {
3046            public void run() {
3047                mHandler.removeCallbacks(this);
3048                int retCode = -1;
3049                synchronized (mInstallLock) {
3050                    retCode = mInstaller.freeCache(volumeUuid, freeStorageSize);
3051                    if (retCode < 0) {
3052                        Slog.w(TAG, "Couldn't clear application caches");
3053                    }
3054                }
3055                if (observer != null) {
3056                    try {
3057                        observer.onRemoveCompleted(null, (retCode >= 0));
3058                    } catch (RemoteException e) {
3059                        Slog.w(TAG, "RemoveException when invoking call back");
3060                    }
3061                }
3062            }
3063        });
3064    }
3065
3066    @Override
3067    public void freeStorage(final String volumeUuid, final long freeStorageSize,
3068            final IntentSender pi) {
3069        mContext.enforceCallingOrSelfPermission(
3070                android.Manifest.permission.CLEAR_APP_CACHE, null);
3071        // Queue up an async operation since clearing cache may take a little while.
3072        mHandler.post(new Runnable() {
3073            public void run() {
3074                mHandler.removeCallbacks(this);
3075                int retCode = -1;
3076                synchronized (mInstallLock) {
3077                    retCode = mInstaller.freeCache(volumeUuid, freeStorageSize);
3078                    if (retCode < 0) {
3079                        Slog.w(TAG, "Couldn't clear application caches");
3080                    }
3081                }
3082                if(pi != null) {
3083                    try {
3084                        // Callback via pending intent
3085                        int code = (retCode >= 0) ? 1 : 0;
3086                        pi.sendIntent(null, code, null,
3087                                null, null);
3088                    } catch (SendIntentException e1) {
3089                        Slog.i(TAG, "Failed to send pending intent");
3090                    }
3091                }
3092            }
3093        });
3094    }
3095
3096    void freeStorage(String volumeUuid, long freeStorageSize) throws IOException {
3097        synchronized (mInstallLock) {
3098            if (mInstaller.freeCache(volumeUuid, freeStorageSize) < 0) {
3099                throw new IOException("Failed to free enough space");
3100            }
3101        }
3102    }
3103
3104    /**
3105     * Return if the user key is currently unlocked.
3106     */
3107    private boolean isUserKeyUnlocked(int userId) {
3108        if (StorageManager.isFileBasedEncryptionEnabled()) {
3109            final IMountService mount = IMountService.Stub
3110                    .asInterface(ServiceManager.getService("mount"));
3111            if (mount == null) {
3112                Slog.w(TAG, "Early during boot, assuming locked");
3113                return false;
3114            }
3115            final long token = Binder.clearCallingIdentity();
3116            try {
3117                return mount.isUserKeyUnlocked(userId);
3118            } catch (RemoteException e) {
3119                throw e.rethrowAsRuntimeException();
3120            } finally {
3121                Binder.restoreCallingIdentity(token);
3122            }
3123        } else {
3124            return true;
3125        }
3126    }
3127
3128    /**
3129     * Update given flags based on encryption status of current user.
3130     */
3131    private int updateFlagsForEncryption(int flags, int userId) {
3132        if ((flags & (PackageManager.MATCH_ENCRYPTION_UNAWARE
3133                | PackageManager.MATCH_ENCRYPTION_AWARE)) != 0) {
3134            // Caller expressed an explicit opinion about what encryption
3135            // aware/unaware components they want to see, so fall through and
3136            // give them what they want
3137        } else {
3138            // Caller expressed no opinion, so match based on user state
3139            if (isUserKeyUnlocked(userId)) {
3140                flags |= PackageManager.MATCH_ENCRYPTION_AWARE_AND_UNAWARE;
3141            } else {
3142                flags |= PackageManager.MATCH_ENCRYPTION_AWARE;
3143            }
3144        }
3145        return flags;
3146    }
3147
3148    /**
3149     * Update given flags when being used to request {@link PackageInfo}.
3150     */
3151    private int updateFlagsForPackage(int flags, int userId, Object cookie) {
3152        boolean triaged = true;
3153        if ((flags & (PackageManager.GET_ACTIVITIES | PackageManager.GET_RECEIVERS
3154                | PackageManager.GET_SERVICES | PackageManager.GET_PROVIDERS)) != 0) {
3155            // Caller is asking for component details, so they'd better be
3156            // asking for specific encryption matching behavior, or be triaged
3157            if ((flags & (PackageManager.MATCH_ENCRYPTION_UNAWARE
3158                    | PackageManager.MATCH_ENCRYPTION_AWARE
3159                    | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
3160                triaged = false;
3161            }
3162        }
3163        if ((flags & (PackageManager.MATCH_UNINSTALLED_PACKAGES
3164                | PackageManager.MATCH_SYSTEM_ONLY
3165                | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
3166            triaged = false;
3167        }
3168        if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) {
3169            Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie
3170                    + " with flags 0x" + Integer.toHexString(flags), new Throwable());
3171        }
3172        return updateFlagsForEncryption(flags, userId);
3173    }
3174
3175    /**
3176     * Update given flags when being used to request {@link ApplicationInfo}.
3177     */
3178    private int updateFlagsForApplication(int flags, int userId, Object cookie) {
3179        return updateFlagsForPackage(flags, userId, cookie);
3180    }
3181
3182    /**
3183     * Update given flags when being used to request {@link ComponentInfo}.
3184     */
3185    private int updateFlagsForComponent(int flags, int userId, Object cookie) {
3186        if (cookie instanceof Intent) {
3187            if ((((Intent) cookie).getFlags() & Intent.FLAG_DEBUG_TRIAGED_MISSING) != 0) {
3188                flags |= PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
3189            }
3190        }
3191
3192        boolean triaged = true;
3193        // Caller is asking for component details, so they'd better be
3194        // asking for specific encryption matching behavior, or be triaged
3195        if ((flags & (PackageManager.MATCH_ENCRYPTION_UNAWARE
3196                | PackageManager.MATCH_ENCRYPTION_AWARE
3197                | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
3198            triaged = false;
3199        }
3200        if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) {
3201            Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie
3202                    + " with flags 0x" + Integer.toHexString(flags), new Throwable());
3203        }
3204        return updateFlagsForEncryption(flags, userId);
3205    }
3206
3207    /**
3208     * Update given flags when being used to request {@link ResolveInfo}.
3209     */
3210    private int updateFlagsForResolve(int flags, int userId, Object cookie) {
3211        return updateFlagsForComponent(flags, userId, cookie);
3212    }
3213
3214    @Override
3215    public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) {
3216        if (!sUserManager.exists(userId)) return null;
3217        flags = updateFlagsForComponent(flags, userId, component);
3218        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get activity info");
3219        synchronized (mPackages) {
3220            PackageParser.Activity a = mActivities.mActivities.get(component);
3221
3222            if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a);
3223            if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) {
3224                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
3225                if (ps == null) return null;
3226                return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId),
3227                        userId);
3228            }
3229            if (mResolveComponentName.equals(component)) {
3230                return PackageParser.generateActivityInfo(mResolveActivity, flags,
3231                        new PackageUserState(), userId);
3232            }
3233        }
3234        return null;
3235    }
3236
3237    @Override
3238    public boolean activitySupportsIntent(ComponentName component, Intent intent,
3239            String resolvedType) {
3240        synchronized (mPackages) {
3241            if (component.equals(mResolveComponentName)) {
3242                // The resolver supports EVERYTHING!
3243                return true;
3244            }
3245            PackageParser.Activity a = mActivities.mActivities.get(component);
3246            if (a == null) {
3247                return false;
3248            }
3249            for (int i=0; i<a.intents.size(); i++) {
3250                if (a.intents.get(i).match(intent.getAction(), resolvedType, intent.getScheme(),
3251                        intent.getData(), intent.getCategories(), TAG) >= 0) {
3252                    return true;
3253                }
3254            }
3255            return false;
3256        }
3257    }
3258
3259    @Override
3260    public ActivityInfo getReceiverInfo(ComponentName component, int flags, int userId) {
3261        if (!sUserManager.exists(userId)) return null;
3262        flags = updateFlagsForComponent(flags, userId, component);
3263        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get receiver info");
3264        synchronized (mPackages) {
3265            PackageParser.Activity a = mReceivers.mActivities.get(component);
3266            if (DEBUG_PACKAGE_INFO) Log.v(
3267                TAG, "getReceiverInfo " + component + ": " + a);
3268            if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) {
3269                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
3270                if (ps == null) return null;
3271                return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId),
3272                        userId);
3273            }
3274        }
3275        return null;
3276    }
3277
3278    @Override
3279    public ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) {
3280        if (!sUserManager.exists(userId)) return null;
3281        flags = updateFlagsForComponent(flags, userId, component);
3282        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get service info");
3283        synchronized (mPackages) {
3284            PackageParser.Service s = mServices.mServices.get(component);
3285            if (DEBUG_PACKAGE_INFO) Log.v(
3286                TAG, "getServiceInfo " + component + ": " + s);
3287            if (s != null && mSettings.isEnabledAndMatchLPr(s.info, flags, userId)) {
3288                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
3289                if (ps == null) return null;
3290                return PackageParser.generateServiceInfo(s, flags, ps.readUserState(userId),
3291                        userId);
3292            }
3293        }
3294        return null;
3295    }
3296
3297    @Override
3298    public ProviderInfo getProviderInfo(ComponentName component, int flags, int userId) {
3299        if (!sUserManager.exists(userId)) return null;
3300        flags = updateFlagsForComponent(flags, userId, component);
3301        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get provider info");
3302        synchronized (mPackages) {
3303            PackageParser.Provider p = mProviders.mProviders.get(component);
3304            if (DEBUG_PACKAGE_INFO) Log.v(
3305                TAG, "getProviderInfo " + component + ": " + p);
3306            if (p != null && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) {
3307                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
3308                if (ps == null) return null;
3309                return PackageParser.generateProviderInfo(p, flags, ps.readUserState(userId),
3310                        userId);
3311            }
3312        }
3313        return null;
3314    }
3315
3316    @Override
3317    public String[] getSystemSharedLibraryNames() {
3318        Set<String> libSet;
3319        synchronized (mPackages) {
3320            libSet = mSharedLibraries.keySet();
3321            int size = libSet.size();
3322            if (size > 0) {
3323                String[] libs = new String[size];
3324                libSet.toArray(libs);
3325                return libs;
3326            }
3327        }
3328        return null;
3329    }
3330
3331    /**
3332     * @hide
3333     */
3334    PackageParser.Package findSharedNonSystemLibrary(String libName) {
3335        synchronized (mPackages) {
3336            PackageManagerService.SharedLibraryEntry lib = mSharedLibraries.get(libName);
3337            if (lib != null && lib.apk != null) {
3338                return mPackages.get(lib.apk);
3339            }
3340        }
3341        return null;
3342    }
3343
3344    @Override
3345    public FeatureInfo[] getSystemAvailableFeatures() {
3346        Collection<FeatureInfo> featSet;
3347        synchronized (mPackages) {
3348            featSet = mAvailableFeatures.values();
3349            int size = featSet.size();
3350            if (size > 0) {
3351                FeatureInfo[] features = new FeatureInfo[size+1];
3352                featSet.toArray(features);
3353                FeatureInfo fi = new FeatureInfo();
3354                fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version",
3355                        FeatureInfo.GL_ES_VERSION_UNDEFINED);
3356                features[size] = fi;
3357                return features;
3358            }
3359        }
3360        return null;
3361    }
3362
3363    @Override
3364    public boolean hasSystemFeature(String name) {
3365        synchronized (mPackages) {
3366            return mAvailableFeatures.containsKey(name);
3367        }
3368    }
3369
3370    @Override
3371    public int checkPermission(String permName, String pkgName, int userId) {
3372        if (!sUserManager.exists(userId)) {
3373            return PackageManager.PERMISSION_DENIED;
3374        }
3375
3376        synchronized (mPackages) {
3377            final PackageParser.Package p = mPackages.get(pkgName);
3378            if (p != null && p.mExtras != null) {
3379                final PackageSetting ps = (PackageSetting) p.mExtras;
3380                final PermissionsState permissionsState = ps.getPermissionsState();
3381                if (permissionsState.hasPermission(permName, userId)) {
3382                    return PackageManager.PERMISSION_GRANTED;
3383                }
3384                // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION
3385                if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState
3386                        .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) {
3387                    return PackageManager.PERMISSION_GRANTED;
3388                }
3389            }
3390        }
3391
3392        return PackageManager.PERMISSION_DENIED;
3393    }
3394
3395    @Override
3396    public int checkUidPermission(String permName, int uid) {
3397        final int userId = UserHandle.getUserId(uid);
3398
3399        if (!sUserManager.exists(userId)) {
3400            return PackageManager.PERMISSION_DENIED;
3401        }
3402
3403        synchronized (mPackages) {
3404            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
3405            if (obj != null) {
3406                final SettingBase ps = (SettingBase) obj;
3407                final PermissionsState permissionsState = ps.getPermissionsState();
3408                if (permissionsState.hasPermission(permName, userId)) {
3409                    return PackageManager.PERMISSION_GRANTED;
3410                }
3411                // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION
3412                if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState
3413                        .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) {
3414                    return PackageManager.PERMISSION_GRANTED;
3415                }
3416            } else {
3417                ArraySet<String> perms = mSystemPermissions.get(uid);
3418                if (perms != null) {
3419                    if (perms.contains(permName)) {
3420                        return PackageManager.PERMISSION_GRANTED;
3421                    }
3422                    if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && perms
3423                            .contains(Manifest.permission.ACCESS_FINE_LOCATION)) {
3424                        return PackageManager.PERMISSION_GRANTED;
3425                    }
3426                }
3427            }
3428        }
3429
3430        return PackageManager.PERMISSION_DENIED;
3431    }
3432
3433    @Override
3434    public boolean isPermissionRevokedByPolicy(String permission, String packageName, int userId) {
3435        if (UserHandle.getCallingUserId() != userId) {
3436            mContext.enforceCallingPermission(
3437                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
3438                    "isPermissionRevokedByPolicy for user " + userId);
3439        }
3440
3441        if (checkPermission(permission, packageName, userId)
3442                == PackageManager.PERMISSION_GRANTED) {
3443            return false;
3444        }
3445
3446        final long identity = Binder.clearCallingIdentity();
3447        try {
3448            final int flags = getPermissionFlags(permission, packageName, userId);
3449            return (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0;
3450        } finally {
3451            Binder.restoreCallingIdentity(identity);
3452        }
3453    }
3454
3455    @Override
3456    public String getPermissionControllerPackageName() {
3457        synchronized (mPackages) {
3458            return mRequiredInstallerPackage;
3459        }
3460    }
3461
3462    /**
3463     * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS
3464     * or INTERACT_ACROSS_USERS_FULL permissions, if the userid is not for the caller.
3465     * @param checkShell TODO(yamasani):
3466     * @param message the message to log on security exception
3467     */
3468    void enforceCrossUserPermission(int callingUid, int userId, boolean requireFullPermission,
3469            boolean checkShell, String message) {
3470        if (userId < 0) {
3471            throw new IllegalArgumentException("Invalid userId " + userId);
3472        }
3473        if (checkShell) {
3474            enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId);
3475        }
3476        if (userId == UserHandle.getUserId(callingUid)) return;
3477        if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
3478            if (requireFullPermission) {
3479                mContext.enforceCallingOrSelfPermission(
3480                        android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
3481            } else {
3482                try {
3483                    mContext.enforceCallingOrSelfPermission(
3484                            android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
3485                } catch (SecurityException se) {
3486                    mContext.enforceCallingOrSelfPermission(
3487                            android.Manifest.permission.INTERACT_ACROSS_USERS, message);
3488                }
3489            }
3490        }
3491    }
3492
3493    void enforceShellRestriction(String restriction, int callingUid, int userHandle) {
3494        if (callingUid == Process.SHELL_UID) {
3495            if (userHandle >= 0
3496                    && sUserManager.hasUserRestriction(restriction, userHandle)) {
3497                throw new SecurityException("Shell does not have permission to access user "
3498                        + userHandle);
3499            } else if (userHandle < 0) {
3500                Slog.e(TAG, "Unable to check shell permission for user " + userHandle + "\n\t"
3501                        + Debug.getCallers(3));
3502            }
3503        }
3504    }
3505
3506    private BasePermission findPermissionTreeLP(String permName) {
3507        for(BasePermission bp : mSettings.mPermissionTrees.values()) {
3508            if (permName.startsWith(bp.name) &&
3509                    permName.length() > bp.name.length() &&
3510                    permName.charAt(bp.name.length()) == '.') {
3511                return bp;
3512            }
3513        }
3514        return null;
3515    }
3516
3517    private BasePermission checkPermissionTreeLP(String permName) {
3518        if (permName != null) {
3519            BasePermission bp = findPermissionTreeLP(permName);
3520            if (bp != null) {
3521                if (bp.uid == UserHandle.getAppId(Binder.getCallingUid())) {
3522                    return bp;
3523                }
3524                throw new SecurityException("Calling uid "
3525                        + Binder.getCallingUid()
3526                        + " is not allowed to add to permission tree "
3527                        + bp.name + " owned by uid " + bp.uid);
3528            }
3529        }
3530        throw new SecurityException("No permission tree found for " + permName);
3531    }
3532
3533    static boolean compareStrings(CharSequence s1, CharSequence s2) {
3534        if (s1 == null) {
3535            return s2 == null;
3536        }
3537        if (s2 == null) {
3538            return false;
3539        }
3540        if (s1.getClass() != s2.getClass()) {
3541            return false;
3542        }
3543        return s1.equals(s2);
3544    }
3545
3546    static boolean comparePermissionInfos(PermissionInfo pi1, PermissionInfo pi2) {
3547        if (pi1.icon != pi2.icon) return false;
3548        if (pi1.logo != pi2.logo) return false;
3549        if (pi1.protectionLevel != pi2.protectionLevel) return false;
3550        if (!compareStrings(pi1.name, pi2.name)) return false;
3551        if (!compareStrings(pi1.nonLocalizedLabel, pi2.nonLocalizedLabel)) return false;
3552        // We'll take care of setting this one.
3553        if (!compareStrings(pi1.packageName, pi2.packageName)) return false;
3554        // These are not currently stored in settings.
3555        //if (!compareStrings(pi1.group, pi2.group)) return false;
3556        //if (!compareStrings(pi1.nonLocalizedDescription, pi2.nonLocalizedDescription)) return false;
3557        //if (pi1.labelRes != pi2.labelRes) return false;
3558        //if (pi1.descriptionRes != pi2.descriptionRes) return false;
3559        return true;
3560    }
3561
3562    int permissionInfoFootprint(PermissionInfo info) {
3563        int size = info.name.length();
3564        if (info.nonLocalizedLabel != null) size += info.nonLocalizedLabel.length();
3565        if (info.nonLocalizedDescription != null) size += info.nonLocalizedDescription.length();
3566        return size;
3567    }
3568
3569    int calculateCurrentPermissionFootprintLocked(BasePermission tree) {
3570        int size = 0;
3571        for (BasePermission perm : mSettings.mPermissions.values()) {
3572            if (perm.uid == tree.uid) {
3573                size += perm.name.length() + permissionInfoFootprint(perm.perm.info);
3574            }
3575        }
3576        return size;
3577    }
3578
3579    void enforcePermissionCapLocked(PermissionInfo info, BasePermission tree) {
3580        // We calculate the max size of permissions defined by this uid and throw
3581        // if that plus the size of 'info' would exceed our stated maximum.
3582        if (tree.uid != Process.SYSTEM_UID) {
3583            final int curTreeSize = calculateCurrentPermissionFootprintLocked(tree);
3584            if (curTreeSize + permissionInfoFootprint(info) > MAX_PERMISSION_TREE_FOOTPRINT) {
3585                throw new SecurityException("Permission tree size cap exceeded");
3586            }
3587        }
3588    }
3589
3590    boolean addPermissionLocked(PermissionInfo info, boolean async) {
3591        if (info.labelRes == 0 && info.nonLocalizedLabel == null) {
3592            throw new SecurityException("Label must be specified in permission");
3593        }
3594        BasePermission tree = checkPermissionTreeLP(info.name);
3595        BasePermission bp = mSettings.mPermissions.get(info.name);
3596        boolean added = bp == null;
3597        boolean changed = true;
3598        int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel);
3599        if (added) {
3600            enforcePermissionCapLocked(info, tree);
3601            bp = new BasePermission(info.name, tree.sourcePackage,
3602                    BasePermission.TYPE_DYNAMIC);
3603        } else if (bp.type != BasePermission.TYPE_DYNAMIC) {
3604            throw new SecurityException(
3605                    "Not allowed to modify non-dynamic permission "
3606                    + info.name);
3607        } else {
3608            if (bp.protectionLevel == fixedLevel
3609                    && bp.perm.owner.equals(tree.perm.owner)
3610                    && bp.uid == tree.uid
3611                    && comparePermissionInfos(bp.perm.info, info)) {
3612                changed = false;
3613            }
3614        }
3615        bp.protectionLevel = fixedLevel;
3616        info = new PermissionInfo(info);
3617        info.protectionLevel = fixedLevel;
3618        bp.perm = new PackageParser.Permission(tree.perm.owner, info);
3619        bp.perm.info.packageName = tree.perm.info.packageName;
3620        bp.uid = tree.uid;
3621        if (added) {
3622            mSettings.mPermissions.put(info.name, bp);
3623        }
3624        if (changed) {
3625            if (!async) {
3626                mSettings.writeLPr();
3627            } else {
3628                scheduleWriteSettingsLocked();
3629            }
3630        }
3631        return added;
3632    }
3633
3634    @Override
3635    public boolean addPermission(PermissionInfo info) {
3636        synchronized (mPackages) {
3637            return addPermissionLocked(info, false);
3638        }
3639    }
3640
3641    @Override
3642    public boolean addPermissionAsync(PermissionInfo info) {
3643        synchronized (mPackages) {
3644            return addPermissionLocked(info, true);
3645        }
3646    }
3647
3648    @Override
3649    public void removePermission(String name) {
3650        synchronized (mPackages) {
3651            checkPermissionTreeLP(name);
3652            BasePermission bp = mSettings.mPermissions.get(name);
3653            if (bp != null) {
3654                if (bp.type != BasePermission.TYPE_DYNAMIC) {
3655                    throw new SecurityException(
3656                            "Not allowed to modify non-dynamic permission "
3657                            + name);
3658                }
3659                mSettings.mPermissions.remove(name);
3660                mSettings.writeLPr();
3661            }
3662        }
3663    }
3664
3665    private static void enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(PackageParser.Package pkg,
3666            BasePermission bp) {
3667        int index = pkg.requestedPermissions.indexOf(bp.name);
3668        if (index == -1) {
3669            throw new SecurityException("Package " + pkg.packageName
3670                    + " has not requested permission " + bp.name);
3671        }
3672        if (!bp.isRuntime() && !bp.isDevelopment()) {
3673            throw new SecurityException("Permission " + bp.name
3674                    + " is not a changeable permission type");
3675        }
3676    }
3677
3678    @Override
3679    public void grantRuntimePermission(String packageName, String name, final int userId) {
3680        if (!sUserManager.exists(userId)) {
3681            Log.e(TAG, "No such user:" + userId);
3682            return;
3683        }
3684
3685        mContext.enforceCallingOrSelfPermission(
3686                android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
3687                "grantRuntimePermission");
3688
3689        enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false,
3690                "grantRuntimePermission");
3691
3692        final int uid;
3693        final SettingBase sb;
3694
3695        synchronized (mPackages) {
3696            final PackageParser.Package pkg = mPackages.get(packageName);
3697            if (pkg == null) {
3698                throw new IllegalArgumentException("Unknown package: " + packageName);
3699            }
3700
3701            final BasePermission bp = mSettings.mPermissions.get(name);
3702            if (bp == null) {
3703                throw new IllegalArgumentException("Unknown permission: " + name);
3704            }
3705
3706            enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(pkg, bp);
3707
3708            // If a permission review is required for legacy apps we represent
3709            // their permissions as always granted runtime ones since we need
3710            // to keep the review required permission flag per user while an
3711            // install permission's state is shared across all users.
3712            if (Build.PERMISSIONS_REVIEW_REQUIRED
3713                    && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
3714                    && bp.isRuntime()) {
3715                return;
3716            }
3717
3718            uid = UserHandle.getUid(userId, pkg.applicationInfo.uid);
3719            sb = (SettingBase) pkg.mExtras;
3720            if (sb == null) {
3721                throw new IllegalArgumentException("Unknown package: " + packageName);
3722            }
3723
3724            final PermissionsState permissionsState = sb.getPermissionsState();
3725
3726            final int flags = permissionsState.getPermissionFlags(name, userId);
3727            if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
3728                throw new SecurityException("Cannot grant system fixed permission "
3729                        + name + " for package " + packageName);
3730            }
3731
3732            if (bp.isDevelopment()) {
3733                // Development permissions must be handled specially, since they are not
3734                // normal runtime permissions.  For now they apply to all users.
3735                if (permissionsState.grantInstallPermission(bp) !=
3736                        PermissionsState.PERMISSION_OPERATION_FAILURE) {
3737                    scheduleWriteSettingsLocked();
3738                }
3739                return;
3740            }
3741
3742            if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
3743                Slog.w(TAG, "Cannot grant runtime permission to a legacy app");
3744                return;
3745            }
3746
3747            final int result = permissionsState.grantRuntimePermission(bp, userId);
3748            switch (result) {
3749                case PermissionsState.PERMISSION_OPERATION_FAILURE: {
3750                    return;
3751                }
3752
3753                case PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
3754                    final int appId = UserHandle.getAppId(pkg.applicationInfo.uid);
3755                    mHandler.post(new Runnable() {
3756                        @Override
3757                        public void run() {
3758                            killUid(appId, userId, KILL_APP_REASON_GIDS_CHANGED);
3759                        }
3760                    });
3761                }
3762                break;
3763            }
3764
3765            mOnPermissionChangeListeners.onPermissionsChanged(uid);
3766
3767            // Not critical if that is lost - app has to request again.
3768            mSettings.writeRuntimePermissionsForUserLPr(userId, false);
3769        }
3770
3771        // Only need to do this if user is initialized. Otherwise it's a new user
3772        // and there are no processes running as the user yet and there's no need
3773        // to make an expensive call to remount processes for the changed permissions.
3774        if (READ_EXTERNAL_STORAGE.equals(name)
3775                || WRITE_EXTERNAL_STORAGE.equals(name)) {
3776            final long token = Binder.clearCallingIdentity();
3777            try {
3778                if (sUserManager.isInitialized(userId)) {
3779                    MountServiceInternal mountServiceInternal = LocalServices.getService(
3780                            MountServiceInternal.class);
3781                    mountServiceInternal.onExternalStoragePolicyChanged(uid, packageName);
3782                }
3783            } finally {
3784                Binder.restoreCallingIdentity(token);
3785            }
3786        }
3787    }
3788
3789    @Override
3790    public void revokeRuntimePermission(String packageName, String name, int userId) {
3791        if (!sUserManager.exists(userId)) {
3792            Log.e(TAG, "No such user:" + userId);
3793            return;
3794        }
3795
3796        mContext.enforceCallingOrSelfPermission(
3797                android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
3798                "revokeRuntimePermission");
3799
3800        enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false,
3801                "revokeRuntimePermission");
3802
3803        final int appId;
3804
3805        synchronized (mPackages) {
3806            final PackageParser.Package pkg = mPackages.get(packageName);
3807            if (pkg == null) {
3808                throw new IllegalArgumentException("Unknown package: " + packageName);
3809            }
3810
3811            final BasePermission bp = mSettings.mPermissions.get(name);
3812            if (bp == null) {
3813                throw new IllegalArgumentException("Unknown permission: " + name);
3814            }
3815
3816            enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(pkg, bp);
3817
3818            // If a permission review is required for legacy apps we represent
3819            // their permissions as always granted runtime ones since we need
3820            // to keep the review required permission flag per user while an
3821            // install permission's state is shared across all users.
3822            if (Build.PERMISSIONS_REVIEW_REQUIRED
3823                    && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
3824                    && bp.isRuntime()) {
3825                return;
3826            }
3827
3828            SettingBase sb = (SettingBase) pkg.mExtras;
3829            if (sb == null) {
3830                throw new IllegalArgumentException("Unknown package: " + packageName);
3831            }
3832
3833            final PermissionsState permissionsState = sb.getPermissionsState();
3834
3835            final int flags = permissionsState.getPermissionFlags(name, userId);
3836            if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
3837                throw new SecurityException("Cannot revoke system fixed permission "
3838                        + name + " for package " + packageName);
3839            }
3840
3841            if (bp.isDevelopment()) {
3842                // Development permissions must be handled specially, since they are not
3843                // normal runtime permissions.  For now they apply to all users.
3844                if (permissionsState.revokeInstallPermission(bp) !=
3845                        PermissionsState.PERMISSION_OPERATION_FAILURE) {
3846                    scheduleWriteSettingsLocked();
3847                }
3848                return;
3849            }
3850
3851            if (permissionsState.revokeRuntimePermission(bp, userId) ==
3852                    PermissionsState.PERMISSION_OPERATION_FAILURE) {
3853                return;
3854            }
3855
3856            mOnPermissionChangeListeners.onPermissionsChanged(pkg.applicationInfo.uid);
3857
3858            // Critical, after this call app should never have the permission.
3859            mSettings.writeRuntimePermissionsForUserLPr(userId, true);
3860
3861            appId = UserHandle.getAppId(pkg.applicationInfo.uid);
3862        }
3863
3864        killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED);
3865    }
3866
3867    @Override
3868    public void resetRuntimePermissions() {
3869        mContext.enforceCallingOrSelfPermission(
3870                android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
3871                "revokeRuntimePermission");
3872
3873        int callingUid = Binder.getCallingUid();
3874        if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
3875            mContext.enforceCallingOrSelfPermission(
3876                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
3877                    "resetRuntimePermissions");
3878        }
3879
3880        synchronized (mPackages) {
3881            updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL);
3882            for (int userId : UserManagerService.getInstance().getUserIds()) {
3883                final int packageCount = mPackages.size();
3884                for (int i = 0; i < packageCount; i++) {
3885                    PackageParser.Package pkg = mPackages.valueAt(i);
3886                    if (!(pkg.mExtras instanceof PackageSetting)) {
3887                        continue;
3888                    }
3889                    PackageSetting ps = (PackageSetting) pkg.mExtras;
3890                    resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
3891                }
3892            }
3893        }
3894    }
3895
3896    @Override
3897    public int getPermissionFlags(String name, String packageName, int userId) {
3898        if (!sUserManager.exists(userId)) {
3899            return 0;
3900        }
3901
3902        enforceGrantRevokeRuntimePermissionPermissions("getPermissionFlags");
3903
3904        enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false,
3905                "getPermissionFlags");
3906
3907        synchronized (mPackages) {
3908            final PackageParser.Package pkg = mPackages.get(packageName);
3909            if (pkg == null) {
3910                throw new IllegalArgumentException("Unknown package: " + packageName);
3911            }
3912
3913            final BasePermission bp = mSettings.mPermissions.get(name);
3914            if (bp == null) {
3915                throw new IllegalArgumentException("Unknown permission: " + name);
3916            }
3917
3918            SettingBase sb = (SettingBase) pkg.mExtras;
3919            if (sb == null) {
3920                throw new IllegalArgumentException("Unknown package: " + packageName);
3921            }
3922
3923            PermissionsState permissionsState = sb.getPermissionsState();
3924            return permissionsState.getPermissionFlags(name, userId);
3925        }
3926    }
3927
3928    @Override
3929    public void updatePermissionFlags(String name, String packageName, int flagMask,
3930            int flagValues, int userId) {
3931        if (!sUserManager.exists(userId)) {
3932            return;
3933        }
3934
3935        enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlags");
3936
3937        enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false,
3938                "updatePermissionFlags");
3939
3940        // Only the system can change these flags and nothing else.
3941        if (getCallingUid() != Process.SYSTEM_UID) {
3942            flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
3943            flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
3944            flagMask &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
3945            flagValues &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
3946            flagValues &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
3947        }
3948
3949        synchronized (mPackages) {
3950            final PackageParser.Package pkg = mPackages.get(packageName);
3951            if (pkg == null) {
3952                throw new IllegalArgumentException("Unknown package: " + packageName);
3953            }
3954
3955            final BasePermission bp = mSettings.mPermissions.get(name);
3956            if (bp == null) {
3957                throw new IllegalArgumentException("Unknown permission: " + name);
3958            }
3959
3960            SettingBase sb = (SettingBase) pkg.mExtras;
3961            if (sb == null) {
3962                throw new IllegalArgumentException("Unknown package: " + packageName);
3963            }
3964
3965            PermissionsState permissionsState = sb.getPermissionsState();
3966
3967            boolean hadState = permissionsState.getRuntimePermissionState(name, userId) != null;
3968
3969            if (permissionsState.updatePermissionFlags(bp, userId, flagMask, flagValues)) {
3970                // Install and runtime permissions are stored in different places,
3971                // so figure out what permission changed and persist the change.
3972                if (permissionsState.getInstallPermissionState(name) != null) {
3973                    scheduleWriteSettingsLocked();
3974                } else if (permissionsState.getRuntimePermissionState(name, userId) != null
3975                        || hadState) {
3976                    mSettings.writeRuntimePermissionsForUserLPr(userId, false);
3977                }
3978            }
3979        }
3980    }
3981
3982    /**
3983     * Update the permission flags for all packages and runtime permissions of a user in order
3984     * to allow device or profile owner to remove POLICY_FIXED.
3985     */
3986    @Override
3987    public void updatePermissionFlagsForAllApps(int flagMask, int flagValues, int userId) {
3988        if (!sUserManager.exists(userId)) {
3989            return;
3990        }
3991
3992        enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlagsForAllApps");
3993
3994        enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false,
3995                "updatePermissionFlagsForAllApps");
3996
3997        // Only the system can change system fixed flags.
3998        if (getCallingUid() != Process.SYSTEM_UID) {
3999            flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
4000            flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
4001        }
4002
4003        synchronized (mPackages) {
4004            boolean changed = false;
4005            final int packageCount = mPackages.size();
4006            for (int pkgIndex = 0; pkgIndex < packageCount; pkgIndex++) {
4007                final PackageParser.Package pkg = mPackages.valueAt(pkgIndex);
4008                SettingBase sb = (SettingBase) pkg.mExtras;
4009                if (sb == null) {
4010                    continue;
4011                }
4012                PermissionsState permissionsState = sb.getPermissionsState();
4013                changed |= permissionsState.updatePermissionFlagsForAllPermissions(
4014                        userId, flagMask, flagValues);
4015            }
4016            if (changed) {
4017                mSettings.writeRuntimePermissionsForUserLPr(userId, false);
4018            }
4019        }
4020    }
4021
4022    private void enforceGrantRevokeRuntimePermissionPermissions(String message) {
4023        if (mContext.checkCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS)
4024                != PackageManager.PERMISSION_GRANTED
4025            && mContext.checkCallingOrSelfPermission(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS)
4026                != PackageManager.PERMISSION_GRANTED) {
4027            throw new SecurityException(message + " requires "
4028                    + Manifest.permission.GRANT_RUNTIME_PERMISSIONS + " or "
4029                    + Manifest.permission.REVOKE_RUNTIME_PERMISSIONS);
4030        }
4031    }
4032
4033    @Override
4034    public boolean shouldShowRequestPermissionRationale(String permissionName,
4035            String packageName, int userId) {
4036        if (UserHandle.getCallingUserId() != userId) {
4037            mContext.enforceCallingPermission(
4038                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
4039                    "canShowRequestPermissionRationale for user " + userId);
4040        }
4041
4042        final int uid = getPackageUid(packageName, userId);
4043        if (UserHandle.getAppId(getCallingUid()) != UserHandle.getAppId(uid)) {
4044            return false;
4045        }
4046
4047        if (checkPermission(permissionName, packageName, userId)
4048                == PackageManager.PERMISSION_GRANTED) {
4049            return false;
4050        }
4051
4052        final int flags;
4053
4054        final long identity = Binder.clearCallingIdentity();
4055        try {
4056            flags = getPermissionFlags(permissionName,
4057                    packageName, userId);
4058        } finally {
4059            Binder.restoreCallingIdentity(identity);
4060        }
4061
4062        final int fixedFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
4063                | PackageManager.FLAG_PERMISSION_POLICY_FIXED
4064                | PackageManager.FLAG_PERMISSION_USER_FIXED;
4065
4066        if ((flags & fixedFlags) != 0) {
4067            return false;
4068        }
4069
4070        return (flags & PackageManager.FLAG_PERMISSION_USER_SET) != 0;
4071    }
4072
4073    @Override
4074    public void addOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
4075        mContext.enforceCallingOrSelfPermission(
4076                Manifest.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS,
4077                "addOnPermissionsChangeListener");
4078
4079        synchronized (mPackages) {
4080            mOnPermissionChangeListeners.addListenerLocked(listener);
4081        }
4082    }
4083
4084    @Override
4085    public void removeOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
4086        synchronized (mPackages) {
4087            mOnPermissionChangeListeners.removeListenerLocked(listener);
4088        }
4089    }
4090
4091    @Override
4092    public boolean isProtectedBroadcast(String actionName) {
4093        synchronized (mPackages) {
4094            if (mProtectedBroadcasts.contains(actionName)) {
4095                return true;
4096            } else if (actionName != null) {
4097                // TODO: remove these terrible hacks
4098                if (actionName.startsWith("android.net.netmon.lingerExpired")
4099                        || actionName.startsWith("com.android.server.sip.SipWakeupTimer")) {
4100                    return true;
4101                }
4102            }
4103        }
4104        return false;
4105    }
4106
4107    @Override
4108    public int checkSignatures(String pkg1, String pkg2) {
4109        synchronized (mPackages) {
4110            final PackageParser.Package p1 = mPackages.get(pkg1);
4111            final PackageParser.Package p2 = mPackages.get(pkg2);
4112            if (p1 == null || p1.mExtras == null
4113                    || p2 == null || p2.mExtras == null) {
4114                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
4115            }
4116            return compareSignatures(p1.mSignatures, p2.mSignatures);
4117        }
4118    }
4119
4120    @Override
4121    public int checkUidSignatures(int uid1, int uid2) {
4122        // Map to base uids.
4123        uid1 = UserHandle.getAppId(uid1);
4124        uid2 = UserHandle.getAppId(uid2);
4125        // reader
4126        synchronized (mPackages) {
4127            Signature[] s1;
4128            Signature[] s2;
4129            Object obj = mSettings.getUserIdLPr(uid1);
4130            if (obj != null) {
4131                if (obj instanceof SharedUserSetting) {
4132                    s1 = ((SharedUserSetting)obj).signatures.mSignatures;
4133                } else if (obj instanceof PackageSetting) {
4134                    s1 = ((PackageSetting)obj).signatures.mSignatures;
4135                } else {
4136                    return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
4137                }
4138            } else {
4139                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
4140            }
4141            obj = mSettings.getUserIdLPr(uid2);
4142            if (obj != null) {
4143                if (obj instanceof SharedUserSetting) {
4144                    s2 = ((SharedUserSetting)obj).signatures.mSignatures;
4145                } else if (obj instanceof PackageSetting) {
4146                    s2 = ((PackageSetting)obj).signatures.mSignatures;
4147                } else {
4148                    return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
4149                }
4150            } else {
4151                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
4152            }
4153            return compareSignatures(s1, s2);
4154        }
4155    }
4156
4157    private void killUid(int appId, int userId, String reason) {
4158        final long identity = Binder.clearCallingIdentity();
4159        try {
4160            IActivityManager am = ActivityManagerNative.getDefault();
4161            if (am != null) {
4162                try {
4163                    am.killUid(appId, userId, reason);
4164                } catch (RemoteException e) {
4165                    /* ignore - same process */
4166                }
4167            }
4168        } finally {
4169            Binder.restoreCallingIdentity(identity);
4170        }
4171    }
4172
4173    /**
4174     * Compares two sets of signatures. Returns:
4175     * <br />
4176     * {@link PackageManager#SIGNATURE_NEITHER_SIGNED}: if both signature sets are null,
4177     * <br />
4178     * {@link PackageManager#SIGNATURE_FIRST_NOT_SIGNED}: if the first signature set is null,
4179     * <br />
4180     * {@link PackageManager#SIGNATURE_SECOND_NOT_SIGNED}: if the second signature set is null,
4181     * <br />
4182     * {@link PackageManager#SIGNATURE_MATCH}: if the two signature sets are identical,
4183     * <br />
4184     * {@link PackageManager#SIGNATURE_NO_MATCH}: if the two signature sets differ.
4185     */
4186    static int compareSignatures(Signature[] s1, Signature[] s2) {
4187        if (s1 == null) {
4188            return s2 == null
4189                    ? PackageManager.SIGNATURE_NEITHER_SIGNED
4190                    : PackageManager.SIGNATURE_FIRST_NOT_SIGNED;
4191        }
4192
4193        if (s2 == null) {
4194            return PackageManager.SIGNATURE_SECOND_NOT_SIGNED;
4195        }
4196
4197        if (s1.length != s2.length) {
4198            return PackageManager.SIGNATURE_NO_MATCH;
4199        }
4200
4201        // Since both signature sets are of size 1, we can compare without HashSets.
4202        if (s1.length == 1) {
4203            return s1[0].equals(s2[0]) ?
4204                    PackageManager.SIGNATURE_MATCH :
4205                    PackageManager.SIGNATURE_NO_MATCH;
4206        }
4207
4208        ArraySet<Signature> set1 = new ArraySet<Signature>();
4209        for (Signature sig : s1) {
4210            set1.add(sig);
4211        }
4212        ArraySet<Signature> set2 = new ArraySet<Signature>();
4213        for (Signature sig : s2) {
4214            set2.add(sig);
4215        }
4216        // Make sure s2 contains all signatures in s1.
4217        if (set1.equals(set2)) {
4218            return PackageManager.SIGNATURE_MATCH;
4219        }
4220        return PackageManager.SIGNATURE_NO_MATCH;
4221    }
4222
4223    /**
4224     * If the database version for this type of package (internal storage or
4225     * external storage) is less than the version where package signatures
4226     * were updated, return true.
4227     */
4228    private boolean isCompatSignatureUpdateNeeded(PackageParser.Package scannedPkg) {
4229        final VersionInfo ver = getSettingsVersionForPackage(scannedPkg);
4230        return ver.databaseVersion < DatabaseVersion.SIGNATURE_END_ENTITY;
4231    }
4232
4233    /**
4234     * Used for backward compatibility to make sure any packages with
4235     * certificate chains get upgraded to the new style. {@code existingSigs}
4236     * will be in the old format (since they were stored on disk from before the
4237     * system upgrade) and {@code scannedSigs} will be in the newer format.
4238     */
4239    private int compareSignaturesCompat(PackageSignatures existingSigs,
4240            PackageParser.Package scannedPkg) {
4241        if (!isCompatSignatureUpdateNeeded(scannedPkg)) {
4242            return PackageManager.SIGNATURE_NO_MATCH;
4243        }
4244
4245        ArraySet<Signature> existingSet = new ArraySet<Signature>();
4246        for (Signature sig : existingSigs.mSignatures) {
4247            existingSet.add(sig);
4248        }
4249        ArraySet<Signature> scannedCompatSet = new ArraySet<Signature>();
4250        for (Signature sig : scannedPkg.mSignatures) {
4251            try {
4252                Signature[] chainSignatures = sig.getChainSignatures();
4253                for (Signature chainSig : chainSignatures) {
4254                    scannedCompatSet.add(chainSig);
4255                }
4256            } catch (CertificateEncodingException e) {
4257                scannedCompatSet.add(sig);
4258            }
4259        }
4260        /*
4261         * Make sure the expanded scanned set contains all signatures in the
4262         * existing one.
4263         */
4264        if (scannedCompatSet.equals(existingSet)) {
4265            // Migrate the old signatures to the new scheme.
4266            existingSigs.assignSignatures(scannedPkg.mSignatures);
4267            // The new KeySets will be re-added later in the scanning process.
4268            synchronized (mPackages) {
4269                mSettings.mKeySetManagerService.removeAppKeySetDataLPw(scannedPkg.packageName);
4270            }
4271            return PackageManager.SIGNATURE_MATCH;
4272        }
4273        return PackageManager.SIGNATURE_NO_MATCH;
4274    }
4275
4276    private boolean isRecoverSignatureUpdateNeeded(PackageParser.Package scannedPkg) {
4277        final VersionInfo ver = getSettingsVersionForPackage(scannedPkg);
4278        return ver.databaseVersion < DatabaseVersion.SIGNATURE_MALFORMED_RECOVER;
4279    }
4280
4281    private int compareSignaturesRecover(PackageSignatures existingSigs,
4282            PackageParser.Package scannedPkg) {
4283        if (!isRecoverSignatureUpdateNeeded(scannedPkg)) {
4284            return PackageManager.SIGNATURE_NO_MATCH;
4285        }
4286
4287        String msg = null;
4288        try {
4289            if (Signature.areEffectiveMatch(existingSigs.mSignatures, scannedPkg.mSignatures)) {
4290                logCriticalInfo(Log.INFO, "Recovered effectively matching certificates for "
4291                        + scannedPkg.packageName);
4292                return PackageManager.SIGNATURE_MATCH;
4293            }
4294        } catch (CertificateException e) {
4295            msg = e.getMessage();
4296        }
4297
4298        logCriticalInfo(Log.INFO,
4299                "Failed to recover certificates for " + scannedPkg.packageName + ": " + msg);
4300        return PackageManager.SIGNATURE_NO_MATCH;
4301    }
4302
4303    @Override
4304    public String[] getPackagesForUid(int uid) {
4305        uid = UserHandle.getAppId(uid);
4306        // reader
4307        synchronized (mPackages) {
4308            Object obj = mSettings.getUserIdLPr(uid);
4309            if (obj instanceof SharedUserSetting) {
4310                final SharedUserSetting sus = (SharedUserSetting) obj;
4311                final int N = sus.packages.size();
4312                final String[] res = new String[N];
4313                final Iterator<PackageSetting> it = sus.packages.iterator();
4314                int i = 0;
4315                while (it.hasNext()) {
4316                    res[i++] = it.next().name;
4317                }
4318                return res;
4319            } else if (obj instanceof PackageSetting) {
4320                final PackageSetting ps = (PackageSetting) obj;
4321                return new String[] { ps.name };
4322            }
4323        }
4324        return null;
4325    }
4326
4327    @Override
4328    public String getNameForUid(int uid) {
4329        // reader
4330        synchronized (mPackages) {
4331            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
4332            if (obj instanceof SharedUserSetting) {
4333                final SharedUserSetting sus = (SharedUserSetting) obj;
4334                return sus.name + ":" + sus.userId;
4335            } else if (obj instanceof PackageSetting) {
4336                final PackageSetting ps = (PackageSetting) obj;
4337                return ps.name;
4338            }
4339        }
4340        return null;
4341    }
4342
4343    @Override
4344    public int getUidForSharedUser(String sharedUserName) {
4345        if(sharedUserName == null) {
4346            return -1;
4347        }
4348        // reader
4349        synchronized (mPackages) {
4350            final SharedUserSetting suid = mSettings.getSharedUserLPw(sharedUserName, 0, 0, false);
4351            if (suid == null) {
4352                return -1;
4353            }
4354            return suid.userId;
4355        }
4356    }
4357
4358    @Override
4359    public int getFlagsForUid(int uid) {
4360        synchronized (mPackages) {
4361            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
4362            if (obj instanceof SharedUserSetting) {
4363                final SharedUserSetting sus = (SharedUserSetting) obj;
4364                return sus.pkgFlags;
4365            } else if (obj instanceof PackageSetting) {
4366                final PackageSetting ps = (PackageSetting) obj;
4367                return ps.pkgFlags;
4368            }
4369        }
4370        return 0;
4371    }
4372
4373    @Override
4374    public int getPrivateFlagsForUid(int uid) {
4375        synchronized (mPackages) {
4376            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
4377            if (obj instanceof SharedUserSetting) {
4378                final SharedUserSetting sus = (SharedUserSetting) obj;
4379                return sus.pkgPrivateFlags;
4380            } else if (obj instanceof PackageSetting) {
4381                final PackageSetting ps = (PackageSetting) obj;
4382                return ps.pkgPrivateFlags;
4383            }
4384        }
4385        return 0;
4386    }
4387
4388    @Override
4389    public boolean isUidPrivileged(int uid) {
4390        uid = UserHandle.getAppId(uid);
4391        // reader
4392        synchronized (mPackages) {
4393            Object obj = mSettings.getUserIdLPr(uid);
4394            if (obj instanceof SharedUserSetting) {
4395                final SharedUserSetting sus = (SharedUserSetting) obj;
4396                final Iterator<PackageSetting> it = sus.packages.iterator();
4397                while (it.hasNext()) {
4398                    if (it.next().isPrivileged()) {
4399                        return true;
4400                    }
4401                }
4402            } else if (obj instanceof PackageSetting) {
4403                final PackageSetting ps = (PackageSetting) obj;
4404                return ps.isPrivileged();
4405            }
4406        }
4407        return false;
4408    }
4409
4410    @Override
4411    public String[] getAppOpPermissionPackages(String permissionName) {
4412        synchronized (mPackages) {
4413            ArraySet<String> pkgs = mAppOpPermissionPackages.get(permissionName);
4414            if (pkgs == null) {
4415                return null;
4416            }
4417            return pkgs.toArray(new String[pkgs.size()]);
4418        }
4419    }
4420
4421    @Override
4422    public ResolveInfo resolveIntent(Intent intent, String resolvedType,
4423            int flags, int userId) {
4424        if (!sUserManager.exists(userId)) return null;
4425        flags = updateFlagsForResolve(flags, userId, intent);
4426        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "resolve intent");
4427        List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId);
4428        final ResolveInfo bestChoice =
4429                chooseBestActivity(intent, resolvedType, flags, query, userId);
4430
4431        if (isEphemeralAllowed(intent, query, userId)) {
4432            final EphemeralResolveInfo ai =
4433                    getEphemeralResolveInfo(intent, resolvedType, userId);
4434            if (ai != null) {
4435                if (DEBUG_EPHEMERAL) {
4436                    Slog.v(TAG, "Returning an EphemeralResolveInfo");
4437                }
4438                bestChoice.ephemeralInstaller = mEphemeralInstallerInfo;
4439                bestChoice.ephemeralResolveInfo = ai;
4440            }
4441        }
4442        return bestChoice;
4443    }
4444
4445    @Override
4446    public void setLastChosenActivity(Intent intent, String resolvedType, int flags,
4447            IntentFilter filter, int match, ComponentName activity) {
4448        final int userId = UserHandle.getCallingUserId();
4449        if (DEBUG_PREFERRED) {
4450            Log.v(TAG, "setLastChosenActivity intent=" + intent
4451                + " resolvedType=" + resolvedType
4452                + " flags=" + flags
4453                + " filter=" + filter
4454                + " match=" + match
4455                + " activity=" + activity);
4456            filter.dump(new PrintStreamPrinter(System.out), "    ");
4457        }
4458        intent.setComponent(null);
4459        List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId);
4460        // Find any earlier preferred or last chosen entries and nuke them
4461        findPreferredActivity(intent, resolvedType,
4462                flags, query, 0, false, true, false, userId);
4463        // Add the new activity as the last chosen for this filter
4464        addPreferredActivityInternal(filter, match, null, activity, false, userId,
4465                "Setting last chosen");
4466    }
4467
4468    @Override
4469    public ResolveInfo getLastChosenActivity(Intent intent, String resolvedType, int flags) {
4470        final int userId = UserHandle.getCallingUserId();
4471        if (DEBUG_PREFERRED) Log.v(TAG, "Querying last chosen activity for " + intent);
4472        List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId);
4473        return findPreferredActivity(intent, resolvedType, flags, query, 0,
4474                false, false, false, userId);
4475    }
4476
4477
4478    private boolean isEphemeralAllowed(
4479            Intent intent, List<ResolveInfo> resolvedActivites, int userId) {
4480        // Short circuit and return early if possible.
4481        final int callingUser = UserHandle.getCallingUserId();
4482        if (callingUser != UserHandle.USER_SYSTEM) {
4483            return false;
4484        }
4485        if (mEphemeralResolverConnection == null) {
4486            return false;
4487        }
4488        if (intent.getComponent() != null) {
4489            return false;
4490        }
4491        if (intent.getPackage() != null) {
4492            return false;
4493        }
4494        final boolean isWebUri = hasWebURI(intent);
4495        if (!isWebUri) {
4496            return false;
4497        }
4498        // Deny ephemeral apps if the user chose _ALWAYS or _ALWAYS_ASK for intent resolution.
4499        synchronized (mPackages) {
4500            final int count = resolvedActivites.size();
4501            for (int n = 0; n < count; n++) {
4502                ResolveInfo info = resolvedActivites.get(n);
4503                String packageName = info.activityInfo.packageName;
4504                PackageSetting ps = mSettings.mPackages.get(packageName);
4505                if (ps != null) {
4506                    // Try to get the status from User settings first
4507                    long packedStatus = getDomainVerificationStatusLPr(ps, userId);
4508                    int status = (int) (packedStatus >> 32);
4509                    if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS
4510                            || status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
4511                        if (DEBUG_EPHEMERAL) {
4512                            Slog.v(TAG, "DENY ephemeral apps;"
4513                                + " pkg: " + packageName + ", status: " + status);
4514                        }
4515                        return false;
4516                    }
4517                }
4518            }
4519        }
4520        // We've exhausted all ways to deny ephemeral application; let the system look for them.
4521        return true;
4522    }
4523
4524    private EphemeralResolveInfo getEphemeralResolveInfo(Intent intent, String resolvedType,
4525            int userId) {
4526        MessageDigest digest = null;
4527        try {
4528            digest = MessageDigest.getInstance(EphemeralResolveInfo.SHA_ALGORITHM);
4529        } catch (NoSuchAlgorithmException e) {
4530            // If we can't create a digest, ignore ephemeral apps.
4531            return null;
4532        }
4533
4534        final byte[] hostBytes = intent.getData().getHost().getBytes();
4535        final byte[] digestBytes = digest.digest(hostBytes);
4536        int shaPrefix =
4537                digestBytes[0] << 24
4538                | digestBytes[1] << 16
4539                | digestBytes[2] << 8
4540                | digestBytes[3] << 0;
4541        final List<EphemeralResolveInfo> ephemeralResolveInfoList =
4542                mEphemeralResolverConnection.getEphemeralResolveInfoList(shaPrefix);
4543        if (ephemeralResolveInfoList == null || ephemeralResolveInfoList.size() == 0) {
4544            // No hash prefix match; there are no ephemeral apps for this domain.
4545            return null;
4546        }
4547        for (int i = ephemeralResolveInfoList.size() - 1; i >= 0; --i) {
4548            EphemeralResolveInfo ephemeralApplication = ephemeralResolveInfoList.get(i);
4549            if (!Arrays.equals(digestBytes, ephemeralApplication.getDigestBytes())) {
4550                continue;
4551            }
4552            final List<IntentFilter> filters = ephemeralApplication.getFilters();
4553            // No filters; this should never happen.
4554            if (filters.isEmpty()) {
4555                continue;
4556            }
4557            // We have a domain match; resolve the filters to see if anything matches.
4558            final EphemeralIntentResolver ephemeralResolver = new EphemeralIntentResolver();
4559            for (int j = filters.size() - 1; j >= 0; --j) {
4560                final EphemeralResolveIntentInfo intentInfo =
4561                        new EphemeralResolveIntentInfo(filters.get(j), ephemeralApplication);
4562                ephemeralResolver.addFilter(intentInfo);
4563            }
4564            List<EphemeralResolveInfo> matchedResolveInfoList = ephemeralResolver.queryIntent(
4565                    intent, resolvedType, false /*defaultOnly*/, userId);
4566            if (!matchedResolveInfoList.isEmpty()) {
4567                return matchedResolveInfoList.get(0);
4568            }
4569        }
4570        // Hash or filter mis-match; no ephemeral apps for this domain.
4571        return null;
4572    }
4573
4574    private ResolveInfo chooseBestActivity(Intent intent, String resolvedType,
4575            int flags, List<ResolveInfo> query, int userId) {
4576        if (query != null) {
4577            final int N = query.size();
4578            if (N == 1) {
4579                return query.get(0);
4580            } else if (N > 1) {
4581                final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4582                // If there is more than one activity with the same priority,
4583                // then let the user decide between them.
4584                ResolveInfo r0 = query.get(0);
4585                ResolveInfo r1 = query.get(1);
4586                if (DEBUG_INTENT_MATCHING || debug) {
4587                    Slog.v(TAG, r0.activityInfo.name + "=" + r0.priority + " vs "
4588                            + r1.activityInfo.name + "=" + r1.priority);
4589                }
4590                // If the first activity has a higher priority, or a different
4591                // default, then it is always desirable to pick it.
4592                if (r0.priority != r1.priority
4593                        || r0.preferredOrder != r1.preferredOrder
4594                        || r0.isDefault != r1.isDefault) {
4595                    return query.get(0);
4596                }
4597                // If we have saved a preference for a preferred activity for
4598                // this Intent, use that.
4599                ResolveInfo ri = findPreferredActivity(intent, resolvedType,
4600                        flags, query, r0.priority, true, false, debug, userId);
4601                if (ri != null) {
4602                    return ri;
4603                }
4604                ri = new ResolveInfo(mResolveInfo);
4605                ri.activityInfo = new ActivityInfo(ri.activityInfo);
4606                ri.activityInfo.applicationInfo = new ApplicationInfo(
4607                        ri.activityInfo.applicationInfo);
4608                if (userId != 0) {
4609                    ri.activityInfo.applicationInfo.uid = UserHandle.getUid(userId,
4610                            UserHandle.getAppId(ri.activityInfo.applicationInfo.uid));
4611                }
4612                // Make sure that the resolver is displayable in car mode
4613                if (ri.activityInfo.metaData == null) ri.activityInfo.metaData = new Bundle();
4614                ri.activityInfo.metaData.putBoolean(Intent.METADATA_DOCK_HOME, true);
4615                return ri;
4616            }
4617        }
4618        return null;
4619    }
4620
4621    private ResolveInfo findPersistentPreferredActivityLP(Intent intent, String resolvedType,
4622            int flags, List<ResolveInfo> query, boolean debug, int userId) {
4623        final int N = query.size();
4624        PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
4625                .get(userId);
4626        // Get the list of persistent preferred activities that handle the intent
4627        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for presistent preferred activities...");
4628        List<PersistentPreferredActivity> pprefs = ppir != null
4629                ? ppir.queryIntent(intent, resolvedType,
4630                        (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId)
4631                : null;
4632        if (pprefs != null && pprefs.size() > 0) {
4633            final int M = pprefs.size();
4634            for (int i=0; i<M; i++) {
4635                final PersistentPreferredActivity ppa = pprefs.get(i);
4636                if (DEBUG_PREFERRED || debug) {
4637                    Slog.v(TAG, "Checking PersistentPreferredActivity ds="
4638                            + (ppa.countDataSchemes() > 0 ? ppa.getDataScheme(0) : "<none>")
4639                            + "\n  component=" + ppa.mComponent);
4640                    ppa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
4641                }
4642                final ActivityInfo ai = getActivityInfo(ppa.mComponent,
4643                        flags | MATCH_DISABLED_COMPONENTS, userId);
4644                if (DEBUG_PREFERRED || debug) {
4645                    Slog.v(TAG, "Found persistent preferred activity:");
4646                    if (ai != null) {
4647                        ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
4648                    } else {
4649                        Slog.v(TAG, "  null");
4650                    }
4651                }
4652                if (ai == null) {
4653                    // This previously registered persistent preferred activity
4654                    // component is no longer known. Ignore it and do NOT remove it.
4655                    continue;
4656                }
4657                for (int j=0; j<N; j++) {
4658                    final ResolveInfo ri = query.get(j);
4659                    if (!ri.activityInfo.applicationInfo.packageName
4660                            .equals(ai.applicationInfo.packageName)) {
4661                        continue;
4662                    }
4663                    if (!ri.activityInfo.name.equals(ai.name)) {
4664                        continue;
4665                    }
4666                    //  Found a persistent preference that can handle the intent.
4667                    if (DEBUG_PREFERRED || debug) {
4668                        Slog.v(TAG, "Returning persistent preferred activity: " +
4669                                ri.activityInfo.packageName + "/" + ri.activityInfo.name);
4670                    }
4671                    return ri;
4672                }
4673            }
4674        }
4675        return null;
4676    }
4677
4678    // TODO: handle preferred activities missing while user has amnesia
4679    ResolveInfo findPreferredActivity(Intent intent, String resolvedType, int flags,
4680            List<ResolveInfo> query, int priority, boolean always,
4681            boolean removeMatches, boolean debug, int userId) {
4682        if (!sUserManager.exists(userId)) return null;
4683        flags = updateFlagsForResolve(flags, userId, intent);
4684        // writer
4685        synchronized (mPackages) {
4686            if (intent.getSelector() != null) {
4687                intent = intent.getSelector();
4688            }
4689            if (DEBUG_PREFERRED) intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION);
4690
4691            // Try to find a matching persistent preferred activity.
4692            ResolveInfo pri = findPersistentPreferredActivityLP(intent, resolvedType, flags, query,
4693                    debug, userId);
4694
4695            // If a persistent preferred activity matched, use it.
4696            if (pri != null) {
4697                return pri;
4698            }
4699
4700            PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
4701            // Get the list of preferred activities that handle the intent
4702            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for preferred activities...");
4703            List<PreferredActivity> prefs = pir != null
4704                    ? pir.queryIntent(intent, resolvedType,
4705                            (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId)
4706                    : null;
4707            if (prefs != null && prefs.size() > 0) {
4708                boolean changed = false;
4709                try {
4710                    // First figure out how good the original match set is.
4711                    // We will only allow preferred activities that came
4712                    // from the same match quality.
4713                    int match = 0;
4714
4715                    if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Figuring out best match...");
4716
4717                    final int N = query.size();
4718                    for (int j=0; j<N; j++) {
4719                        final ResolveInfo ri = query.get(j);
4720                        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Match for " + ri.activityInfo
4721                                + ": 0x" + Integer.toHexString(match));
4722                        if (ri.match > match) {
4723                            match = ri.match;
4724                        }
4725                    }
4726
4727                    if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Best match: 0x"
4728                            + Integer.toHexString(match));
4729
4730                    match &= IntentFilter.MATCH_CATEGORY_MASK;
4731                    final int M = prefs.size();
4732                    for (int i=0; i<M; i++) {
4733                        final PreferredActivity pa = prefs.get(i);
4734                        if (DEBUG_PREFERRED || debug) {
4735                            Slog.v(TAG, "Checking PreferredActivity ds="
4736                                    + (pa.countDataSchemes() > 0 ? pa.getDataScheme(0) : "<none>")
4737                                    + "\n  component=" + pa.mPref.mComponent);
4738                            pa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
4739                        }
4740                        if (pa.mPref.mMatch != match) {
4741                            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping bad match "
4742                                    + Integer.toHexString(pa.mPref.mMatch));
4743                            continue;
4744                        }
4745                        // If it's not an "always" type preferred activity and that's what we're
4746                        // looking for, skip it.
4747                        if (always && !pa.mPref.mAlways) {
4748                            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping mAlways=false entry");
4749                            continue;
4750                        }
4751                        final ActivityInfo ai = getActivityInfo(pa.mPref.mComponent,
4752                                flags | MATCH_DISABLED_COMPONENTS, userId);
4753                        if (DEBUG_PREFERRED || debug) {
4754                            Slog.v(TAG, "Found preferred activity:");
4755                            if (ai != null) {
4756                                ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
4757                            } else {
4758                                Slog.v(TAG, "  null");
4759                            }
4760                        }
4761                        if (ai == null) {
4762                            // This previously registered preferred activity
4763                            // component is no longer known.  Most likely an update
4764                            // to the app was installed and in the new version this
4765                            // component no longer exists.  Clean it up by removing
4766                            // it from the preferred activities list, and skip it.
4767                            Slog.w(TAG, "Removing dangling preferred activity: "
4768                                    + pa.mPref.mComponent);
4769                            pir.removeFilter(pa);
4770                            changed = true;
4771                            continue;
4772                        }
4773                        for (int j=0; j<N; j++) {
4774                            final ResolveInfo ri = query.get(j);
4775                            if (!ri.activityInfo.applicationInfo.packageName
4776                                    .equals(ai.applicationInfo.packageName)) {
4777                                continue;
4778                            }
4779                            if (!ri.activityInfo.name.equals(ai.name)) {
4780                                continue;
4781                            }
4782
4783                            if (removeMatches) {
4784                                pir.removeFilter(pa);
4785                                changed = true;
4786                                if (DEBUG_PREFERRED) {
4787                                    Slog.v(TAG, "Removing match " + pa.mPref.mComponent);
4788                                }
4789                                break;
4790                            }
4791
4792                            // Okay we found a previously set preferred or last chosen app.
4793                            // If the result set is different from when this
4794                            // was created, we need to clear it and re-ask the
4795                            // user their preference, if we're looking for an "always" type entry.
4796                            if (always && !pa.mPref.sameSet(query)) {
4797                                Slog.i(TAG, "Result set changed, dropping preferred activity for "
4798                                        + intent + " type " + resolvedType);
4799                                if (DEBUG_PREFERRED) {
4800                                    Slog.v(TAG, "Removing preferred activity since set changed "
4801                                            + pa.mPref.mComponent);
4802                                }
4803                                pir.removeFilter(pa);
4804                                // Re-add the filter as a "last chosen" entry (!always)
4805                                PreferredActivity lastChosen = new PreferredActivity(
4806                                        pa, pa.mPref.mMatch, null, pa.mPref.mComponent, false);
4807                                pir.addFilter(lastChosen);
4808                                changed = true;
4809                                return null;
4810                            }
4811
4812                            // Yay! Either the set matched or we're looking for the last chosen
4813                            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Returning preferred activity: "
4814                                    + ri.activityInfo.packageName + "/" + ri.activityInfo.name);
4815                            return ri;
4816                        }
4817                    }
4818                } finally {
4819                    if (changed) {
4820                        if (DEBUG_PREFERRED) {
4821                            Slog.v(TAG, "Preferred activity bookkeeping changed; writing restrictions");
4822                        }
4823                        scheduleWritePackageRestrictionsLocked(userId);
4824                    }
4825                }
4826            }
4827        }
4828        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "No preferred activity to return");
4829        return null;
4830    }
4831
4832    /*
4833     * Returns if intent can be forwarded from the sourceUserId to the targetUserId
4834     */
4835    @Override
4836    public boolean canForwardTo(Intent intent, String resolvedType, int sourceUserId,
4837            int targetUserId) {
4838        mContext.enforceCallingOrSelfPermission(
4839                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
4840        List<CrossProfileIntentFilter> matches =
4841                getMatchingCrossProfileIntentFilters(intent, resolvedType, sourceUserId);
4842        if (matches != null) {
4843            int size = matches.size();
4844            for (int i = 0; i < size; i++) {
4845                if (matches.get(i).getTargetUserId() == targetUserId) return true;
4846            }
4847        }
4848        if (hasWebURI(intent)) {
4849            // cross-profile app linking works only towards the parent.
4850            final UserInfo parent = getProfileParent(sourceUserId);
4851            synchronized(mPackages) {
4852                CrossProfileDomainInfo xpDomainInfo = getCrossProfileDomainPreferredLpr(
4853                        intent, resolvedType, 0, sourceUserId, parent.id);
4854                return xpDomainInfo != null;
4855            }
4856        }
4857        return false;
4858    }
4859
4860    private UserInfo getProfileParent(int userId) {
4861        final long identity = Binder.clearCallingIdentity();
4862        try {
4863            return sUserManager.getProfileParent(userId);
4864        } finally {
4865            Binder.restoreCallingIdentity(identity);
4866        }
4867    }
4868
4869    private List<CrossProfileIntentFilter> getMatchingCrossProfileIntentFilters(Intent intent,
4870            String resolvedType, int userId) {
4871        CrossProfileIntentResolver resolver = mSettings.mCrossProfileIntentResolvers.get(userId);
4872        if (resolver != null) {
4873            return resolver.queryIntent(intent, resolvedType, false, userId);
4874        }
4875        return null;
4876    }
4877
4878    @Override
4879    public List<ResolveInfo> queryIntentActivities(Intent intent,
4880            String resolvedType, int flags, int userId) {
4881        if (!sUserManager.exists(userId)) return Collections.emptyList();
4882        flags = updateFlagsForResolve(flags, userId, intent);
4883        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "query intent activities");
4884        ComponentName comp = intent.getComponent();
4885        if (comp == null) {
4886            if (intent.getSelector() != null) {
4887                intent = intent.getSelector();
4888                comp = intent.getComponent();
4889            }
4890        }
4891
4892        if (comp != null) {
4893            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
4894            final ActivityInfo ai = getActivityInfo(comp, flags, userId);
4895            if (ai != null) {
4896                final ResolveInfo ri = new ResolveInfo();
4897                ri.activityInfo = ai;
4898                list.add(ri);
4899            }
4900            return list;
4901        }
4902
4903        // reader
4904        synchronized (mPackages) {
4905            final String pkgName = intent.getPackage();
4906            if (pkgName == null) {
4907                List<CrossProfileIntentFilter> matchingFilters =
4908                        getMatchingCrossProfileIntentFilters(intent, resolvedType, userId);
4909                // Check for results that need to skip the current profile.
4910                ResolveInfo xpResolveInfo  = querySkipCurrentProfileIntents(matchingFilters, intent,
4911                        resolvedType, flags, userId);
4912                if (xpResolveInfo != null) {
4913                    List<ResolveInfo> result = new ArrayList<ResolveInfo>(1);
4914                    result.add(xpResolveInfo);
4915                    return filterIfNotSystemUser(result, userId);
4916                }
4917
4918                // Check for results in the current profile.
4919                List<ResolveInfo> result = mActivities.queryIntent(
4920                        intent, resolvedType, flags, userId);
4921                result = filterIfNotSystemUser(result, userId);
4922
4923                // Check for cross profile results.
4924                boolean hasNonNegativePriorityResult = hasNonNegativePriority(result);
4925                xpResolveInfo = queryCrossProfileIntents(
4926                        matchingFilters, intent, resolvedType, flags, userId,
4927                        hasNonNegativePriorityResult);
4928                if (xpResolveInfo != null && isUserEnabled(xpResolveInfo.targetUserId)) {
4929                    boolean isVisibleToUser = filterIfNotSystemUser(
4930                            Collections.singletonList(xpResolveInfo), userId).size() > 0;
4931                    if (isVisibleToUser) {
4932                        result.add(xpResolveInfo);
4933                        Collections.sort(result, mResolvePrioritySorter);
4934                    }
4935                }
4936                if (hasWebURI(intent)) {
4937                    CrossProfileDomainInfo xpDomainInfo = null;
4938                    final UserInfo parent = getProfileParent(userId);
4939                    if (parent != null) {
4940                        xpDomainInfo = getCrossProfileDomainPreferredLpr(intent, resolvedType,
4941                                flags, userId, parent.id);
4942                    }
4943                    if (xpDomainInfo != null) {
4944                        if (xpResolveInfo != null) {
4945                            // If we didn't remove it, the cross-profile ResolveInfo would be twice
4946                            // in the result.
4947                            result.remove(xpResolveInfo);
4948                        }
4949                        if (result.size() == 0) {
4950                            result.add(xpDomainInfo.resolveInfo);
4951                            return result;
4952                        }
4953                    } else if (result.size() <= 1) {
4954                        return result;
4955                    }
4956                    result = filterCandidatesWithDomainPreferredActivitiesLPr(intent, flags, result,
4957                            xpDomainInfo, userId);
4958                    Collections.sort(result, mResolvePrioritySorter);
4959                }
4960                return result;
4961            }
4962            final PackageParser.Package pkg = mPackages.get(pkgName);
4963            if (pkg != null) {
4964                return filterIfNotSystemUser(
4965                        mActivities.queryIntentForPackage(
4966                                intent, resolvedType, flags, pkg.activities, userId),
4967                        userId);
4968            }
4969            return new ArrayList<ResolveInfo>();
4970        }
4971    }
4972
4973    private static class CrossProfileDomainInfo {
4974        /* ResolveInfo for IntentForwarderActivity to send the intent to the other profile */
4975        ResolveInfo resolveInfo;
4976        /* Best domain verification status of the activities found in the other profile */
4977        int bestDomainVerificationStatus;
4978    }
4979
4980    private CrossProfileDomainInfo getCrossProfileDomainPreferredLpr(Intent intent,
4981            String resolvedType, int flags, int sourceUserId, int parentUserId) {
4982        if (!sUserManager.hasUserRestriction(UserManager.ALLOW_PARENT_PROFILE_APP_LINKING,
4983                sourceUserId)) {
4984            return null;
4985        }
4986        List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent,
4987                resolvedType, flags, parentUserId);
4988
4989        if (resultTargetUser == null || resultTargetUser.isEmpty()) {
4990            return null;
4991        }
4992        CrossProfileDomainInfo result = null;
4993        int size = resultTargetUser.size();
4994        for (int i = 0; i < size; i++) {
4995            ResolveInfo riTargetUser = resultTargetUser.get(i);
4996            // Intent filter verification is only for filters that specify a host. So don't return
4997            // those that handle all web uris.
4998            if (riTargetUser.handleAllWebDataURI) {
4999                continue;
5000            }
5001            String packageName = riTargetUser.activityInfo.packageName;
5002            PackageSetting ps = mSettings.mPackages.get(packageName);
5003            if (ps == null) {
5004                continue;
5005            }
5006            long verificationState = getDomainVerificationStatusLPr(ps, parentUserId);
5007            int status = (int)(verificationState >> 32);
5008            if (result == null) {
5009                result = new CrossProfileDomainInfo();
5010                result.resolveInfo = createForwardingResolveInfoUnchecked(new IntentFilter(),
5011                        sourceUserId, parentUserId);
5012                result.bestDomainVerificationStatus = status;
5013            } else {
5014                result.bestDomainVerificationStatus = bestDomainVerificationStatus(status,
5015                        result.bestDomainVerificationStatus);
5016            }
5017        }
5018        // Don't consider matches with status NEVER across profiles.
5019        if (result != null && result.bestDomainVerificationStatus
5020                == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
5021            return null;
5022        }
5023        return result;
5024    }
5025
5026    /**
5027     * Verification statuses are ordered from the worse to the best, except for
5028     * INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER, which is the worse.
5029     */
5030    private int bestDomainVerificationStatus(int status1, int status2) {
5031        if (status1 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
5032            return status2;
5033        }
5034        if (status2 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
5035            return status1;
5036        }
5037        return (int) MathUtils.max(status1, status2);
5038    }
5039
5040    private boolean isUserEnabled(int userId) {
5041        long callingId = Binder.clearCallingIdentity();
5042        try {
5043            UserInfo userInfo = sUserManager.getUserInfo(userId);
5044            return userInfo != null && userInfo.isEnabled();
5045        } finally {
5046            Binder.restoreCallingIdentity(callingId);
5047        }
5048    }
5049
5050    /**
5051     * Filter out activities with systemUserOnly flag set, when current user is not System.
5052     *
5053     * @return filtered list
5054     */
5055    private List<ResolveInfo> filterIfNotSystemUser(List<ResolveInfo> resolveInfos, int userId) {
5056        if (userId == UserHandle.USER_SYSTEM) {
5057            return resolveInfos;
5058        }
5059        for (int i = resolveInfos.size() - 1; i >= 0; i--) {
5060            ResolveInfo info = resolveInfos.get(i);
5061            if ((info.activityInfo.flags & ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
5062                resolveInfos.remove(i);
5063            }
5064        }
5065        return resolveInfos;
5066    }
5067
5068    /**
5069     * @param resolveInfos list of resolve infos in descending priority order
5070     * @return if the list contains a resolve info with non-negative priority
5071     */
5072    private boolean hasNonNegativePriority(List<ResolveInfo> resolveInfos) {
5073        return resolveInfos.size() > 0 && resolveInfos.get(0).priority >= 0;
5074    }
5075
5076    private static boolean hasWebURI(Intent intent) {
5077        if (intent.getData() == null) {
5078            return false;
5079        }
5080        final String scheme = intent.getScheme();
5081        if (TextUtils.isEmpty(scheme)) {
5082            return false;
5083        }
5084        return scheme.equals(IntentFilter.SCHEME_HTTP) || scheme.equals(IntentFilter.SCHEME_HTTPS);
5085    }
5086
5087    private List<ResolveInfo> filterCandidatesWithDomainPreferredActivitiesLPr(Intent intent,
5088            int matchFlags, List<ResolveInfo> candidates, CrossProfileDomainInfo xpDomainInfo,
5089            int userId) {
5090        final boolean debug = (intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0;
5091
5092        if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) {
5093            Slog.v(TAG, "Filtering results with preferred activities. Candidates count: " +
5094                    candidates.size());
5095        }
5096
5097        ArrayList<ResolveInfo> result = new ArrayList<ResolveInfo>();
5098        ArrayList<ResolveInfo> alwaysList = new ArrayList<ResolveInfo>();
5099        ArrayList<ResolveInfo> undefinedList = new ArrayList<ResolveInfo>();
5100        ArrayList<ResolveInfo> alwaysAskList = new ArrayList<ResolveInfo>();
5101        ArrayList<ResolveInfo> neverList = new ArrayList<ResolveInfo>();
5102        ArrayList<ResolveInfo> matchAllList = new ArrayList<ResolveInfo>();
5103
5104        synchronized (mPackages) {
5105            final int count = candidates.size();
5106            // First, try to use linked apps. Partition the candidates into four lists:
5107            // one for the final results, one for the "do not use ever", one for "undefined status"
5108            // and finally one for "browser app type".
5109            for (int n=0; n<count; n++) {
5110                ResolveInfo info = candidates.get(n);
5111                String packageName = info.activityInfo.packageName;
5112                PackageSetting ps = mSettings.mPackages.get(packageName);
5113                if (ps != null) {
5114                    // Add to the special match all list (Browser use case)
5115                    if (info.handleAllWebDataURI) {
5116                        matchAllList.add(info);
5117                        continue;
5118                    }
5119                    // Try to get the status from User settings first
5120                    long packedStatus = getDomainVerificationStatusLPr(ps, userId);
5121                    int status = (int)(packedStatus >> 32);
5122                    int linkGeneration = (int)(packedStatus & 0xFFFFFFFF);
5123                    if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) {
5124                        if (DEBUG_DOMAIN_VERIFICATION) {
5125                            Slog.i(TAG, "  + always: " + info.activityInfo.packageName
5126                                    + " : linkgen=" + linkGeneration);
5127                        }
5128                        // Use link-enabled generation as preferredOrder, i.e.
5129                        // prefer newly-enabled over earlier-enabled.
5130                        info.preferredOrder = linkGeneration;
5131                        alwaysList.add(info);
5132                    } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
5133                        if (DEBUG_DOMAIN_VERIFICATION) {
5134                            Slog.i(TAG, "  + never: " + info.activityInfo.packageName);
5135                        }
5136                        neverList.add(info);
5137                    } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
5138                        if (DEBUG_DOMAIN_VERIFICATION) {
5139                            Slog.i(TAG, "  + always-ask: " + info.activityInfo.packageName);
5140                        }
5141                        alwaysAskList.add(info);
5142                    } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED ||
5143                            status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK) {
5144                        if (DEBUG_DOMAIN_VERIFICATION) {
5145                            Slog.i(TAG, "  + ask: " + info.activityInfo.packageName);
5146                        }
5147                        undefinedList.add(info);
5148                    }
5149                }
5150            }
5151
5152            // We'll want to include browser possibilities in a few cases
5153            boolean includeBrowser = false;
5154
5155            // First try to add the "always" resolution(s) for the current user, if any
5156            if (alwaysList.size() > 0) {
5157                result.addAll(alwaysList);
5158            } else {
5159                // Add all undefined apps as we want them to appear in the disambiguation dialog.
5160                result.addAll(undefinedList);
5161                // Maybe add one for the other profile.
5162                if (xpDomainInfo != null && (
5163                        xpDomainInfo.bestDomainVerificationStatus
5164                        != INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER)) {
5165                    result.add(xpDomainInfo.resolveInfo);
5166                }
5167                includeBrowser = true;
5168            }
5169
5170            // The presence of any 'always ask' alternatives means we'll also offer browsers.
5171            // If there were 'always' entries their preferred order has been set, so we also
5172            // back that off to make the alternatives equivalent
5173            if (alwaysAskList.size() > 0) {
5174                for (ResolveInfo i : result) {
5175                    i.preferredOrder = 0;
5176                }
5177                result.addAll(alwaysAskList);
5178                includeBrowser = true;
5179            }
5180
5181            if (includeBrowser) {
5182                // Also add browsers (all of them or only the default one)
5183                if (DEBUG_DOMAIN_VERIFICATION) {
5184                    Slog.v(TAG, "   ...including browsers in candidate set");
5185                }
5186                if ((matchFlags & MATCH_ALL) != 0) {
5187                    result.addAll(matchAllList);
5188                } else {
5189                    // Browser/generic handling case.  If there's a default browser, go straight
5190                    // to that (but only if there is no other higher-priority match).
5191                    final String defaultBrowserPackageName = getDefaultBrowserPackageName(userId);
5192                    int maxMatchPrio = 0;
5193                    ResolveInfo defaultBrowserMatch = null;
5194                    final int numCandidates = matchAllList.size();
5195                    for (int n = 0; n < numCandidates; n++) {
5196                        ResolveInfo info = matchAllList.get(n);
5197                        // track the highest overall match priority...
5198                        if (info.priority > maxMatchPrio) {
5199                            maxMatchPrio = info.priority;
5200                        }
5201                        // ...and the highest-priority default browser match
5202                        if (info.activityInfo.packageName.equals(defaultBrowserPackageName)) {
5203                            if (defaultBrowserMatch == null
5204                                    || (defaultBrowserMatch.priority < info.priority)) {
5205                                if (debug) {
5206                                    Slog.v(TAG, "Considering default browser match " + info);
5207                                }
5208                                defaultBrowserMatch = info;
5209                            }
5210                        }
5211                    }
5212                    if (defaultBrowserMatch != null
5213                            && defaultBrowserMatch.priority >= maxMatchPrio
5214                            && !TextUtils.isEmpty(defaultBrowserPackageName))
5215                    {
5216                        if (debug) {
5217                            Slog.v(TAG, "Default browser match " + defaultBrowserMatch);
5218                        }
5219                        result.add(defaultBrowserMatch);
5220                    } else {
5221                        result.addAll(matchAllList);
5222                    }
5223                }
5224
5225                // If there is nothing selected, add all candidates and remove the ones that the user
5226                // has explicitly put into the INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER state
5227                if (result.size() == 0) {
5228                    result.addAll(candidates);
5229                    result.removeAll(neverList);
5230                }
5231            }
5232        }
5233        if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) {
5234            Slog.v(TAG, "Filtered results with preferred activities. New candidates count: " +
5235                    result.size());
5236            for (ResolveInfo info : result) {
5237                Slog.v(TAG, "  + " + info.activityInfo);
5238            }
5239        }
5240        return result;
5241    }
5242
5243    // Returns a packed value as a long:
5244    //
5245    // high 'int'-sized word: link status: undefined/ask/never/always.
5246    // low 'int'-sized word: relative priority among 'always' results.
5247    private long getDomainVerificationStatusLPr(PackageSetting ps, int userId) {
5248        long result = ps.getDomainVerificationStatusForUser(userId);
5249        // if none available, get the master status
5250        if (result >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) {
5251            if (ps.getIntentFilterVerificationInfo() != null) {
5252                result = ((long)ps.getIntentFilterVerificationInfo().getStatus()) << 32;
5253            }
5254        }
5255        return result;
5256    }
5257
5258    private ResolveInfo querySkipCurrentProfileIntents(
5259            List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
5260            int flags, int sourceUserId) {
5261        if (matchingFilters != null) {
5262            int size = matchingFilters.size();
5263            for (int i = 0; i < size; i ++) {
5264                CrossProfileIntentFilter filter = matchingFilters.get(i);
5265                if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0) {
5266                    // Checking if there are activities in the target user that can handle the
5267                    // intent.
5268                    ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent,
5269                            resolvedType, flags, sourceUserId);
5270                    if (resolveInfo != null) {
5271                        return resolveInfo;
5272                    }
5273                }
5274            }
5275        }
5276        return null;
5277    }
5278
5279    // Return matching ResolveInfo in target user if any.
5280    private ResolveInfo queryCrossProfileIntents(
5281            List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
5282            int flags, int sourceUserId, boolean matchInCurrentProfile) {
5283        if (matchingFilters != null) {
5284            // Two {@link CrossProfileIntentFilter}s can have the same targetUserId and
5285            // match the same intent. For performance reasons, it is better not to
5286            // run queryIntent twice for the same userId
5287            SparseBooleanArray alreadyTriedUserIds = new SparseBooleanArray();
5288            int size = matchingFilters.size();
5289            for (int i = 0; i < size; i++) {
5290                CrossProfileIntentFilter filter = matchingFilters.get(i);
5291                int targetUserId = filter.getTargetUserId();
5292                boolean skipCurrentProfile =
5293                        (filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0;
5294                boolean skipCurrentProfileIfNoMatchFound =
5295                        (filter.getFlags() & PackageManager.ONLY_IF_NO_MATCH_FOUND) != 0;
5296                if (!skipCurrentProfile && !alreadyTriedUserIds.get(targetUserId)
5297                        && (!skipCurrentProfileIfNoMatchFound || !matchInCurrentProfile)) {
5298                    // Checking if there are activities in the target user that can handle the
5299                    // intent.
5300                    ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent,
5301                            resolvedType, flags, sourceUserId);
5302                    if (resolveInfo != null) return resolveInfo;
5303                    alreadyTriedUserIds.put(targetUserId, true);
5304                }
5305            }
5306        }
5307        return null;
5308    }
5309
5310    /**
5311     * If the filter's target user can handle the intent and is enabled: returns a ResolveInfo that
5312     * will forward the intent to the filter's target user.
5313     * Otherwise, returns null.
5314     */
5315    private ResolveInfo createForwardingResolveInfo(CrossProfileIntentFilter filter, Intent intent,
5316            String resolvedType, int flags, int sourceUserId) {
5317        int targetUserId = filter.getTargetUserId();
5318        List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent,
5319                resolvedType, flags, targetUserId);
5320        if (resultTargetUser != null && !resultTargetUser.isEmpty()
5321                && isUserEnabled(targetUserId)) {
5322            return createForwardingResolveInfoUnchecked(filter, sourceUserId, targetUserId);
5323        }
5324        return null;
5325    }
5326
5327    private ResolveInfo createForwardingResolveInfoUnchecked(IntentFilter filter,
5328            int sourceUserId, int targetUserId) {
5329        ResolveInfo forwardingResolveInfo = new ResolveInfo();
5330        long ident = Binder.clearCallingIdentity();
5331        boolean targetIsProfile;
5332        try {
5333            targetIsProfile = sUserManager.getUserInfo(targetUserId).isManagedProfile();
5334        } finally {
5335            Binder.restoreCallingIdentity(ident);
5336        }
5337        String className;
5338        if (targetIsProfile) {
5339            className = FORWARD_INTENT_TO_MANAGED_PROFILE;
5340        } else {
5341            className = FORWARD_INTENT_TO_PARENT;
5342        }
5343        ComponentName forwardingActivityComponentName = new ComponentName(
5344                mAndroidApplication.packageName, className);
5345        ActivityInfo forwardingActivityInfo = getActivityInfo(forwardingActivityComponentName, 0,
5346                sourceUserId);
5347        if (!targetIsProfile) {
5348            forwardingActivityInfo.showUserIcon = targetUserId;
5349            forwardingResolveInfo.noResourceId = true;
5350        }
5351        forwardingResolveInfo.activityInfo = forwardingActivityInfo;
5352        forwardingResolveInfo.priority = 0;
5353        forwardingResolveInfo.preferredOrder = 0;
5354        forwardingResolveInfo.match = 0;
5355        forwardingResolveInfo.isDefault = true;
5356        forwardingResolveInfo.filter = filter;
5357        forwardingResolveInfo.targetUserId = targetUserId;
5358        return forwardingResolveInfo;
5359    }
5360
5361    @Override
5362    public List<ResolveInfo> queryIntentActivityOptions(ComponentName caller,
5363            Intent[] specifics, String[] specificTypes, Intent intent,
5364            String resolvedType, int flags, int userId) {
5365        if (!sUserManager.exists(userId)) return Collections.emptyList();
5366        flags = updateFlagsForResolve(flags, userId, intent);
5367        enforceCrossUserPermission(Binder.getCallingUid(), userId, false,
5368                false, "query intent activity options");
5369        final String resultsAction = intent.getAction();
5370
5371        List<ResolveInfo> results = queryIntentActivities(intent, resolvedType, flags
5372                | PackageManager.GET_RESOLVED_FILTER, userId);
5373
5374        if (DEBUG_INTENT_MATCHING) {
5375            Log.v(TAG, "Query " + intent + ": " + results);
5376        }
5377
5378        int specificsPos = 0;
5379        int N;
5380
5381        // todo: note that the algorithm used here is O(N^2).  This
5382        // isn't a problem in our current environment, but if we start running
5383        // into situations where we have more than 5 or 10 matches then this
5384        // should probably be changed to something smarter...
5385
5386        // First we go through and resolve each of the specific items
5387        // that were supplied, taking care of removing any corresponding
5388        // duplicate items in the generic resolve list.
5389        if (specifics != null) {
5390            for (int i=0; i<specifics.length; i++) {
5391                final Intent sintent = specifics[i];
5392                if (sintent == null) {
5393                    continue;
5394                }
5395
5396                if (DEBUG_INTENT_MATCHING) {
5397                    Log.v(TAG, "Specific #" + i + ": " + sintent);
5398                }
5399
5400                String action = sintent.getAction();
5401                if (resultsAction != null && resultsAction.equals(action)) {
5402                    // If this action was explicitly requested, then don't
5403                    // remove things that have it.
5404                    action = null;
5405                }
5406
5407                ResolveInfo ri = null;
5408                ActivityInfo ai = null;
5409
5410                ComponentName comp = sintent.getComponent();
5411                if (comp == null) {
5412                    ri = resolveIntent(
5413                        sintent,
5414                        specificTypes != null ? specificTypes[i] : null,
5415                            flags, userId);
5416                    if (ri == null) {
5417                        continue;
5418                    }
5419                    if (ri == mResolveInfo) {
5420                        // ACK!  Must do something better with this.
5421                    }
5422                    ai = ri.activityInfo;
5423                    comp = new ComponentName(ai.applicationInfo.packageName,
5424                            ai.name);
5425                } else {
5426                    ai = getActivityInfo(comp, flags, userId);
5427                    if (ai == null) {
5428                        continue;
5429                    }
5430                }
5431
5432                // Look for any generic query activities that are duplicates
5433                // of this specific one, and remove them from the results.
5434                if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Specific #" + i + ": " + ai);
5435                N = results.size();
5436                int j;
5437                for (j=specificsPos; j<N; j++) {
5438                    ResolveInfo sri = results.get(j);
5439                    if ((sri.activityInfo.name.equals(comp.getClassName())
5440                            && sri.activityInfo.applicationInfo.packageName.equals(
5441                                    comp.getPackageName()))
5442                        || (action != null && sri.filter.matchAction(action))) {
5443                        results.remove(j);
5444                        if (DEBUG_INTENT_MATCHING) Log.v(
5445                            TAG, "Removing duplicate item from " + j
5446                            + " due to specific " + specificsPos);
5447                        if (ri == null) {
5448                            ri = sri;
5449                        }
5450                        j--;
5451                        N--;
5452                    }
5453                }
5454
5455                // Add this specific item to its proper place.
5456                if (ri == null) {
5457                    ri = new ResolveInfo();
5458                    ri.activityInfo = ai;
5459                }
5460                results.add(specificsPos, ri);
5461                ri.specificIndex = i;
5462                specificsPos++;
5463            }
5464        }
5465
5466        // Now we go through the remaining generic results and remove any
5467        // duplicate actions that are found here.
5468        N = results.size();
5469        for (int i=specificsPos; i<N-1; i++) {
5470            final ResolveInfo rii = results.get(i);
5471            if (rii.filter == null) {
5472                continue;
5473            }
5474
5475            // Iterate over all of the actions of this result's intent
5476            // filter...  typically this should be just one.
5477            final Iterator<String> it = rii.filter.actionsIterator();
5478            if (it == null) {
5479                continue;
5480            }
5481            while (it.hasNext()) {
5482                final String action = it.next();
5483                if (resultsAction != null && resultsAction.equals(action)) {
5484                    // If this action was explicitly requested, then don't
5485                    // remove things that have it.
5486                    continue;
5487                }
5488                for (int j=i+1; j<N; j++) {
5489                    final ResolveInfo rij = results.get(j);
5490                    if (rij.filter != null && rij.filter.hasAction(action)) {
5491                        results.remove(j);
5492                        if (DEBUG_INTENT_MATCHING) Log.v(
5493                            TAG, "Removing duplicate item from " + j
5494                            + " due to action " + action + " at " + i);
5495                        j--;
5496                        N--;
5497                    }
5498                }
5499            }
5500
5501            // If the caller didn't request filter information, drop it now
5502            // so we don't have to marshall/unmarshall it.
5503            if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
5504                rii.filter = null;
5505            }
5506        }
5507
5508        // Filter out the caller activity if so requested.
5509        if (caller != null) {
5510            N = results.size();
5511            for (int i=0; i<N; i++) {
5512                ActivityInfo ainfo = results.get(i).activityInfo;
5513                if (caller.getPackageName().equals(ainfo.applicationInfo.packageName)
5514                        && caller.getClassName().equals(ainfo.name)) {
5515                    results.remove(i);
5516                    break;
5517                }
5518            }
5519        }
5520
5521        // If the caller didn't request filter information,
5522        // drop them now so we don't have to
5523        // marshall/unmarshall it.
5524        if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
5525            N = results.size();
5526            for (int i=0; i<N; i++) {
5527                results.get(i).filter = null;
5528            }
5529        }
5530
5531        if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Result: " + results);
5532        return results;
5533    }
5534
5535    @Override
5536    public List<ResolveInfo> queryIntentReceivers(Intent intent, String resolvedType, int flags,
5537            int userId) {
5538        if (!sUserManager.exists(userId)) return Collections.emptyList();
5539        flags = updateFlagsForResolve(flags, userId, intent);
5540        ComponentName comp = intent.getComponent();
5541        if (comp == null) {
5542            if (intent.getSelector() != null) {
5543                intent = intent.getSelector();
5544                comp = intent.getComponent();
5545            }
5546        }
5547        if (comp != null) {
5548            List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
5549            ActivityInfo ai = getReceiverInfo(comp, flags, userId);
5550            if (ai != null) {
5551                ResolveInfo ri = new ResolveInfo();
5552                ri.activityInfo = ai;
5553                list.add(ri);
5554            }
5555            return list;
5556        }
5557
5558        // reader
5559        synchronized (mPackages) {
5560            String pkgName = intent.getPackage();
5561            if (pkgName == null) {
5562                return mReceivers.queryIntent(intent, resolvedType, flags, userId);
5563            }
5564            final PackageParser.Package pkg = mPackages.get(pkgName);
5565            if (pkg != null) {
5566                return mReceivers.queryIntentForPackage(intent, resolvedType, flags, pkg.receivers,
5567                        userId);
5568            }
5569            return null;
5570        }
5571    }
5572
5573    @Override
5574    public ResolveInfo resolveService(Intent intent, String resolvedType, int flags, int userId) {
5575        if (!sUserManager.exists(userId)) return null;
5576        flags = updateFlagsForResolve(flags, userId, intent);
5577        List<ResolveInfo> query = queryIntentServices(intent, resolvedType, flags, userId);
5578        if (query != null) {
5579            if (query.size() >= 1) {
5580                // If there is more than one service with the same priority,
5581                // just arbitrarily pick the first one.
5582                return query.get(0);
5583            }
5584        }
5585        return null;
5586    }
5587
5588    @Override
5589    public List<ResolveInfo> queryIntentServices(Intent intent, String resolvedType, int flags,
5590            int userId) {
5591        if (!sUserManager.exists(userId)) return Collections.emptyList();
5592        flags = updateFlagsForResolve(flags, userId, intent);
5593        ComponentName comp = intent.getComponent();
5594        if (comp == null) {
5595            if (intent.getSelector() != null) {
5596                intent = intent.getSelector();
5597                comp = intent.getComponent();
5598            }
5599        }
5600        if (comp != null) {
5601            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
5602            final ServiceInfo si = getServiceInfo(comp, flags, userId);
5603            if (si != null) {
5604                final ResolveInfo ri = new ResolveInfo();
5605                ri.serviceInfo = si;
5606                list.add(ri);
5607            }
5608            return list;
5609        }
5610
5611        // reader
5612        synchronized (mPackages) {
5613            String pkgName = intent.getPackage();
5614            if (pkgName == null) {
5615                return mServices.queryIntent(intent, resolvedType, flags, userId);
5616            }
5617            final PackageParser.Package pkg = mPackages.get(pkgName);
5618            if (pkg != null) {
5619                return mServices.queryIntentForPackage(intent, resolvedType, flags, pkg.services,
5620                        userId);
5621            }
5622            return null;
5623        }
5624    }
5625
5626    @Override
5627    public List<ResolveInfo> queryIntentContentProviders(
5628            Intent intent, String resolvedType, int flags, int userId) {
5629        if (!sUserManager.exists(userId)) return Collections.emptyList();
5630        flags = updateFlagsForResolve(flags, userId, intent);
5631        ComponentName comp = intent.getComponent();
5632        if (comp == null) {
5633            if (intent.getSelector() != null) {
5634                intent = intent.getSelector();
5635                comp = intent.getComponent();
5636            }
5637        }
5638        if (comp != null) {
5639            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
5640            final ProviderInfo pi = getProviderInfo(comp, flags, userId);
5641            if (pi != null) {
5642                final ResolveInfo ri = new ResolveInfo();
5643                ri.providerInfo = pi;
5644                list.add(ri);
5645            }
5646            return list;
5647        }
5648
5649        // reader
5650        synchronized (mPackages) {
5651            String pkgName = intent.getPackage();
5652            if (pkgName == null) {
5653                return mProviders.queryIntent(intent, resolvedType, flags, userId);
5654            }
5655            final PackageParser.Package pkg = mPackages.get(pkgName);
5656            if (pkg != null) {
5657                return mProviders.queryIntentForPackage(
5658                        intent, resolvedType, flags, pkg.providers, userId);
5659            }
5660            return null;
5661        }
5662    }
5663
5664    @Override
5665    public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) {
5666        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
5667        flags = updateFlagsForPackage(flags, userId, null);
5668        final boolean listUninstalled = (flags & MATCH_UNINSTALLED_PACKAGES) != 0;
5669        enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, "get installed packages");
5670
5671        // writer
5672        synchronized (mPackages) {
5673            ArrayList<PackageInfo> list;
5674            if (listUninstalled) {
5675                list = new ArrayList<PackageInfo>(mSettings.mPackages.size());
5676                for (PackageSetting ps : mSettings.mPackages.values()) {
5677                    PackageInfo pi;
5678                    if (ps.pkg != null) {
5679                        pi = generatePackageInfo(ps.pkg, flags, userId);
5680                    } else {
5681                        pi = generatePackageInfoFromSettingsLPw(ps.name, flags, userId);
5682                    }
5683                    if (pi != null) {
5684                        list.add(pi);
5685                    }
5686                }
5687            } else {
5688                list = new ArrayList<PackageInfo>(mPackages.size());
5689                for (PackageParser.Package p : mPackages.values()) {
5690                    PackageInfo pi = generatePackageInfo(p, flags, userId);
5691                    if (pi != null) {
5692                        list.add(pi);
5693                    }
5694                }
5695            }
5696
5697            return new ParceledListSlice<PackageInfo>(list);
5698        }
5699    }
5700
5701    private void addPackageHoldingPermissions(ArrayList<PackageInfo> list, PackageSetting ps,
5702            String[] permissions, boolean[] tmp, int flags, int userId) {
5703        int numMatch = 0;
5704        final PermissionsState permissionsState = ps.getPermissionsState();
5705        for (int i=0; i<permissions.length; i++) {
5706            final String permission = permissions[i];
5707            if (permissionsState.hasPermission(permission, userId)) {
5708                tmp[i] = true;
5709                numMatch++;
5710            } else {
5711                tmp[i] = false;
5712            }
5713        }
5714        if (numMatch == 0) {
5715            return;
5716        }
5717        PackageInfo pi;
5718        if (ps.pkg != null) {
5719            pi = generatePackageInfo(ps.pkg, flags, userId);
5720        } else {
5721            pi = generatePackageInfoFromSettingsLPw(ps.name, flags, userId);
5722        }
5723        // The above might return null in cases of uninstalled apps or install-state
5724        // skew across users/profiles.
5725        if (pi != null) {
5726            if ((flags&PackageManager.GET_PERMISSIONS) == 0) {
5727                if (numMatch == permissions.length) {
5728                    pi.requestedPermissions = permissions;
5729                } else {
5730                    pi.requestedPermissions = new String[numMatch];
5731                    numMatch = 0;
5732                    for (int i=0; i<permissions.length; i++) {
5733                        if (tmp[i]) {
5734                            pi.requestedPermissions[numMatch] = permissions[i];
5735                            numMatch++;
5736                        }
5737                    }
5738                }
5739            }
5740            list.add(pi);
5741        }
5742    }
5743
5744    @Override
5745    public ParceledListSlice<PackageInfo> getPackagesHoldingPermissions(
5746            String[] permissions, int flags, int userId) {
5747        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
5748        flags = updateFlagsForPackage(flags, userId, permissions);
5749        final boolean listUninstalled = (flags & MATCH_UNINSTALLED_PACKAGES) != 0;
5750
5751        // writer
5752        synchronized (mPackages) {
5753            ArrayList<PackageInfo> list = new ArrayList<PackageInfo>();
5754            boolean[] tmpBools = new boolean[permissions.length];
5755            if (listUninstalled) {
5756                for (PackageSetting ps : mSettings.mPackages.values()) {
5757                    addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags, userId);
5758                }
5759            } else {
5760                for (PackageParser.Package pkg : mPackages.values()) {
5761                    PackageSetting ps = (PackageSetting)pkg.mExtras;
5762                    if (ps != null) {
5763                        addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags,
5764                                userId);
5765                    }
5766                }
5767            }
5768
5769            return new ParceledListSlice<PackageInfo>(list);
5770        }
5771    }
5772
5773    @Override
5774    public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags, int userId) {
5775        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
5776        flags = updateFlagsForApplication(flags, userId, null);
5777        final boolean listUninstalled = (flags & MATCH_UNINSTALLED_PACKAGES) != 0;
5778
5779        // writer
5780        synchronized (mPackages) {
5781            ArrayList<ApplicationInfo> list;
5782            if (listUninstalled) {
5783                list = new ArrayList<ApplicationInfo>(mSettings.mPackages.size());
5784                for (PackageSetting ps : mSettings.mPackages.values()) {
5785                    ApplicationInfo ai;
5786                    if (ps.pkg != null) {
5787                        ai = PackageParser.generateApplicationInfo(ps.pkg, flags,
5788                                ps.readUserState(userId), userId);
5789                    } else {
5790                        ai = generateApplicationInfoFromSettingsLPw(ps.name, flags, userId);
5791                    }
5792                    if (ai != null) {
5793                        list.add(ai);
5794                    }
5795                }
5796            } else {
5797                list = new ArrayList<ApplicationInfo>(mPackages.size());
5798                for (PackageParser.Package p : mPackages.values()) {
5799                    if (p.mExtras != null) {
5800                        ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
5801                                ((PackageSetting)p.mExtras).readUserState(userId), userId);
5802                        if (ai != null) {
5803                            list.add(ai);
5804                        }
5805                    }
5806                }
5807            }
5808
5809            return new ParceledListSlice<ApplicationInfo>(list);
5810        }
5811    }
5812
5813    @Override
5814    public ParceledListSlice<EphemeralApplicationInfo> getEphemeralApplications(int userId) {
5815        mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_EPHEMERAL_APPS,
5816                "getEphemeralApplications");
5817        enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false,
5818                "getEphemeralApplications");
5819        synchronized (mPackages) {
5820            List<EphemeralApplicationInfo> ephemeralApps = mEphemeralApplicationRegistry
5821                    .getEphemeralApplicationsLPw(userId);
5822            if (ephemeralApps != null) {
5823                return new ParceledListSlice<>(ephemeralApps);
5824            }
5825        }
5826        return null;
5827    }
5828
5829    @Override
5830    public boolean isEphemeralApplication(String packageName, int userId) {
5831        enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false,
5832                "isEphemeral");
5833        if (!isCallerSameApp(packageName)) {
5834            return false;
5835        }
5836        synchronized (mPackages) {
5837            PackageParser.Package pkg = mPackages.get(packageName);
5838            if (pkg != null) {
5839                return pkg.applicationInfo.isEphemeralApp();
5840            }
5841        }
5842        return false;
5843    }
5844
5845    @Override
5846    public byte[] getEphemeralApplicationCookie(String packageName, int userId) {
5847        enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false,
5848                "getCookie");
5849        if (!isCallerSameApp(packageName)) {
5850            return null;
5851        }
5852        synchronized (mPackages) {
5853            return mEphemeralApplicationRegistry.getEphemeralApplicationCookieLPw(
5854                    packageName, userId);
5855        }
5856    }
5857
5858    @Override
5859    public boolean setEphemeralApplicationCookie(String packageName, byte[] cookie, int userId) {
5860        enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false,
5861                "setCookie");
5862        if (!isCallerSameApp(packageName)) {
5863            return false;
5864        }
5865        synchronized (mPackages) {
5866            return mEphemeralApplicationRegistry.setEphemeralApplicationCookieLPw(
5867                    packageName, cookie, userId);
5868        }
5869    }
5870
5871    @Override
5872    public Bitmap getEphemeralApplicationIcon(String packageName, int userId) {
5873        mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_EPHEMERAL_APPS,
5874                "getEphemeralApplicationIcon");
5875        enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false,
5876                "getEphemeralApplicationIcon");
5877        synchronized (mPackages) {
5878            return mEphemeralApplicationRegistry.getEphemeralApplicationIconLPw(
5879                    packageName, userId);
5880        }
5881    }
5882
5883    private boolean isCallerSameApp(String packageName) {
5884        PackageParser.Package pkg = mPackages.get(packageName);
5885        return pkg != null
5886                && UserHandle.getAppId(Binder.getCallingUid()) == pkg.applicationInfo.uid;
5887    }
5888
5889    public List<ApplicationInfo> getPersistentApplications(int flags) {
5890        final ArrayList<ApplicationInfo> finalList = new ArrayList<ApplicationInfo>();
5891
5892        // reader
5893        synchronized (mPackages) {
5894            final Iterator<PackageParser.Package> i = mPackages.values().iterator();
5895            final int userId = UserHandle.getCallingUserId();
5896            while (i.hasNext()) {
5897                final PackageParser.Package p = i.next();
5898                if (p.applicationInfo != null
5899                        && (p.applicationInfo.flags&ApplicationInfo.FLAG_PERSISTENT) != 0
5900                        && (!mSafeMode || isSystemApp(p))) {
5901                    PackageSetting ps = mSettings.mPackages.get(p.packageName);
5902                    if (ps != null) {
5903                        ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
5904                                ps.readUserState(userId), userId);
5905                        if (ai != null) {
5906                            finalList.add(ai);
5907                        }
5908                    }
5909                }
5910            }
5911        }
5912
5913        return finalList;
5914    }
5915
5916    @Override
5917    public ProviderInfo resolveContentProvider(String name, int flags, int userId) {
5918        if (!sUserManager.exists(userId)) return null;
5919        flags = updateFlagsForComponent(flags, userId, name);
5920        // reader
5921        synchronized (mPackages) {
5922            final PackageParser.Provider provider = mProvidersByAuthority.get(name);
5923            PackageSetting ps = provider != null
5924                    ? mSettings.mPackages.get(provider.owner.packageName)
5925                    : null;
5926            return ps != null
5927                    && mSettings.isEnabledAndMatchLPr(provider.info, flags, userId)
5928                    && (!mSafeMode || (provider.info.applicationInfo.flags
5929                            &ApplicationInfo.FLAG_SYSTEM) != 0)
5930                    ? PackageParser.generateProviderInfo(provider, flags,
5931                            ps.readUserState(userId), userId)
5932                    : null;
5933        }
5934    }
5935
5936    /**
5937     * @deprecated
5938     */
5939    @Deprecated
5940    public void querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo) {
5941        // reader
5942        synchronized (mPackages) {
5943            final Iterator<Map.Entry<String, PackageParser.Provider>> i = mProvidersByAuthority
5944                    .entrySet().iterator();
5945            final int userId = UserHandle.getCallingUserId();
5946            while (i.hasNext()) {
5947                Map.Entry<String, PackageParser.Provider> entry = i.next();
5948                PackageParser.Provider p = entry.getValue();
5949                PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
5950
5951                if (ps != null && p.syncable
5952                        && (!mSafeMode || (p.info.applicationInfo.flags
5953                                &ApplicationInfo.FLAG_SYSTEM) != 0)) {
5954                    ProviderInfo info = PackageParser.generateProviderInfo(p, 0,
5955                            ps.readUserState(userId), userId);
5956                    if (info != null) {
5957                        outNames.add(entry.getKey());
5958                        outInfo.add(info);
5959                    }
5960                }
5961            }
5962        }
5963    }
5964
5965    @Override
5966    public ParceledListSlice<ProviderInfo> queryContentProviders(String processName,
5967            int uid, int flags) {
5968        final int userId = processName != null ? UserHandle.getUserId(uid)
5969                : UserHandle.getCallingUserId();
5970        if (!sUserManager.exists(userId)) return null;
5971        flags = updateFlagsForComponent(flags, userId, processName);
5972
5973        ArrayList<ProviderInfo> finalList = null;
5974        // reader
5975        synchronized (mPackages) {
5976            final Iterator<PackageParser.Provider> i = mProviders.mProviders.values().iterator();
5977            while (i.hasNext()) {
5978                final PackageParser.Provider p = i.next();
5979                PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
5980                if (ps != null && p.info.authority != null
5981                        && (processName == null
5982                                || (p.info.processName.equals(processName)
5983                                        && UserHandle.isSameApp(p.info.applicationInfo.uid, uid)))
5984                        && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)
5985                        && (!mSafeMode
5986                                || (p.info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0)) {
5987                    if (finalList == null) {
5988                        finalList = new ArrayList<ProviderInfo>(3);
5989                    }
5990                    ProviderInfo info = PackageParser.generateProviderInfo(p, flags,
5991                            ps.readUserState(userId), userId);
5992                    if (info != null) {
5993                        finalList.add(info);
5994                    }
5995                }
5996            }
5997        }
5998
5999        if (finalList != null) {
6000            Collections.sort(finalList, mProviderInitOrderSorter);
6001            return new ParceledListSlice<ProviderInfo>(finalList);
6002        }
6003
6004        return null;
6005    }
6006
6007    @Override
6008    public InstrumentationInfo getInstrumentationInfo(ComponentName name, int flags) {
6009        // reader
6010        synchronized (mPackages) {
6011            final PackageParser.Instrumentation i = mInstrumentation.get(name);
6012            return PackageParser.generateInstrumentationInfo(i, flags);
6013        }
6014    }
6015
6016    @Override
6017    public List<InstrumentationInfo> queryInstrumentation(String targetPackage,
6018            int flags) {
6019        ArrayList<InstrumentationInfo> finalList =
6020            new ArrayList<InstrumentationInfo>();
6021
6022        // reader
6023        synchronized (mPackages) {
6024            final Iterator<PackageParser.Instrumentation> i = mInstrumentation.values().iterator();
6025            while (i.hasNext()) {
6026                final PackageParser.Instrumentation p = i.next();
6027                if (targetPackage == null
6028                        || targetPackage.equals(p.info.targetPackage)) {
6029                    InstrumentationInfo ii = PackageParser.generateInstrumentationInfo(p,
6030                            flags);
6031                    if (ii != null) {
6032                        finalList.add(ii);
6033                    }
6034                }
6035            }
6036        }
6037
6038        return finalList;
6039    }
6040
6041    private void createIdmapsForPackageLI(PackageParser.Package pkg) {
6042        ArrayMap<String, PackageParser.Package> overlays = mOverlays.get(pkg.packageName);
6043        if (overlays == null) {
6044            Slog.w(TAG, "Unable to create idmap for " + pkg.packageName + ": no overlay packages");
6045            return;
6046        }
6047        for (PackageParser.Package opkg : overlays.values()) {
6048            // Not much to do if idmap fails: we already logged the error
6049            // and we certainly don't want to abort installation of pkg simply
6050            // because an overlay didn't fit properly. For these reasons,
6051            // ignore the return value of createIdmapForPackagePairLI.
6052            createIdmapForPackagePairLI(pkg, opkg);
6053        }
6054    }
6055
6056    private boolean createIdmapForPackagePairLI(PackageParser.Package pkg,
6057            PackageParser.Package opkg) {
6058        if (!opkg.mTrustedOverlay) {
6059            Slog.w(TAG, "Skipping target and overlay pair " + pkg.baseCodePath + " and " +
6060                    opkg.baseCodePath + ": overlay not trusted");
6061            return false;
6062        }
6063        ArrayMap<String, PackageParser.Package> overlaySet = mOverlays.get(pkg.packageName);
6064        if (overlaySet == null) {
6065            Slog.e(TAG, "was about to create idmap for " + pkg.baseCodePath + " and " +
6066                    opkg.baseCodePath + " but target package has no known overlays");
6067            return false;
6068        }
6069        final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
6070        // TODO: generate idmap for split APKs
6071        if (mInstaller.idmap(pkg.baseCodePath, opkg.baseCodePath, sharedGid) != 0) {
6072            Slog.e(TAG, "Failed to generate idmap for " + pkg.baseCodePath + " and "
6073                    + opkg.baseCodePath);
6074            return false;
6075        }
6076        PackageParser.Package[] overlayArray =
6077            overlaySet.values().toArray(new PackageParser.Package[0]);
6078        Comparator<PackageParser.Package> cmp = new Comparator<PackageParser.Package>() {
6079            public int compare(PackageParser.Package p1, PackageParser.Package p2) {
6080                return p1.mOverlayPriority - p2.mOverlayPriority;
6081            }
6082        };
6083        Arrays.sort(overlayArray, cmp);
6084
6085        pkg.applicationInfo.resourceDirs = new String[overlayArray.length];
6086        int i = 0;
6087        for (PackageParser.Package p : overlayArray) {
6088            pkg.applicationInfo.resourceDirs[i++] = p.baseCodePath;
6089        }
6090        return true;
6091    }
6092
6093    private void scanDirTracedLI(File dir, int parseFlags, int scanFlags, long currentTime) {
6094        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanDir");
6095        try {
6096            scanDirLI(dir, parseFlags, scanFlags, currentTime);
6097        } finally {
6098            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
6099        }
6100    }
6101
6102    private void scanDirLI(File dir, int parseFlags, int scanFlags, long currentTime) {
6103        final File[] files = dir.listFiles();
6104        if (ArrayUtils.isEmpty(files)) {
6105            Log.d(TAG, "No files in app dir " + dir);
6106            return;
6107        }
6108
6109        if (DEBUG_PACKAGE_SCANNING) {
6110            Log.d(TAG, "Scanning app dir " + dir + " scanFlags=" + scanFlags
6111                    + " flags=0x" + Integer.toHexString(parseFlags));
6112        }
6113
6114        for (File file : files) {
6115            final boolean isPackage = (isApkFile(file) || file.isDirectory())
6116                    && !PackageInstallerService.isStageName(file.getName());
6117            if (!isPackage) {
6118                // Ignore entries which are not packages
6119                continue;
6120            }
6121            try {
6122                scanPackageTracedLI(file, parseFlags | PackageParser.PARSE_MUST_BE_APK,
6123                        scanFlags, currentTime, null);
6124            } catch (PackageManagerException e) {
6125                Slog.w(TAG, "Failed to parse " + file + ": " + e.getMessage());
6126
6127                // Delete invalid userdata apps
6128                if ((parseFlags & PackageParser.PARSE_IS_SYSTEM) == 0 &&
6129                        e.error == PackageManager.INSTALL_FAILED_INVALID_APK) {
6130                    logCriticalInfo(Log.WARN, "Deleting invalid package at " + file);
6131                    if (file.isDirectory()) {
6132                        mInstaller.rmPackageDir(file.getAbsolutePath());
6133                    } else {
6134                        file.delete();
6135                    }
6136                }
6137            }
6138        }
6139    }
6140
6141    private static File getSettingsProblemFile() {
6142        File dataDir = Environment.getDataDirectory();
6143        File systemDir = new File(dataDir, "system");
6144        File fname = new File(systemDir, "uiderrors.txt");
6145        return fname;
6146    }
6147
6148    static void reportSettingsProblem(int priority, String msg) {
6149        logCriticalInfo(priority, msg);
6150    }
6151
6152    static void logCriticalInfo(int priority, String msg) {
6153        Slog.println(priority, TAG, msg);
6154        EventLogTags.writePmCriticalInfo(msg);
6155        try {
6156            File fname = getSettingsProblemFile();
6157            FileOutputStream out = new FileOutputStream(fname, true);
6158            PrintWriter pw = new FastPrintWriter(out);
6159            SimpleDateFormat formatter = new SimpleDateFormat();
6160            String dateString = formatter.format(new Date(System.currentTimeMillis()));
6161            pw.println(dateString + ": " + msg);
6162            pw.close();
6163            FileUtils.setPermissions(
6164                    fname.toString(),
6165                    FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IROTH,
6166                    -1, -1);
6167        } catch (java.io.IOException e) {
6168        }
6169    }
6170
6171    private void collectCertificatesLI(PackageParser pp, PackageSetting ps,
6172            PackageParser.Package pkg, File srcFile, int parseFlags)
6173            throws PackageManagerException {
6174        if (ps != null
6175                && ps.codePath.equals(srcFile)
6176                && ps.timeStamp == srcFile.lastModified()
6177                && !isCompatSignatureUpdateNeeded(pkg)
6178                && !isRecoverSignatureUpdateNeeded(pkg)) {
6179            long mSigningKeySetId = ps.keySetData.getProperSigningKeySet();
6180            KeySetManagerService ksms = mSettings.mKeySetManagerService;
6181            ArraySet<PublicKey> signingKs;
6182            synchronized (mPackages) {
6183                signingKs = ksms.getPublicKeysFromKeySetLPr(mSigningKeySetId);
6184            }
6185            if (ps.signatures.mSignatures != null
6186                    && ps.signatures.mSignatures.length != 0
6187                    && signingKs != null) {
6188                // Optimization: reuse the existing cached certificates
6189                // if the package appears to be unchanged.
6190                pkg.mSignatures = ps.signatures.mSignatures;
6191                pkg.mSigningKeys = signingKs;
6192                return;
6193            }
6194
6195            Slog.w(TAG, "PackageSetting for " + ps.name
6196                    + " is missing signatures.  Collecting certs again to recover them.");
6197        } else {
6198            Log.i(TAG, srcFile.toString() + " changed; collecting certs");
6199        }
6200
6201        try {
6202            pp.collectCertificates(pkg, parseFlags);
6203        } catch (PackageParserException e) {
6204            throw PackageManagerException.from(e);
6205        }
6206    }
6207
6208    /**
6209     *  Traces a package scan.
6210     *  @see #scanPackageLI(File, int, int, long, UserHandle)
6211     */
6212    private PackageParser.Package scanPackageTracedLI(File scanFile, int parseFlags, int scanFlags,
6213            long currentTime, UserHandle user) throws PackageManagerException {
6214        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage");
6215        try {
6216            return scanPackageLI(scanFile, parseFlags, scanFlags, currentTime, user);
6217        } finally {
6218            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
6219        }
6220    }
6221
6222    /**
6223     *  Scans a package and returns the newly parsed package.
6224     *  Returns {@code null} in case of errors and the error code is stored in mLastScanError
6225     */
6226    private PackageParser.Package scanPackageLI(File scanFile, int parseFlags, int scanFlags,
6227            long currentTime, UserHandle user) throws PackageManagerException {
6228        if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanFile);
6229        parseFlags |= mDefParseFlags;
6230        PackageParser pp = new PackageParser();
6231        pp.setSeparateProcesses(mSeparateProcesses);
6232        pp.setOnlyCoreApps(mOnlyCore);
6233        pp.setDisplayMetrics(mMetrics);
6234
6235        if ((scanFlags & SCAN_TRUSTED_OVERLAY) != 0) {
6236            parseFlags |= PackageParser.PARSE_TRUSTED_OVERLAY;
6237        }
6238
6239        final PackageParser.Package pkg;
6240        try {
6241            pkg = pp.parsePackage(scanFile, parseFlags);
6242        } catch (PackageParserException e) {
6243            throw PackageManagerException.from(e);
6244        }
6245
6246        PackageSetting ps = null;
6247        PackageSetting updatedPkg;
6248        // reader
6249        synchronized (mPackages) {
6250            // Look to see if we already know about this package.
6251            String oldName = mSettings.mRenamedPackages.get(pkg.packageName);
6252            if (pkg.mOriginalPackages != null && pkg.mOriginalPackages.contains(oldName)) {
6253                // This package has been renamed to its original name.  Let's
6254                // use that.
6255                ps = mSettings.peekPackageLPr(oldName);
6256            }
6257            // If there was no original package, see one for the real package name.
6258            if (ps == null) {
6259                ps = mSettings.peekPackageLPr(pkg.packageName);
6260            }
6261            // Check to see if this package could be hiding/updating a system
6262            // package.  Must look for it either under the original or real
6263            // package name depending on our state.
6264            updatedPkg = mSettings.getDisabledSystemPkgLPr(ps != null ? ps.name : pkg.packageName);
6265            if (DEBUG_INSTALL && updatedPkg != null) Slog.d(TAG, "updatedPkg = " + updatedPkg);
6266        }
6267        boolean updatedPkgBetter = false;
6268        // First check if this is a system package that may involve an update
6269        if (updatedPkg != null && (parseFlags & PackageParser.PARSE_IS_SYSTEM) != 0) {
6270            // If new package is not located in "/system/priv-app" (e.g. due to an OTA),
6271            // it needs to drop FLAG_PRIVILEGED.
6272            if (locationIsPrivileged(scanFile)) {
6273                updatedPkg.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
6274            } else {
6275                updatedPkg.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
6276            }
6277
6278            if (ps != null && !ps.codePath.equals(scanFile)) {
6279                // The path has changed from what was last scanned...  check the
6280                // version of the new path against what we have stored to determine
6281                // what to do.
6282                if (DEBUG_INSTALL) Slog.d(TAG, "Path changing from " + ps.codePath);
6283                if (pkg.mVersionCode <= ps.versionCode) {
6284                    // The system package has been updated and the code path does not match
6285                    // Ignore entry. Skip it.
6286                    if (DEBUG_INSTALL) Slog.i(TAG, "Package " + ps.name + " at " + scanFile
6287                            + " ignored: updated version " + ps.versionCode
6288                            + " better than this " + pkg.mVersionCode);
6289                    if (!updatedPkg.codePath.equals(scanFile)) {
6290                        Slog.w(PackageManagerService.TAG, "Code path for hidden system pkg "
6291                                + ps.name + " changing from " + updatedPkg.codePathString
6292                                + " to " + scanFile);
6293                        updatedPkg.codePath = scanFile;
6294                        updatedPkg.codePathString = scanFile.toString();
6295                        updatedPkg.resourcePath = scanFile;
6296                        updatedPkg.resourcePathString = scanFile.toString();
6297                    }
6298                    updatedPkg.pkg = pkg;
6299                    throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
6300                            "Package " + ps.name + " at " + scanFile
6301                                    + " ignored: updated version " + ps.versionCode
6302                                    + " better than this " + pkg.mVersionCode);
6303                } else {
6304                    // The current app on the system partition is better than
6305                    // what we have updated to on the data partition; switch
6306                    // back to the system partition version.
6307                    // At this point, its safely assumed that package installation for
6308                    // apps in system partition will go through. If not there won't be a working
6309                    // version of the app
6310                    // writer
6311                    synchronized (mPackages) {
6312                        // Just remove the loaded entries from package lists.
6313                        mPackages.remove(ps.name);
6314                    }
6315
6316                    logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile
6317                            + " reverting from " + ps.codePathString
6318                            + ": new version " + pkg.mVersionCode
6319                            + " better than installed " + ps.versionCode);
6320
6321                    InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
6322                            ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
6323                    synchronized (mInstallLock) {
6324                        args.cleanUpResourcesLI();
6325                    }
6326                    synchronized (mPackages) {
6327                        mSettings.enableSystemPackageLPw(ps.name);
6328                    }
6329                    updatedPkgBetter = true;
6330                }
6331            }
6332        }
6333
6334        if (updatedPkg != null) {
6335            // An updated system app will not have the PARSE_IS_SYSTEM flag set
6336            // initially
6337            parseFlags |= PackageParser.PARSE_IS_SYSTEM;
6338
6339            // An updated privileged app will not have the PARSE_IS_PRIVILEGED
6340            // flag set initially
6341            if ((updatedPkg.pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0) {
6342                parseFlags |= PackageParser.PARSE_IS_PRIVILEGED;
6343            }
6344        }
6345
6346        // Verify certificates against what was last scanned
6347        collectCertificatesLI(pp, ps, pkg, scanFile, parseFlags);
6348
6349        /*
6350         * A new system app appeared, but we already had a non-system one of the
6351         * same name installed earlier.
6352         */
6353        boolean shouldHideSystemApp = false;
6354        if (updatedPkg == null && ps != null
6355                && (parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0 && !isSystemApp(ps)) {
6356            /*
6357             * Check to make sure the signatures match first. If they don't,
6358             * wipe the installed application and its data.
6359             */
6360            if (compareSignatures(ps.signatures.mSignatures, pkg.mSignatures)
6361                    != PackageManager.SIGNATURE_MATCH) {
6362                logCriticalInfo(Log.WARN, "Package " + ps.name + " appeared on system, but"
6363                        + " signatures don't match existing userdata copy; removing");
6364                deletePackageLI(pkg.packageName, null, true, null, null, 0, null, false);
6365                ps = null;
6366            } else {
6367                /*
6368                 * If the newly-added system app is an older version than the
6369                 * already installed version, hide it. It will be scanned later
6370                 * and re-added like an update.
6371                 */
6372                if (pkg.mVersionCode <= ps.versionCode) {
6373                    shouldHideSystemApp = true;
6374                    logCriticalInfo(Log.INFO, "Package " + ps.name + " appeared at " + scanFile
6375                            + " but new version " + pkg.mVersionCode + " better than installed "
6376                            + ps.versionCode + "; hiding system");
6377                } else {
6378                    /*
6379                     * The newly found system app is a newer version that the
6380                     * one previously installed. Simply remove the
6381                     * already-installed application and replace it with our own
6382                     * while keeping the application data.
6383                     */
6384                    logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile
6385                            + " reverting from " + ps.codePathString + ": new version "
6386                            + pkg.mVersionCode + " better than installed " + ps.versionCode);
6387                    InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
6388                            ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
6389                    synchronized (mInstallLock) {
6390                        args.cleanUpResourcesLI();
6391                    }
6392                }
6393            }
6394        }
6395
6396        // The apk is forward locked (not public) if its code and resources
6397        // are kept in different files. (except for app in either system or
6398        // vendor path).
6399        // TODO grab this value from PackageSettings
6400        if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
6401            if (ps != null && !ps.codePath.equals(ps.resourcePath)) {
6402                parseFlags |= PackageParser.PARSE_FORWARD_LOCK;
6403            }
6404        }
6405
6406        // TODO: extend to support forward-locked splits
6407        String resourcePath = null;
6408        String baseResourcePath = null;
6409        if ((parseFlags & PackageParser.PARSE_FORWARD_LOCK) != 0 && !updatedPkgBetter) {
6410            if (ps != null && ps.resourcePathString != null) {
6411                resourcePath = ps.resourcePathString;
6412                baseResourcePath = ps.resourcePathString;
6413            } else {
6414                // Should not happen at all. Just log an error.
6415                Slog.e(TAG, "Resource path not set for package " + pkg.packageName);
6416            }
6417        } else {
6418            resourcePath = pkg.codePath;
6419            baseResourcePath = pkg.baseCodePath;
6420        }
6421
6422        // Set application objects path explicitly.
6423        pkg.applicationInfo.volumeUuid = pkg.volumeUuid;
6424        pkg.applicationInfo.setCodePath(pkg.codePath);
6425        pkg.applicationInfo.setBaseCodePath(pkg.baseCodePath);
6426        pkg.applicationInfo.setSplitCodePaths(pkg.splitCodePaths);
6427        pkg.applicationInfo.setResourcePath(resourcePath);
6428        pkg.applicationInfo.setBaseResourcePath(baseResourcePath);
6429        pkg.applicationInfo.setSplitResourcePaths(pkg.splitCodePaths);
6430
6431        // Note that we invoke the following method only if we are about to unpack an application
6432        PackageParser.Package scannedPkg = scanPackageLI(pkg, parseFlags, scanFlags
6433                | SCAN_UPDATE_SIGNATURE, currentTime, user);
6434
6435        /*
6436         * If the system app should be overridden by a previously installed
6437         * data, hide the system app now and let the /data/app scan pick it up
6438         * again.
6439         */
6440        if (shouldHideSystemApp) {
6441            synchronized (mPackages) {
6442                mSettings.disableSystemPackageLPw(pkg.packageName);
6443            }
6444        }
6445
6446        return scannedPkg;
6447    }
6448
6449    private static String fixProcessName(String defProcessName,
6450            String processName, int uid) {
6451        if (processName == null) {
6452            return defProcessName;
6453        }
6454        return processName;
6455    }
6456
6457    private void verifySignaturesLP(PackageSetting pkgSetting, PackageParser.Package pkg)
6458            throws PackageManagerException {
6459        if (pkgSetting.signatures.mSignatures != null) {
6460            // Already existing package. Make sure signatures match
6461            boolean match = compareSignatures(pkgSetting.signatures.mSignatures, pkg.mSignatures)
6462                    == PackageManager.SIGNATURE_MATCH;
6463            if (!match) {
6464                match = compareSignaturesCompat(pkgSetting.signatures, pkg)
6465                        == PackageManager.SIGNATURE_MATCH;
6466            }
6467            if (!match) {
6468                match = compareSignaturesRecover(pkgSetting.signatures, pkg)
6469                        == PackageManager.SIGNATURE_MATCH;
6470            }
6471            if (!match) {
6472                throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
6473                        + pkg.packageName + " signatures do not match the "
6474                        + "previously installed version; ignoring!");
6475            }
6476        }
6477
6478        // Check for shared user signatures
6479        if (pkgSetting.sharedUser != null && pkgSetting.sharedUser.signatures.mSignatures != null) {
6480            // Already existing package. Make sure signatures match
6481            boolean match = compareSignatures(pkgSetting.sharedUser.signatures.mSignatures,
6482                    pkg.mSignatures) == PackageManager.SIGNATURE_MATCH;
6483            if (!match) {
6484                match = compareSignaturesCompat(pkgSetting.sharedUser.signatures, pkg)
6485                        == PackageManager.SIGNATURE_MATCH;
6486            }
6487            if (!match) {
6488                match = compareSignaturesRecover(pkgSetting.sharedUser.signatures, pkg)
6489                        == PackageManager.SIGNATURE_MATCH;
6490            }
6491            if (!match) {
6492                throw new PackageManagerException(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
6493                        "Package " + pkg.packageName
6494                        + " has no signatures that match those in shared user "
6495                        + pkgSetting.sharedUser.name + "; ignoring!");
6496            }
6497        }
6498    }
6499
6500    /**
6501     * Enforces that only the system UID or root's UID can call a method exposed
6502     * via Binder.
6503     *
6504     * @param message used as message if SecurityException is thrown
6505     * @throws SecurityException if the caller is not system or root
6506     */
6507    private static final void enforceSystemOrRoot(String message) {
6508        final int uid = Binder.getCallingUid();
6509        if (uid != Process.SYSTEM_UID && uid != 0) {
6510            throw new SecurityException(message);
6511        }
6512    }
6513
6514    @Override
6515    public void performFstrimIfNeeded() {
6516        enforceSystemOrRoot("Only the system can request fstrim");
6517
6518        // Before everything else, see whether we need to fstrim.
6519        try {
6520            IMountService ms = PackageHelper.getMountService();
6521            if (ms != null) {
6522                final boolean isUpgrade = isUpgrade();
6523                boolean doTrim = isUpgrade;
6524                if (doTrim) {
6525                    Slog.w(TAG, "Running disk maintenance immediately due to system update");
6526                } else {
6527                    final long interval = android.provider.Settings.Global.getLong(
6528                            mContext.getContentResolver(),
6529                            android.provider.Settings.Global.FSTRIM_MANDATORY_INTERVAL,
6530                            DEFAULT_MANDATORY_FSTRIM_INTERVAL);
6531                    if (interval > 0) {
6532                        final long timeSinceLast = System.currentTimeMillis() - ms.lastMaintenance();
6533                        if (timeSinceLast > interval) {
6534                            doTrim = true;
6535                            Slog.w(TAG, "No disk maintenance in " + timeSinceLast
6536                                    + "; running immediately");
6537                        }
6538                    }
6539                }
6540                if (doTrim) {
6541                    if (!isFirstBoot()) {
6542                        try {
6543                            ActivityManagerNative.getDefault().showBootMessage(
6544                                    mContext.getResources().getString(
6545                                            R.string.android_upgrading_fstrim), true);
6546                        } catch (RemoteException e) {
6547                        }
6548                    }
6549                    ms.runMaintenance();
6550                }
6551            } else {
6552                Slog.e(TAG, "Mount service unavailable!");
6553            }
6554        } catch (RemoteException e) {
6555            // Can't happen; MountService is local
6556        }
6557    }
6558
6559    private ArraySet<String> getPackageNamesForIntent(Intent intent, int userId) {
6560        List<ResolveInfo> ris = null;
6561        try {
6562            ris = AppGlobals.getPackageManager().queryIntentReceivers(
6563                    intent, null, 0, userId);
6564        } catch (RemoteException e) {
6565        }
6566        ArraySet<String> pkgNames = new ArraySet<String>();
6567        if (ris != null) {
6568            for (ResolveInfo ri : ris) {
6569                pkgNames.add(ri.activityInfo.packageName);
6570            }
6571        }
6572        return pkgNames;
6573    }
6574
6575    @Override
6576    public void notifyPackageUse(String packageName) {
6577        synchronized (mPackages) {
6578            PackageParser.Package p = mPackages.get(packageName);
6579            if (p == null) {
6580                return;
6581            }
6582            p.mLastPackageUsageTimeInMills = System.currentTimeMillis();
6583        }
6584    }
6585
6586    @Override
6587    public boolean performDexOptIfNeeded(String packageName, String instructionSet) {
6588        return performDexOptTraced(packageName, instructionSet);
6589    }
6590
6591    public boolean performDexOpt(String packageName, String instructionSet) {
6592        return performDexOptTraced(packageName, instructionSet);
6593    }
6594
6595    private boolean performDexOptTraced(String packageName, String instructionSet) {
6596        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
6597        try {
6598            return performDexOptInternal(packageName, instructionSet);
6599        } finally {
6600            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
6601        }
6602    }
6603
6604    private boolean performDexOptInternal(String packageName, String instructionSet) {
6605        PackageParser.Package p;
6606        final String targetInstructionSet;
6607        synchronized (mPackages) {
6608            p = mPackages.get(packageName);
6609            if (p == null) {
6610                return false;
6611            }
6612            mPackageUsage.write(false);
6613
6614            targetInstructionSet = instructionSet != null ? instructionSet :
6615                    getPrimaryInstructionSet(p.applicationInfo);
6616            if (p.mDexOptPerformed.contains(targetInstructionSet)) {
6617                return false;
6618            }
6619        }
6620        long callingId = Binder.clearCallingIdentity();
6621        try {
6622            synchronized (mInstallLock) {
6623                final String[] instructionSets = new String[] { targetInstructionSet };
6624                int result = mPackageDexOptimizer.performDexOpt(p, instructionSets,
6625                        true /* inclDependencies */);
6626                return result == PackageDexOptimizer.DEX_OPT_PERFORMED;
6627            }
6628        } finally {
6629            Binder.restoreCallingIdentity(callingId);
6630        }
6631    }
6632
6633    public ArraySet<String> getPackagesThatNeedDexOpt() {
6634        ArraySet<String> pkgs = null;
6635        synchronized (mPackages) {
6636            for (PackageParser.Package p : mPackages.values()) {
6637                if (DEBUG_DEXOPT) {
6638                    Log.i(TAG, p.packageName + " mDexOptPerformed=" + p.mDexOptPerformed.toArray());
6639                }
6640                if (!p.mDexOptPerformed.isEmpty()) {
6641                    continue;
6642                }
6643                if (pkgs == null) {
6644                    pkgs = new ArraySet<String>();
6645                }
6646                pkgs.add(p.packageName);
6647            }
6648        }
6649        return pkgs;
6650    }
6651
6652    public void shutdown() {
6653        mPackageUsage.write(true);
6654    }
6655
6656    @Override
6657    public void forceDexOpt(String packageName) {
6658        enforceSystemOrRoot("forceDexOpt");
6659
6660        PackageParser.Package pkg;
6661        synchronized (mPackages) {
6662            pkg = mPackages.get(packageName);
6663            if (pkg == null) {
6664                throw new IllegalArgumentException("Unknown package: " + packageName);
6665            }
6666        }
6667
6668        synchronized (mInstallLock) {
6669            final String[] instructionSets = new String[] {
6670                    getPrimaryInstructionSet(pkg.applicationInfo) };
6671
6672            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
6673
6674            final int res = mPackageDexOptimizer.performDexOpt(pkg, instructionSets,
6675                    true /* inclDependencies */);
6676
6677            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
6678            if (res != PackageDexOptimizer.DEX_OPT_PERFORMED) {
6679                throw new IllegalStateException("Failed to dexopt: " + res);
6680            }
6681        }
6682    }
6683
6684    private boolean verifyPackageUpdateLPr(PackageSetting oldPkg, PackageParser.Package newPkg) {
6685        if ((oldPkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) {
6686            Slog.w(TAG, "Unable to update from " + oldPkg.name
6687                    + " to " + newPkg.packageName
6688                    + ": old package not in system partition");
6689            return false;
6690        } else if (mPackages.get(oldPkg.name) != null) {
6691            Slog.w(TAG, "Unable to update from " + oldPkg.name
6692                    + " to " + newPkg.packageName
6693                    + ": old package still exists");
6694            return false;
6695        }
6696        return true;
6697    }
6698
6699    private void createDataDirsLI(String volumeUuid, String packageName, int uid, String seinfo)
6700            throws PackageManagerException {
6701        int res = mInstaller.install(volumeUuid, packageName, uid, uid, seinfo);
6702        if (res != 0) {
6703            throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE,
6704                    "Failed to install " + packageName + ": " + res);
6705        }
6706
6707        final int[] users = sUserManager.getUserIds();
6708        for (int user : users) {
6709            if (user != 0) {
6710                res = mInstaller.createUserData(volumeUuid, packageName,
6711                        UserHandle.getUid(user, uid), user, seinfo);
6712                if (res != 0) {
6713                    throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE,
6714                            "Failed to createUserData " + packageName + ": " + res);
6715                }
6716            }
6717        }
6718    }
6719
6720    private int removeDataDirsLI(String volumeUuid, String packageName) {
6721        int[] users = sUserManager.getUserIds();
6722        int res = 0;
6723        for (int user : users) {
6724            int resInner = mInstaller.remove(volumeUuid, packageName, user);
6725            if (resInner < 0) {
6726                res = resInner;
6727            }
6728        }
6729
6730        return res;
6731    }
6732
6733    private int deleteCodeCacheDirsLI(String volumeUuid, String packageName) {
6734        int[] users = sUserManager.getUserIds();
6735        int res = 0;
6736        for (int user : users) {
6737            int resInner = mInstaller.deleteCodeCacheFiles(volumeUuid, packageName, user);
6738            if (resInner < 0) {
6739                res = resInner;
6740            }
6741        }
6742        return res;
6743    }
6744
6745    private void addSharedLibraryLPw(ArraySet<String> usesLibraryFiles, SharedLibraryEntry file,
6746            PackageParser.Package changingLib) {
6747        if (file.path != null) {
6748            usesLibraryFiles.add(file.path);
6749            return;
6750        }
6751        PackageParser.Package p = mPackages.get(file.apk);
6752        if (changingLib != null && changingLib.packageName.equals(file.apk)) {
6753            // If we are doing this while in the middle of updating a library apk,
6754            // then we need to make sure to use that new apk for determining the
6755            // dependencies here.  (We haven't yet finished committing the new apk
6756            // to the package manager state.)
6757            if (p == null || p.packageName.equals(changingLib.packageName)) {
6758                p = changingLib;
6759            }
6760        }
6761        if (p != null) {
6762            usesLibraryFiles.addAll(p.getAllCodePaths());
6763        }
6764    }
6765
6766    private void updateSharedLibrariesLPw(PackageParser.Package pkg,
6767            PackageParser.Package changingLib) throws PackageManagerException {
6768        if (pkg.usesLibraries != null || pkg.usesOptionalLibraries != null) {
6769            final ArraySet<String> usesLibraryFiles = new ArraySet<>();
6770            int N = pkg.usesLibraries != null ? pkg.usesLibraries.size() : 0;
6771            for (int i=0; i<N; i++) {
6772                final SharedLibraryEntry file = mSharedLibraries.get(pkg.usesLibraries.get(i));
6773                if (file == null) {
6774                    throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
6775                            "Package " + pkg.packageName + " requires unavailable shared library "
6776                            + pkg.usesLibraries.get(i) + "; failing!");
6777                }
6778                addSharedLibraryLPw(usesLibraryFiles, file, changingLib);
6779            }
6780            N = pkg.usesOptionalLibraries != null ? pkg.usesOptionalLibraries.size() : 0;
6781            for (int i=0; i<N; i++) {
6782                final SharedLibraryEntry file = mSharedLibraries.get(pkg.usesOptionalLibraries.get(i));
6783                if (file == null) {
6784                    Slog.w(TAG, "Package " + pkg.packageName
6785                            + " desires unavailable shared library "
6786                            + pkg.usesOptionalLibraries.get(i) + "; ignoring!");
6787                } else {
6788                    addSharedLibraryLPw(usesLibraryFiles, file, changingLib);
6789                }
6790            }
6791            N = usesLibraryFiles.size();
6792            if (N > 0) {
6793                pkg.usesLibraryFiles = usesLibraryFiles.toArray(new String[N]);
6794            } else {
6795                pkg.usesLibraryFiles = null;
6796            }
6797        }
6798    }
6799
6800    private static boolean hasString(List<String> list, List<String> which) {
6801        if (list == null) {
6802            return false;
6803        }
6804        for (int i=list.size()-1; i>=0; i--) {
6805            for (int j=which.size()-1; j>=0; j--) {
6806                if (which.get(j).equals(list.get(i))) {
6807                    return true;
6808                }
6809            }
6810        }
6811        return false;
6812    }
6813
6814    private void updateAllSharedLibrariesLPw() {
6815        for (PackageParser.Package pkg : mPackages.values()) {
6816            try {
6817                updateSharedLibrariesLPw(pkg, null);
6818            } catch (PackageManagerException e) {
6819                Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
6820            }
6821        }
6822    }
6823
6824    private ArrayList<PackageParser.Package> updateAllSharedLibrariesLPw(
6825            PackageParser.Package changingPkg) {
6826        ArrayList<PackageParser.Package> res = null;
6827        for (PackageParser.Package pkg : mPackages.values()) {
6828            if (hasString(pkg.usesLibraries, changingPkg.libraryNames)
6829                    || hasString(pkg.usesOptionalLibraries, changingPkg.libraryNames)) {
6830                if (res == null) {
6831                    res = new ArrayList<PackageParser.Package>();
6832                }
6833                res.add(pkg);
6834                try {
6835                    updateSharedLibrariesLPw(pkg, changingPkg);
6836                } catch (PackageManagerException e) {
6837                    Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
6838                }
6839            }
6840        }
6841        return res;
6842    }
6843
6844    /**
6845     * Derive the value of the {@code cpuAbiOverride} based on the provided
6846     * value and an optional stored value from the package settings.
6847     */
6848    private static String deriveAbiOverride(String abiOverride, PackageSetting settings) {
6849        String cpuAbiOverride = null;
6850
6851        if (NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(abiOverride)) {
6852            cpuAbiOverride = null;
6853        } else if (abiOverride != null) {
6854            cpuAbiOverride = abiOverride;
6855        } else if (settings != null) {
6856            cpuAbiOverride = settings.cpuAbiOverrideString;
6857        }
6858
6859        return cpuAbiOverride;
6860    }
6861
6862    private PackageParser.Package scanPackageTracedLI(PackageParser.Package pkg, int parseFlags,
6863            int scanFlags, long currentTime, UserHandle user) throws PackageManagerException {
6864        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage");
6865        try {
6866            return scanPackageLI(pkg, parseFlags, scanFlags, currentTime, user);
6867        } finally {
6868            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
6869        }
6870    }
6871
6872    private PackageParser.Package scanPackageLI(PackageParser.Package pkg, int parseFlags,
6873            int scanFlags, long currentTime, UserHandle user) throws PackageManagerException {
6874        boolean success = false;
6875        try {
6876            final PackageParser.Package res = scanPackageDirtyLI(pkg, parseFlags, scanFlags,
6877                    currentTime, user);
6878            success = true;
6879            return res;
6880        } finally {
6881            if (!success && (scanFlags & SCAN_DELETE_DATA_ON_FAILURES) != 0) {
6882                removeDataDirsLI(pkg.volumeUuid, pkg.packageName);
6883            }
6884        }
6885    }
6886
6887    private PackageParser.Package scanPackageDirtyLI(PackageParser.Package pkg, int parseFlags,
6888            int scanFlags, long currentTime, UserHandle user) throws PackageManagerException {
6889        final File scanFile = new File(pkg.codePath);
6890        if (pkg.applicationInfo.getCodePath() == null ||
6891                pkg.applicationInfo.getResourcePath() == null) {
6892            // Bail out. The resource and code paths haven't been set.
6893            throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
6894                    "Code and resource paths haven't been set correctly");
6895        }
6896
6897        if ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) {
6898            pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
6899        } else {
6900            // Only allow system apps to be flagged as core apps.
6901            pkg.coreApp = false;
6902        }
6903
6904        if ((parseFlags&PackageParser.PARSE_IS_PRIVILEGED) != 0) {
6905            pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
6906        }
6907
6908        if (mCustomResolverComponentName != null &&
6909                mCustomResolverComponentName.getPackageName().equals(pkg.packageName)) {
6910            setUpCustomResolverActivity(pkg);
6911        }
6912
6913        if (pkg.packageName.equals("android")) {
6914            synchronized (mPackages) {
6915                if (mAndroidApplication != null) {
6916                    Slog.w(TAG, "*************************************************");
6917                    Slog.w(TAG, "Core android package being redefined.  Skipping.");
6918                    Slog.w(TAG, " file=" + scanFile);
6919                    Slog.w(TAG, "*************************************************");
6920                    throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
6921                            "Core android package being redefined.  Skipping.");
6922                }
6923
6924                // Set up information for our fall-back user intent resolution activity.
6925                mPlatformPackage = pkg;
6926                pkg.mVersionCode = mSdkVersion;
6927                mAndroidApplication = pkg.applicationInfo;
6928
6929                if (!mResolverReplaced) {
6930                    mResolveActivity.applicationInfo = mAndroidApplication;
6931                    mResolveActivity.name = ResolverActivity.class.getName();
6932                    mResolveActivity.packageName = mAndroidApplication.packageName;
6933                    mResolveActivity.processName = "system:ui";
6934                    mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
6935                    mResolveActivity.documentLaunchMode = ActivityInfo.DOCUMENT_LAUNCH_NEVER;
6936                    mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS;
6937                    mResolveActivity.theme = R.style.Theme_Holo_Dialog_Alert;
6938                    mResolveActivity.exported = true;
6939                    mResolveActivity.enabled = true;
6940                    mResolveInfo.activityInfo = mResolveActivity;
6941                    mResolveInfo.priority = 0;
6942                    mResolveInfo.preferredOrder = 0;
6943                    mResolveInfo.match = 0;
6944                    mResolveComponentName = new ComponentName(
6945                            mAndroidApplication.packageName, mResolveActivity.name);
6946                }
6947            }
6948        }
6949
6950        if (DEBUG_PACKAGE_SCANNING) {
6951            if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
6952                Log.d(TAG, "Scanning package " + pkg.packageName);
6953        }
6954
6955        if (mPackages.containsKey(pkg.packageName)
6956                || mSharedLibraries.containsKey(pkg.packageName)) {
6957            throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
6958                    "Application package " + pkg.packageName
6959                    + " already installed.  Skipping duplicate.");
6960        }
6961
6962        // If we're only installing presumed-existing packages, require that the
6963        // scanned APK is both already known and at the path previously established
6964        // for it.  Previously unknown packages we pick up normally, but if we have an
6965        // a priori expectation about this package's install presence, enforce it.
6966        // With a singular exception for new system packages. When an OTA contains
6967        // a new system package, we allow the codepath to change from a system location
6968        // to the user-installed location. If we don't allow this change, any newer,
6969        // user-installed version of the application will be ignored.
6970        if ((scanFlags & SCAN_REQUIRE_KNOWN) != 0) {
6971            if (mExpectingBetter.containsKey(pkg.packageName)) {
6972                logCriticalInfo(Log.WARN,
6973                        "Relax SCAN_REQUIRE_KNOWN requirement for package " + pkg.packageName);
6974            } else {
6975                PackageSetting known = mSettings.peekPackageLPr(pkg.packageName);
6976                if (known != null) {
6977                    if (DEBUG_PACKAGE_SCANNING) {
6978                        Log.d(TAG, "Examining " + pkg.codePath
6979                                + " and requiring known paths " + known.codePathString
6980                                + " & " + known.resourcePathString);
6981                    }
6982                    if (!pkg.applicationInfo.getCodePath().equals(known.codePathString)
6983                            || !pkg.applicationInfo.getResourcePath().equals(known.resourcePathString)) {
6984                        throw new PackageManagerException(INSTALL_FAILED_PACKAGE_CHANGED,
6985                                "Application package " + pkg.packageName
6986                                + " found at " + pkg.applicationInfo.getCodePath()
6987                                + " but expected at " + known.codePathString + "; ignoring.");
6988                    }
6989                }
6990            }
6991        }
6992
6993        // Initialize package source and resource directories
6994        File destCodeFile = new File(pkg.applicationInfo.getCodePath());
6995        File destResourceFile = new File(pkg.applicationInfo.getResourcePath());
6996
6997        SharedUserSetting suid = null;
6998        PackageSetting pkgSetting = null;
6999
7000        if (!isSystemApp(pkg)) {
7001            // Only system apps can use these features.
7002            pkg.mOriginalPackages = null;
7003            pkg.mRealPackage = null;
7004            pkg.mAdoptPermissions = null;
7005        }
7006
7007        // writer
7008        synchronized (mPackages) {
7009            if (pkg.mSharedUserId != null) {
7010                suid = mSettings.getSharedUserLPw(pkg.mSharedUserId, 0, 0, true);
7011                if (suid == null) {
7012                    throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE,
7013                            "Creating application package " + pkg.packageName
7014                            + " for shared user failed");
7015                }
7016                if (DEBUG_PACKAGE_SCANNING) {
7017                    if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
7018                        Log.d(TAG, "Shared UserID " + pkg.mSharedUserId + " (uid=" + suid.userId
7019                                + "): packages=" + suid.packages);
7020                }
7021            }
7022
7023            // Check if we are renaming from an original package name.
7024            PackageSetting origPackage = null;
7025            String realName = null;
7026            if (pkg.mOriginalPackages != null) {
7027                // This package may need to be renamed to a previously
7028                // installed name.  Let's check on that...
7029                final String renamed = mSettings.mRenamedPackages.get(pkg.mRealPackage);
7030                if (pkg.mOriginalPackages.contains(renamed)) {
7031                    // This package had originally been installed as the
7032                    // original name, and we have already taken care of
7033                    // transitioning to the new one.  Just update the new
7034                    // one to continue using the old name.
7035                    realName = pkg.mRealPackage;
7036                    if (!pkg.packageName.equals(renamed)) {
7037                        // Callers into this function may have already taken
7038                        // care of renaming the package; only do it here if
7039                        // it is not already done.
7040                        pkg.setPackageName(renamed);
7041                    }
7042
7043                } else {
7044                    for (int i=pkg.mOriginalPackages.size()-1; i>=0; i--) {
7045                        if ((origPackage = mSettings.peekPackageLPr(
7046                                pkg.mOriginalPackages.get(i))) != null) {
7047                            // We do have the package already installed under its
7048                            // original name...  should we use it?
7049                            if (!verifyPackageUpdateLPr(origPackage, pkg)) {
7050                                // New package is not compatible with original.
7051                                origPackage = null;
7052                                continue;
7053                            } else if (origPackage.sharedUser != null) {
7054                                // Make sure uid is compatible between packages.
7055                                if (!origPackage.sharedUser.name.equals(pkg.mSharedUserId)) {
7056                                    Slog.w(TAG, "Unable to migrate data from " + origPackage.name
7057                                            + " to " + pkg.packageName + ": old uid "
7058                                            + origPackage.sharedUser.name
7059                                            + " differs from " + pkg.mSharedUserId);
7060                                    origPackage = null;
7061                                    continue;
7062                                }
7063                            } else {
7064                                if (DEBUG_UPGRADE) Log.v(TAG, "Renaming new package "
7065                                        + pkg.packageName + " to old name " + origPackage.name);
7066                            }
7067                            break;
7068                        }
7069                    }
7070                }
7071            }
7072
7073            if (mTransferedPackages.contains(pkg.packageName)) {
7074                Slog.w(TAG, "Package " + pkg.packageName
7075                        + " was transferred to another, but its .apk remains");
7076            }
7077
7078            // Just create the setting, don't add it yet. For already existing packages
7079            // the PkgSetting exists already and doesn't have to be created.
7080            pkgSetting = mSettings.getPackageLPw(pkg, origPackage, realName, suid, destCodeFile,
7081                    destResourceFile, pkg.applicationInfo.nativeLibraryRootDir,
7082                    pkg.applicationInfo.primaryCpuAbi,
7083                    pkg.applicationInfo.secondaryCpuAbi,
7084                    pkg.applicationInfo.flags, pkg.applicationInfo.privateFlags,
7085                    user, false);
7086            if (pkgSetting == null) {
7087                throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE,
7088                        "Creating application package " + pkg.packageName + " failed");
7089            }
7090
7091            if (pkgSetting.origPackage != null) {
7092                // If we are first transitioning from an original package,
7093                // fix up the new package's name now.  We need to do this after
7094                // looking up the package under its new name, so getPackageLP
7095                // can take care of fiddling things correctly.
7096                pkg.setPackageName(origPackage.name);
7097
7098                // File a report about this.
7099                String msg = "New package " + pkgSetting.realName
7100                        + " renamed to replace old package " + pkgSetting.name;
7101                reportSettingsProblem(Log.WARN, msg);
7102
7103                // Make a note of it.
7104                mTransferedPackages.add(origPackage.name);
7105
7106                // No longer need to retain this.
7107                pkgSetting.origPackage = null;
7108            }
7109
7110            if (realName != null) {
7111                // Make a note of it.
7112                mTransferedPackages.add(pkg.packageName);
7113            }
7114
7115            if (mSettings.isDisabledSystemPackageLPr(pkg.packageName)) {
7116                pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
7117            }
7118
7119            if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
7120                // Check all shared libraries and map to their actual file path.
7121                // We only do this here for apps not on a system dir, because those
7122                // are the only ones that can fail an install due to this.  We
7123                // will take care of the system apps by updating all of their
7124                // library paths after the scan is done.
7125                updateSharedLibrariesLPw(pkg, null);
7126            }
7127
7128            if (mFoundPolicyFile) {
7129                SELinuxMMAC.assignSeinfoValue(pkg);
7130            }
7131
7132            pkg.applicationInfo.uid = pkgSetting.appId;
7133            pkg.mExtras = pkgSetting;
7134            if (shouldCheckUpgradeKeySetLP(pkgSetting, scanFlags)) {
7135                if (checkUpgradeKeySetLP(pkgSetting, pkg)) {
7136                    // We just determined the app is signed correctly, so bring
7137                    // over the latest parsed certs.
7138                    pkgSetting.signatures.mSignatures = pkg.mSignatures;
7139                } else {
7140                    if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
7141                        throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
7142                                "Package " + pkg.packageName + " upgrade keys do not match the "
7143                                + "previously installed version");
7144                    } else {
7145                        pkgSetting.signatures.mSignatures = pkg.mSignatures;
7146                        String msg = "System package " + pkg.packageName
7147                            + " signature changed; retaining data.";
7148                        reportSettingsProblem(Log.WARN, msg);
7149                    }
7150                }
7151            } else {
7152                try {
7153                    verifySignaturesLP(pkgSetting, pkg);
7154                    // We just determined the app is signed correctly, so bring
7155                    // over the latest parsed certs.
7156                    pkgSetting.signatures.mSignatures = pkg.mSignatures;
7157                } catch (PackageManagerException e) {
7158                    if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
7159                        throw e;
7160                    }
7161                    // The signature has changed, but this package is in the system
7162                    // image...  let's recover!
7163                    pkgSetting.signatures.mSignatures = pkg.mSignatures;
7164                    // However...  if this package is part of a shared user, but it
7165                    // doesn't match the signature of the shared user, let's fail.
7166                    // What this means is that you can't change the signatures
7167                    // associated with an overall shared user, which doesn't seem all
7168                    // that unreasonable.
7169                    if (pkgSetting.sharedUser != null) {
7170                        if (compareSignatures(pkgSetting.sharedUser.signatures.mSignatures,
7171                                              pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) {
7172                            throw new PackageManagerException(
7173                                    INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES,
7174                                            "Signature mismatch for shared user: "
7175                                            + pkgSetting.sharedUser);
7176                        }
7177                    }
7178                    // File a report about this.
7179                    String msg = "System package " + pkg.packageName
7180                        + " signature changed; retaining data.";
7181                    reportSettingsProblem(Log.WARN, msg);
7182                }
7183            }
7184            // Verify that this new package doesn't have any content providers
7185            // that conflict with existing packages.  Only do this if the
7186            // package isn't already installed, since we don't want to break
7187            // things that are installed.
7188            if ((scanFlags & SCAN_NEW_INSTALL) != 0) {
7189                final int N = pkg.providers.size();
7190                int i;
7191                for (i=0; i<N; i++) {
7192                    PackageParser.Provider p = pkg.providers.get(i);
7193                    if (p.info.authority != null) {
7194                        String names[] = p.info.authority.split(";");
7195                        for (int j = 0; j < names.length; j++) {
7196                            if (mProvidersByAuthority.containsKey(names[j])) {
7197                                PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
7198                                final String otherPackageName =
7199                                        ((other != null && other.getComponentName() != null) ?
7200                                                other.getComponentName().getPackageName() : "?");
7201                                throw new PackageManagerException(
7202                                        INSTALL_FAILED_CONFLICTING_PROVIDER,
7203                                                "Can't install because provider name " + names[j]
7204                                                + " (in package " + pkg.applicationInfo.packageName
7205                                                + ") is already used by " + otherPackageName);
7206                            }
7207                        }
7208                    }
7209                }
7210            }
7211
7212            if (pkg.mAdoptPermissions != null) {
7213                // This package wants to adopt ownership of permissions from
7214                // another package.
7215                for (int i = pkg.mAdoptPermissions.size() - 1; i >= 0; i--) {
7216                    final String origName = pkg.mAdoptPermissions.get(i);
7217                    final PackageSetting orig = mSettings.peekPackageLPr(origName);
7218                    if (orig != null) {
7219                        if (verifyPackageUpdateLPr(orig, pkg)) {
7220                            Slog.i(TAG, "Adopting permissions from " + origName + " to "
7221                                    + pkg.packageName);
7222                            mSettings.transferPermissionsLPw(origName, pkg.packageName);
7223                        }
7224                    }
7225                }
7226            }
7227        }
7228
7229        final String pkgName = pkg.packageName;
7230
7231        final long scanFileTime = scanFile.lastModified();
7232        final boolean forceDex = (scanFlags & SCAN_FORCE_DEX) != 0;
7233        pkg.applicationInfo.processName = fixProcessName(
7234                pkg.applicationInfo.packageName,
7235                pkg.applicationInfo.processName,
7236                pkg.applicationInfo.uid);
7237
7238        if (pkg != mPlatformPackage) {
7239            // This is a normal package, need to make its data directory.
7240            final File dataPath = Environment.getDataUserCredentialEncryptedPackageDirectory(
7241                    pkg.volumeUuid, UserHandle.USER_SYSTEM, pkg.packageName);
7242
7243            boolean uidError = false;
7244            if (dataPath.exists()) {
7245                int currentUid = 0;
7246                try {
7247                    StructStat stat = Os.stat(dataPath.getPath());
7248                    currentUid = stat.st_uid;
7249                } catch (ErrnoException e) {
7250                    Slog.e(TAG, "Couldn't stat path " + dataPath.getPath(), e);
7251                }
7252
7253                // If we have mismatched owners for the data path, we have a problem.
7254                if (currentUid != pkg.applicationInfo.uid) {
7255                    boolean recovered = false;
7256                    if (currentUid == 0) {
7257                        // The directory somehow became owned by root.  Wow.
7258                        // This is probably because the system was stopped while
7259                        // installd was in the middle of messing with its libs
7260                        // directory.  Ask installd to fix that.
7261                        int ret = mInstaller.fixUid(pkg.volumeUuid, pkgName,
7262                                pkg.applicationInfo.uid, pkg.applicationInfo.uid);
7263                        if (ret >= 0) {
7264                            recovered = true;
7265                            String msg = "Package " + pkg.packageName
7266                                    + " unexpectedly changed to uid 0; recovered to " +
7267                                    + pkg.applicationInfo.uid;
7268                            reportSettingsProblem(Log.WARN, msg);
7269                        }
7270                    }
7271                    if (!recovered && ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0
7272                            || (scanFlags&SCAN_BOOTING) != 0)) {
7273                        // If this is a system app, we can at least delete its
7274                        // current data so the application will still work.
7275                        int ret = removeDataDirsLI(pkg.volumeUuid, pkgName);
7276                        if (ret >= 0) {
7277                            // TODO: Kill the processes first
7278                            // Old data gone!
7279                            String prefix = (parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0
7280                                    ? "System package " : "Third party package ";
7281                            String msg = prefix + pkg.packageName
7282                                    + " has changed from uid: "
7283                                    + currentUid + " to "
7284                                    + pkg.applicationInfo.uid + "; old data erased";
7285                            reportSettingsProblem(Log.WARN, msg);
7286                            recovered = true;
7287                        }
7288                        if (!recovered) {
7289                            mHasSystemUidErrors = true;
7290                        }
7291                    } else if (!recovered) {
7292                        // If we allow this install to proceed, we will be broken.
7293                        // Abort, abort!
7294                        throw new PackageManagerException(INSTALL_FAILED_UID_CHANGED,
7295                                "scanPackageLI");
7296                    }
7297                    if (!recovered) {
7298                        pkg.applicationInfo.dataDir = "/mismatched_uid/settings_"
7299                            + pkg.applicationInfo.uid + "/fs_"
7300                            + currentUid;
7301                        pkg.applicationInfo.nativeLibraryDir = pkg.applicationInfo.dataDir;
7302                        pkg.applicationInfo.nativeLibraryRootDir = pkg.applicationInfo.dataDir;
7303                        String msg = "Package " + pkg.packageName
7304                                + " has mismatched uid: "
7305                                + currentUid + " on disk, "
7306                                + pkg.applicationInfo.uid + " in settings";
7307                        // writer
7308                        synchronized (mPackages) {
7309                            mSettings.mReadMessages.append(msg);
7310                            mSettings.mReadMessages.append('\n');
7311                            uidError = true;
7312                            if (!pkgSetting.uidError) {
7313                                reportSettingsProblem(Log.ERROR, msg);
7314                            }
7315                        }
7316                    }
7317                }
7318
7319                // Ensure that directories are prepared
7320                createDataDirsLI(pkg.volumeUuid, pkgName, pkg.applicationInfo.uid,
7321                        pkg.applicationInfo.seinfo);
7322
7323                if (mShouldRestoreconData) {
7324                    Slog.i(TAG, "SELinux relabeling of " + pkg.packageName + " issued.");
7325                    mInstaller.restoreconData(pkg.volumeUuid, pkg.packageName,
7326                            pkg.applicationInfo.seinfo, pkg.applicationInfo.uid);
7327                }
7328            } else {
7329                if (DEBUG_PACKAGE_SCANNING) {
7330                    if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
7331                        Log.v(TAG, "Want this data dir: " + dataPath);
7332                }
7333                createDataDirsLI(pkg.volumeUuid, pkgName, pkg.applicationInfo.uid,
7334                        pkg.applicationInfo.seinfo);
7335            }
7336
7337            // Get all of our default paths setup
7338            pkg.applicationInfo.initForUser(UserHandle.USER_SYSTEM);
7339
7340            pkgSetting.uidError = uidError;
7341        }
7342
7343        final String path = scanFile.getPath();
7344        final String cpuAbiOverride = deriveAbiOverride(pkg.cpuAbiOverride, pkgSetting);
7345
7346        if ((scanFlags & SCAN_NEW_INSTALL) == 0) {
7347            derivePackageAbi(pkg, scanFile, cpuAbiOverride, true /* extract libs */);
7348
7349            // Some system apps still use directory structure for native libraries
7350            // in which case we might end up not detecting abi solely based on apk
7351            // structure. Try to detect abi based on directory structure.
7352            if (isSystemApp(pkg) && !pkg.isUpdatedSystemApp() &&
7353                    pkg.applicationInfo.primaryCpuAbi == null) {
7354                setBundledAppAbisAndRoots(pkg, pkgSetting);
7355                setNativeLibraryPaths(pkg);
7356            }
7357
7358        } else {
7359            if ((scanFlags & SCAN_MOVE) != 0) {
7360                // We haven't run dex-opt for this move (since we've moved the compiled output too)
7361                // but we already have this packages package info in the PackageSetting. We just
7362                // use that and derive the native library path based on the new codepath.
7363                pkg.applicationInfo.primaryCpuAbi = pkgSetting.primaryCpuAbiString;
7364                pkg.applicationInfo.secondaryCpuAbi = pkgSetting.secondaryCpuAbiString;
7365            }
7366
7367            // Set native library paths again. For moves, the path will be updated based on the
7368            // ABIs we've determined above. For non-moves, the path will be updated based on the
7369            // ABIs we determined during compilation, but the path will depend on the final
7370            // package path (after the rename away from the stage path).
7371            setNativeLibraryPaths(pkg);
7372        }
7373
7374        if (DEBUG_INSTALL) Slog.i(TAG, "Linking native library dir for " + path);
7375        final int[] userIds = sUserManager.getUserIds();
7376        synchronized (mInstallLock) {
7377            // Make sure all user data directories are ready to roll; we're okay
7378            // if they already exist
7379            if (!TextUtils.isEmpty(pkg.volumeUuid)) {
7380                for (int userId : userIds) {
7381                    if (userId != UserHandle.USER_SYSTEM) {
7382                        mInstaller.createUserData(pkg.volumeUuid, pkg.packageName,
7383                                UserHandle.getUid(userId, pkg.applicationInfo.uid), userId,
7384                                pkg.applicationInfo.seinfo);
7385                    }
7386                }
7387            }
7388
7389            // Create a native library symlink only if we have native libraries
7390            // and if the native libraries are 32 bit libraries. We do not provide
7391            // this symlink for 64 bit libraries.
7392            if (pkg.applicationInfo.primaryCpuAbi != null &&
7393                    !VMRuntime.is64BitAbi(pkg.applicationInfo.primaryCpuAbi)) {
7394                Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "linkNativeLib");
7395                try {
7396                    final String nativeLibPath = pkg.applicationInfo.nativeLibraryDir;
7397                    for (int userId : userIds) {
7398                        if (mInstaller.linkNativeLibraryDirectory(pkg.volumeUuid, pkg.packageName,
7399                                nativeLibPath, userId) < 0) {
7400                            throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
7401                                    "Failed linking native library dir (user=" + userId + ")");
7402                        }
7403                    }
7404                } finally {
7405                    Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
7406                }
7407            }
7408        }
7409
7410        // This is a special case for the "system" package, where the ABI is
7411        // dictated by the zygote configuration (and init.rc). We should keep track
7412        // of this ABI so that we can deal with "normal" applications that run under
7413        // the same UID correctly.
7414        if (mPlatformPackage == pkg) {
7415            pkg.applicationInfo.primaryCpuAbi = VMRuntime.getRuntime().is64Bit() ?
7416                    Build.SUPPORTED_64_BIT_ABIS[0] : Build.SUPPORTED_32_BIT_ABIS[0];
7417        }
7418
7419        // If there's a mismatch between the abi-override in the package setting
7420        // and the abiOverride specified for the install. Warn about this because we
7421        // would've already compiled the app without taking the package setting into
7422        // account.
7423        if ((scanFlags & SCAN_NO_DEX) == 0 && (scanFlags & SCAN_NEW_INSTALL) != 0) {
7424            if (cpuAbiOverride == null && pkgSetting.cpuAbiOverrideString != null) {
7425                Slog.w(TAG, "Ignoring persisted ABI override " + cpuAbiOverride +
7426                        " for package " + pkg.packageName);
7427            }
7428        }
7429
7430        pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
7431        pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
7432        pkgSetting.cpuAbiOverrideString = cpuAbiOverride;
7433
7434        // Copy the derived override back to the parsed package, so that we can
7435        // update the package settings accordingly.
7436        pkg.cpuAbiOverride = cpuAbiOverride;
7437
7438        if (DEBUG_ABI_SELECTION) {
7439            Slog.d(TAG, "Resolved nativeLibraryRoot for " + pkg.applicationInfo.packageName
7440                    + " to root=" + pkg.applicationInfo.nativeLibraryRootDir + ", isa="
7441                    + pkg.applicationInfo.nativeLibraryRootRequiresIsa);
7442        }
7443
7444        // Push the derived path down into PackageSettings so we know what to
7445        // clean up at uninstall time.
7446        pkgSetting.legacyNativeLibraryPathString = pkg.applicationInfo.nativeLibraryRootDir;
7447
7448        if (DEBUG_ABI_SELECTION) {
7449            Log.d(TAG, "Abis for package[" + pkg.packageName + "] are" +
7450                    " primary=" + pkg.applicationInfo.primaryCpuAbi +
7451                    " secondary=" + pkg.applicationInfo.secondaryCpuAbi);
7452        }
7453
7454        if ((scanFlags & SCAN_BOOTING) == 0 && pkgSetting.sharedUser != null) {
7455            // We don't do this here during boot because we can do it all
7456            // at once after scanning all existing packages.
7457            //
7458            // We also do this *before* we perform dexopt on this package, so that
7459            // we can avoid redundant dexopts, and also to make sure we've got the
7460            // code and package path correct.
7461            adjustCpuAbisForSharedUserLPw(pkgSetting.sharedUser.packages,
7462                    pkg, true /* boot complete */);
7463        }
7464
7465        if (mFactoryTest && pkg.requestedPermissions.contains(
7466                android.Manifest.permission.FACTORY_TEST)) {
7467            pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST;
7468        }
7469
7470        ArrayList<PackageParser.Package> clientLibPkgs = null;
7471
7472        // writer
7473        synchronized (mPackages) {
7474            if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
7475                // Only system apps can add new shared libraries.
7476                if (pkg.libraryNames != null) {
7477                    for (int i=0; i<pkg.libraryNames.size(); i++) {
7478                        String name = pkg.libraryNames.get(i);
7479                        boolean allowed = false;
7480                        if (pkg.isUpdatedSystemApp()) {
7481                            // New library entries can only be added through the
7482                            // system image.  This is important to get rid of a lot
7483                            // of nasty edge cases: for example if we allowed a non-
7484                            // system update of the app to add a library, then uninstalling
7485                            // the update would make the library go away, and assumptions
7486                            // we made such as through app install filtering would now
7487                            // have allowed apps on the device which aren't compatible
7488                            // with it.  Better to just have the restriction here, be
7489                            // conservative, and create many fewer cases that can negatively
7490                            // impact the user experience.
7491                            final PackageSetting sysPs = mSettings
7492                                    .getDisabledSystemPkgLPr(pkg.packageName);
7493                            if (sysPs.pkg != null && sysPs.pkg.libraryNames != null) {
7494                                for (int j=0; j<sysPs.pkg.libraryNames.size(); j++) {
7495                                    if (name.equals(sysPs.pkg.libraryNames.get(j))) {
7496                                        allowed = true;
7497                                        break;
7498                                    }
7499                                }
7500                            }
7501                        } else {
7502                            allowed = true;
7503                        }
7504                        if (allowed) {
7505                            if (!mSharedLibraries.containsKey(name)) {
7506                                mSharedLibraries.put(name, new SharedLibraryEntry(null, pkg.packageName));
7507                            } else if (!name.equals(pkg.packageName)) {
7508                                Slog.w(TAG, "Package " + pkg.packageName + " library "
7509                                        + name + " already exists; skipping");
7510                            }
7511                        } else {
7512                            Slog.w(TAG, "Package " + pkg.packageName + " declares lib "
7513                                    + name + " that is not declared on system image; skipping");
7514                        }
7515                    }
7516                    if ((scanFlags & SCAN_BOOTING) == 0) {
7517                        // If we are not booting, we need to update any applications
7518                        // that are clients of our shared library.  If we are booting,
7519                        // this will all be done once the scan is complete.
7520                        clientLibPkgs = updateAllSharedLibrariesLPw(pkg);
7521                    }
7522                }
7523            }
7524        }
7525
7526        // Request the ActivityManager to kill the process(only for existing packages)
7527        // so that we do not end up in a confused state while the user is still using the older
7528        // version of the application while the new one gets installed.
7529        if ((scanFlags & SCAN_REPLACING) != 0) {
7530            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "killApplication");
7531
7532            killApplication(pkg.applicationInfo.packageName,
7533                        pkg.applicationInfo.uid, "replace pkg");
7534
7535            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
7536        }
7537
7538        // Also need to kill any apps that are dependent on the library.
7539        if (clientLibPkgs != null) {
7540            for (int i=0; i<clientLibPkgs.size(); i++) {
7541                PackageParser.Package clientPkg = clientLibPkgs.get(i);
7542                killApplication(clientPkg.applicationInfo.packageName,
7543                        clientPkg.applicationInfo.uid, "update lib");
7544            }
7545        }
7546
7547        // Make sure we're not adding any bogus keyset info
7548        KeySetManagerService ksms = mSettings.mKeySetManagerService;
7549        ksms.assertScannedPackageValid(pkg);
7550
7551        // writer
7552        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");
7553
7554        boolean createIdmapFailed = false;
7555        synchronized (mPackages) {
7556            // We don't expect installation to fail beyond this point
7557
7558            // Add the new setting to mSettings
7559            mSettings.insertPackageSettingLPw(pkgSetting, pkg);
7560            // Add the new setting to mPackages
7561            mPackages.put(pkg.applicationInfo.packageName, pkg);
7562            // Make sure we don't accidentally delete its data.
7563            final Iterator<PackageCleanItem> iter = mSettings.mPackagesToBeCleaned.iterator();
7564            while (iter.hasNext()) {
7565                PackageCleanItem item = iter.next();
7566                if (pkgName.equals(item.packageName)) {
7567                    iter.remove();
7568                }
7569            }
7570
7571            // Take care of first install / last update times.
7572            if (currentTime != 0) {
7573                if (pkgSetting.firstInstallTime == 0) {
7574                    pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = currentTime;
7575                } else if ((scanFlags&SCAN_UPDATE_TIME) != 0) {
7576                    pkgSetting.lastUpdateTime = currentTime;
7577                }
7578            } else if (pkgSetting.firstInstallTime == 0) {
7579                // We need *something*.  Take time time stamp of the file.
7580                pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = scanFileTime;
7581            } else if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) != 0) {
7582                if (scanFileTime != pkgSetting.timeStamp) {
7583                    // A package on the system image has changed; consider this
7584                    // to be an update.
7585                    pkgSetting.lastUpdateTime = scanFileTime;
7586                }
7587            }
7588
7589            // Add the package's KeySets to the global KeySetManagerService
7590            ksms.addScannedPackageLPw(pkg);
7591
7592            int N = pkg.providers.size();
7593            StringBuilder r = null;
7594            int i;
7595            for (i=0; i<N; i++) {
7596                PackageParser.Provider p = pkg.providers.get(i);
7597                p.info.processName = fixProcessName(pkg.applicationInfo.processName,
7598                        p.info.processName, pkg.applicationInfo.uid);
7599                mProviders.addProvider(p);
7600                p.syncable = p.info.isSyncable;
7601                if (p.info.authority != null) {
7602                    String names[] = p.info.authority.split(";");
7603                    p.info.authority = null;
7604                    for (int j = 0; j < names.length; j++) {
7605                        if (j == 1 && p.syncable) {
7606                            // We only want the first authority for a provider to possibly be
7607                            // syncable, so if we already added this provider using a different
7608                            // authority clear the syncable flag. We copy the provider before
7609                            // changing it because the mProviders object contains a reference
7610                            // to a provider that we don't want to change.
7611                            // Only do this for the second authority since the resulting provider
7612                            // object can be the same for all future authorities for this provider.
7613                            p = new PackageParser.Provider(p);
7614                            p.syncable = false;
7615                        }
7616                        if (!mProvidersByAuthority.containsKey(names[j])) {
7617                            mProvidersByAuthority.put(names[j], p);
7618                            if (p.info.authority == null) {
7619                                p.info.authority = names[j];
7620                            } else {
7621                                p.info.authority = p.info.authority + ";" + names[j];
7622                            }
7623                            if (DEBUG_PACKAGE_SCANNING) {
7624                                if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
7625                                    Log.d(TAG, "Registered content provider: " + names[j]
7626                                            + ", className = " + p.info.name + ", isSyncable = "
7627                                            + p.info.isSyncable);
7628                            }
7629                        } else {
7630                            PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
7631                            Slog.w(TAG, "Skipping provider name " + names[j] +
7632                                    " (in package " + pkg.applicationInfo.packageName +
7633                                    "): name already used by "
7634                                    + ((other != null && other.getComponentName() != null)
7635                                            ? other.getComponentName().getPackageName() : "?"));
7636                        }
7637                    }
7638                }
7639                if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
7640                    if (r == null) {
7641                        r = new StringBuilder(256);
7642                    } else {
7643                        r.append(' ');
7644                    }
7645                    r.append(p.info.name);
7646                }
7647            }
7648            if (r != null) {
7649                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Providers: " + r);
7650            }
7651
7652            N = pkg.services.size();
7653            r = null;
7654            for (i=0; i<N; i++) {
7655                PackageParser.Service s = pkg.services.get(i);
7656                s.info.processName = fixProcessName(pkg.applicationInfo.processName,
7657                        s.info.processName, pkg.applicationInfo.uid);
7658                mServices.addService(s);
7659                if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
7660                    if (r == null) {
7661                        r = new StringBuilder(256);
7662                    } else {
7663                        r.append(' ');
7664                    }
7665                    r.append(s.info.name);
7666                }
7667            }
7668            if (r != null) {
7669                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Services: " + r);
7670            }
7671
7672            N = pkg.receivers.size();
7673            r = null;
7674            for (i=0; i<N; i++) {
7675                PackageParser.Activity a = pkg.receivers.get(i);
7676                a.info.processName = fixProcessName(pkg.applicationInfo.processName,
7677                        a.info.processName, pkg.applicationInfo.uid);
7678                mReceivers.addActivity(a, "receiver");
7679                if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
7680                    if (r == null) {
7681                        r = new StringBuilder(256);
7682                    } else {
7683                        r.append(' ');
7684                    }
7685                    r.append(a.info.name);
7686                }
7687            }
7688            if (r != null) {
7689                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Receivers: " + r);
7690            }
7691
7692            N = pkg.activities.size();
7693            r = null;
7694            for (i=0; i<N; i++) {
7695                PackageParser.Activity a = pkg.activities.get(i);
7696                a.info.processName = fixProcessName(pkg.applicationInfo.processName,
7697                        a.info.processName, pkg.applicationInfo.uid);
7698                mActivities.addActivity(a, "activity");
7699                if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
7700                    if (r == null) {
7701                        r = new StringBuilder(256);
7702                    } else {
7703                        r.append(' ');
7704                    }
7705                    r.append(a.info.name);
7706                }
7707            }
7708            if (r != null) {
7709                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Activities: " + r);
7710            }
7711
7712            N = pkg.permissionGroups.size();
7713            r = null;
7714            for (i=0; i<N; i++) {
7715                PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i);
7716                PackageParser.PermissionGroup cur = mPermissionGroups.get(pg.info.name);
7717                if (cur == null) {
7718                    mPermissionGroups.put(pg.info.name, pg);
7719                    if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
7720                        if (r == null) {
7721                            r = new StringBuilder(256);
7722                        } else {
7723                            r.append(' ');
7724                        }
7725                        r.append(pg.info.name);
7726                    }
7727                } else {
7728                    Slog.w(TAG, "Permission group " + pg.info.name + " from package "
7729                            + pg.info.packageName + " ignored: original from "
7730                            + cur.info.packageName);
7731                    if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
7732                        if (r == null) {
7733                            r = new StringBuilder(256);
7734                        } else {
7735                            r.append(' ');
7736                        }
7737                        r.append("DUP:");
7738                        r.append(pg.info.name);
7739                    }
7740                }
7741            }
7742            if (r != null) {
7743                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Permission Groups: " + r);
7744            }
7745
7746            N = pkg.permissions.size();
7747            r = null;
7748            for (i=0; i<N; i++) {
7749                PackageParser.Permission p = pkg.permissions.get(i);
7750
7751                // Assume by default that we did not install this permission into the system.
7752                p.info.flags &= ~PermissionInfo.FLAG_INSTALLED;
7753
7754                // Now that permission groups have a special meaning, we ignore permission
7755                // groups for legacy apps to prevent unexpected behavior. In particular,
7756                // permissions for one app being granted to someone just becuase they happen
7757                // to be in a group defined by another app (before this had no implications).
7758                if (pkg.applicationInfo.targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1) {
7759                    p.group = mPermissionGroups.get(p.info.group);
7760                    // Warn for a permission in an unknown group.
7761                    if (p.info.group != null && p.group == null) {
7762                        Slog.w(TAG, "Permission " + p.info.name + " from package "
7763                                + p.info.packageName + " in an unknown group " + p.info.group);
7764                    }
7765                }
7766
7767                ArrayMap<String, BasePermission> permissionMap =
7768                        p.tree ? mSettings.mPermissionTrees
7769                                : mSettings.mPermissions;
7770                BasePermission bp = permissionMap.get(p.info.name);
7771
7772                // Allow system apps to redefine non-system permissions
7773                if (bp != null && !Objects.equals(bp.sourcePackage, p.info.packageName)) {
7774                    final boolean currentOwnerIsSystem = (bp.perm != null
7775                            && isSystemApp(bp.perm.owner));
7776                    if (isSystemApp(p.owner)) {
7777                        if (bp.type == BasePermission.TYPE_BUILTIN && bp.perm == null) {
7778                            // It's a built-in permission and no owner, take ownership now
7779                            bp.packageSetting = pkgSetting;
7780                            bp.perm = p;
7781                            bp.uid = pkg.applicationInfo.uid;
7782                            bp.sourcePackage = p.info.packageName;
7783                            p.info.flags |= PermissionInfo.FLAG_INSTALLED;
7784                        } else if (!currentOwnerIsSystem) {
7785                            String msg = "New decl " + p.owner + " of permission  "
7786                                    + p.info.name + " is system; overriding " + bp.sourcePackage;
7787                            reportSettingsProblem(Log.WARN, msg);
7788                            bp = null;
7789                        }
7790                    }
7791                }
7792
7793                if (bp == null) {
7794                    bp = new BasePermission(p.info.name, p.info.packageName,
7795                            BasePermission.TYPE_NORMAL);
7796                    permissionMap.put(p.info.name, bp);
7797                }
7798
7799                if (bp.perm == null) {
7800                    if (bp.sourcePackage == null
7801                            || bp.sourcePackage.equals(p.info.packageName)) {
7802                        BasePermission tree = findPermissionTreeLP(p.info.name);
7803                        if (tree == null
7804                                || tree.sourcePackage.equals(p.info.packageName)) {
7805                            bp.packageSetting = pkgSetting;
7806                            bp.perm = p;
7807                            bp.uid = pkg.applicationInfo.uid;
7808                            bp.sourcePackage = p.info.packageName;
7809                            p.info.flags |= PermissionInfo.FLAG_INSTALLED;
7810                            if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
7811                                if (r == null) {
7812                                    r = new StringBuilder(256);
7813                                } else {
7814                                    r.append(' ');
7815                                }
7816                                r.append(p.info.name);
7817                            }
7818                        } else {
7819                            Slog.w(TAG, "Permission " + p.info.name + " from package "
7820                                    + p.info.packageName + " ignored: base tree "
7821                                    + tree.name + " is from package "
7822                                    + tree.sourcePackage);
7823                        }
7824                    } else {
7825                        Slog.w(TAG, "Permission " + p.info.name + " from package "
7826                                + p.info.packageName + " ignored: original from "
7827                                + bp.sourcePackage);
7828                    }
7829                } else if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
7830                    if (r == null) {
7831                        r = new StringBuilder(256);
7832                    } else {
7833                        r.append(' ');
7834                    }
7835                    r.append("DUP:");
7836                    r.append(p.info.name);
7837                }
7838                if (bp.perm == p) {
7839                    bp.protectionLevel = p.info.protectionLevel;
7840                }
7841            }
7842
7843            if (r != null) {
7844                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Permissions: " + r);
7845            }
7846
7847            N = pkg.instrumentation.size();
7848            r = null;
7849            for (i=0; i<N; i++) {
7850                PackageParser.Instrumentation a = pkg.instrumentation.get(i);
7851                a.info.packageName = pkg.applicationInfo.packageName;
7852                a.info.sourceDir = pkg.applicationInfo.sourceDir;
7853                a.info.publicSourceDir = pkg.applicationInfo.publicSourceDir;
7854                a.info.splitSourceDirs = pkg.applicationInfo.splitSourceDirs;
7855                a.info.splitPublicSourceDirs = pkg.applicationInfo.splitPublicSourceDirs;
7856                a.info.dataDir = pkg.applicationInfo.dataDir;
7857                a.info.deviceEncryptedDataDir = pkg.applicationInfo.deviceEncryptedDataDir;
7858                a.info.credentialEncryptedDataDir = pkg.applicationInfo.credentialEncryptedDataDir;
7859
7860                // TODO: Update instrumentation.nativeLibraryDir as well ? Does it
7861                // need other information about the application, like the ABI and what not ?
7862                a.info.nativeLibraryDir = pkg.applicationInfo.nativeLibraryDir;
7863                mInstrumentation.put(a.getComponentName(), a);
7864                if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
7865                    if (r == null) {
7866                        r = new StringBuilder(256);
7867                    } else {
7868                        r.append(' ');
7869                    }
7870                    r.append(a.info.name);
7871                }
7872            }
7873            if (r != null) {
7874                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Instrumentation: " + r);
7875            }
7876
7877            if (pkg.protectedBroadcasts != null) {
7878                N = pkg.protectedBroadcasts.size();
7879                for (i=0; i<N; i++) {
7880                    mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i));
7881                }
7882            }
7883
7884            pkgSetting.setTimeStamp(scanFileTime);
7885
7886            // Create idmap files for pairs of (packages, overlay packages).
7887            // Note: "android", ie framework-res.apk, is handled by native layers.
7888            if (pkg.mOverlayTarget != null) {
7889                // This is an overlay package.
7890                if (pkg.mOverlayTarget != null && !pkg.mOverlayTarget.equals("android")) {
7891                    if (!mOverlays.containsKey(pkg.mOverlayTarget)) {
7892                        mOverlays.put(pkg.mOverlayTarget,
7893                                new ArrayMap<String, PackageParser.Package>());
7894                    }
7895                    ArrayMap<String, PackageParser.Package> map = mOverlays.get(pkg.mOverlayTarget);
7896                    map.put(pkg.packageName, pkg);
7897                    PackageParser.Package orig = mPackages.get(pkg.mOverlayTarget);
7898                    if (orig != null && !createIdmapForPackagePairLI(orig, pkg)) {
7899                        createIdmapFailed = true;
7900                    }
7901                }
7902            } else if (mOverlays.containsKey(pkg.packageName) &&
7903                    !pkg.packageName.equals("android")) {
7904                // This is a regular package, with one or more known overlay packages.
7905                createIdmapsForPackageLI(pkg);
7906            }
7907        }
7908
7909        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
7910
7911        if (createIdmapFailed) {
7912            throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
7913                    "scanPackageLI failed to createIdmap");
7914        }
7915        return pkg;
7916    }
7917
7918    /**
7919     * Derive the ABI of a non-system package located at {@code scanFile}. This information
7920     * is derived purely on the basis of the contents of {@code scanFile} and
7921     * {@code cpuAbiOverride}.
7922     *
7923     * If {@code extractLibs} is true, native libraries are extracted from the app if required.
7924     */
7925    public void derivePackageAbi(PackageParser.Package pkg, File scanFile,
7926                                 String cpuAbiOverride, boolean extractLibs)
7927            throws PackageManagerException {
7928        // TODO: We can probably be smarter about this stuff. For installed apps,
7929        // we can calculate this information at install time once and for all. For
7930        // system apps, we can probably assume that this information doesn't change
7931        // after the first boot scan. As things stand, we do lots of unnecessary work.
7932
7933        // Give ourselves some initial paths; we'll come back for another
7934        // pass once we've determined ABI below.
7935        setNativeLibraryPaths(pkg);
7936
7937        // We would never need to extract libs for forward-locked and external packages,
7938        // since the container service will do it for us. We shouldn't attempt to
7939        // extract libs from system app when it was not updated.
7940        if (pkg.isForwardLocked() || pkg.applicationInfo.isExternalAsec() ||
7941                (isSystemApp(pkg) && !pkg.isUpdatedSystemApp())) {
7942            extractLibs = false;
7943        }
7944
7945        final String nativeLibraryRootStr = pkg.applicationInfo.nativeLibraryRootDir;
7946        final boolean useIsaSpecificSubdirs = pkg.applicationInfo.nativeLibraryRootRequiresIsa;
7947
7948        NativeLibraryHelper.Handle handle = null;
7949        try {
7950            handle = NativeLibraryHelper.Handle.create(pkg);
7951            // TODO(multiArch): This can be null for apps that didn't go through the
7952            // usual installation process. We can calculate it again, like we
7953            // do during install time.
7954            //
7955            // TODO(multiArch): Why do we need to rescan ASEC apps again ? It seems totally
7956            // unnecessary.
7957            final File nativeLibraryRoot = new File(nativeLibraryRootStr);
7958
7959            // Null out the abis so that they can be recalculated.
7960            pkg.applicationInfo.primaryCpuAbi = null;
7961            pkg.applicationInfo.secondaryCpuAbi = null;
7962            if (isMultiArch(pkg.applicationInfo)) {
7963                // Warn if we've set an abiOverride for multi-lib packages..
7964                // By definition, we need to copy both 32 and 64 bit libraries for
7965                // such packages.
7966                if (pkg.cpuAbiOverride != null
7967                        && !NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(pkg.cpuAbiOverride)) {
7968                    Slog.w(TAG, "Ignoring abiOverride for multi arch application.");
7969                }
7970
7971                int abi32 = PackageManager.NO_NATIVE_LIBRARIES;
7972                int abi64 = PackageManager.NO_NATIVE_LIBRARIES;
7973                if (Build.SUPPORTED_32_BIT_ABIS.length > 0) {
7974                    if (extractLibs) {
7975                        abi32 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
7976                                nativeLibraryRoot, Build.SUPPORTED_32_BIT_ABIS,
7977                                useIsaSpecificSubdirs);
7978                    } else {
7979                        abi32 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_32_BIT_ABIS);
7980                    }
7981                }
7982
7983                maybeThrowExceptionForMultiArchCopy(
7984                        "Error unpackaging 32 bit native libs for multiarch app.", abi32);
7985
7986                if (Build.SUPPORTED_64_BIT_ABIS.length > 0) {
7987                    if (extractLibs) {
7988                        abi64 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
7989                                nativeLibraryRoot, Build.SUPPORTED_64_BIT_ABIS,
7990                                useIsaSpecificSubdirs);
7991                    } else {
7992                        abi64 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_64_BIT_ABIS);
7993                    }
7994                }
7995
7996                maybeThrowExceptionForMultiArchCopy(
7997                        "Error unpackaging 64 bit native libs for multiarch app.", abi64);
7998
7999                if (abi64 >= 0) {
8000                    pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[abi64];
8001                }
8002
8003                if (abi32 >= 0) {
8004                    final String abi = Build.SUPPORTED_32_BIT_ABIS[abi32];
8005                    if (abi64 >= 0) {
8006                        pkg.applicationInfo.secondaryCpuAbi = abi;
8007                    } else {
8008                        pkg.applicationInfo.primaryCpuAbi = abi;
8009                    }
8010                }
8011            } else {
8012                String[] abiList = (cpuAbiOverride != null) ?
8013                        new String[] { cpuAbiOverride } : Build.SUPPORTED_ABIS;
8014
8015                // Enable gross and lame hacks for apps that are built with old
8016                // SDK tools. We must scan their APKs for renderscript bitcode and
8017                // not launch them if it's present. Don't bother checking on devices
8018                // that don't have 64 bit support.
8019                boolean needsRenderScriptOverride = false;
8020                if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && cpuAbiOverride == null &&
8021                        NativeLibraryHelper.hasRenderscriptBitcode(handle)) {
8022                    abiList = Build.SUPPORTED_32_BIT_ABIS;
8023                    needsRenderScriptOverride = true;
8024                }
8025
8026                final int copyRet;
8027                if (extractLibs) {
8028                    copyRet = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
8029                            nativeLibraryRoot, abiList, useIsaSpecificSubdirs);
8030                } else {
8031                    copyRet = NativeLibraryHelper.findSupportedAbi(handle, abiList);
8032                }
8033
8034                if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) {
8035                    throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
8036                            "Error unpackaging native libs for app, errorCode=" + copyRet);
8037                }
8038
8039                if (copyRet >= 0) {
8040                    pkg.applicationInfo.primaryCpuAbi = abiList[copyRet];
8041                } else if (copyRet == PackageManager.NO_NATIVE_LIBRARIES && cpuAbiOverride != null) {
8042                    pkg.applicationInfo.primaryCpuAbi = cpuAbiOverride;
8043                } else if (needsRenderScriptOverride) {
8044                    pkg.applicationInfo.primaryCpuAbi = abiList[0];
8045                }
8046            }
8047        } catch (IOException ioe) {
8048            Slog.e(TAG, "Unable to get canonical file " + ioe.toString());
8049        } finally {
8050            IoUtils.closeQuietly(handle);
8051        }
8052
8053        // Now that we've calculated the ABIs and determined if it's an internal app,
8054        // we will go ahead and populate the nativeLibraryPath.
8055        setNativeLibraryPaths(pkg);
8056    }
8057
8058    /**
8059     * Adjusts ABIs for a set of packages belonging to a shared user so that they all match.
8060     * i.e, so that all packages can be run inside a single process if required.
8061     *
8062     * Optionally, callers can pass in a parsed package via {@code newPackage} in which case
8063     * this function will either try and make the ABI for all packages in {@code packagesForUser}
8064     * match {@code scannedPackage} or will update the ABI of {@code scannedPackage} to match
8065     * the ABI selected for {@code packagesForUser}. This variant is used when installing or
8066     * updating a package that belongs to a shared user.
8067     *
8068     * NOTE: We currently only match for the primary CPU abi string. Matching the secondary
8069     * adds unnecessary complexity.
8070     */
8071    private void adjustCpuAbisForSharedUserLPw(Set<PackageSetting> packagesForUser,
8072            PackageParser.Package scannedPackage, boolean bootComplete) {
8073        String requiredInstructionSet = null;
8074        if (scannedPackage != null && scannedPackage.applicationInfo.primaryCpuAbi != null) {
8075            requiredInstructionSet = VMRuntime.getInstructionSet(
8076                     scannedPackage.applicationInfo.primaryCpuAbi);
8077        }
8078
8079        PackageSetting requirer = null;
8080        for (PackageSetting ps : packagesForUser) {
8081            // If packagesForUser contains scannedPackage, we skip it. This will happen
8082            // when scannedPackage is an update of an existing package. Without this check,
8083            // we will never be able to change the ABI of any package belonging to a shared
8084            // user, even if it's compatible with other packages.
8085            if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
8086                if (ps.primaryCpuAbiString == null) {
8087                    continue;
8088                }
8089
8090                final String instructionSet = VMRuntime.getInstructionSet(ps.primaryCpuAbiString);
8091                if (requiredInstructionSet != null && !instructionSet.equals(requiredInstructionSet)) {
8092                    // We have a mismatch between instruction sets (say arm vs arm64) warn about
8093                    // this but there's not much we can do.
8094                    String errorMessage = "Instruction set mismatch, "
8095                            + ((requirer == null) ? "[caller]" : requirer)
8096                            + " requires " + requiredInstructionSet + " whereas " + ps
8097                            + " requires " + instructionSet;
8098                    Slog.w(TAG, errorMessage);
8099                }
8100
8101                if (requiredInstructionSet == null) {
8102                    requiredInstructionSet = instructionSet;
8103                    requirer = ps;
8104                }
8105            }
8106        }
8107
8108        if (requiredInstructionSet != null) {
8109            String adjustedAbi;
8110            if (requirer != null) {
8111                // requirer != null implies that either scannedPackage was null or that scannedPackage
8112                // did not require an ABI, in which case we have to adjust scannedPackage to match
8113                // the ABI of the set (which is the same as requirer's ABI)
8114                adjustedAbi = requirer.primaryCpuAbiString;
8115                if (scannedPackage != null) {
8116                    scannedPackage.applicationInfo.primaryCpuAbi = adjustedAbi;
8117                }
8118            } else {
8119                // requirer == null implies that we're updating all ABIs in the set to
8120                // match scannedPackage.
8121                adjustedAbi =  scannedPackage.applicationInfo.primaryCpuAbi;
8122            }
8123
8124            for (PackageSetting ps : packagesForUser) {
8125                if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
8126                    if (ps.primaryCpuAbiString != null) {
8127                        continue;
8128                    }
8129
8130                    ps.primaryCpuAbiString = adjustedAbi;
8131                    if (ps.pkg != null && ps.pkg.applicationInfo != null) {
8132                        ps.pkg.applicationInfo.primaryCpuAbi = adjustedAbi;
8133                        Slog.i(TAG, "Adjusting ABI for " + ps.name + " to " + adjustedAbi);
8134                        mInstaller.rmdex(ps.codePathString,
8135                                getDexCodeInstructionSet(getPreferredInstructionSet()));
8136                    }
8137                }
8138            }
8139        }
8140    }
8141
8142    private void setUpCustomResolverActivity(PackageParser.Package pkg) {
8143        synchronized (mPackages) {
8144            mResolverReplaced = true;
8145            // Set up information for custom user intent resolution activity.
8146            mResolveActivity.applicationInfo = pkg.applicationInfo;
8147            mResolveActivity.name = mCustomResolverComponentName.getClassName();
8148            mResolveActivity.packageName = pkg.applicationInfo.packageName;
8149            mResolveActivity.processName = pkg.applicationInfo.packageName;
8150            mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
8151            mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS |
8152                    ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
8153            mResolveActivity.theme = 0;
8154            mResolveActivity.exported = true;
8155            mResolveActivity.enabled = true;
8156            mResolveInfo.activityInfo = mResolveActivity;
8157            mResolveInfo.priority = 0;
8158            mResolveInfo.preferredOrder = 0;
8159            mResolveInfo.match = 0;
8160            mResolveComponentName = mCustomResolverComponentName;
8161            Slog.i(TAG, "Replacing default ResolverActivity with custom activity: " +
8162                    mResolveComponentName);
8163        }
8164    }
8165
8166    private void setUpEphemeralInstallerActivityLP(ComponentName installerComponent) {
8167        final PackageParser.Package pkg = mPackages.get(installerComponent.getPackageName());
8168
8169        // Set up information for ephemeral installer activity
8170        mEphemeralInstallerActivity.applicationInfo = pkg.applicationInfo;
8171        mEphemeralInstallerActivity.name = mEphemeralInstallerComponent.getClassName();
8172        mEphemeralInstallerActivity.packageName = pkg.applicationInfo.packageName;
8173        mEphemeralInstallerActivity.processName = pkg.applicationInfo.packageName;
8174        mEphemeralInstallerActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
8175        mEphemeralInstallerActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS |
8176                ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
8177        mEphemeralInstallerActivity.theme = 0;
8178        mEphemeralInstallerActivity.exported = true;
8179        mEphemeralInstallerActivity.enabled = true;
8180        mEphemeralInstallerInfo.activityInfo = mEphemeralInstallerActivity;
8181        mEphemeralInstallerInfo.priority = 0;
8182        mEphemeralInstallerInfo.preferredOrder = 0;
8183        mEphemeralInstallerInfo.match = 0;
8184
8185        if (DEBUG_EPHEMERAL) {
8186            Slog.d(TAG, "Set ephemeral installer activity: " + mEphemeralInstallerComponent);
8187        }
8188    }
8189
8190    private static String calculateBundledApkRoot(final String codePathString) {
8191        final File codePath = new File(codePathString);
8192        final File codeRoot;
8193        if (FileUtils.contains(Environment.getRootDirectory(), codePath)) {
8194            codeRoot = Environment.getRootDirectory();
8195        } else if (FileUtils.contains(Environment.getOemDirectory(), codePath)) {
8196            codeRoot = Environment.getOemDirectory();
8197        } else if (FileUtils.contains(Environment.getVendorDirectory(), codePath)) {
8198            codeRoot = Environment.getVendorDirectory();
8199        } else {
8200            // Unrecognized code path; take its top real segment as the apk root:
8201            // e.g. /something/app/blah.apk => /something
8202            try {
8203                File f = codePath.getCanonicalFile();
8204                File parent = f.getParentFile();    // non-null because codePath is a file
8205                File tmp;
8206                while ((tmp = parent.getParentFile()) != null) {
8207                    f = parent;
8208                    parent = tmp;
8209                }
8210                codeRoot = f;
8211                Slog.w(TAG, "Unrecognized code path "
8212                        + codePath + " - using " + codeRoot);
8213            } catch (IOException e) {
8214                // Can't canonicalize the code path -- shenanigans?
8215                Slog.w(TAG, "Can't canonicalize code path " + codePath);
8216                return Environment.getRootDirectory().getPath();
8217            }
8218        }
8219        return codeRoot.getPath();
8220    }
8221
8222    /**
8223     * Derive and set the location of native libraries for the given package,
8224     * which varies depending on where and how the package was installed.
8225     */
8226    private void setNativeLibraryPaths(PackageParser.Package pkg) {
8227        final ApplicationInfo info = pkg.applicationInfo;
8228        final String codePath = pkg.codePath;
8229        final File codeFile = new File(codePath);
8230        final boolean bundledApp = info.isSystemApp() && !info.isUpdatedSystemApp();
8231        final boolean asecApp = info.isForwardLocked() || info.isExternalAsec();
8232
8233        info.nativeLibraryRootDir = null;
8234        info.nativeLibraryRootRequiresIsa = false;
8235        info.nativeLibraryDir = null;
8236        info.secondaryNativeLibraryDir = null;
8237
8238        if (isApkFile(codeFile)) {
8239            // Monolithic install
8240            if (bundledApp) {
8241                // If "/system/lib64/apkname" exists, assume that is the per-package
8242                // native library directory to use; otherwise use "/system/lib/apkname".
8243                final String apkRoot = calculateBundledApkRoot(info.sourceDir);
8244                final boolean is64Bit = VMRuntime.is64BitInstructionSet(
8245                        getPrimaryInstructionSet(info));
8246
8247                // This is a bundled system app so choose the path based on the ABI.
8248                // if it's a 64 bit abi, use lib64 otherwise use lib32. Note that this
8249                // is just the default path.
8250                final String apkName = deriveCodePathName(codePath);
8251                final String libDir = is64Bit ? LIB64_DIR_NAME : LIB_DIR_NAME;
8252                info.nativeLibraryRootDir = Environment.buildPath(new File(apkRoot), libDir,
8253                        apkName).getAbsolutePath();
8254
8255                if (info.secondaryCpuAbi != null) {
8256                    final String secondaryLibDir = is64Bit ? LIB_DIR_NAME : LIB64_DIR_NAME;
8257                    info.secondaryNativeLibraryDir = Environment.buildPath(new File(apkRoot),
8258                            secondaryLibDir, apkName).getAbsolutePath();
8259                }
8260            } else if (asecApp) {
8261                info.nativeLibraryRootDir = new File(codeFile.getParentFile(), LIB_DIR_NAME)
8262                        .getAbsolutePath();
8263            } else {
8264                final String apkName = deriveCodePathName(codePath);
8265                info.nativeLibraryRootDir = new File(mAppLib32InstallDir, apkName)
8266                        .getAbsolutePath();
8267            }
8268
8269            info.nativeLibraryRootRequiresIsa = false;
8270            info.nativeLibraryDir = info.nativeLibraryRootDir;
8271        } else {
8272            // Cluster install
8273            info.nativeLibraryRootDir = new File(codeFile, LIB_DIR_NAME).getAbsolutePath();
8274            info.nativeLibraryRootRequiresIsa = true;
8275
8276            info.nativeLibraryDir = new File(info.nativeLibraryRootDir,
8277                    getPrimaryInstructionSet(info)).getAbsolutePath();
8278
8279            if (info.secondaryCpuAbi != null) {
8280                info.secondaryNativeLibraryDir = new File(info.nativeLibraryRootDir,
8281                        VMRuntime.getInstructionSet(info.secondaryCpuAbi)).getAbsolutePath();
8282            }
8283        }
8284    }
8285
8286    /**
8287     * Calculate the abis and roots for a bundled app. These can uniquely
8288     * be determined from the contents of the system partition, i.e whether
8289     * it contains 64 or 32 bit shared libraries etc. We do not validate any
8290     * of this information, and instead assume that the system was built
8291     * sensibly.
8292     */
8293    private void setBundledAppAbisAndRoots(PackageParser.Package pkg,
8294                                           PackageSetting pkgSetting) {
8295        final String apkName = deriveCodePathName(pkg.applicationInfo.getCodePath());
8296
8297        // If "/system/lib64/apkname" exists, assume that is the per-package
8298        // native library directory to use; otherwise use "/system/lib/apkname".
8299        final String apkRoot = calculateBundledApkRoot(pkg.applicationInfo.sourceDir);
8300        setBundledAppAbi(pkg, apkRoot, apkName);
8301        // pkgSetting might be null during rescan following uninstall of updates
8302        // to a bundled app, so accommodate that possibility.  The settings in
8303        // that case will be established later from the parsed package.
8304        //
8305        // If the settings aren't null, sync them up with what we've just derived.
8306        // note that apkRoot isn't stored in the package settings.
8307        if (pkgSetting != null) {
8308            pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
8309            pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
8310        }
8311    }
8312
8313    /**
8314     * Deduces the ABI of a bundled app and sets the relevant fields on the
8315     * parsed pkg object.
8316     *
8317     * @param apkRoot the root of the installed apk, something like {@code /system} or {@code /oem}
8318     *        under which system libraries are installed.
8319     * @param apkName the name of the installed package.
8320     */
8321    private static void setBundledAppAbi(PackageParser.Package pkg, String apkRoot, String apkName) {
8322        final File codeFile = new File(pkg.codePath);
8323
8324        final boolean has64BitLibs;
8325        final boolean has32BitLibs;
8326        if (isApkFile(codeFile)) {
8327            // Monolithic install
8328            has64BitLibs = (new File(apkRoot, new File(LIB64_DIR_NAME, apkName).getPath())).exists();
8329            has32BitLibs = (new File(apkRoot, new File(LIB_DIR_NAME, apkName).getPath())).exists();
8330        } else {
8331            // Cluster install
8332            final File rootDir = new File(codeFile, LIB_DIR_NAME);
8333            if (!ArrayUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS)
8334                    && !TextUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS[0])) {
8335                final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_64_BIT_ABIS[0]);
8336                has64BitLibs = (new File(rootDir, isa)).exists();
8337            } else {
8338                has64BitLibs = false;
8339            }
8340            if (!ArrayUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS)
8341                    && !TextUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS[0])) {
8342                final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_32_BIT_ABIS[0]);
8343                has32BitLibs = (new File(rootDir, isa)).exists();
8344            } else {
8345                has32BitLibs = false;
8346            }
8347        }
8348
8349        if (has64BitLibs && !has32BitLibs) {
8350            // The package has 64 bit libs, but not 32 bit libs. Its primary
8351            // ABI should be 64 bit. We can safely assume here that the bundled
8352            // native libraries correspond to the most preferred ABI in the list.
8353
8354            pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
8355            pkg.applicationInfo.secondaryCpuAbi = null;
8356        } else if (has32BitLibs && !has64BitLibs) {
8357            // The package has 32 bit libs but not 64 bit libs. Its primary
8358            // ABI should be 32 bit.
8359
8360            pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
8361            pkg.applicationInfo.secondaryCpuAbi = null;
8362        } else if (has32BitLibs && has64BitLibs) {
8363            // The application has both 64 and 32 bit bundled libraries. We check
8364            // here that the app declares multiArch support, and warn if it doesn't.
8365            //
8366            // We will be lenient here and record both ABIs. The primary will be the
8367            // ABI that's higher on the list, i.e, a device that's configured to prefer
8368            // 64 bit apps will see a 64 bit primary ABI,
8369
8370            if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) == 0) {
8371                Slog.e(TAG, "Package " + pkg + " has multiple bundled libs, but is not multiarch.");
8372            }
8373
8374            if (VMRuntime.is64BitInstructionSet(getPreferredInstructionSet())) {
8375                pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
8376                pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
8377            } else {
8378                pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
8379                pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
8380            }
8381        } else {
8382            pkg.applicationInfo.primaryCpuAbi = null;
8383            pkg.applicationInfo.secondaryCpuAbi = null;
8384        }
8385    }
8386
8387    private void killApplication(String pkgName, int appId, String reason) {
8388        // Request the ActivityManager to kill the process(only for existing packages)
8389        // so that we do not end up in a confused state while the user is still using the older
8390        // version of the application while the new one gets installed.
8391        IActivityManager am = ActivityManagerNative.getDefault();
8392        if (am != null) {
8393            try {
8394                am.killApplicationWithAppId(pkgName, appId, reason);
8395            } catch (RemoteException e) {
8396            }
8397        }
8398    }
8399
8400    void removePackageLI(PackageSetting ps, boolean chatty) {
8401        if (DEBUG_INSTALL) {
8402            if (chatty)
8403                Log.d(TAG, "Removing package " + ps.name);
8404        }
8405
8406        // writer
8407        synchronized (mPackages) {
8408            mPackages.remove(ps.name);
8409            final PackageParser.Package pkg = ps.pkg;
8410            if (pkg != null) {
8411                cleanPackageDataStructuresLILPw(pkg, chatty);
8412            }
8413        }
8414    }
8415
8416    void removeInstalledPackageLI(PackageParser.Package pkg, boolean chatty) {
8417        if (DEBUG_INSTALL) {
8418            if (chatty)
8419                Log.d(TAG, "Removing package " + pkg.applicationInfo.packageName);
8420        }
8421
8422        // writer
8423        synchronized (mPackages) {
8424            mPackages.remove(pkg.applicationInfo.packageName);
8425            cleanPackageDataStructuresLILPw(pkg, chatty);
8426        }
8427    }
8428
8429    void cleanPackageDataStructuresLILPw(PackageParser.Package pkg, boolean chatty) {
8430        int N = pkg.providers.size();
8431        StringBuilder r = null;
8432        int i;
8433        for (i=0; i<N; i++) {
8434            PackageParser.Provider p = pkg.providers.get(i);
8435            mProviders.removeProvider(p);
8436            if (p.info.authority == null) {
8437
8438                /* There was another ContentProvider with this authority when
8439                 * this app was installed so this authority is null,
8440                 * Ignore it as we don't have to unregister the provider.
8441                 */
8442                continue;
8443            }
8444            String names[] = p.info.authority.split(";");
8445            for (int j = 0; j < names.length; j++) {
8446                if (mProvidersByAuthority.get(names[j]) == p) {
8447                    mProvidersByAuthority.remove(names[j]);
8448                    if (DEBUG_REMOVE) {
8449                        if (chatty)
8450                            Log.d(TAG, "Unregistered content provider: " + names[j]
8451                                    + ", className = " + p.info.name + ", isSyncable = "
8452                                    + p.info.isSyncable);
8453                    }
8454                }
8455            }
8456            if (DEBUG_REMOVE && chatty) {
8457                if (r == null) {
8458                    r = new StringBuilder(256);
8459                } else {
8460                    r.append(' ');
8461                }
8462                r.append(p.info.name);
8463            }
8464        }
8465        if (r != null) {
8466            if (DEBUG_REMOVE) Log.d(TAG, "  Providers: " + r);
8467        }
8468
8469        N = pkg.services.size();
8470        r = null;
8471        for (i=0; i<N; i++) {
8472            PackageParser.Service s = pkg.services.get(i);
8473            mServices.removeService(s);
8474            if (chatty) {
8475                if (r == null) {
8476                    r = new StringBuilder(256);
8477                } else {
8478                    r.append(' ');
8479                }
8480                r.append(s.info.name);
8481            }
8482        }
8483        if (r != null) {
8484            if (DEBUG_REMOVE) Log.d(TAG, "  Services: " + r);
8485        }
8486
8487        N = pkg.receivers.size();
8488        r = null;
8489        for (i=0; i<N; i++) {
8490            PackageParser.Activity a = pkg.receivers.get(i);
8491            mReceivers.removeActivity(a, "receiver");
8492            if (DEBUG_REMOVE && chatty) {
8493                if (r == null) {
8494                    r = new StringBuilder(256);
8495                } else {
8496                    r.append(' ');
8497                }
8498                r.append(a.info.name);
8499            }
8500        }
8501        if (r != null) {
8502            if (DEBUG_REMOVE) Log.d(TAG, "  Receivers: " + r);
8503        }
8504
8505        N = pkg.activities.size();
8506        r = null;
8507        for (i=0; i<N; i++) {
8508            PackageParser.Activity a = pkg.activities.get(i);
8509            mActivities.removeActivity(a, "activity");
8510            if (DEBUG_REMOVE && chatty) {
8511                if (r == null) {
8512                    r = new StringBuilder(256);
8513                } else {
8514                    r.append(' ');
8515                }
8516                r.append(a.info.name);
8517            }
8518        }
8519        if (r != null) {
8520            if (DEBUG_REMOVE) Log.d(TAG, "  Activities: " + r);
8521        }
8522
8523        N = pkg.permissions.size();
8524        r = null;
8525        for (i=0; i<N; i++) {
8526            PackageParser.Permission p = pkg.permissions.get(i);
8527            BasePermission bp = mSettings.mPermissions.get(p.info.name);
8528            if (bp == null) {
8529                bp = mSettings.mPermissionTrees.get(p.info.name);
8530            }
8531            if (bp != null && bp.perm == p) {
8532                bp.perm = null;
8533                if (DEBUG_REMOVE && chatty) {
8534                    if (r == null) {
8535                        r = new StringBuilder(256);
8536                    } else {
8537                        r.append(' ');
8538                    }
8539                    r.append(p.info.name);
8540                }
8541            }
8542            if ((p.info.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
8543                ArraySet<String> appOpPkgs = mAppOpPermissionPackages.get(p.info.name);
8544                if (appOpPkgs != null) {
8545                    appOpPkgs.remove(pkg.packageName);
8546                }
8547            }
8548        }
8549        if (r != null) {
8550            if (DEBUG_REMOVE) Log.d(TAG, "  Permissions: " + r);
8551        }
8552
8553        N = pkg.requestedPermissions.size();
8554        r = null;
8555        for (i=0; i<N; i++) {
8556            String perm = pkg.requestedPermissions.get(i);
8557            BasePermission bp = mSettings.mPermissions.get(perm);
8558            if (bp != null && (bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
8559                ArraySet<String> appOpPkgs = mAppOpPermissionPackages.get(perm);
8560                if (appOpPkgs != null) {
8561                    appOpPkgs.remove(pkg.packageName);
8562                    if (appOpPkgs.isEmpty()) {
8563                        mAppOpPermissionPackages.remove(perm);
8564                    }
8565                }
8566            }
8567        }
8568        if (r != null) {
8569            if (DEBUG_REMOVE) Log.d(TAG, "  Permissions: " + r);
8570        }
8571
8572        N = pkg.instrumentation.size();
8573        r = null;
8574        for (i=0; i<N; i++) {
8575            PackageParser.Instrumentation a = pkg.instrumentation.get(i);
8576            mInstrumentation.remove(a.getComponentName());
8577            if (DEBUG_REMOVE && chatty) {
8578                if (r == null) {
8579                    r = new StringBuilder(256);
8580                } else {
8581                    r.append(' ');
8582                }
8583                r.append(a.info.name);
8584            }
8585        }
8586        if (r != null) {
8587            if (DEBUG_REMOVE) Log.d(TAG, "  Instrumentation: " + r);
8588        }
8589
8590        r = null;
8591        if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
8592            // Only system apps can hold shared libraries.
8593            if (pkg.libraryNames != null) {
8594                for (i=0; i<pkg.libraryNames.size(); i++) {
8595                    String name = pkg.libraryNames.get(i);
8596                    SharedLibraryEntry cur = mSharedLibraries.get(name);
8597                    if (cur != null && cur.apk != null && cur.apk.equals(pkg.packageName)) {
8598                        mSharedLibraries.remove(name);
8599                        if (DEBUG_REMOVE && chatty) {
8600                            if (r == null) {
8601                                r = new StringBuilder(256);
8602                            } else {
8603                                r.append(' ');
8604                            }
8605                            r.append(name);
8606                        }
8607                    }
8608                }
8609            }
8610        }
8611        if (r != null) {
8612            if (DEBUG_REMOVE) Log.d(TAG, "  Libraries: " + r);
8613        }
8614    }
8615
8616    private static boolean hasPermission(PackageParser.Package pkgInfo, String perm) {
8617        for (int i=pkgInfo.permissions.size()-1; i>=0; i--) {
8618            if (pkgInfo.permissions.get(i).info.name.equals(perm)) {
8619                return true;
8620            }
8621        }
8622        return false;
8623    }
8624
8625    static final int UPDATE_PERMISSIONS_ALL = 1<<0;
8626    static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1<<1;
8627    static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1<<2;
8628
8629    private void updatePermissionsLPw(String changingPkg, PackageParser.Package pkgInfo,
8630            int flags) {
8631        final String volumeUuid = (pkgInfo != null) ? getVolumeUuidForPackage(pkgInfo) : null;
8632        updatePermissionsLPw(changingPkg, pkgInfo, volumeUuid, flags);
8633    }
8634
8635    private void updatePermissionsLPw(String changingPkg,
8636            PackageParser.Package pkgInfo, String replaceVolumeUuid, int flags) {
8637        // Make sure there are no dangling permission trees.
8638        Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator();
8639        while (it.hasNext()) {
8640            final BasePermission bp = it.next();
8641            if (bp.packageSetting == null) {
8642                // We may not yet have parsed the package, so just see if
8643                // we still know about its settings.
8644                bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage);
8645            }
8646            if (bp.packageSetting == null) {
8647                Slog.w(TAG, "Removing dangling permission tree: " + bp.name
8648                        + " from package " + bp.sourcePackage);
8649                it.remove();
8650            } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) {
8651                if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
8652                    Slog.i(TAG, "Removing old permission tree: " + bp.name
8653                            + " from package " + bp.sourcePackage);
8654                    flags |= UPDATE_PERMISSIONS_ALL;
8655                    it.remove();
8656                }
8657            }
8658        }
8659
8660        // Make sure all dynamic permissions have been assigned to a package,
8661        // and make sure there are no dangling permissions.
8662        it = mSettings.mPermissions.values().iterator();
8663        while (it.hasNext()) {
8664            final BasePermission bp = it.next();
8665            if (bp.type == BasePermission.TYPE_DYNAMIC) {
8666                if (DEBUG_SETTINGS) Log.v(TAG, "Dynamic permission: name="
8667                        + bp.name + " pkg=" + bp.sourcePackage
8668                        + " info=" + bp.pendingInfo);
8669                if (bp.packageSetting == null && bp.pendingInfo != null) {
8670                    final BasePermission tree = findPermissionTreeLP(bp.name);
8671                    if (tree != null && tree.perm != null) {
8672                        bp.packageSetting = tree.packageSetting;
8673                        bp.perm = new PackageParser.Permission(tree.perm.owner,
8674                                new PermissionInfo(bp.pendingInfo));
8675                        bp.perm.info.packageName = tree.perm.info.packageName;
8676                        bp.perm.info.name = bp.name;
8677                        bp.uid = tree.uid;
8678                    }
8679                }
8680            }
8681            if (bp.packageSetting == null) {
8682                // We may not yet have parsed the package, so just see if
8683                // we still know about its settings.
8684                bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage);
8685            }
8686            if (bp.packageSetting == null) {
8687                Slog.w(TAG, "Removing dangling permission: " + bp.name
8688                        + " from package " + bp.sourcePackage);
8689                it.remove();
8690            } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) {
8691                if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
8692                    Slog.i(TAG, "Removing old permission: " + bp.name
8693                            + " from package " + bp.sourcePackage);
8694                    flags |= UPDATE_PERMISSIONS_ALL;
8695                    it.remove();
8696                }
8697            }
8698        }
8699
8700        // Now update the permissions for all packages, in particular
8701        // replace the granted permissions of the system packages.
8702        if ((flags&UPDATE_PERMISSIONS_ALL) != 0) {
8703            for (PackageParser.Package pkg : mPackages.values()) {
8704                if (pkg != pkgInfo) {
8705                    // Only replace for packages on requested volume
8706                    final String volumeUuid = getVolumeUuidForPackage(pkg);
8707                    final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_ALL) != 0)
8708                            && Objects.equals(replaceVolumeUuid, volumeUuid);
8709                    grantPermissionsLPw(pkg, replace, changingPkg);
8710                }
8711            }
8712        }
8713
8714        if (pkgInfo != null) {
8715            // Only replace for packages on requested volume
8716            final String volumeUuid = getVolumeUuidForPackage(pkgInfo);
8717            final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_PKG) != 0)
8718                    && Objects.equals(replaceVolumeUuid, volumeUuid);
8719            grantPermissionsLPw(pkgInfo, replace, changingPkg);
8720        }
8721    }
8722
8723    private void grantPermissionsLPw(PackageParser.Package pkg, boolean replace,
8724            String packageOfInterest) {
8725        // IMPORTANT: There are two types of permissions: install and runtime.
8726        // Install time permissions are granted when the app is installed to
8727        // all device users and users added in the future. Runtime permissions
8728        // are granted at runtime explicitly to specific users. Normal and signature
8729        // protected permissions are install time permissions. Dangerous permissions
8730        // are install permissions if the app's target SDK is Lollipop MR1 or older,
8731        // otherwise they are runtime permissions. This function does not manage
8732        // runtime permissions except for the case an app targeting Lollipop MR1
8733        // being upgraded to target a newer SDK, in which case dangerous permissions
8734        // are transformed from install time to runtime ones.
8735
8736        final PackageSetting ps = (PackageSetting) pkg.mExtras;
8737        if (ps == null) {
8738            return;
8739        }
8740
8741        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "grantPermissions");
8742
8743        PermissionsState permissionsState = ps.getPermissionsState();
8744        PermissionsState origPermissions = permissionsState;
8745
8746        final int[] currentUserIds = UserManagerService.getInstance().getUserIds();
8747
8748        boolean runtimePermissionsRevoked = false;
8749        int[] changedRuntimePermissionUserIds = EMPTY_INT_ARRAY;
8750
8751        boolean changedInstallPermission = false;
8752
8753        if (replace) {
8754            ps.installPermissionsFixed = false;
8755            if (!ps.isSharedUser()) {
8756                origPermissions = new PermissionsState(permissionsState);
8757                permissionsState.reset();
8758            } else {
8759                // We need to know only about runtime permission changes since the
8760                // calling code always writes the install permissions state but
8761                // the runtime ones are written only if changed. The only cases of
8762                // changed runtime permissions here are promotion of an install to
8763                // runtime and revocation of a runtime from a shared user.
8764                changedRuntimePermissionUserIds = revokeUnusedSharedUserPermissionsLPw(
8765                        ps.sharedUser, UserManagerService.getInstance().getUserIds());
8766                if (!ArrayUtils.isEmpty(changedRuntimePermissionUserIds)) {
8767                    runtimePermissionsRevoked = true;
8768                }
8769            }
8770        }
8771
8772        permissionsState.setGlobalGids(mGlobalGids);
8773
8774        final int N = pkg.requestedPermissions.size();
8775        for (int i=0; i<N; i++) {
8776            final String name = pkg.requestedPermissions.get(i);
8777            final BasePermission bp = mSettings.mPermissions.get(name);
8778
8779            if (DEBUG_INSTALL) {
8780                Log.i(TAG, "Package " + pkg.packageName + " checking " + name + ": " + bp);
8781            }
8782
8783            if (bp == null || bp.packageSetting == null) {
8784                if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) {
8785                    Slog.w(TAG, "Unknown permission " + name
8786                            + " in package " + pkg.packageName);
8787                }
8788                continue;
8789            }
8790
8791            final String perm = bp.name;
8792            boolean allowedSig = false;
8793            int grant = GRANT_DENIED;
8794
8795            // Keep track of app op permissions.
8796            if ((bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
8797                ArraySet<String> pkgs = mAppOpPermissionPackages.get(bp.name);
8798                if (pkgs == null) {
8799                    pkgs = new ArraySet<>();
8800                    mAppOpPermissionPackages.put(bp.name, pkgs);
8801                }
8802                pkgs.add(pkg.packageName);
8803            }
8804
8805            final int level = bp.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE;
8806            final boolean appSupportsRuntimePermissions = pkg.applicationInfo.targetSdkVersion
8807                    >= Build.VERSION_CODES.M;
8808            switch (level) {
8809                case PermissionInfo.PROTECTION_NORMAL: {
8810                    // For all apps normal permissions are install time ones.
8811                    grant = GRANT_INSTALL;
8812                } break;
8813
8814                case PermissionInfo.PROTECTION_DANGEROUS: {
8815                    // If a permission review is required for legacy apps we represent
8816                    // their permissions as always granted runtime ones since we need
8817                    // to keep the review required permission flag per user while an
8818                    // install permission's state is shared across all users.
8819                    if (!appSupportsRuntimePermissions && !Build.PERMISSIONS_REVIEW_REQUIRED) {
8820                        // For legacy apps dangerous permissions are install time ones.
8821                        grant = GRANT_INSTALL;
8822                    } else if (origPermissions.hasInstallPermission(bp.name)) {
8823                        // For legacy apps that became modern, install becomes runtime.
8824                        grant = GRANT_UPGRADE;
8825                    } else if (mPromoteSystemApps
8826                            && isSystemApp(ps)
8827                            && mExistingSystemPackages.contains(ps.name)) {
8828                        // For legacy system apps, install becomes runtime.
8829                        // We cannot check hasInstallPermission() for system apps since those
8830                        // permissions were granted implicitly and not persisted pre-M.
8831                        grant = GRANT_UPGRADE;
8832                    } else {
8833                        // For modern apps keep runtime permissions unchanged.
8834                        grant = GRANT_RUNTIME;
8835                    }
8836                } break;
8837
8838                case PermissionInfo.PROTECTION_SIGNATURE: {
8839                    // For all apps signature permissions are install time ones.
8840                    allowedSig = grantSignaturePermission(perm, pkg, bp, origPermissions);
8841                    if (allowedSig) {
8842                        grant = GRANT_INSTALL;
8843                    }
8844                } break;
8845            }
8846
8847            if (DEBUG_INSTALL) {
8848                Log.i(TAG, "Package " + pkg.packageName + " granting " + perm);
8849            }
8850
8851            if (grant != GRANT_DENIED) {
8852                if (!isSystemApp(ps) && ps.installPermissionsFixed) {
8853                    // If this is an existing, non-system package, then
8854                    // we can't add any new permissions to it.
8855                    if (!allowedSig && !origPermissions.hasInstallPermission(perm)) {
8856                        // Except...  if this is a permission that was added
8857                        // to the platform (note: need to only do this when
8858                        // updating the platform).
8859                        if (!isNewPlatformPermissionForPackage(perm, pkg)) {
8860                            grant = GRANT_DENIED;
8861                        }
8862                    }
8863                }
8864
8865                switch (grant) {
8866                    case GRANT_INSTALL: {
8867                        // Revoke this as runtime permission to handle the case of
8868                        // a runtime permission being downgraded to an install one. Also in permission review mode we keep dangerous permissions for legacy apps
8869                        for (int userId : UserManagerService.getInstance().getUserIds()) {
8870                            if (origPermissions.getRuntimePermissionState(
8871                                    bp.name, userId) != null) {
8872                                // Revoke the runtime permission and clear the flags.
8873                                origPermissions.revokeRuntimePermission(bp, userId);
8874                                origPermissions.updatePermissionFlags(bp, userId,
8875                                      PackageManager.MASK_PERMISSION_FLAGS, 0);
8876                                // If we revoked a permission permission, we have to write.
8877                                changedRuntimePermissionUserIds = ArrayUtils.appendInt(
8878                                        changedRuntimePermissionUserIds, userId);
8879                            }
8880                        }
8881                        // Grant an install permission.
8882                        if (permissionsState.grantInstallPermission(bp) !=
8883                                PermissionsState.PERMISSION_OPERATION_FAILURE) {
8884                            changedInstallPermission = true;
8885                        }
8886                    } break;
8887
8888                    case GRANT_RUNTIME: {
8889                        // Grant previously granted runtime permissions.
8890                        for (int userId : UserManagerService.getInstance().getUserIds()) {
8891                            PermissionState permissionState = origPermissions
8892                                    .getRuntimePermissionState(bp.name, userId);
8893                            int flags = permissionState != null
8894                                    ? permissionState.getFlags() : 0;
8895                            if (origPermissions.hasRuntimePermission(bp.name, userId)) {
8896                                if (permissionsState.grantRuntimePermission(bp, userId) ==
8897                                        PermissionsState.PERMISSION_OPERATION_FAILURE) {
8898                                    // If we cannot put the permission as it was, we have to write.
8899                                    changedRuntimePermissionUserIds = ArrayUtils.appendInt(
8900                                            changedRuntimePermissionUserIds, userId);
8901                                }
8902                                // If the app supports runtime permissions no need for a review.
8903                                if (Build.PERMISSIONS_REVIEW_REQUIRED
8904                                        && appSupportsRuntimePermissions
8905                                        && (flags & PackageManager
8906                                                .FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
8907                                    flags &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
8908                                    // Since we changed the flags, we have to write.
8909                                    changedRuntimePermissionUserIds = ArrayUtils.appendInt(
8910                                            changedRuntimePermissionUserIds, userId);
8911                                }
8912                            } else if (Build.PERMISSIONS_REVIEW_REQUIRED
8913                                    && !appSupportsRuntimePermissions) {
8914                                // For legacy apps that need a permission review, every new
8915                                // runtime permission is granted but it is pending a review.
8916                                if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) {
8917                                    permissionsState.grantRuntimePermission(bp, userId);
8918                                    flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
8919                                    // We changed the permission and flags, hence have to write.
8920                                    changedRuntimePermissionUserIds = ArrayUtils.appendInt(
8921                                            changedRuntimePermissionUserIds, userId);
8922                                }
8923                            }
8924                            // Propagate the permission flags.
8925                            permissionsState.updatePermissionFlags(bp, userId, flags, flags);
8926                        }
8927                    } break;
8928
8929                    case GRANT_UPGRADE: {
8930                        // Grant runtime permissions for a previously held install permission.
8931                        PermissionState permissionState = origPermissions
8932                                .getInstallPermissionState(bp.name);
8933                        final int flags = permissionState != null ? permissionState.getFlags() : 0;
8934
8935                        if (origPermissions.revokeInstallPermission(bp)
8936                                != PermissionsState.PERMISSION_OPERATION_FAILURE) {
8937                            // We will be transferring the permission flags, so clear them.
8938                            origPermissions.updatePermissionFlags(bp, UserHandle.USER_ALL,
8939                                    PackageManager.MASK_PERMISSION_FLAGS, 0);
8940                            changedInstallPermission = true;
8941                        }
8942
8943                        // If the permission is not to be promoted to runtime we ignore it and
8944                        // also its other flags as they are not applicable to install permissions.
8945                        if ((flags & PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE) == 0) {
8946                            for (int userId : currentUserIds) {
8947                                if (permissionsState.grantRuntimePermission(bp, userId) !=
8948                                        PermissionsState.PERMISSION_OPERATION_FAILURE) {
8949                                    // Transfer the permission flags.
8950                                    permissionsState.updatePermissionFlags(bp, userId,
8951                                            flags, flags);
8952                                    // If we granted the permission, we have to write.
8953                                    changedRuntimePermissionUserIds = ArrayUtils.appendInt(
8954                                            changedRuntimePermissionUserIds, userId);
8955                                }
8956                            }
8957                        }
8958                    } break;
8959
8960                    default: {
8961                        if (packageOfInterest == null
8962                                || packageOfInterest.equals(pkg.packageName)) {
8963                            Slog.w(TAG, "Not granting permission " + perm
8964                                    + " to package " + pkg.packageName
8965                                    + " because it was previously installed without");
8966                        }
8967                    } break;
8968                }
8969            } else {
8970                if (permissionsState.revokeInstallPermission(bp) !=
8971                        PermissionsState.PERMISSION_OPERATION_FAILURE) {
8972                    // Also drop the permission flags.
8973                    permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
8974                            PackageManager.MASK_PERMISSION_FLAGS, 0);
8975                    changedInstallPermission = true;
8976                    Slog.i(TAG, "Un-granting permission " + perm
8977                            + " from package " + pkg.packageName
8978                            + " (protectionLevel=" + bp.protectionLevel
8979                            + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
8980                            + ")");
8981                } else if ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) == 0) {
8982                    // Don't print warning for app op permissions, since it is fine for them
8983                    // not to be granted, there is a UI for the user to decide.
8984                    if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) {
8985                        Slog.w(TAG, "Not granting permission " + perm
8986                                + " to package " + pkg.packageName
8987                                + " (protectionLevel=" + bp.protectionLevel
8988                                + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
8989                                + ")");
8990                    }
8991                }
8992            }
8993        }
8994
8995        if ((changedInstallPermission || replace) && !ps.installPermissionsFixed &&
8996                !isSystemApp(ps) || isUpdatedSystemApp(ps)){
8997            // This is the first that we have heard about this package, so the
8998            // permissions we have now selected are fixed until explicitly
8999            // changed.
9000            ps.installPermissionsFixed = true;
9001        }
9002
9003        // Persist the runtime permissions state for users with changes. If permissions
9004        // were revoked because no app in the shared user declares them we have to
9005        // write synchronously to avoid losing runtime permissions state.
9006        for (int userId : changedRuntimePermissionUserIds) {
9007            mSettings.writeRuntimePermissionsForUserLPr(userId, runtimePermissionsRevoked);
9008        }
9009
9010        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9011    }
9012
9013    private boolean isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg) {
9014        boolean allowed = false;
9015        final int NP = PackageParser.NEW_PERMISSIONS.length;
9016        for (int ip=0; ip<NP; ip++) {
9017            final PackageParser.NewPermissionInfo npi
9018                    = PackageParser.NEW_PERMISSIONS[ip];
9019            if (npi.name.equals(perm)
9020                    && pkg.applicationInfo.targetSdkVersion < npi.sdkVersion) {
9021                allowed = true;
9022                Log.i(TAG, "Auto-granting " + perm + " to old pkg "
9023                        + pkg.packageName);
9024                break;
9025            }
9026        }
9027        return allowed;
9028    }
9029
9030    private boolean grantSignaturePermission(String perm, PackageParser.Package pkg,
9031            BasePermission bp, PermissionsState origPermissions) {
9032        boolean allowed;
9033        allowed = (compareSignatures(
9034                bp.packageSetting.signatures.mSignatures, pkg.mSignatures)
9035                        == PackageManager.SIGNATURE_MATCH)
9036                || (compareSignatures(mPlatformPackage.mSignatures, pkg.mSignatures)
9037                        == PackageManager.SIGNATURE_MATCH);
9038        if (!allowed && (bp.protectionLevel
9039                & PermissionInfo.PROTECTION_FLAG_PRIVILEGED) != 0) {
9040            if (isSystemApp(pkg)) {
9041                // For updated system applications, a system permission
9042                // is granted only if it had been defined by the original application.
9043                if (pkg.isUpdatedSystemApp()) {
9044                    final PackageSetting sysPs = mSettings
9045                            .getDisabledSystemPkgLPr(pkg.packageName);
9046                    if (sysPs.getPermissionsState().hasInstallPermission(perm)) {
9047                        // If the original was granted this permission, we take
9048                        // that grant decision as read and propagate it to the
9049                        // update.
9050                        if (sysPs.isPrivileged()) {
9051                            allowed = true;
9052                        }
9053                    } else {
9054                        // The system apk may have been updated with an older
9055                        // version of the one on the data partition, but which
9056                        // granted a new system permission that it didn't have
9057                        // before.  In this case we do want to allow the app to
9058                        // now get the new permission if the ancestral apk is
9059                        // privileged to get it.
9060                        if (sysPs.pkg != null && sysPs.isPrivileged()) {
9061                            for (int j=0;
9062                                    j<sysPs.pkg.requestedPermissions.size(); j++) {
9063                                if (perm.equals(
9064                                        sysPs.pkg.requestedPermissions.get(j))) {
9065                                    allowed = true;
9066                                    break;
9067                                }
9068                            }
9069                        }
9070                    }
9071                } else {
9072                    allowed = isPrivilegedApp(pkg);
9073                }
9074            }
9075        }
9076        if (!allowed) {
9077            if (!allowed && (bp.protectionLevel
9078                    & PermissionInfo.PROTECTION_FLAG_PRE23) != 0
9079                    && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
9080                // If this was a previously normal/dangerous permission that got moved
9081                // to a system permission as part of the runtime permission redesign, then
9082                // we still want to blindly grant it to old apps.
9083                allowed = true;
9084            }
9085            if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_INSTALLER) != 0
9086                    && pkg.packageName.equals(mRequiredInstallerPackage)) {
9087                // If this permission is to be granted to the system installer and
9088                // this app is an installer, then it gets the permission.
9089                allowed = true;
9090            }
9091            if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_VERIFIER) != 0
9092                    && pkg.packageName.equals(mRequiredVerifierPackage)) {
9093                // If this permission is to be granted to the system verifier and
9094                // this app is a verifier, then it gets the permission.
9095                allowed = true;
9096            }
9097            if (!allowed && (bp.protectionLevel
9098                    & PermissionInfo.PROTECTION_FLAG_PREINSTALLED) != 0
9099                    && isSystemApp(pkg)) {
9100                // Any pre-installed system app is allowed to get this permission.
9101                allowed = true;
9102            }
9103            if (!allowed && (bp.protectionLevel
9104                    & PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0) {
9105                // For development permissions, a development permission
9106                // is granted only if it was already granted.
9107                allowed = origPermissions.hasInstallPermission(perm);
9108            }
9109        }
9110        return allowed;
9111    }
9112
9113    final class ActivityIntentResolver
9114            extends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo> {
9115        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
9116                boolean defaultOnly, int userId) {
9117            if (!sUserManager.exists(userId)) return null;
9118            mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
9119            return super.queryIntent(intent, resolvedType, defaultOnly, userId);
9120        }
9121
9122        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
9123                int userId) {
9124            if (!sUserManager.exists(userId)) return null;
9125            mFlags = flags;
9126            return super.queryIntent(intent, resolvedType,
9127                    (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId);
9128        }
9129
9130        public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
9131                int flags, ArrayList<PackageParser.Activity> packageActivities, int userId) {
9132            if (!sUserManager.exists(userId)) return null;
9133            if (packageActivities == null) {
9134                return null;
9135            }
9136            mFlags = flags;
9137            final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0;
9138            final int N = packageActivities.size();
9139            ArrayList<PackageParser.ActivityIntentInfo[]> listCut =
9140                new ArrayList<PackageParser.ActivityIntentInfo[]>(N);
9141
9142            ArrayList<PackageParser.ActivityIntentInfo> intentFilters;
9143            for (int i = 0; i < N; ++i) {
9144                intentFilters = packageActivities.get(i).intents;
9145                if (intentFilters != null && intentFilters.size() > 0) {
9146                    PackageParser.ActivityIntentInfo[] array =
9147                            new PackageParser.ActivityIntentInfo[intentFilters.size()];
9148                    intentFilters.toArray(array);
9149                    listCut.add(array);
9150                }
9151            }
9152            return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
9153        }
9154
9155        public final void addActivity(PackageParser.Activity a, String type) {
9156            final boolean systemApp = a.info.applicationInfo.isSystemApp();
9157            mActivities.put(a.getComponentName(), a);
9158            if (DEBUG_SHOW_INFO)
9159                Log.v(
9160                TAG, "  " + type + " " +
9161                (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel : a.info.name) + ":");
9162            if (DEBUG_SHOW_INFO)
9163                Log.v(TAG, "    Class=" + a.info.name);
9164            final int NI = a.intents.size();
9165            for (int j=0; j<NI; j++) {
9166                PackageParser.ActivityIntentInfo intent = a.intents.get(j);
9167                if (!systemApp && intent.getPriority() > 0 && "activity".equals(type)) {
9168                    intent.setPriority(0);
9169                    Log.w(TAG, "Package " + a.info.applicationInfo.packageName + " has activity "
9170                            + a.className + " with priority > 0, forcing to 0");
9171                }
9172                if (DEBUG_SHOW_INFO) {
9173                    Log.v(TAG, "    IntentFilter:");
9174                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
9175                }
9176                if (!intent.debugCheck()) {
9177                    Log.w(TAG, "==> For Activity " + a.info.name);
9178                }
9179                addFilter(intent);
9180            }
9181        }
9182
9183        public final void removeActivity(PackageParser.Activity a, String type) {
9184            mActivities.remove(a.getComponentName());
9185            if (DEBUG_SHOW_INFO) {
9186                Log.v(TAG, "  " + type + " "
9187                        + (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel
9188                                : a.info.name) + ":");
9189                Log.v(TAG, "    Class=" + a.info.name);
9190            }
9191            final int NI = a.intents.size();
9192            for (int j=0; j<NI; j++) {
9193                PackageParser.ActivityIntentInfo intent = a.intents.get(j);
9194                if (DEBUG_SHOW_INFO) {
9195                    Log.v(TAG, "    IntentFilter:");
9196                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
9197                }
9198                removeFilter(intent);
9199            }
9200        }
9201
9202        @Override
9203        protected boolean allowFilterResult(
9204                PackageParser.ActivityIntentInfo filter, List<ResolveInfo> dest) {
9205            ActivityInfo filterAi = filter.activity.info;
9206            for (int i=dest.size()-1; i>=0; i--) {
9207                ActivityInfo destAi = dest.get(i).activityInfo;
9208                if (destAi.name == filterAi.name
9209                        && destAi.packageName == filterAi.packageName) {
9210                    return false;
9211                }
9212            }
9213            return true;
9214        }
9215
9216        @Override
9217        protected ActivityIntentInfo[] newArray(int size) {
9218            return new ActivityIntentInfo[size];
9219        }
9220
9221        @Override
9222        protected boolean isFilterStopped(PackageParser.ActivityIntentInfo filter, int userId) {
9223            if (!sUserManager.exists(userId)) return true;
9224            PackageParser.Package p = filter.activity.owner;
9225            if (p != null) {
9226                PackageSetting ps = (PackageSetting)p.mExtras;
9227                if (ps != null) {
9228                    // System apps are never considered stopped for purposes of
9229                    // filtering, because there may be no way for the user to
9230                    // actually re-launch them.
9231                    return (ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0
9232                            && ps.getStopped(userId);
9233                }
9234            }
9235            return false;
9236        }
9237
9238        @Override
9239        protected boolean isPackageForFilter(String packageName,
9240                PackageParser.ActivityIntentInfo info) {
9241            return packageName.equals(info.activity.owner.packageName);
9242        }
9243
9244        @Override
9245        protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info,
9246                int match, int userId) {
9247            if (!sUserManager.exists(userId)) return null;
9248            if (!mSettings.isEnabledAndMatchLPr(info.activity.info, mFlags, userId)) {
9249                return null;
9250            }
9251            final PackageParser.Activity activity = info.activity;
9252            if (mSafeMode && (activity.info.applicationInfo.flags
9253                    &ApplicationInfo.FLAG_SYSTEM) == 0) {
9254                return null;
9255            }
9256            PackageSetting ps = (PackageSetting) activity.owner.mExtras;
9257            if (ps == null) {
9258                return null;
9259            }
9260            ActivityInfo ai = PackageParser.generateActivityInfo(activity, mFlags,
9261                    ps.readUserState(userId), userId);
9262            if (ai == null) {
9263                return null;
9264            }
9265            final ResolveInfo res = new ResolveInfo();
9266            res.activityInfo = ai;
9267            if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
9268                res.filter = info;
9269            }
9270            if (info != null) {
9271                res.handleAllWebDataURI = info.handleAllWebDataURI();
9272            }
9273            res.priority = info.getPriority();
9274            res.preferredOrder = activity.owner.mPreferredOrder;
9275            //System.out.println("Result: " + res.activityInfo.className +
9276            //                   " = " + res.priority);
9277            res.match = match;
9278            res.isDefault = info.hasDefault;
9279            res.labelRes = info.labelRes;
9280            res.nonLocalizedLabel = info.nonLocalizedLabel;
9281            if (userNeedsBadging(userId)) {
9282                res.noResourceId = true;
9283            } else {
9284                res.icon = info.icon;
9285            }
9286            res.iconResourceId = info.icon;
9287            res.system = res.activityInfo.applicationInfo.isSystemApp();
9288            return res;
9289        }
9290
9291        @Override
9292        protected void sortResults(List<ResolveInfo> results) {
9293            Collections.sort(results, mResolvePrioritySorter);
9294        }
9295
9296        @Override
9297        protected void dumpFilter(PrintWriter out, String prefix,
9298                PackageParser.ActivityIntentInfo filter) {
9299            out.print(prefix); out.print(
9300                    Integer.toHexString(System.identityHashCode(filter.activity)));
9301                    out.print(' ');
9302                    filter.activity.printComponentShortName(out);
9303                    out.print(" filter ");
9304                    out.println(Integer.toHexString(System.identityHashCode(filter)));
9305        }
9306
9307        @Override
9308        protected Object filterToLabel(PackageParser.ActivityIntentInfo filter) {
9309            return filter.activity;
9310        }
9311
9312        protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
9313            PackageParser.Activity activity = (PackageParser.Activity)label;
9314            out.print(prefix); out.print(
9315                    Integer.toHexString(System.identityHashCode(activity)));
9316                    out.print(' ');
9317                    activity.printComponentShortName(out);
9318            if (count > 1) {
9319                out.print(" ("); out.print(count); out.print(" filters)");
9320            }
9321            out.println();
9322        }
9323
9324//        List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) {
9325//            final Iterator<ResolveInfo> i = resolveInfoList.iterator();
9326//            final List<ResolveInfo> retList = Lists.newArrayList();
9327//            while (i.hasNext()) {
9328//                final ResolveInfo resolveInfo = i.next();
9329//                if (isEnabledLP(resolveInfo.activityInfo)) {
9330//                    retList.add(resolveInfo);
9331//                }
9332//            }
9333//            return retList;
9334//        }
9335
9336        // Keys are String (activity class name), values are Activity.
9337        private final ArrayMap<ComponentName, PackageParser.Activity> mActivities
9338                = new ArrayMap<ComponentName, PackageParser.Activity>();
9339        private int mFlags;
9340    }
9341
9342    private final class ServiceIntentResolver
9343            extends IntentResolver<PackageParser.ServiceIntentInfo, ResolveInfo> {
9344        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
9345                boolean defaultOnly, int userId) {
9346            mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
9347            return super.queryIntent(intent, resolvedType, defaultOnly, userId);
9348        }
9349
9350        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
9351                int userId) {
9352            if (!sUserManager.exists(userId)) return null;
9353            mFlags = flags;
9354            return super.queryIntent(intent, resolvedType,
9355                    (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId);
9356        }
9357
9358        public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
9359                int flags, ArrayList<PackageParser.Service> packageServices, int userId) {
9360            if (!sUserManager.exists(userId)) return null;
9361            if (packageServices == null) {
9362                return null;
9363            }
9364            mFlags = flags;
9365            final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0;
9366            final int N = packageServices.size();
9367            ArrayList<PackageParser.ServiceIntentInfo[]> listCut =
9368                new ArrayList<PackageParser.ServiceIntentInfo[]>(N);
9369
9370            ArrayList<PackageParser.ServiceIntentInfo> intentFilters;
9371            for (int i = 0; i < N; ++i) {
9372                intentFilters = packageServices.get(i).intents;
9373                if (intentFilters != null && intentFilters.size() > 0) {
9374                    PackageParser.ServiceIntentInfo[] array =
9375                            new PackageParser.ServiceIntentInfo[intentFilters.size()];
9376                    intentFilters.toArray(array);
9377                    listCut.add(array);
9378                }
9379            }
9380            return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
9381        }
9382
9383        public final void addService(PackageParser.Service s) {
9384            mServices.put(s.getComponentName(), s);
9385            if (DEBUG_SHOW_INFO) {
9386                Log.v(TAG, "  "
9387                        + (s.info.nonLocalizedLabel != null
9388                        ? s.info.nonLocalizedLabel : s.info.name) + ":");
9389                Log.v(TAG, "    Class=" + s.info.name);
9390            }
9391            final int NI = s.intents.size();
9392            int j;
9393            for (j=0; j<NI; j++) {
9394                PackageParser.ServiceIntentInfo intent = s.intents.get(j);
9395                if (DEBUG_SHOW_INFO) {
9396                    Log.v(TAG, "    IntentFilter:");
9397                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
9398                }
9399                if (!intent.debugCheck()) {
9400                    Log.w(TAG, "==> For Service " + s.info.name);
9401                }
9402                addFilter(intent);
9403            }
9404        }
9405
9406        public final void removeService(PackageParser.Service s) {
9407            mServices.remove(s.getComponentName());
9408            if (DEBUG_SHOW_INFO) {
9409                Log.v(TAG, "  " + (s.info.nonLocalizedLabel != null
9410                        ? s.info.nonLocalizedLabel : s.info.name) + ":");
9411                Log.v(TAG, "    Class=" + s.info.name);
9412            }
9413            final int NI = s.intents.size();
9414            int j;
9415            for (j=0; j<NI; j++) {
9416                PackageParser.ServiceIntentInfo intent = s.intents.get(j);
9417                if (DEBUG_SHOW_INFO) {
9418                    Log.v(TAG, "    IntentFilter:");
9419                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
9420                }
9421                removeFilter(intent);
9422            }
9423        }
9424
9425        @Override
9426        protected boolean allowFilterResult(
9427                PackageParser.ServiceIntentInfo filter, List<ResolveInfo> dest) {
9428            ServiceInfo filterSi = filter.service.info;
9429            for (int i=dest.size()-1; i>=0; i--) {
9430                ServiceInfo destAi = dest.get(i).serviceInfo;
9431                if (destAi.name == filterSi.name
9432                        && destAi.packageName == filterSi.packageName) {
9433                    return false;
9434                }
9435            }
9436            return true;
9437        }
9438
9439        @Override
9440        protected PackageParser.ServiceIntentInfo[] newArray(int size) {
9441            return new PackageParser.ServiceIntentInfo[size];
9442        }
9443
9444        @Override
9445        protected boolean isFilterStopped(PackageParser.ServiceIntentInfo filter, int userId) {
9446            if (!sUserManager.exists(userId)) return true;
9447            PackageParser.Package p = filter.service.owner;
9448            if (p != null) {
9449                PackageSetting ps = (PackageSetting)p.mExtras;
9450                if (ps != null) {
9451                    // System apps are never considered stopped for purposes of
9452                    // filtering, because there may be no way for the user to
9453                    // actually re-launch them.
9454                    return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
9455                            && ps.getStopped(userId);
9456                }
9457            }
9458            return false;
9459        }
9460
9461        @Override
9462        protected boolean isPackageForFilter(String packageName,
9463                PackageParser.ServiceIntentInfo info) {
9464            return packageName.equals(info.service.owner.packageName);
9465        }
9466
9467        @Override
9468        protected ResolveInfo newResult(PackageParser.ServiceIntentInfo filter,
9469                int match, int userId) {
9470            if (!sUserManager.exists(userId)) return null;
9471            final PackageParser.ServiceIntentInfo info = (PackageParser.ServiceIntentInfo)filter;
9472            if (!mSettings.isEnabledAndMatchLPr(info.service.info, mFlags, userId)) {
9473                return null;
9474            }
9475            final PackageParser.Service service = info.service;
9476            if (mSafeMode && (service.info.applicationInfo.flags
9477                    &ApplicationInfo.FLAG_SYSTEM) == 0) {
9478                return null;
9479            }
9480            PackageSetting ps = (PackageSetting) service.owner.mExtras;
9481            if (ps == null) {
9482                return null;
9483            }
9484            ServiceInfo si = PackageParser.generateServiceInfo(service, mFlags,
9485                    ps.readUserState(userId), userId);
9486            if (si == null) {
9487                return null;
9488            }
9489            final ResolveInfo res = new ResolveInfo();
9490            res.serviceInfo = si;
9491            if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
9492                res.filter = filter;
9493            }
9494            res.priority = info.getPriority();
9495            res.preferredOrder = service.owner.mPreferredOrder;
9496            res.match = match;
9497            res.isDefault = info.hasDefault;
9498            res.labelRes = info.labelRes;
9499            res.nonLocalizedLabel = info.nonLocalizedLabel;
9500            res.icon = info.icon;
9501            res.system = res.serviceInfo.applicationInfo.isSystemApp();
9502            return res;
9503        }
9504
9505        @Override
9506        protected void sortResults(List<ResolveInfo> results) {
9507            Collections.sort(results, mResolvePrioritySorter);
9508        }
9509
9510        @Override
9511        protected void dumpFilter(PrintWriter out, String prefix,
9512                PackageParser.ServiceIntentInfo filter) {
9513            out.print(prefix); out.print(
9514                    Integer.toHexString(System.identityHashCode(filter.service)));
9515                    out.print(' ');
9516                    filter.service.printComponentShortName(out);
9517                    out.print(" filter ");
9518                    out.println(Integer.toHexString(System.identityHashCode(filter)));
9519        }
9520
9521        @Override
9522        protected Object filterToLabel(PackageParser.ServiceIntentInfo filter) {
9523            return filter.service;
9524        }
9525
9526        protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
9527            PackageParser.Service service = (PackageParser.Service)label;
9528            out.print(prefix); out.print(
9529                    Integer.toHexString(System.identityHashCode(service)));
9530                    out.print(' ');
9531                    service.printComponentShortName(out);
9532            if (count > 1) {
9533                out.print(" ("); out.print(count); out.print(" filters)");
9534            }
9535            out.println();
9536        }
9537
9538//        List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) {
9539//            final Iterator<ResolveInfo> i = resolveInfoList.iterator();
9540//            final List<ResolveInfo> retList = Lists.newArrayList();
9541//            while (i.hasNext()) {
9542//                final ResolveInfo resolveInfo = (ResolveInfo) i;
9543//                if (isEnabledLP(resolveInfo.serviceInfo)) {
9544//                    retList.add(resolveInfo);
9545//                }
9546//            }
9547//            return retList;
9548//        }
9549
9550        // Keys are String (activity class name), values are Activity.
9551        private final ArrayMap<ComponentName, PackageParser.Service> mServices
9552                = new ArrayMap<ComponentName, PackageParser.Service>();
9553        private int mFlags;
9554    };
9555
9556    private final class ProviderIntentResolver
9557            extends IntentResolver<PackageParser.ProviderIntentInfo, ResolveInfo> {
9558        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
9559                boolean defaultOnly, int userId) {
9560            mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
9561            return super.queryIntent(intent, resolvedType, defaultOnly, userId);
9562        }
9563
9564        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
9565                int userId) {
9566            if (!sUserManager.exists(userId))
9567                return null;
9568            mFlags = flags;
9569            return super.queryIntent(intent, resolvedType,
9570                    (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId);
9571        }
9572
9573        public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
9574                int flags, ArrayList<PackageParser.Provider> packageProviders, int userId) {
9575            if (!sUserManager.exists(userId))
9576                return null;
9577            if (packageProviders == null) {
9578                return null;
9579            }
9580            mFlags = flags;
9581            final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0;
9582            final int N = packageProviders.size();
9583            ArrayList<PackageParser.ProviderIntentInfo[]> listCut =
9584                    new ArrayList<PackageParser.ProviderIntentInfo[]>(N);
9585
9586            ArrayList<PackageParser.ProviderIntentInfo> intentFilters;
9587            for (int i = 0; i < N; ++i) {
9588                intentFilters = packageProviders.get(i).intents;
9589                if (intentFilters != null && intentFilters.size() > 0) {
9590                    PackageParser.ProviderIntentInfo[] array =
9591                            new PackageParser.ProviderIntentInfo[intentFilters.size()];
9592                    intentFilters.toArray(array);
9593                    listCut.add(array);
9594                }
9595            }
9596            return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
9597        }
9598
9599        public final void addProvider(PackageParser.Provider p) {
9600            if (mProviders.containsKey(p.getComponentName())) {
9601                Slog.w(TAG, "Provider " + p.getComponentName() + " already defined; ignoring");
9602                return;
9603            }
9604
9605            mProviders.put(p.getComponentName(), p);
9606            if (DEBUG_SHOW_INFO) {
9607                Log.v(TAG, "  "
9608                        + (p.info.nonLocalizedLabel != null
9609                                ? p.info.nonLocalizedLabel : p.info.name) + ":");
9610                Log.v(TAG, "    Class=" + p.info.name);
9611            }
9612            final int NI = p.intents.size();
9613            int j;
9614            for (j = 0; j < NI; j++) {
9615                PackageParser.ProviderIntentInfo intent = p.intents.get(j);
9616                if (DEBUG_SHOW_INFO) {
9617                    Log.v(TAG, "    IntentFilter:");
9618                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
9619                }
9620                if (!intent.debugCheck()) {
9621                    Log.w(TAG, "==> For Provider " + p.info.name);
9622                }
9623                addFilter(intent);
9624            }
9625        }
9626
9627        public final void removeProvider(PackageParser.Provider p) {
9628            mProviders.remove(p.getComponentName());
9629            if (DEBUG_SHOW_INFO) {
9630                Log.v(TAG, "  " + (p.info.nonLocalizedLabel != null
9631                        ? p.info.nonLocalizedLabel : p.info.name) + ":");
9632                Log.v(TAG, "    Class=" + p.info.name);
9633            }
9634            final int NI = p.intents.size();
9635            int j;
9636            for (j = 0; j < NI; j++) {
9637                PackageParser.ProviderIntentInfo intent = p.intents.get(j);
9638                if (DEBUG_SHOW_INFO) {
9639                    Log.v(TAG, "    IntentFilter:");
9640                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
9641                }
9642                removeFilter(intent);
9643            }
9644        }
9645
9646        @Override
9647        protected boolean allowFilterResult(
9648                PackageParser.ProviderIntentInfo filter, List<ResolveInfo> dest) {
9649            ProviderInfo filterPi = filter.provider.info;
9650            for (int i = dest.size() - 1; i >= 0; i--) {
9651                ProviderInfo destPi = dest.get(i).providerInfo;
9652                if (destPi.name == filterPi.name
9653                        && destPi.packageName == filterPi.packageName) {
9654                    return false;
9655                }
9656            }
9657            return true;
9658        }
9659
9660        @Override
9661        protected PackageParser.ProviderIntentInfo[] newArray(int size) {
9662            return new PackageParser.ProviderIntentInfo[size];
9663        }
9664
9665        @Override
9666        protected boolean isFilterStopped(PackageParser.ProviderIntentInfo filter, int userId) {
9667            if (!sUserManager.exists(userId))
9668                return true;
9669            PackageParser.Package p = filter.provider.owner;
9670            if (p != null) {
9671                PackageSetting ps = (PackageSetting) p.mExtras;
9672                if (ps != null) {
9673                    // System apps are never considered stopped for purposes of
9674                    // filtering, because there may be no way for the user to
9675                    // actually re-launch them.
9676                    return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
9677                            && ps.getStopped(userId);
9678                }
9679            }
9680            return false;
9681        }
9682
9683        @Override
9684        protected boolean isPackageForFilter(String packageName,
9685                PackageParser.ProviderIntentInfo info) {
9686            return packageName.equals(info.provider.owner.packageName);
9687        }
9688
9689        @Override
9690        protected ResolveInfo newResult(PackageParser.ProviderIntentInfo filter,
9691                int match, int userId) {
9692            if (!sUserManager.exists(userId))
9693                return null;
9694            final PackageParser.ProviderIntentInfo info = filter;
9695            if (!mSettings.isEnabledAndMatchLPr(info.provider.info, mFlags, userId)) {
9696                return null;
9697            }
9698            final PackageParser.Provider provider = info.provider;
9699            if (mSafeMode && (provider.info.applicationInfo.flags
9700                    & ApplicationInfo.FLAG_SYSTEM) == 0) {
9701                return null;
9702            }
9703            PackageSetting ps = (PackageSetting) provider.owner.mExtras;
9704            if (ps == null) {
9705                return null;
9706            }
9707            ProviderInfo pi = PackageParser.generateProviderInfo(provider, mFlags,
9708                    ps.readUserState(userId), userId);
9709            if (pi == null) {
9710                return null;
9711            }
9712            final ResolveInfo res = new ResolveInfo();
9713            res.providerInfo = pi;
9714            if ((mFlags & PackageManager.GET_RESOLVED_FILTER) != 0) {
9715                res.filter = filter;
9716            }
9717            res.priority = info.getPriority();
9718            res.preferredOrder = provider.owner.mPreferredOrder;
9719            res.match = match;
9720            res.isDefault = info.hasDefault;
9721            res.labelRes = info.labelRes;
9722            res.nonLocalizedLabel = info.nonLocalizedLabel;
9723            res.icon = info.icon;
9724            res.system = res.providerInfo.applicationInfo.isSystemApp();
9725            return res;
9726        }
9727
9728        @Override
9729        protected void sortResults(List<ResolveInfo> results) {
9730            Collections.sort(results, mResolvePrioritySorter);
9731        }
9732
9733        @Override
9734        protected void dumpFilter(PrintWriter out, String prefix,
9735                PackageParser.ProviderIntentInfo filter) {
9736            out.print(prefix);
9737            out.print(
9738                    Integer.toHexString(System.identityHashCode(filter.provider)));
9739            out.print(' ');
9740            filter.provider.printComponentShortName(out);
9741            out.print(" filter ");
9742            out.println(Integer.toHexString(System.identityHashCode(filter)));
9743        }
9744
9745        @Override
9746        protected Object filterToLabel(PackageParser.ProviderIntentInfo filter) {
9747            return filter.provider;
9748        }
9749
9750        protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
9751            PackageParser.Provider provider = (PackageParser.Provider)label;
9752            out.print(prefix); out.print(
9753                    Integer.toHexString(System.identityHashCode(provider)));
9754                    out.print(' ');
9755                    provider.printComponentShortName(out);
9756            if (count > 1) {
9757                out.print(" ("); out.print(count); out.print(" filters)");
9758            }
9759            out.println();
9760        }
9761
9762        private final ArrayMap<ComponentName, PackageParser.Provider> mProviders
9763                = new ArrayMap<ComponentName, PackageParser.Provider>();
9764        private int mFlags;
9765    }
9766
9767    private static final class EphemeralIntentResolver
9768            extends IntentResolver<EphemeralResolveIntentInfo, EphemeralResolveInfo> {
9769        @Override
9770        protected EphemeralResolveIntentInfo[] newArray(int size) {
9771            return new EphemeralResolveIntentInfo[size];
9772        }
9773
9774        @Override
9775        protected boolean isPackageForFilter(String packageName, EphemeralResolveIntentInfo info) {
9776            return true;
9777        }
9778
9779        @Override
9780        protected EphemeralResolveInfo newResult(EphemeralResolveIntentInfo info, int match,
9781                int userId) {
9782            if (!sUserManager.exists(userId)) {
9783                return null;
9784            }
9785            return info.getEphemeralResolveInfo();
9786        }
9787    }
9788
9789    private static final Comparator<ResolveInfo> mResolvePrioritySorter =
9790            new Comparator<ResolveInfo>() {
9791        public int compare(ResolveInfo r1, ResolveInfo r2) {
9792            int v1 = r1.priority;
9793            int v2 = r2.priority;
9794            //System.out.println("Comparing: q1=" + q1 + " q2=" + q2);
9795            if (v1 != v2) {
9796                return (v1 > v2) ? -1 : 1;
9797            }
9798            v1 = r1.preferredOrder;
9799            v2 = r2.preferredOrder;
9800            if (v1 != v2) {
9801                return (v1 > v2) ? -1 : 1;
9802            }
9803            if (r1.isDefault != r2.isDefault) {
9804                return r1.isDefault ? -1 : 1;
9805            }
9806            v1 = r1.match;
9807            v2 = r2.match;
9808            //System.out.println("Comparing: m1=" + m1 + " m2=" + m2);
9809            if (v1 != v2) {
9810                return (v1 > v2) ? -1 : 1;
9811            }
9812            if (r1.system != r2.system) {
9813                return r1.system ? -1 : 1;
9814            }
9815            if (r1.activityInfo != null) {
9816                return r1.activityInfo.packageName.compareTo(r2.activityInfo.packageName);
9817            }
9818            if (r1.serviceInfo != null) {
9819                return r1.serviceInfo.packageName.compareTo(r2.serviceInfo.packageName);
9820            }
9821            if (r1.providerInfo != null) {
9822                return r1.providerInfo.packageName.compareTo(r2.providerInfo.packageName);
9823            }
9824            return 0;
9825        }
9826    };
9827
9828    private static final Comparator<ProviderInfo> mProviderInitOrderSorter =
9829            new Comparator<ProviderInfo>() {
9830        public int compare(ProviderInfo p1, ProviderInfo p2) {
9831            final int v1 = p1.initOrder;
9832            final int v2 = p2.initOrder;
9833            return (v1 > v2) ? -1 : ((v1 < v2) ? 1 : 0);
9834        }
9835    };
9836
9837    final void sendPackageBroadcast(final String action, final String pkg, final Bundle extras,
9838            final int flags, final String targetPkg, final IIntentReceiver finishedReceiver,
9839            final int[] userIds) {
9840        mHandler.post(new Runnable() {
9841            @Override
9842            public void run() {
9843                try {
9844                    final IActivityManager am = ActivityManagerNative.getDefault();
9845                    if (am == null) return;
9846                    final int[] resolvedUserIds;
9847                    if (userIds == null) {
9848                        resolvedUserIds = am.getRunningUserIds();
9849                    } else {
9850                        resolvedUserIds = userIds;
9851                    }
9852                    for (int id : resolvedUserIds) {
9853                        final Intent intent = new Intent(action,
9854                                pkg != null ? Uri.fromParts("package", pkg, null) : null);
9855                        if (extras != null) {
9856                            intent.putExtras(extras);
9857                        }
9858                        if (targetPkg != null) {
9859                            intent.setPackage(targetPkg);
9860                        }
9861                        // Modify the UID when posting to other users
9862                        int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
9863                        if (uid > 0 && UserHandle.getUserId(uid) != id) {
9864                            uid = UserHandle.getUid(id, UserHandle.getAppId(uid));
9865                            intent.putExtra(Intent.EXTRA_UID, uid);
9866                        }
9867                        intent.putExtra(Intent.EXTRA_USER_HANDLE, id);
9868                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT | flags);
9869                        if (DEBUG_BROADCASTS) {
9870                            RuntimeException here = new RuntimeException("here");
9871                            here.fillInStackTrace();
9872                            Slog.d(TAG, "Sending to user " + id + ": "
9873                                    + intent.toShortString(false, true, false, false)
9874                                    + " " + intent.getExtras(), here);
9875                        }
9876                        am.broadcastIntent(null, intent, null, finishedReceiver,
9877                                0, null, null, null, android.app.AppOpsManager.OP_NONE,
9878                                null, finishedReceiver != null, false, id);
9879                    }
9880                } catch (RemoteException ex) {
9881                }
9882            }
9883        });
9884    }
9885
9886    /**
9887     * Check if the external storage media is available. This is true if there
9888     * is a mounted external storage medium or if the external storage is
9889     * emulated.
9890     */
9891    private boolean isExternalMediaAvailable() {
9892        return mMediaMounted || Environment.isExternalStorageEmulated();
9893    }
9894
9895    @Override
9896    public PackageCleanItem nextPackageToClean(PackageCleanItem lastPackage) {
9897        // writer
9898        synchronized (mPackages) {
9899            if (!isExternalMediaAvailable()) {
9900                // If the external storage is no longer mounted at this point,
9901                // the caller may not have been able to delete all of this
9902                // packages files and can not delete any more.  Bail.
9903                return null;
9904            }
9905            final ArrayList<PackageCleanItem> pkgs = mSettings.mPackagesToBeCleaned;
9906            if (lastPackage != null) {
9907                pkgs.remove(lastPackage);
9908            }
9909            if (pkgs.size() > 0) {
9910                return pkgs.get(0);
9911            }
9912        }
9913        return null;
9914    }
9915
9916    void schedulePackageCleaning(String packageName, int userId, boolean andCode) {
9917        final Message msg = mHandler.obtainMessage(START_CLEANING_PACKAGE,
9918                userId, andCode ? 1 : 0, packageName);
9919        if (mSystemReady) {
9920            msg.sendToTarget();
9921        } else {
9922            if (mPostSystemReadyMessages == null) {
9923                mPostSystemReadyMessages = new ArrayList<>();
9924            }
9925            mPostSystemReadyMessages.add(msg);
9926        }
9927    }
9928
9929    void startCleaningPackages() {
9930        // reader
9931        synchronized (mPackages) {
9932            if (!isExternalMediaAvailable()) {
9933                return;
9934            }
9935            if (mSettings.mPackagesToBeCleaned.isEmpty()) {
9936                return;
9937            }
9938        }
9939        Intent intent = new Intent(PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE);
9940        intent.setComponent(DEFAULT_CONTAINER_COMPONENT);
9941        IActivityManager am = ActivityManagerNative.getDefault();
9942        if (am != null) {
9943            try {
9944                am.startService(null, intent, null, mContext.getOpPackageName(),
9945                        UserHandle.USER_SYSTEM);
9946            } catch (RemoteException e) {
9947            }
9948        }
9949    }
9950
9951    @Override
9952    public void installPackage(String originPath, IPackageInstallObserver2 observer,
9953            int installFlags, String installerPackageName, VerificationParams verificationParams,
9954            String packageAbiOverride) {
9955        installPackageAsUser(originPath, observer, installFlags, installerPackageName,
9956                verificationParams, packageAbiOverride, UserHandle.getCallingUserId());
9957    }
9958
9959    @Override
9960    public void installPackageAsUser(String originPath, IPackageInstallObserver2 observer,
9961            int installFlags, String installerPackageName, VerificationParams verificationParams,
9962            String packageAbiOverride, int userId) {
9963        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null);
9964
9965        final int callingUid = Binder.getCallingUid();
9966        enforceCrossUserPermission(callingUid, userId, true, true, "installPackageAsUser");
9967
9968        if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
9969            try {
9970                if (observer != null) {
9971                    observer.onPackageInstalled("", INSTALL_FAILED_USER_RESTRICTED, null, null);
9972                }
9973            } catch (RemoteException re) {
9974            }
9975            return;
9976        }
9977
9978        if ((callingUid == Process.SHELL_UID) || (callingUid == Process.ROOT_UID)) {
9979            installFlags |= PackageManager.INSTALL_FROM_ADB;
9980
9981        } else {
9982            // Caller holds INSTALL_PACKAGES permission, so we're less strict
9983            // about installerPackageName.
9984
9985            installFlags &= ~PackageManager.INSTALL_FROM_ADB;
9986            installFlags &= ~PackageManager.INSTALL_ALL_USERS;
9987        }
9988
9989        UserHandle user;
9990        if ((installFlags & PackageManager.INSTALL_ALL_USERS) != 0) {
9991            user = UserHandle.ALL;
9992        } else {
9993            user = new UserHandle(userId);
9994        }
9995
9996        // Only system components can circumvent runtime permissions when installing.
9997        if ((installFlags & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0
9998                && mContext.checkCallingOrSelfPermission(Manifest.permission
9999                .INSTALL_GRANT_RUNTIME_PERMISSIONS) == PackageManager.PERMISSION_DENIED) {
10000            throw new SecurityException("You need the "
10001                    + "android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS permission "
10002                    + "to use the PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS flag");
10003        }
10004
10005        verificationParams.setInstallerUid(callingUid);
10006
10007        final File originFile = new File(originPath);
10008        final OriginInfo origin = OriginInfo.fromUntrustedFile(originFile);
10009
10010        final Message msg = mHandler.obtainMessage(INIT_COPY);
10011        final InstallParams params = new InstallParams(origin, null, observer, installFlags,
10012                installerPackageName, null, verificationParams, user, packageAbiOverride, null);
10013        params.setTraceMethod("installAsUser").setTraceCookie(System.identityHashCode(params));
10014        msg.obj = params;
10015
10016        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installAsUser",
10017                System.identityHashCode(msg.obj));
10018        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
10019                System.identityHashCode(msg.obj));
10020
10021        mHandler.sendMessage(msg);
10022    }
10023
10024    void installStage(String packageName, File stagedDir, String stagedCid,
10025            IPackageInstallObserver2 observer, PackageInstaller.SessionParams sessionParams,
10026            String installerPackageName, int installerUid, UserHandle user) {
10027        if (DEBUG_EPHEMERAL) {
10028            if ((sessionParams.installFlags & PackageManager.INSTALL_EPHEMERAL) != 0) {
10029                Slog.d(TAG, "Ephemeral install of " + packageName);
10030            }
10031        }
10032        final VerificationParams verifParams = new VerificationParams(
10033                null, sessionParams.originatingUri, sessionParams.referrerUri,
10034                sessionParams.originatingUid);
10035        verifParams.setInstallerUid(installerUid);
10036
10037        final OriginInfo origin;
10038        if (stagedDir != null) {
10039            origin = OriginInfo.fromStagedFile(stagedDir);
10040        } else {
10041            origin = OriginInfo.fromStagedContainer(stagedCid);
10042        }
10043
10044        final Message msg = mHandler.obtainMessage(INIT_COPY);
10045        final InstallParams params = new InstallParams(origin, null, observer,
10046                sessionParams.installFlags, installerPackageName, sessionParams.volumeUuid,
10047                verifParams, user, sessionParams.abiOverride,
10048                sessionParams.grantedRuntimePermissions);
10049        params.setTraceMethod("installStage").setTraceCookie(System.identityHashCode(params));
10050        msg.obj = params;
10051
10052        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installStage",
10053                System.identityHashCode(msg.obj));
10054        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
10055                System.identityHashCode(msg.obj));
10056
10057        mHandler.sendMessage(msg);
10058    }
10059
10060    private void sendPackageAddedForUser(String packageName, PackageSetting pkgSetting, int userId) {
10061        Bundle extras = new Bundle(1);
10062        extras.putInt(Intent.EXTRA_UID, UserHandle.getUid(userId, pkgSetting.appId));
10063
10064        sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
10065                packageName, extras, 0, null, null, new int[] {userId});
10066        try {
10067            IActivityManager am = ActivityManagerNative.getDefault();
10068            final boolean isSystem =
10069                    isSystemApp(pkgSetting) || isUpdatedSystemApp(pkgSetting);
10070            if (isSystem && am.isUserRunning(userId, 0)) {
10071                // The just-installed/enabled app is bundled on the system, so presumed
10072                // to be able to run automatically without needing an explicit launch.
10073                // Send it a BOOT_COMPLETED if it would ordinarily have gotten one.
10074                Intent bcIntent = new Intent(Intent.ACTION_BOOT_COMPLETED)
10075                        .addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES)
10076                        .setPackage(packageName);
10077                am.broadcastIntent(null, bcIntent, null, null, 0, null, null, null,
10078                        android.app.AppOpsManager.OP_NONE, null, false, false, userId);
10079            }
10080        } catch (RemoteException e) {
10081            // shouldn't happen
10082            Slog.w(TAG, "Unable to bootstrap installed package", e);
10083        }
10084    }
10085
10086    @Override
10087    public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden,
10088            int userId) {
10089        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
10090        PackageSetting pkgSetting;
10091        final int uid = Binder.getCallingUid();
10092        enforceCrossUserPermission(uid, userId, true, true,
10093                "setApplicationHiddenSetting for user " + userId);
10094
10095        if (hidden && isPackageDeviceAdmin(packageName, userId)) {
10096            Slog.w(TAG, "Not hiding package " + packageName + ": has active device admin");
10097            return false;
10098        }
10099
10100        long callingId = Binder.clearCallingIdentity();
10101        try {
10102            boolean sendAdded = false;
10103            boolean sendRemoved = false;
10104            // writer
10105            synchronized (mPackages) {
10106                pkgSetting = mSettings.mPackages.get(packageName);
10107                if (pkgSetting == null) {
10108                    return false;
10109                }
10110                if (pkgSetting.getHidden(userId) != hidden) {
10111                    pkgSetting.setHidden(hidden, userId);
10112                    mSettings.writePackageRestrictionsLPr(userId);
10113                    if (hidden) {
10114                        sendRemoved = true;
10115                    } else {
10116                        sendAdded = true;
10117                    }
10118                }
10119            }
10120            if (sendAdded) {
10121                sendPackageAddedForUser(packageName, pkgSetting, userId);
10122                return true;
10123            }
10124            if (sendRemoved) {
10125                killApplication(packageName, UserHandle.getUid(userId, pkgSetting.appId),
10126                        "hiding pkg");
10127                sendApplicationHiddenForUser(packageName, pkgSetting, userId);
10128                return true;
10129            }
10130        } finally {
10131            Binder.restoreCallingIdentity(callingId);
10132        }
10133        return false;
10134    }
10135
10136    private void sendApplicationHiddenForUser(String packageName, PackageSetting pkgSetting,
10137            int userId) {
10138        final PackageRemovedInfo info = new PackageRemovedInfo();
10139        info.removedPackage = packageName;
10140        info.removedUsers = new int[] {userId};
10141        info.uid = UserHandle.getUid(userId, pkgSetting.appId);
10142        info.sendBroadcast(false, false, false);
10143    }
10144
10145    /**
10146     * Returns true if application is not found or there was an error. Otherwise it returns
10147     * the hidden state of the package for the given user.
10148     */
10149    @Override
10150    public boolean getApplicationHiddenSettingAsUser(String packageName, int userId) {
10151        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
10152        enforceCrossUserPermission(Binder.getCallingUid(), userId, true,
10153                false, "getApplicationHidden for user " + userId);
10154        PackageSetting pkgSetting;
10155        long callingId = Binder.clearCallingIdentity();
10156        try {
10157            // writer
10158            synchronized (mPackages) {
10159                pkgSetting = mSettings.mPackages.get(packageName);
10160                if (pkgSetting == null) {
10161                    return true;
10162                }
10163                return pkgSetting.getHidden(userId);
10164            }
10165        } finally {
10166            Binder.restoreCallingIdentity(callingId);
10167        }
10168    }
10169
10170    /**
10171     * @hide
10172     */
10173    @Override
10174    public int installExistingPackageAsUser(String packageName, int userId) {
10175        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES,
10176                null);
10177        PackageSetting pkgSetting;
10178        final int uid = Binder.getCallingUid();
10179        enforceCrossUserPermission(uid, userId, true, true, "installExistingPackage for user "
10180                + userId);
10181        if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
10182            return PackageManager.INSTALL_FAILED_USER_RESTRICTED;
10183        }
10184
10185        long callingId = Binder.clearCallingIdentity();
10186        try {
10187            boolean sendAdded = false;
10188
10189            // writer
10190            synchronized (mPackages) {
10191                pkgSetting = mSettings.mPackages.get(packageName);
10192                if (pkgSetting == null) {
10193                    return PackageManager.INSTALL_FAILED_INVALID_URI;
10194                }
10195                if (!pkgSetting.getInstalled(userId)) {
10196                    pkgSetting.setInstalled(true, userId);
10197                    pkgSetting.setHidden(false, userId);
10198                    mSettings.writePackageRestrictionsLPr(userId);
10199                    sendAdded = true;
10200                }
10201            }
10202
10203            if (sendAdded) {
10204                sendPackageAddedForUser(packageName, pkgSetting, userId);
10205            }
10206        } finally {
10207            Binder.restoreCallingIdentity(callingId);
10208        }
10209
10210        return PackageManager.INSTALL_SUCCEEDED;
10211    }
10212
10213    boolean isUserRestricted(int userId, String restrictionKey) {
10214        Bundle restrictions = sUserManager.getUserRestrictions(userId);
10215        if (restrictions.getBoolean(restrictionKey, false)) {
10216            Log.w(TAG, "User is restricted: " + restrictionKey);
10217            return true;
10218        }
10219        return false;
10220    }
10221
10222    @Override
10223    public boolean setPackageSuspendedAsUser(String packageName, boolean suspended, int userId) {
10224        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
10225        enforceCrossUserPermission(Binder.getCallingUid(), userId, true, true,
10226                "setPackageSuspended for user " + userId);
10227
10228        long callingId = Binder.clearCallingIdentity();
10229        try {
10230            synchronized (mPackages) {
10231                final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
10232                if (pkgSetting != null) {
10233                    if (pkgSetting.getSuspended(userId) != suspended) {
10234                        pkgSetting.setSuspended(suspended, userId);
10235                        mSettings.writePackageRestrictionsLPr(userId);
10236                    }
10237
10238                    // TODO:
10239                    // * broadcast a PACKAGE_(UN)SUSPENDED intent for launchers to pick up
10240                    // * remove app from recents (kill app it if it is running)
10241                    // * erase existing notifications for this app
10242                    return true;
10243                }
10244
10245                return false;
10246            }
10247        } finally {
10248            Binder.restoreCallingIdentity(callingId);
10249        }
10250    }
10251
10252    @Override
10253    public void verifyPendingInstall(int id, int verificationCode) throws RemoteException {
10254        mContext.enforceCallingOrSelfPermission(
10255                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
10256                "Only package verification agents can verify applications");
10257
10258        final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
10259        final PackageVerificationResponse response = new PackageVerificationResponse(
10260                verificationCode, Binder.getCallingUid());
10261        msg.arg1 = id;
10262        msg.obj = response;
10263        mHandler.sendMessage(msg);
10264    }
10265
10266    @Override
10267    public void extendVerificationTimeout(int id, int verificationCodeAtTimeout,
10268            long millisecondsToDelay) {
10269        mContext.enforceCallingOrSelfPermission(
10270                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
10271                "Only package verification agents can extend verification timeouts");
10272
10273        final PackageVerificationState state = mPendingVerification.get(id);
10274        final PackageVerificationResponse response = new PackageVerificationResponse(
10275                verificationCodeAtTimeout, Binder.getCallingUid());
10276
10277        if (millisecondsToDelay > PackageManager.MAXIMUM_VERIFICATION_TIMEOUT) {
10278            millisecondsToDelay = PackageManager.MAXIMUM_VERIFICATION_TIMEOUT;
10279        }
10280        if (millisecondsToDelay < 0) {
10281            millisecondsToDelay = 0;
10282        }
10283        if ((verificationCodeAtTimeout != PackageManager.VERIFICATION_ALLOW)
10284                && (verificationCodeAtTimeout != PackageManager.VERIFICATION_REJECT)) {
10285            verificationCodeAtTimeout = PackageManager.VERIFICATION_REJECT;
10286        }
10287
10288        if ((state != null) && !state.timeoutExtended()) {
10289            state.extendTimeout();
10290
10291            final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
10292            msg.arg1 = id;
10293            msg.obj = response;
10294            mHandler.sendMessageDelayed(msg, millisecondsToDelay);
10295        }
10296    }
10297
10298    private void broadcastPackageVerified(int verificationId, Uri packageUri,
10299            int verificationCode, UserHandle user) {
10300        final Intent intent = new Intent(Intent.ACTION_PACKAGE_VERIFIED);
10301        intent.setDataAndType(packageUri, PACKAGE_MIME_TYPE);
10302        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
10303        intent.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
10304        intent.putExtra(PackageManager.EXTRA_VERIFICATION_RESULT, verificationCode);
10305
10306        mContext.sendBroadcastAsUser(intent, user,
10307                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT);
10308    }
10309
10310    private ComponentName matchComponentForVerifier(String packageName,
10311            List<ResolveInfo> receivers) {
10312        ActivityInfo targetReceiver = null;
10313
10314        final int NR = receivers.size();
10315        for (int i = 0; i < NR; i++) {
10316            final ResolveInfo info = receivers.get(i);
10317            if (info.activityInfo == null) {
10318                continue;
10319            }
10320
10321            if (packageName.equals(info.activityInfo.packageName)) {
10322                targetReceiver = info.activityInfo;
10323                break;
10324            }
10325        }
10326
10327        if (targetReceiver == null) {
10328            return null;
10329        }
10330
10331        return new ComponentName(targetReceiver.packageName, targetReceiver.name);
10332    }
10333
10334    private List<ComponentName> matchVerifiers(PackageInfoLite pkgInfo,
10335            List<ResolveInfo> receivers, final PackageVerificationState verificationState) {
10336        if (pkgInfo.verifiers.length == 0) {
10337            return null;
10338        }
10339
10340        final int N = pkgInfo.verifiers.length;
10341        final List<ComponentName> sufficientVerifiers = new ArrayList<ComponentName>(N + 1);
10342        for (int i = 0; i < N; i++) {
10343            final VerifierInfo verifierInfo = pkgInfo.verifiers[i];
10344
10345            final ComponentName comp = matchComponentForVerifier(verifierInfo.packageName,
10346                    receivers);
10347            if (comp == null) {
10348                continue;
10349            }
10350
10351            final int verifierUid = getUidForVerifier(verifierInfo);
10352            if (verifierUid == -1) {
10353                continue;
10354            }
10355
10356            if (DEBUG_VERIFY) {
10357                Slog.d(TAG, "Added sufficient verifier " + verifierInfo.packageName
10358                        + " with the correct signature");
10359            }
10360            sufficientVerifiers.add(comp);
10361            verificationState.addSufficientVerifier(verifierUid);
10362        }
10363
10364        return sufficientVerifiers;
10365    }
10366
10367    private int getUidForVerifier(VerifierInfo verifierInfo) {
10368        synchronized (mPackages) {
10369            final PackageParser.Package pkg = mPackages.get(verifierInfo.packageName);
10370            if (pkg == null) {
10371                return -1;
10372            } else if (pkg.mSignatures.length != 1) {
10373                Slog.i(TAG, "Verifier package " + verifierInfo.packageName
10374                        + " has more than one signature; ignoring");
10375                return -1;
10376            }
10377
10378            /*
10379             * If the public key of the package's signature does not match
10380             * our expected public key, then this is a different package and
10381             * we should skip.
10382             */
10383
10384            final byte[] expectedPublicKey;
10385            try {
10386                final Signature verifierSig = pkg.mSignatures[0];
10387                final PublicKey publicKey = verifierSig.getPublicKey();
10388                expectedPublicKey = publicKey.getEncoded();
10389            } catch (CertificateException e) {
10390                return -1;
10391            }
10392
10393            final byte[] actualPublicKey = verifierInfo.publicKey.getEncoded();
10394
10395            if (!Arrays.equals(actualPublicKey, expectedPublicKey)) {
10396                Slog.i(TAG, "Verifier package " + verifierInfo.packageName
10397                        + " does not have the expected public key; ignoring");
10398                return -1;
10399            }
10400
10401            return pkg.applicationInfo.uid;
10402        }
10403    }
10404
10405    @Override
10406    public void finishPackageInstall(int token) {
10407        enforceSystemOrRoot("Only the system is allowed to finish installs");
10408
10409        if (DEBUG_INSTALL) {
10410            Slog.v(TAG, "BM finishing package install for " + token);
10411        }
10412        Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "restore", token);
10413
10414        final Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0);
10415        mHandler.sendMessage(msg);
10416    }
10417
10418    /**
10419     * Get the verification agent timeout.
10420     *
10421     * @return verification timeout in milliseconds
10422     */
10423    private long getVerificationTimeout() {
10424        return android.provider.Settings.Global.getLong(mContext.getContentResolver(),
10425                android.provider.Settings.Global.PACKAGE_VERIFIER_TIMEOUT,
10426                DEFAULT_VERIFICATION_TIMEOUT);
10427    }
10428
10429    /**
10430     * Get the default verification agent response code.
10431     *
10432     * @return default verification response code
10433     */
10434    private int getDefaultVerificationResponse() {
10435        return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
10436                android.provider.Settings.Global.PACKAGE_VERIFIER_DEFAULT_RESPONSE,
10437                DEFAULT_VERIFICATION_RESPONSE);
10438    }
10439
10440    /**
10441     * Check whether or not package verification has been enabled.
10442     *
10443     * @return true if verification should be performed
10444     */
10445    private boolean isVerificationEnabled(int userId, int installFlags) {
10446        if (!DEFAULT_VERIFY_ENABLE) {
10447            return false;
10448        }
10449        // Ephemeral apps don't get the full verification treatment
10450        if ((installFlags & PackageManager.INSTALL_EPHEMERAL) != 0) {
10451            if (DEBUG_EPHEMERAL) {
10452                Slog.d(TAG, "INSTALL_EPHEMERAL so skipping verification");
10453            }
10454            return false;
10455        }
10456
10457        boolean ensureVerifyAppsEnabled = isUserRestricted(userId, UserManager.ENSURE_VERIFY_APPS);
10458
10459        // Check if installing from ADB
10460        if ((installFlags & PackageManager.INSTALL_FROM_ADB) != 0) {
10461            // Do not run verification in a test harness environment
10462            if (ActivityManager.isRunningInTestHarness()) {
10463                return false;
10464            }
10465            if (ensureVerifyAppsEnabled) {
10466                return true;
10467            }
10468            // Check if the developer does not want package verification for ADB installs
10469            if (android.provider.Settings.Global.getInt(mContext.getContentResolver(),
10470                    android.provider.Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, 1) == 0) {
10471                return false;
10472            }
10473        }
10474
10475        if (ensureVerifyAppsEnabled) {
10476            return true;
10477        }
10478
10479        return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
10480                android.provider.Settings.Global.PACKAGE_VERIFIER_ENABLE, 1) == 1;
10481    }
10482
10483    @Override
10484    public void verifyIntentFilter(int id, int verificationCode, List<String> failedDomains)
10485            throws RemoteException {
10486        mContext.enforceCallingOrSelfPermission(
10487                Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT,
10488                "Only intentfilter verification agents can verify applications");
10489
10490        final Message msg = mHandler.obtainMessage(INTENT_FILTER_VERIFIED);
10491        final IntentFilterVerificationResponse response = new IntentFilterVerificationResponse(
10492                Binder.getCallingUid(), verificationCode, failedDomains);
10493        msg.arg1 = id;
10494        msg.obj = response;
10495        mHandler.sendMessage(msg);
10496    }
10497
10498    @Override
10499    public int getIntentVerificationStatus(String packageName, int userId) {
10500        synchronized (mPackages) {
10501            return mSettings.getIntentFilterVerificationStatusLPr(packageName, userId);
10502        }
10503    }
10504
10505    @Override
10506    public boolean updateIntentVerificationStatus(String packageName, int status, int userId) {
10507        mContext.enforceCallingOrSelfPermission(
10508                android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
10509
10510        boolean result = false;
10511        synchronized (mPackages) {
10512            result = mSettings.updateIntentFilterVerificationStatusLPw(packageName, status, userId);
10513        }
10514        if (result) {
10515            scheduleWritePackageRestrictionsLocked(userId);
10516        }
10517        return result;
10518    }
10519
10520    @Override
10521    public List<IntentFilterVerificationInfo> getIntentFilterVerifications(String packageName) {
10522        synchronized (mPackages) {
10523            return mSettings.getIntentFilterVerificationsLPr(packageName);
10524        }
10525    }
10526
10527    @Override
10528    public List<IntentFilter> getAllIntentFilters(String packageName) {
10529        if (TextUtils.isEmpty(packageName)) {
10530            return Collections.<IntentFilter>emptyList();
10531        }
10532        synchronized (mPackages) {
10533            PackageParser.Package pkg = mPackages.get(packageName);
10534            if (pkg == null || pkg.activities == null) {
10535                return Collections.<IntentFilter>emptyList();
10536            }
10537            final int count = pkg.activities.size();
10538            ArrayList<IntentFilter> result = new ArrayList<>();
10539            for (int n=0; n<count; n++) {
10540                PackageParser.Activity activity = pkg.activities.get(n);
10541                if (activity.intents != null && activity.intents.size() > 0) {
10542                    result.addAll(activity.intents);
10543                }
10544            }
10545            return result;
10546        }
10547    }
10548
10549    @Override
10550    public boolean setDefaultBrowserPackageName(String packageName, int userId) {
10551        mContext.enforceCallingOrSelfPermission(
10552                android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
10553
10554        synchronized (mPackages) {
10555            boolean result = mSettings.setDefaultBrowserPackageNameLPw(packageName, userId);
10556            if (packageName != null) {
10557                result |= updateIntentVerificationStatus(packageName,
10558                        PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS,
10559                        userId);
10560                mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultBrowserLPr(
10561                        packageName, userId);
10562            }
10563            return result;
10564        }
10565    }
10566
10567    @Override
10568    public String getDefaultBrowserPackageName(int userId) {
10569        synchronized (mPackages) {
10570            return mSettings.getDefaultBrowserPackageNameLPw(userId);
10571        }
10572    }
10573
10574    /**
10575     * Get the "allow unknown sources" setting.
10576     *
10577     * @return the current "allow unknown sources" setting
10578     */
10579    private int getUnknownSourcesSettings() {
10580        return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
10581                android.provider.Settings.Global.INSTALL_NON_MARKET_APPS,
10582                -1);
10583    }
10584
10585    @Override
10586    public void setInstallerPackageName(String targetPackage, String installerPackageName) {
10587        final int uid = Binder.getCallingUid();
10588        // writer
10589        synchronized (mPackages) {
10590            PackageSetting targetPackageSetting = mSettings.mPackages.get(targetPackage);
10591            if (targetPackageSetting == null) {
10592                throw new IllegalArgumentException("Unknown target package: " + targetPackage);
10593            }
10594
10595            PackageSetting installerPackageSetting;
10596            if (installerPackageName != null) {
10597                installerPackageSetting = mSettings.mPackages.get(installerPackageName);
10598                if (installerPackageSetting == null) {
10599                    throw new IllegalArgumentException("Unknown installer package: "
10600                            + installerPackageName);
10601                }
10602            } else {
10603                installerPackageSetting = null;
10604            }
10605
10606            Signature[] callerSignature;
10607            Object obj = mSettings.getUserIdLPr(uid);
10608            if (obj != null) {
10609                if (obj instanceof SharedUserSetting) {
10610                    callerSignature = ((SharedUserSetting)obj).signatures.mSignatures;
10611                } else if (obj instanceof PackageSetting) {
10612                    callerSignature = ((PackageSetting)obj).signatures.mSignatures;
10613                } else {
10614                    throw new SecurityException("Bad object " + obj + " for uid " + uid);
10615                }
10616            } else {
10617                throw new SecurityException("Unknown calling UID: " + uid);
10618            }
10619
10620            // Verify: can't set installerPackageName to a package that is
10621            // not signed with the same cert as the caller.
10622            if (installerPackageSetting != null) {
10623                if (compareSignatures(callerSignature,
10624                        installerPackageSetting.signatures.mSignatures)
10625                        != PackageManager.SIGNATURE_MATCH) {
10626                    throw new SecurityException(
10627                            "Caller does not have same cert as new installer package "
10628                            + installerPackageName);
10629                }
10630            }
10631
10632            // Verify: if target already has an installer package, it must
10633            // be signed with the same cert as the caller.
10634            if (targetPackageSetting.installerPackageName != null) {
10635                PackageSetting setting = mSettings.mPackages.get(
10636                        targetPackageSetting.installerPackageName);
10637                // If the currently set package isn't valid, then it's always
10638                // okay to change it.
10639                if (setting != null) {
10640                    if (compareSignatures(callerSignature,
10641                            setting.signatures.mSignatures)
10642                            != PackageManager.SIGNATURE_MATCH) {
10643                        throw new SecurityException(
10644                                "Caller does not have same cert as old installer package "
10645                                + targetPackageSetting.installerPackageName);
10646                    }
10647                }
10648            }
10649
10650            // Okay!
10651            targetPackageSetting.installerPackageName = installerPackageName;
10652            scheduleWriteSettingsLocked();
10653        }
10654    }
10655
10656    private void processPendingInstall(final InstallArgs args, final int currentStatus) {
10657        // Queue up an async operation since the package installation may take a little while.
10658        mHandler.post(new Runnable() {
10659            public void run() {
10660                mHandler.removeCallbacks(this);
10661                 // Result object to be returned
10662                PackageInstalledInfo res = new PackageInstalledInfo();
10663                res.returnCode = currentStatus;
10664                res.uid = -1;
10665                res.pkg = null;
10666                res.removedInfo = new PackageRemovedInfo();
10667                if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
10668                    args.doPreInstall(res.returnCode);
10669                    synchronized (mInstallLock) {
10670                        installPackageTracedLI(args, res);
10671                    }
10672                    args.doPostInstall(res.returnCode, res.uid);
10673                }
10674
10675                // A restore should be performed at this point if (a) the install
10676                // succeeded, (b) the operation is not an update, and (c) the new
10677                // package has not opted out of backup participation.
10678                final boolean update = res.removedInfo.removedPackage != null;
10679                final int flags = (res.pkg == null) ? 0 : res.pkg.applicationInfo.flags;
10680                boolean doRestore = !update
10681                        && ((flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0);
10682
10683                // Set up the post-install work request bookkeeping.  This will be used
10684                // and cleaned up by the post-install event handling regardless of whether
10685                // there's a restore pass performed.  Token values are >= 1.
10686                int token;
10687                if (mNextInstallToken < 0) mNextInstallToken = 1;
10688                token = mNextInstallToken++;
10689
10690                PostInstallData data = new PostInstallData(args, res);
10691                mRunningInstalls.put(token, data);
10692                if (DEBUG_INSTALL) Log.v(TAG, "+ starting restore round-trip " + token);
10693
10694                if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && doRestore) {
10695                    // Pass responsibility to the Backup Manager.  It will perform a
10696                    // restore if appropriate, then pass responsibility back to the
10697                    // Package Manager to run the post-install observer callbacks
10698                    // and broadcasts.
10699                    IBackupManager bm = IBackupManager.Stub.asInterface(
10700                            ServiceManager.getService(Context.BACKUP_SERVICE));
10701                    if (bm != null) {
10702                        if (DEBUG_INSTALL) Log.v(TAG, "token " + token
10703                                + " to BM for possible restore");
10704                        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "restore", token);
10705                        try {
10706                            // TODO: http://b/22388012
10707                            if (bm.isBackupServiceActive(UserHandle.USER_SYSTEM)) {
10708                                bm.restoreAtInstall(res.pkg.applicationInfo.packageName, token);
10709                            } else {
10710                                doRestore = false;
10711                            }
10712                        } catch (RemoteException e) {
10713                            // can't happen; the backup manager is local
10714                        } catch (Exception e) {
10715                            Slog.e(TAG, "Exception trying to enqueue restore", e);
10716                            doRestore = false;
10717                        }
10718                    } else {
10719                        Slog.e(TAG, "Backup Manager not found!");
10720                        doRestore = false;
10721                    }
10722                }
10723
10724                if (!doRestore) {
10725                    // No restore possible, or the Backup Manager was mysteriously not
10726                    // available -- just fire the post-install work request directly.
10727                    if (DEBUG_INSTALL) Log.v(TAG, "No restore - queue post-install for " + token);
10728
10729                    Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "postInstall", token);
10730
10731                    Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0);
10732                    mHandler.sendMessage(msg);
10733                }
10734            }
10735        });
10736    }
10737
10738    private abstract class HandlerParams {
10739        private static final int MAX_RETRIES = 4;
10740
10741        /**
10742         * Number of times startCopy() has been attempted and had a non-fatal
10743         * error.
10744         */
10745        private int mRetries = 0;
10746
10747        /** User handle for the user requesting the information or installation. */
10748        private final UserHandle mUser;
10749        String traceMethod;
10750        int traceCookie;
10751
10752        HandlerParams(UserHandle user) {
10753            mUser = user;
10754        }
10755
10756        UserHandle getUser() {
10757            return mUser;
10758        }
10759
10760        HandlerParams setTraceMethod(String traceMethod) {
10761            this.traceMethod = traceMethod;
10762            return this;
10763        }
10764
10765        HandlerParams setTraceCookie(int traceCookie) {
10766            this.traceCookie = traceCookie;
10767            return this;
10768        }
10769
10770        final boolean startCopy() {
10771            boolean res;
10772            try {
10773                if (DEBUG_INSTALL) Slog.i(TAG, "startCopy " + mUser + ": " + this);
10774
10775                if (++mRetries > MAX_RETRIES) {
10776                    Slog.w(TAG, "Failed to invoke remote methods on default container service. Giving up");
10777                    mHandler.sendEmptyMessage(MCS_GIVE_UP);
10778                    handleServiceError();
10779                    return false;
10780                } else {
10781                    handleStartCopy();
10782                    res = true;
10783                }
10784            } catch (RemoteException e) {
10785                if (DEBUG_INSTALL) Slog.i(TAG, "Posting install MCS_RECONNECT");
10786                mHandler.sendEmptyMessage(MCS_RECONNECT);
10787                res = false;
10788            }
10789            handleReturnCode();
10790            return res;
10791        }
10792
10793        final void serviceError() {
10794            if (DEBUG_INSTALL) Slog.i(TAG, "serviceError");
10795            handleServiceError();
10796            handleReturnCode();
10797        }
10798
10799        abstract void handleStartCopy() throws RemoteException;
10800        abstract void handleServiceError();
10801        abstract void handleReturnCode();
10802    }
10803
10804    class MeasureParams extends HandlerParams {
10805        private final PackageStats mStats;
10806        private boolean mSuccess;
10807
10808        private final IPackageStatsObserver mObserver;
10809
10810        public MeasureParams(PackageStats stats, IPackageStatsObserver observer) {
10811            super(new UserHandle(stats.userHandle));
10812            mObserver = observer;
10813            mStats = stats;
10814        }
10815
10816        @Override
10817        public String toString() {
10818            return "MeasureParams{"
10819                + Integer.toHexString(System.identityHashCode(this))
10820                + " " + mStats.packageName + "}";
10821        }
10822
10823        @Override
10824        void handleStartCopy() throws RemoteException {
10825            synchronized (mInstallLock) {
10826                mSuccess = getPackageSizeInfoLI(mStats.packageName, mStats.userHandle, mStats);
10827            }
10828
10829            if (mSuccess) {
10830                final boolean mounted;
10831                if (Environment.isExternalStorageEmulated()) {
10832                    mounted = true;
10833                } else {
10834                    final String status = Environment.getExternalStorageState();
10835                    mounted = (Environment.MEDIA_MOUNTED.equals(status)
10836                            || Environment.MEDIA_MOUNTED_READ_ONLY.equals(status));
10837                }
10838
10839                if (mounted) {
10840                    final UserEnvironment userEnv = new UserEnvironment(mStats.userHandle);
10841
10842                    mStats.externalCacheSize = calculateDirectorySize(mContainerService,
10843                            userEnv.buildExternalStorageAppCacheDirs(mStats.packageName));
10844
10845                    mStats.externalDataSize = calculateDirectorySize(mContainerService,
10846                            userEnv.buildExternalStorageAppDataDirs(mStats.packageName));
10847
10848                    // Always subtract cache size, since it's a subdirectory
10849                    mStats.externalDataSize -= mStats.externalCacheSize;
10850
10851                    mStats.externalMediaSize = calculateDirectorySize(mContainerService,
10852                            userEnv.buildExternalStorageAppMediaDirs(mStats.packageName));
10853
10854                    mStats.externalObbSize = calculateDirectorySize(mContainerService,
10855                            userEnv.buildExternalStorageAppObbDirs(mStats.packageName));
10856                }
10857            }
10858        }
10859
10860        @Override
10861        void handleReturnCode() {
10862            if (mObserver != null) {
10863                try {
10864                    mObserver.onGetStatsCompleted(mStats, mSuccess);
10865                } catch (RemoteException e) {
10866                    Slog.i(TAG, "Observer no longer exists.");
10867                }
10868            }
10869        }
10870
10871        @Override
10872        void handleServiceError() {
10873            Slog.e(TAG, "Could not measure application " + mStats.packageName
10874                            + " external storage");
10875        }
10876    }
10877
10878    private static long calculateDirectorySize(IMediaContainerService mcs, File[] paths)
10879            throws RemoteException {
10880        long result = 0;
10881        for (File path : paths) {
10882            result += mcs.calculateDirectorySize(path.getAbsolutePath());
10883        }
10884        return result;
10885    }
10886
10887    private static void clearDirectory(IMediaContainerService mcs, File[] paths) {
10888        for (File path : paths) {
10889            try {
10890                mcs.clearDirectory(path.getAbsolutePath());
10891            } catch (RemoteException e) {
10892            }
10893        }
10894    }
10895
10896    static class OriginInfo {
10897        /**
10898         * Location where install is coming from, before it has been
10899         * copied/renamed into place. This could be a single monolithic APK
10900         * file, or a cluster directory. This location may be untrusted.
10901         */
10902        final File file;
10903        final String cid;
10904
10905        /**
10906         * Flag indicating that {@link #file} or {@link #cid} has already been
10907         * staged, meaning downstream users don't need to defensively copy the
10908         * contents.
10909         */
10910        final boolean staged;
10911
10912        /**
10913         * Flag indicating that {@link #file} or {@link #cid} is an already
10914         * installed app that is being moved.
10915         */
10916        final boolean existing;
10917
10918        final String resolvedPath;
10919        final File resolvedFile;
10920
10921        static OriginInfo fromNothing() {
10922            return new OriginInfo(null, null, false, false);
10923        }
10924
10925        static OriginInfo fromUntrustedFile(File file) {
10926            return new OriginInfo(file, null, false, false);
10927        }
10928
10929        static OriginInfo fromExistingFile(File file) {
10930            return new OriginInfo(file, null, false, true);
10931        }
10932
10933        static OriginInfo fromStagedFile(File file) {
10934            return new OriginInfo(file, null, true, false);
10935        }
10936
10937        static OriginInfo fromStagedContainer(String cid) {
10938            return new OriginInfo(null, cid, true, false);
10939        }
10940
10941        private OriginInfo(File file, String cid, boolean staged, boolean existing) {
10942            this.file = file;
10943            this.cid = cid;
10944            this.staged = staged;
10945            this.existing = existing;
10946
10947            if (cid != null) {
10948                resolvedPath = PackageHelper.getSdDir(cid);
10949                resolvedFile = new File(resolvedPath);
10950            } else if (file != null) {
10951                resolvedPath = file.getAbsolutePath();
10952                resolvedFile = file;
10953            } else {
10954                resolvedPath = null;
10955                resolvedFile = null;
10956            }
10957        }
10958    }
10959
10960    static class MoveInfo {
10961        final int moveId;
10962        final String fromUuid;
10963        final String toUuid;
10964        final String packageName;
10965        final String dataAppName;
10966        final int appId;
10967        final String seinfo;
10968
10969        public MoveInfo(int moveId, String fromUuid, String toUuid, String packageName,
10970                String dataAppName, int appId, String seinfo) {
10971            this.moveId = moveId;
10972            this.fromUuid = fromUuid;
10973            this.toUuid = toUuid;
10974            this.packageName = packageName;
10975            this.dataAppName = dataAppName;
10976            this.appId = appId;
10977            this.seinfo = seinfo;
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                    if (mInstaller.freeCache(null, sizeBytes + lowThreshold) >= 0) {
11131                        pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath,
11132                                installFlags, packageAbiOverride);
11133                    }
11134
11135                    /*
11136                     * The cache free must have deleted the file we
11137                     * downloaded to install.
11138                     *
11139                     * TODO: fix the "freeCache" call to not delete
11140                     *       the file we care about.
11141                     */
11142                    if (pkgLite.recommendedInstallLocation
11143                            == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
11144                        pkgLite.recommendedInstallLocation
11145                            = PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE;
11146                    }
11147                }
11148            }
11149
11150            if (ret == PackageManager.INSTALL_SUCCEEDED) {
11151                int loc = pkgLite.recommendedInstallLocation;
11152                if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION) {
11153                    ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
11154                } else if (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS) {
11155                    ret = PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
11156                } else if (loc == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
11157                    ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
11158                } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_APK) {
11159                    ret = PackageManager.INSTALL_FAILED_INVALID_APK;
11160                } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
11161                    ret = PackageManager.INSTALL_FAILED_INVALID_URI;
11162                } else if (loc == PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE) {
11163                    ret = PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE;
11164                } else {
11165                    // Override with defaults if needed.
11166                    loc = installLocationPolicy(pkgLite);
11167                    if (loc == PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE) {
11168                        ret = PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
11169                    } else if (!onSd && !onInt) {
11170                        // Override install location with flags
11171                        if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) {
11172                            // Set the flag to install on external media.
11173                            installFlags |= PackageManager.INSTALL_EXTERNAL;
11174                            installFlags &= ~PackageManager.INSTALL_INTERNAL;
11175                        } else if (loc == PackageHelper.RECOMMEND_INSTALL_EPHEMERAL) {
11176                            if (DEBUG_EPHEMERAL) {
11177                                Slog.v(TAG, "...setting INSTALL_EPHEMERAL install flag");
11178                            }
11179                            installFlags |= PackageManager.INSTALL_EPHEMERAL;
11180                            installFlags &= ~(PackageManager.INSTALL_EXTERNAL
11181                                    |PackageManager.INSTALL_INTERNAL);
11182                        } else {
11183                            // Make sure the flag for installing on external
11184                            // media is unset
11185                            installFlags |= PackageManager.INSTALL_INTERNAL;
11186                            installFlags &= ~PackageManager.INSTALL_EXTERNAL;
11187                        }
11188                    }
11189                }
11190            }
11191
11192            final InstallArgs args = createInstallArgs(this);
11193            mArgs = args;
11194
11195            if (ret == PackageManager.INSTALL_SUCCEEDED) {
11196                // TODO: http://b/22976637
11197                // Apps installed for "all" users use the device owner to verify the app
11198                UserHandle verifierUser = getUser();
11199                if (verifierUser == UserHandle.ALL) {
11200                    verifierUser = UserHandle.SYSTEM;
11201                }
11202
11203                /*
11204                 * Determine if we have any installed package verifiers. If we
11205                 * do, then we'll defer to them to verify the packages.
11206                 */
11207                final int requiredUid = mRequiredVerifierPackage == null ? -1
11208                        : getPackageUid(mRequiredVerifierPackage, verifierUser.getIdentifier());
11209                if (!origin.existing && requiredUid != -1
11210                        && isVerificationEnabled(verifierUser.getIdentifier(), installFlags)) {
11211                    final Intent verification = new Intent(
11212                            Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
11213                    verification.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
11214                    verification.setDataAndType(Uri.fromFile(new File(origin.resolvedPath)),
11215                            PACKAGE_MIME_TYPE);
11216                    verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
11217
11218                    // Query all live verifiers based on current user state
11219                    final List<ResolveInfo> receivers = queryIntentReceivers(verification,
11220                            PACKAGE_MIME_TYPE, 0, verifierUser.getIdentifier());
11221
11222                    if (DEBUG_VERIFY) {
11223                        Slog.d(TAG, "Found " + receivers.size() + " verifiers for intent "
11224                                + verification.toString() + " with " + pkgLite.verifiers.length
11225                                + " optional verifiers");
11226                    }
11227
11228                    final int verificationId = mPendingVerificationToken++;
11229
11230                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
11231
11232                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_PACKAGE,
11233                            installerPackageName);
11234
11235                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALL_FLAGS,
11236                            installFlags);
11237
11238                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_PACKAGE_NAME,
11239                            pkgLite.packageName);
11240
11241                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_VERSION_CODE,
11242                            pkgLite.versionCode);
11243
11244                    if (verificationParams != null) {
11245                        if (verificationParams.getVerificationURI() != null) {
11246                           verification.putExtra(PackageManager.EXTRA_VERIFICATION_URI,
11247                                 verificationParams.getVerificationURI());
11248                        }
11249                        if (verificationParams.getOriginatingURI() != null) {
11250                            verification.putExtra(Intent.EXTRA_ORIGINATING_URI,
11251                                  verificationParams.getOriginatingURI());
11252                        }
11253                        if (verificationParams.getReferrer() != null) {
11254                            verification.putExtra(Intent.EXTRA_REFERRER,
11255                                  verificationParams.getReferrer());
11256                        }
11257                        if (verificationParams.getOriginatingUid() >= 0) {
11258                            verification.putExtra(Intent.EXTRA_ORIGINATING_UID,
11259                                  verificationParams.getOriginatingUid());
11260                        }
11261                        if (verificationParams.getInstallerUid() >= 0) {
11262                            verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_UID,
11263                                  verificationParams.getInstallerUid());
11264                        }
11265                    }
11266
11267                    final PackageVerificationState verificationState = new PackageVerificationState(
11268                            requiredUid, args);
11269
11270                    mPendingVerification.append(verificationId, verificationState);
11271
11272                    final List<ComponentName> sufficientVerifiers = matchVerifiers(pkgLite,
11273                            receivers, verificationState);
11274
11275                    /*
11276                     * If any sufficient verifiers were listed in the package
11277                     * manifest, attempt to ask them.
11278                     */
11279                    if (sufficientVerifiers != null) {
11280                        final int N = sufficientVerifiers.size();
11281                        if (N == 0) {
11282                            Slog.i(TAG, "Additional verifiers required, but none installed.");
11283                            ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
11284                        } else {
11285                            for (int i = 0; i < N; i++) {
11286                                final ComponentName verifierComponent = sufficientVerifiers.get(i);
11287
11288                                final Intent sufficientIntent = new Intent(verification);
11289                                sufficientIntent.setComponent(verifierComponent);
11290                                mContext.sendBroadcastAsUser(sufficientIntent, verifierUser);
11291                            }
11292                        }
11293                    }
11294
11295                    final ComponentName requiredVerifierComponent = matchComponentForVerifier(
11296                            mRequiredVerifierPackage, receivers);
11297                    if (ret == PackageManager.INSTALL_SUCCEEDED
11298                            && mRequiredVerifierPackage != null) {
11299                        Trace.asyncTraceBegin(
11300                                TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
11301                        /*
11302                         * Send the intent to the required verification agent,
11303                         * but only start the verification timeout after the
11304                         * target BroadcastReceivers have run.
11305                         */
11306                        verification.setComponent(requiredVerifierComponent);
11307                        mContext.sendOrderedBroadcastAsUser(verification, verifierUser,
11308                                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
11309                                new BroadcastReceiver() {
11310                                    @Override
11311                                    public void onReceive(Context context, Intent intent) {
11312                                        final Message msg = mHandler
11313                                                .obtainMessage(CHECK_PENDING_VERIFICATION);
11314                                        msg.arg1 = verificationId;
11315                                        mHandler.sendMessageDelayed(msg, getVerificationTimeout());
11316                                    }
11317                                }, null, 0, null, null);
11318
11319                        /*
11320                         * We don't want the copy to proceed until verification
11321                         * succeeds, so null out this field.
11322                         */
11323                        mArgs = null;
11324                    }
11325                } else {
11326                    /*
11327                     * No package verification is enabled, so immediately start
11328                     * the remote call to initiate copy using temporary file.
11329                     */
11330                    ret = args.copyApk(mContainerService, true);
11331                }
11332            }
11333
11334            mRet = ret;
11335        }
11336
11337        @Override
11338        void handleReturnCode() {
11339            // If mArgs is null, then MCS couldn't be reached. When it
11340            // reconnects, it will try again to install. At that point, this
11341            // will succeed.
11342            if (mArgs != null) {
11343                processPendingInstall(mArgs, mRet);
11344            }
11345        }
11346
11347        @Override
11348        void handleServiceError() {
11349            mArgs = createInstallArgs(this);
11350            mRet = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
11351        }
11352
11353        public boolean isForwardLocked() {
11354            return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
11355        }
11356    }
11357
11358    /**
11359     * Used during creation of InstallArgs
11360     *
11361     * @param installFlags package installation flags
11362     * @return true if should be installed on external storage
11363     */
11364    private static boolean installOnExternalAsec(int installFlags) {
11365        if ((installFlags & PackageManager.INSTALL_INTERNAL) != 0) {
11366            return false;
11367        }
11368        if ((installFlags & PackageManager.INSTALL_EXTERNAL) != 0) {
11369            return true;
11370        }
11371        return false;
11372    }
11373
11374    /**
11375     * Used during creation of InstallArgs
11376     *
11377     * @param installFlags package installation flags
11378     * @return true if should be installed as forward locked
11379     */
11380    private static boolean installForwardLocked(int installFlags) {
11381        return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
11382    }
11383
11384    private InstallArgs createInstallArgs(InstallParams params) {
11385        if (params.move != null) {
11386            return new MoveInstallArgs(params);
11387        } else if (installOnExternalAsec(params.installFlags) || params.isForwardLocked()) {
11388            return new AsecInstallArgs(params);
11389        } else {
11390            return new FileInstallArgs(params);
11391        }
11392    }
11393
11394    /**
11395     * Create args that describe an existing installed package. Typically used
11396     * when cleaning up old installs, or used as a move source.
11397     */
11398    private InstallArgs createInstallArgsForExisting(int installFlags, String codePath,
11399            String resourcePath, String[] instructionSets) {
11400        final boolean isInAsec;
11401        if (installOnExternalAsec(installFlags)) {
11402            /* Apps on SD card are always in ASEC containers. */
11403            isInAsec = true;
11404        } else if (installForwardLocked(installFlags)
11405                && !codePath.startsWith(mDrmAppPrivateInstallDir.getAbsolutePath())) {
11406            /*
11407             * Forward-locked apps are only in ASEC containers if they're the
11408             * new style
11409             */
11410            isInAsec = true;
11411        } else {
11412            isInAsec = false;
11413        }
11414
11415        if (isInAsec) {
11416            return new AsecInstallArgs(codePath, instructionSets,
11417                    installOnExternalAsec(installFlags), installForwardLocked(installFlags));
11418        } else {
11419            return new FileInstallArgs(codePath, resourcePath, instructionSets);
11420        }
11421    }
11422
11423    static abstract class InstallArgs {
11424        /** @see InstallParams#origin */
11425        final OriginInfo origin;
11426        /** @see InstallParams#move */
11427        final MoveInfo move;
11428
11429        final IPackageInstallObserver2 observer;
11430        // Always refers to PackageManager flags only
11431        final int installFlags;
11432        final String installerPackageName;
11433        final String volumeUuid;
11434        final UserHandle user;
11435        final String abiOverride;
11436        final String[] installGrantPermissions;
11437        /** If non-null, drop an async trace when the install completes */
11438        final String traceMethod;
11439        final int traceCookie;
11440
11441        // The list of instruction sets supported by this app. This is currently
11442        // only used during the rmdex() phase to clean up resources. We can get rid of this
11443        // if we move dex files under the common app path.
11444        /* nullable */ String[] instructionSets;
11445
11446        InstallArgs(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
11447                int installFlags, String installerPackageName, String volumeUuid,
11448                UserHandle user, String[] instructionSets,
11449                String abiOverride, String[] installGrantPermissions,
11450                String traceMethod, int traceCookie) {
11451            this.origin = origin;
11452            this.move = move;
11453            this.installFlags = installFlags;
11454            this.observer = observer;
11455            this.installerPackageName = installerPackageName;
11456            this.volumeUuid = volumeUuid;
11457            this.user = user;
11458            this.instructionSets = instructionSets;
11459            this.abiOverride = abiOverride;
11460            this.installGrantPermissions = installGrantPermissions;
11461            this.traceMethod = traceMethod;
11462            this.traceCookie = traceCookie;
11463        }
11464
11465        abstract int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException;
11466        abstract int doPreInstall(int status);
11467
11468        /**
11469         * Rename package into final resting place. All paths on the given
11470         * scanned package should be updated to reflect the rename.
11471         */
11472        abstract boolean doRename(int status, PackageParser.Package pkg, String oldCodePath);
11473        abstract int doPostInstall(int status, int uid);
11474
11475        /** @see PackageSettingBase#codePathString */
11476        abstract String getCodePath();
11477        /** @see PackageSettingBase#resourcePathString */
11478        abstract String getResourcePath();
11479
11480        // Need installer lock especially for dex file removal.
11481        abstract void cleanUpResourcesLI();
11482        abstract boolean doPostDeleteLI(boolean delete);
11483
11484        /**
11485         * Called before the source arguments are copied. This is used mostly
11486         * for MoveParams when it needs to read the source file to put it in the
11487         * destination.
11488         */
11489        int doPreCopy() {
11490            return PackageManager.INSTALL_SUCCEEDED;
11491        }
11492
11493        /**
11494         * Called after the source arguments are copied. This is used mostly for
11495         * MoveParams when it needs to read the source file to put it in the
11496         * destination.
11497         *
11498         * @return
11499         */
11500        int doPostCopy(int uid) {
11501            return PackageManager.INSTALL_SUCCEEDED;
11502        }
11503
11504        protected boolean isFwdLocked() {
11505            return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
11506        }
11507
11508        protected boolean isExternalAsec() {
11509            return (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
11510        }
11511
11512        protected boolean isEphemeral() {
11513            return (installFlags & PackageManager.INSTALL_EPHEMERAL) != 0;
11514        }
11515
11516        UserHandle getUser() {
11517            return user;
11518        }
11519    }
11520
11521    private void removeDexFiles(List<String> allCodePaths, String[] instructionSets) {
11522        if (!allCodePaths.isEmpty()) {
11523            if (instructionSets == null) {
11524                throw new IllegalStateException("instructionSet == null");
11525            }
11526            String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
11527            for (String codePath : allCodePaths) {
11528                for (String dexCodeInstructionSet : dexCodeInstructionSets) {
11529                    int retCode = mInstaller.rmdex(codePath, dexCodeInstructionSet);
11530                    if (retCode < 0) {
11531                        Slog.w(TAG, "Couldn't remove dex file for package at location " + codePath
11532                                + ", retcode=" + retCode);
11533                        // we don't consider this to be a failure of the core package deletion
11534                    }
11535                }
11536            }
11537        }
11538    }
11539
11540    /**
11541     * Logic to handle installation of non-ASEC applications, including copying
11542     * and renaming logic.
11543     */
11544    class FileInstallArgs extends InstallArgs {
11545        private File codeFile;
11546        private File resourceFile;
11547
11548        // Example topology:
11549        // /data/app/com.example/base.apk
11550        // /data/app/com.example/split_foo.apk
11551        // /data/app/com.example/lib/arm/libfoo.so
11552        // /data/app/com.example/lib/arm64/libfoo.so
11553        // /data/app/com.example/dalvik/arm/base.apk@classes.dex
11554
11555        /** New install */
11556        FileInstallArgs(InstallParams params) {
11557            super(params.origin, params.move, params.observer, params.installFlags,
11558                    params.installerPackageName, params.volumeUuid,
11559                    params.getUser(), null /* instruction sets */, params.packageAbiOverride,
11560                    params.grantedRuntimePermissions,
11561                    params.traceMethod, params.traceCookie);
11562            if (isFwdLocked()) {
11563                throw new IllegalArgumentException("Forward locking only supported in ASEC");
11564            }
11565        }
11566
11567        /** Existing install */
11568        FileInstallArgs(String codePath, String resourcePath, String[] instructionSets) {
11569            super(OriginInfo.fromNothing(), null, null, 0, null, null, null, instructionSets,
11570                    null, null, null, 0);
11571            this.codeFile = (codePath != null) ? new File(codePath) : null;
11572            this.resourceFile = (resourcePath != null) ? new File(resourcePath) : null;
11573        }
11574
11575        int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
11576            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyApk");
11577            try {
11578                return doCopyApk(imcs, temp);
11579            } finally {
11580                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
11581            }
11582        }
11583
11584        private int doCopyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
11585            if (origin.staged) {
11586                if (DEBUG_INSTALL) Slog.d(TAG, origin.file + " already staged; skipping copy");
11587                codeFile = origin.file;
11588                resourceFile = origin.file;
11589                return PackageManager.INSTALL_SUCCEEDED;
11590            }
11591
11592            try {
11593                final boolean isEphemeral = (installFlags & PackageManager.INSTALL_EPHEMERAL) != 0;
11594                final File tempDir =
11595                        mInstallerService.allocateStageDirLegacy(volumeUuid, isEphemeral);
11596                codeFile = tempDir;
11597                resourceFile = tempDir;
11598            } catch (IOException e) {
11599                Slog.w(TAG, "Failed to create copy file: " + e);
11600                return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
11601            }
11602
11603            final IParcelFileDescriptorFactory target = new IParcelFileDescriptorFactory.Stub() {
11604                @Override
11605                public ParcelFileDescriptor open(String name, int mode) throws RemoteException {
11606                    if (!FileUtils.isValidExtFilename(name)) {
11607                        throw new IllegalArgumentException("Invalid filename: " + name);
11608                    }
11609                    try {
11610                        final File file = new File(codeFile, name);
11611                        final FileDescriptor fd = Os.open(file.getAbsolutePath(),
11612                                O_RDWR | O_CREAT, 0644);
11613                        Os.chmod(file.getAbsolutePath(), 0644);
11614                        return new ParcelFileDescriptor(fd);
11615                    } catch (ErrnoException e) {
11616                        throw new RemoteException("Failed to open: " + e.getMessage());
11617                    }
11618                }
11619            };
11620
11621            int ret = PackageManager.INSTALL_SUCCEEDED;
11622            ret = imcs.copyPackage(origin.file.getAbsolutePath(), target);
11623            if (ret != PackageManager.INSTALL_SUCCEEDED) {
11624                Slog.e(TAG, "Failed to copy package");
11625                return ret;
11626            }
11627
11628            final File libraryRoot = new File(codeFile, LIB_DIR_NAME);
11629            NativeLibraryHelper.Handle handle = null;
11630            try {
11631                handle = NativeLibraryHelper.Handle.create(codeFile);
11632                ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot,
11633                        abiOverride);
11634            } catch (IOException e) {
11635                Slog.e(TAG, "Copying native libraries failed", e);
11636                ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
11637            } finally {
11638                IoUtils.closeQuietly(handle);
11639            }
11640
11641            return ret;
11642        }
11643
11644        int doPreInstall(int status) {
11645            if (status != PackageManager.INSTALL_SUCCEEDED) {
11646                cleanUp();
11647            }
11648            return status;
11649        }
11650
11651        boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
11652            if (status != PackageManager.INSTALL_SUCCEEDED) {
11653                cleanUp();
11654                return false;
11655            }
11656
11657            final File targetDir = codeFile.getParentFile();
11658            final File beforeCodeFile = codeFile;
11659            final File afterCodeFile = getNextCodePath(targetDir, pkg.packageName);
11660
11661            if (DEBUG_INSTALL) Slog.d(TAG, "Renaming " + beforeCodeFile + " to " + afterCodeFile);
11662            try {
11663                Os.rename(beforeCodeFile.getAbsolutePath(), afterCodeFile.getAbsolutePath());
11664            } catch (ErrnoException e) {
11665                Slog.w(TAG, "Failed to rename", e);
11666                return false;
11667            }
11668
11669            if (!SELinux.restoreconRecursive(afterCodeFile)) {
11670                Slog.w(TAG, "Failed to restorecon");
11671                return false;
11672            }
11673
11674            // Reflect the rename internally
11675            codeFile = afterCodeFile;
11676            resourceFile = afterCodeFile;
11677
11678            // Reflect the rename in scanned details
11679            pkg.codePath = afterCodeFile.getAbsolutePath();
11680            pkg.baseCodePath = FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile,
11681                    pkg.baseCodePath);
11682            pkg.splitCodePaths = FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile,
11683                    pkg.splitCodePaths);
11684
11685            // Reflect the rename in app info
11686            pkg.applicationInfo.volumeUuid = pkg.volumeUuid;
11687            pkg.applicationInfo.setCodePath(pkg.codePath);
11688            pkg.applicationInfo.setBaseCodePath(pkg.baseCodePath);
11689            pkg.applicationInfo.setSplitCodePaths(pkg.splitCodePaths);
11690            pkg.applicationInfo.setResourcePath(pkg.codePath);
11691            pkg.applicationInfo.setBaseResourcePath(pkg.baseCodePath);
11692            pkg.applicationInfo.setSplitResourcePaths(pkg.splitCodePaths);
11693
11694            return true;
11695        }
11696
11697        int doPostInstall(int status, int uid) {
11698            if (status != PackageManager.INSTALL_SUCCEEDED) {
11699                cleanUp();
11700            }
11701            return status;
11702        }
11703
11704        @Override
11705        String getCodePath() {
11706            return (codeFile != null) ? codeFile.getAbsolutePath() : null;
11707        }
11708
11709        @Override
11710        String getResourcePath() {
11711            return (resourceFile != null) ? resourceFile.getAbsolutePath() : null;
11712        }
11713
11714        private boolean cleanUp() {
11715            if (codeFile == null || !codeFile.exists()) {
11716                return false;
11717            }
11718
11719            if (codeFile.isDirectory()) {
11720                mInstaller.rmPackageDir(codeFile.getAbsolutePath());
11721            } else {
11722                codeFile.delete();
11723            }
11724
11725            if (resourceFile != null && !FileUtils.contains(codeFile, resourceFile)) {
11726                resourceFile.delete();
11727            }
11728
11729            return true;
11730        }
11731
11732        void cleanUpResourcesLI() {
11733            // Try enumerating all code paths before deleting
11734            List<String> allCodePaths = Collections.EMPTY_LIST;
11735            if (codeFile != null && codeFile.exists()) {
11736                try {
11737                    final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0);
11738                    allCodePaths = pkg.getAllCodePaths();
11739                } catch (PackageParserException e) {
11740                    // Ignored; we tried our best
11741                }
11742            }
11743
11744            cleanUp();
11745            removeDexFiles(allCodePaths, instructionSets);
11746        }
11747
11748        boolean doPostDeleteLI(boolean delete) {
11749            // XXX err, shouldn't we respect the delete flag?
11750            cleanUpResourcesLI();
11751            return true;
11752        }
11753    }
11754
11755    private boolean isAsecExternal(String cid) {
11756        final String asecPath = PackageHelper.getSdFilesystem(cid);
11757        return !asecPath.startsWith(mAsecInternalPath);
11758    }
11759
11760    private static void maybeThrowExceptionForMultiArchCopy(String message, int copyRet) throws
11761            PackageManagerException {
11762        if (copyRet < 0) {
11763            if (copyRet != PackageManager.NO_NATIVE_LIBRARIES &&
11764                    copyRet != PackageManager.INSTALL_FAILED_NO_MATCHING_ABIS) {
11765                throw new PackageManagerException(copyRet, message);
11766            }
11767        }
11768    }
11769
11770    /**
11771     * Extract the MountService "container ID" from the full code path of an
11772     * .apk.
11773     */
11774    static String cidFromCodePath(String fullCodePath) {
11775        int eidx = fullCodePath.lastIndexOf("/");
11776        String subStr1 = fullCodePath.substring(0, eidx);
11777        int sidx = subStr1.lastIndexOf("/");
11778        return subStr1.substring(sidx+1, eidx);
11779    }
11780
11781    /**
11782     * Logic to handle installation of ASEC applications, including copying and
11783     * renaming logic.
11784     */
11785    class AsecInstallArgs extends InstallArgs {
11786        static final String RES_FILE_NAME = "pkg.apk";
11787        static final String PUBLIC_RES_FILE_NAME = "res.zip";
11788
11789        String cid;
11790        String packagePath;
11791        String resourcePath;
11792
11793        /** New install */
11794        AsecInstallArgs(InstallParams params) {
11795            super(params.origin, params.move, params.observer, params.installFlags,
11796                    params.installerPackageName, params.volumeUuid,
11797                    params.getUser(), null /* instruction sets */, params.packageAbiOverride,
11798                    params.grantedRuntimePermissions,
11799                    params.traceMethod, params.traceCookie);
11800        }
11801
11802        /** Existing install */
11803        AsecInstallArgs(String fullCodePath, String[] instructionSets,
11804                        boolean isExternal, boolean isForwardLocked) {
11805            super(OriginInfo.fromNothing(), null, null, (isExternal ? INSTALL_EXTERNAL : 0)
11806                    | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null,
11807                    instructionSets, null, null, null, 0);
11808            // Hackily pretend we're still looking at a full code path
11809            if (!fullCodePath.endsWith(RES_FILE_NAME)) {
11810                fullCodePath = new File(fullCodePath, RES_FILE_NAME).getAbsolutePath();
11811            }
11812
11813            // Extract cid from fullCodePath
11814            int eidx = fullCodePath.lastIndexOf("/");
11815            String subStr1 = fullCodePath.substring(0, eidx);
11816            int sidx = subStr1.lastIndexOf("/");
11817            cid = subStr1.substring(sidx+1, eidx);
11818            setMountPath(subStr1);
11819        }
11820
11821        AsecInstallArgs(String cid, String[] instructionSets, boolean isForwardLocked) {
11822            super(OriginInfo.fromNothing(), null, null, (isAsecExternal(cid) ? INSTALL_EXTERNAL : 0)
11823                    | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null,
11824                    instructionSets, null, null, null, 0);
11825            this.cid = cid;
11826            setMountPath(PackageHelper.getSdDir(cid));
11827        }
11828
11829        void createCopyFile() {
11830            cid = mInstallerService.allocateExternalStageCidLegacy();
11831        }
11832
11833        int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
11834            if (origin.staged && origin.cid != null) {
11835                if (DEBUG_INSTALL) Slog.d(TAG, origin.cid + " already staged; skipping copy");
11836                cid = origin.cid;
11837                setMountPath(PackageHelper.getSdDir(cid));
11838                return PackageManager.INSTALL_SUCCEEDED;
11839            }
11840
11841            if (temp) {
11842                createCopyFile();
11843            } else {
11844                /*
11845                 * Pre-emptively destroy the container since it's destroyed if
11846                 * copying fails due to it existing anyway.
11847                 */
11848                PackageHelper.destroySdDir(cid);
11849            }
11850
11851            final String newMountPath = imcs.copyPackageToContainer(
11852                    origin.file.getAbsolutePath(), cid, getEncryptKey(), isExternalAsec(),
11853                    isFwdLocked(), deriveAbiOverride(abiOverride, null /* settings */));
11854
11855            if (newMountPath != null) {
11856                setMountPath(newMountPath);
11857                return PackageManager.INSTALL_SUCCEEDED;
11858            } else {
11859                return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
11860            }
11861        }
11862
11863        @Override
11864        String getCodePath() {
11865            return packagePath;
11866        }
11867
11868        @Override
11869        String getResourcePath() {
11870            return resourcePath;
11871        }
11872
11873        int doPreInstall(int status) {
11874            if (status != PackageManager.INSTALL_SUCCEEDED) {
11875                // Destroy container
11876                PackageHelper.destroySdDir(cid);
11877            } else {
11878                boolean mounted = PackageHelper.isContainerMounted(cid);
11879                if (!mounted) {
11880                    String newMountPath = PackageHelper.mountSdDir(cid, getEncryptKey(),
11881                            Process.SYSTEM_UID);
11882                    if (newMountPath != null) {
11883                        setMountPath(newMountPath);
11884                    } else {
11885                        return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
11886                    }
11887                }
11888            }
11889            return status;
11890        }
11891
11892        boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
11893            String newCacheId = getNextCodePath(oldCodePath, pkg.packageName, "/" + RES_FILE_NAME);
11894            String newMountPath = null;
11895            if (PackageHelper.isContainerMounted(cid)) {
11896                // Unmount the container
11897                if (!PackageHelper.unMountSdDir(cid)) {
11898                    Slog.i(TAG, "Failed to unmount " + cid + " before renaming");
11899                    return false;
11900                }
11901            }
11902            if (!PackageHelper.renameSdDir(cid, newCacheId)) {
11903                Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId +
11904                        " which might be stale. Will try to clean up.");
11905                // Clean up the stale container and proceed to recreate.
11906                if (!PackageHelper.destroySdDir(newCacheId)) {
11907                    Slog.e(TAG, "Very strange. Cannot clean up stale container " + newCacheId);
11908                    return false;
11909                }
11910                // Successfully cleaned up stale container. Try to rename again.
11911                if (!PackageHelper.renameSdDir(cid, newCacheId)) {
11912                    Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId
11913                            + " inspite of cleaning it up.");
11914                    return false;
11915                }
11916            }
11917            if (!PackageHelper.isContainerMounted(newCacheId)) {
11918                Slog.w(TAG, "Mounting container " + newCacheId);
11919                newMountPath = PackageHelper.mountSdDir(newCacheId,
11920                        getEncryptKey(), Process.SYSTEM_UID);
11921            } else {
11922                newMountPath = PackageHelper.getSdDir(newCacheId);
11923            }
11924            if (newMountPath == null) {
11925                Slog.w(TAG, "Failed to get cache path for  " + newCacheId);
11926                return false;
11927            }
11928            Log.i(TAG, "Succesfully renamed " + cid +
11929                    " to " + newCacheId +
11930                    " at new path: " + newMountPath);
11931            cid = newCacheId;
11932
11933            final File beforeCodeFile = new File(packagePath);
11934            setMountPath(newMountPath);
11935            final File afterCodeFile = new File(packagePath);
11936
11937            // Reflect the rename in scanned details
11938            pkg.codePath = afterCodeFile.getAbsolutePath();
11939            pkg.baseCodePath = FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile,
11940                    pkg.baseCodePath);
11941            pkg.splitCodePaths = FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile,
11942                    pkg.splitCodePaths);
11943
11944            // Reflect the rename in app info
11945            pkg.applicationInfo.volumeUuid = pkg.volumeUuid;
11946            pkg.applicationInfo.setCodePath(pkg.codePath);
11947            pkg.applicationInfo.setBaseCodePath(pkg.baseCodePath);
11948            pkg.applicationInfo.setSplitCodePaths(pkg.splitCodePaths);
11949            pkg.applicationInfo.setResourcePath(pkg.codePath);
11950            pkg.applicationInfo.setBaseResourcePath(pkg.baseCodePath);
11951            pkg.applicationInfo.setSplitResourcePaths(pkg.splitCodePaths);
11952
11953            return true;
11954        }
11955
11956        private void setMountPath(String mountPath) {
11957            final File mountFile = new File(mountPath);
11958
11959            final File monolithicFile = new File(mountFile, RES_FILE_NAME);
11960            if (monolithicFile.exists()) {
11961                packagePath = monolithicFile.getAbsolutePath();
11962                if (isFwdLocked()) {
11963                    resourcePath = new File(mountFile, PUBLIC_RES_FILE_NAME).getAbsolutePath();
11964                } else {
11965                    resourcePath = packagePath;
11966                }
11967            } else {
11968                packagePath = mountFile.getAbsolutePath();
11969                resourcePath = packagePath;
11970            }
11971        }
11972
11973        int doPostInstall(int status, int uid) {
11974            if (status != PackageManager.INSTALL_SUCCEEDED) {
11975                cleanUp();
11976            } else {
11977                final int groupOwner;
11978                final String protectedFile;
11979                if (isFwdLocked()) {
11980                    groupOwner = UserHandle.getSharedAppGid(uid);
11981                    protectedFile = RES_FILE_NAME;
11982                } else {
11983                    groupOwner = -1;
11984                    protectedFile = null;
11985                }
11986
11987                if (uid < Process.FIRST_APPLICATION_UID
11988                        || !PackageHelper.fixSdPermissions(cid, groupOwner, protectedFile)) {
11989                    Slog.e(TAG, "Failed to finalize " + cid);
11990                    PackageHelper.destroySdDir(cid);
11991                    return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
11992                }
11993
11994                boolean mounted = PackageHelper.isContainerMounted(cid);
11995                if (!mounted) {
11996                    PackageHelper.mountSdDir(cid, getEncryptKey(), Process.myUid());
11997                }
11998            }
11999            return status;
12000        }
12001
12002        private void cleanUp() {
12003            if (DEBUG_SD_INSTALL) Slog.i(TAG, "cleanUp");
12004
12005            // Destroy secure container
12006            PackageHelper.destroySdDir(cid);
12007        }
12008
12009        private List<String> getAllCodePaths() {
12010            final File codeFile = new File(getCodePath());
12011            if (codeFile != null && codeFile.exists()) {
12012                try {
12013                    final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0);
12014                    return pkg.getAllCodePaths();
12015                } catch (PackageParserException e) {
12016                    // Ignored; we tried our best
12017                }
12018            }
12019            return Collections.EMPTY_LIST;
12020        }
12021
12022        void cleanUpResourcesLI() {
12023            // Enumerate all code paths before deleting
12024            cleanUpResourcesLI(getAllCodePaths());
12025        }
12026
12027        private void cleanUpResourcesLI(List<String> allCodePaths) {
12028            cleanUp();
12029            removeDexFiles(allCodePaths, instructionSets);
12030        }
12031
12032        String getPackageName() {
12033            return getAsecPackageName(cid);
12034        }
12035
12036        boolean doPostDeleteLI(boolean delete) {
12037            if (DEBUG_SD_INSTALL) Slog.i(TAG, "doPostDeleteLI() del=" + delete);
12038            final List<String> allCodePaths = getAllCodePaths();
12039            boolean mounted = PackageHelper.isContainerMounted(cid);
12040            if (mounted) {
12041                // Unmount first
12042                if (PackageHelper.unMountSdDir(cid)) {
12043                    mounted = false;
12044                }
12045            }
12046            if (!mounted && delete) {
12047                cleanUpResourcesLI(allCodePaths);
12048            }
12049            return !mounted;
12050        }
12051
12052        @Override
12053        int doPreCopy() {
12054            if (isFwdLocked()) {
12055                if (!PackageHelper.fixSdPermissions(cid,
12056                        getPackageUid(DEFAULT_CONTAINER_PACKAGE, 0), RES_FILE_NAME)) {
12057                    return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
12058                }
12059            }
12060
12061            return PackageManager.INSTALL_SUCCEEDED;
12062        }
12063
12064        @Override
12065        int doPostCopy(int uid) {
12066            if (isFwdLocked()) {
12067                if (uid < Process.FIRST_APPLICATION_UID
12068                        || !PackageHelper.fixSdPermissions(cid, UserHandle.getSharedAppGid(uid),
12069                                RES_FILE_NAME)) {
12070                    Slog.e(TAG, "Failed to finalize " + cid);
12071                    PackageHelper.destroySdDir(cid);
12072                    return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
12073                }
12074            }
12075
12076            return PackageManager.INSTALL_SUCCEEDED;
12077        }
12078    }
12079
12080    /**
12081     * Logic to handle movement of existing installed applications.
12082     */
12083    class MoveInstallArgs extends InstallArgs {
12084        private File codeFile;
12085        private File resourceFile;
12086
12087        /** New install */
12088        MoveInstallArgs(InstallParams params) {
12089            super(params.origin, params.move, params.observer, params.installFlags,
12090                    params.installerPackageName, params.volumeUuid,
12091                    params.getUser(), null /* instruction sets */, params.packageAbiOverride,
12092                    params.grantedRuntimePermissions,
12093                    params.traceMethod, params.traceCookie);
12094        }
12095
12096        int copyApk(IMediaContainerService imcs, boolean temp) {
12097            if (DEBUG_INSTALL) Slog.d(TAG, "Moving " + move.packageName + " from "
12098                    + move.fromUuid + " to " + move.toUuid);
12099            synchronized (mInstaller) {
12100                if (mInstaller.copyCompleteApp(move.fromUuid, move.toUuid, move.packageName,
12101                        move.dataAppName, move.appId, move.seinfo) != 0) {
12102                    return PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
12103                }
12104            }
12105
12106            codeFile = new File(Environment.getDataAppDirectory(move.toUuid), move.dataAppName);
12107            resourceFile = codeFile;
12108            if (DEBUG_INSTALL) Slog.d(TAG, "codeFile after move is " + codeFile);
12109
12110            return PackageManager.INSTALL_SUCCEEDED;
12111        }
12112
12113        int doPreInstall(int status) {
12114            if (status != PackageManager.INSTALL_SUCCEEDED) {
12115                cleanUp(move.toUuid);
12116            }
12117            return status;
12118        }
12119
12120        boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
12121            if (status != PackageManager.INSTALL_SUCCEEDED) {
12122                cleanUp(move.toUuid);
12123                return false;
12124            }
12125
12126            // Reflect the move in app info
12127            pkg.applicationInfo.volumeUuid = pkg.volumeUuid;
12128            pkg.applicationInfo.setCodePath(pkg.codePath);
12129            pkg.applicationInfo.setBaseCodePath(pkg.baseCodePath);
12130            pkg.applicationInfo.setSplitCodePaths(pkg.splitCodePaths);
12131            pkg.applicationInfo.setResourcePath(pkg.codePath);
12132            pkg.applicationInfo.setBaseResourcePath(pkg.baseCodePath);
12133            pkg.applicationInfo.setSplitResourcePaths(pkg.splitCodePaths);
12134
12135            return true;
12136        }
12137
12138        int doPostInstall(int status, int uid) {
12139            if (status == PackageManager.INSTALL_SUCCEEDED) {
12140                cleanUp(move.fromUuid);
12141            } else {
12142                cleanUp(move.toUuid);
12143            }
12144            return status;
12145        }
12146
12147        @Override
12148        String getCodePath() {
12149            return (codeFile != null) ? codeFile.getAbsolutePath() : null;
12150        }
12151
12152        @Override
12153        String getResourcePath() {
12154            return (resourceFile != null) ? resourceFile.getAbsolutePath() : null;
12155        }
12156
12157        private boolean cleanUp(String volumeUuid) {
12158            final File codeFile = new File(Environment.getDataAppDirectory(volumeUuid),
12159                    move.dataAppName);
12160            Slog.d(TAG, "Cleaning up " + move.packageName + " on " + volumeUuid);
12161            synchronized (mInstallLock) {
12162                // Clean up both app data and code
12163                removeDataDirsLI(volumeUuid, move.packageName);
12164                if (codeFile.isDirectory()) {
12165                    mInstaller.rmPackageDir(codeFile.getAbsolutePath());
12166                } else {
12167                    codeFile.delete();
12168                }
12169            }
12170            return true;
12171        }
12172
12173        void cleanUpResourcesLI() {
12174            throw new UnsupportedOperationException();
12175        }
12176
12177        boolean doPostDeleteLI(boolean delete) {
12178            throw new UnsupportedOperationException();
12179        }
12180    }
12181
12182    static String getAsecPackageName(String packageCid) {
12183        int idx = packageCid.lastIndexOf("-");
12184        if (idx == -1) {
12185            return packageCid;
12186        }
12187        return packageCid.substring(0, idx);
12188    }
12189
12190    // Utility method used to create code paths based on package name and available index.
12191    private static String getNextCodePath(String oldCodePath, String prefix, String suffix) {
12192        String idxStr = "";
12193        int idx = 1;
12194        // Fall back to default value of idx=1 if prefix is not
12195        // part of oldCodePath
12196        if (oldCodePath != null) {
12197            String subStr = oldCodePath;
12198            // Drop the suffix right away
12199            if (suffix != null && subStr.endsWith(suffix)) {
12200                subStr = subStr.substring(0, subStr.length() - suffix.length());
12201            }
12202            // If oldCodePath already contains prefix find out the
12203            // ending index to either increment or decrement.
12204            int sidx = subStr.lastIndexOf(prefix);
12205            if (sidx != -1) {
12206                subStr = subStr.substring(sidx + prefix.length());
12207                if (subStr != null) {
12208                    if (subStr.startsWith(INSTALL_PACKAGE_SUFFIX)) {
12209                        subStr = subStr.substring(INSTALL_PACKAGE_SUFFIX.length());
12210                    }
12211                    try {
12212                        idx = Integer.parseInt(subStr);
12213                        if (idx <= 1) {
12214                            idx++;
12215                        } else {
12216                            idx--;
12217                        }
12218                    } catch(NumberFormatException e) {
12219                    }
12220                }
12221            }
12222        }
12223        idxStr = INSTALL_PACKAGE_SUFFIX + Integer.toString(idx);
12224        return prefix + idxStr;
12225    }
12226
12227    private File getNextCodePath(File targetDir, String packageName) {
12228        int suffix = 1;
12229        File result;
12230        do {
12231            result = new File(targetDir, packageName + "-" + suffix);
12232            suffix++;
12233        } while (result.exists());
12234        return result;
12235    }
12236
12237    // Utility method that returns the relative package path with respect
12238    // to the installation directory. Like say for /data/data/com.test-1.apk
12239    // string com.test-1 is returned.
12240    static String deriveCodePathName(String codePath) {
12241        if (codePath == null) {
12242            return null;
12243        }
12244        final File codeFile = new File(codePath);
12245        final String name = codeFile.getName();
12246        if (codeFile.isDirectory()) {
12247            return name;
12248        } else if (name.endsWith(".apk") || name.endsWith(".tmp")) {
12249            final int lastDot = name.lastIndexOf('.');
12250            return name.substring(0, lastDot);
12251        } else {
12252            Slog.w(TAG, "Odd, " + codePath + " doesn't look like an APK");
12253            return null;
12254        }
12255    }
12256
12257    static class PackageInstalledInfo {
12258        String name;
12259        int uid;
12260        // The set of users that originally had this package installed.
12261        int[] origUsers;
12262        // The set of users that now have this package installed.
12263        int[] newUsers;
12264        PackageParser.Package pkg;
12265        int returnCode;
12266        String returnMsg;
12267        PackageRemovedInfo removedInfo;
12268
12269        public void setError(int code, String msg) {
12270            returnCode = code;
12271            returnMsg = msg;
12272            Slog.w(TAG, msg);
12273        }
12274
12275        public void setError(String msg, PackageParserException e) {
12276            returnCode = e.error;
12277            returnMsg = ExceptionUtils.getCompleteMessage(msg, e);
12278            Slog.w(TAG, msg, e);
12279        }
12280
12281        public void setError(String msg, PackageManagerException e) {
12282            returnCode = e.error;
12283            returnMsg = ExceptionUtils.getCompleteMessage(msg, e);
12284            Slog.w(TAG, msg, e);
12285        }
12286
12287        // In some error cases we want to convey more info back to the observer
12288        String origPackage;
12289        String origPermission;
12290    }
12291
12292    /*
12293     * Install a non-existing package.
12294     */
12295    private void installNewPackageLI(PackageParser.Package pkg, int parseFlags, int scanFlags,
12296            UserHandle user, String installerPackageName, String volumeUuid,
12297            PackageInstalledInfo res) {
12298        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installNewPackage");
12299
12300        // Remember this for later, in case we need to rollback this install
12301        String pkgName = pkg.packageName;
12302
12303        if (DEBUG_INSTALL) Slog.d(TAG, "installNewPackageLI: " + pkg);
12304        // TODO: b/23350563
12305        final boolean dataDirExists = Environment
12306                .getDataUserPackageDirectory(volumeUuid, UserHandle.USER_SYSTEM, pkgName).exists();
12307
12308        synchronized(mPackages) {
12309            if (mSettings.mRenamedPackages.containsKey(pkgName)) {
12310                // A package with the same name is already installed, though
12311                // it has been renamed to an older name.  The package we
12312                // are trying to install should be installed as an update to
12313                // the existing one, but that has not been requested, so bail.
12314                res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName
12315                        + " without first uninstalling package running as "
12316                        + mSettings.mRenamedPackages.get(pkgName));
12317                return;
12318            }
12319            if (mPackages.containsKey(pkgName)) {
12320                // Don't allow installation over an existing package with the same name.
12321                res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName
12322                        + " without first uninstalling.");
12323                return;
12324            }
12325        }
12326
12327        try {
12328            PackageParser.Package newPackage = scanPackageTracedLI(pkg, parseFlags, scanFlags,
12329                    System.currentTimeMillis(), user);
12330
12331            updateSettingsLI(newPackage, installerPackageName, volumeUuid, null, null, res, user);
12332            // delete the partially installed application. the data directory will have to be
12333            // restored if it was already existing
12334            if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
12335                // remove package from internal structures.  Note that we want deletePackageX to
12336                // delete the package data and cache directories that it created in
12337                // scanPackageLocked, unless those directories existed before we even tried to
12338                // install.
12339                deletePackageLI(pkgName, UserHandle.ALL, false, null, null,
12340                        dataDirExists ? PackageManager.DELETE_KEEP_DATA : 0,
12341                                res.removedInfo, true);
12342            }
12343
12344        } catch (PackageManagerException e) {
12345            res.setError("Package couldn't be installed in " + pkg.codePath, e);
12346        }
12347
12348        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
12349    }
12350
12351    private boolean shouldCheckUpgradeKeySetLP(PackageSetting oldPs, int scanFlags) {
12352        // Can't rotate keys during boot or if sharedUser.
12353        if (oldPs == null || (scanFlags&SCAN_INITIAL) != 0 || oldPs.sharedUser != null
12354                || !oldPs.keySetData.isUsingUpgradeKeySets()) {
12355            return false;
12356        }
12357        // app is using upgradeKeySets; make sure all are valid
12358        KeySetManagerService ksms = mSettings.mKeySetManagerService;
12359        long[] upgradeKeySets = oldPs.keySetData.getUpgradeKeySets();
12360        for (int i = 0; i < upgradeKeySets.length; i++) {
12361            if (!ksms.isIdValidKeySetId(upgradeKeySets[i])) {
12362                Slog.wtf(TAG, "Package "
12363                         + (oldPs.name != null ? oldPs.name : "<null>")
12364                         + " contains upgrade-key-set reference to unknown key-set: "
12365                         + upgradeKeySets[i]
12366                         + " reverting to signatures check.");
12367                return false;
12368            }
12369        }
12370        return true;
12371    }
12372
12373    private boolean checkUpgradeKeySetLP(PackageSetting oldPS, PackageParser.Package newPkg) {
12374        // Upgrade keysets are being used.  Determine if new package has a superset of the
12375        // required keys.
12376        long[] upgradeKeySets = oldPS.keySetData.getUpgradeKeySets();
12377        KeySetManagerService ksms = mSettings.mKeySetManagerService;
12378        for (int i = 0; i < upgradeKeySets.length; i++) {
12379            Set<PublicKey> upgradeSet = ksms.getPublicKeysFromKeySetLPr(upgradeKeySets[i]);
12380            if (upgradeSet != null && newPkg.mSigningKeys.containsAll(upgradeSet)) {
12381                return true;
12382            }
12383        }
12384        return false;
12385    }
12386
12387    private void replacePackageLI(PackageParser.Package pkg, int parseFlags, int scanFlags,
12388            UserHandle user, String installerPackageName, String volumeUuid,
12389            PackageInstalledInfo res) {
12390        final boolean isEphemeral = (parseFlags & PackageParser.PARSE_IS_EPHEMERAL) != 0;
12391
12392        final PackageParser.Package oldPackage;
12393        final String pkgName = pkg.packageName;
12394        final int[] allUsers;
12395        final boolean[] perUserInstalled;
12396
12397        // First find the old package info and check signatures
12398        synchronized(mPackages) {
12399            oldPackage = mPackages.get(pkgName);
12400            final boolean oldIsEphemeral = oldPackage.applicationInfo.isEphemeralApp();
12401            if (isEphemeral && !oldIsEphemeral) {
12402                // can't downgrade from full to ephemeral
12403                Slog.w(TAG, "Can't replace app with ephemeral: " + pkgName);
12404                res.returnCode = PackageManager.INSTALL_FAILED_EPHEMERAL_INVALID;
12405                return;
12406            }
12407            if (DEBUG_INSTALL) Slog.d(TAG, "replacePackageLI: new=" + pkg + ", old=" + oldPackage);
12408            final PackageSetting ps = mSettings.mPackages.get(pkgName);
12409            if (shouldCheckUpgradeKeySetLP(ps, scanFlags)) {
12410                if(!checkUpgradeKeySetLP(ps, pkg)) {
12411                    res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
12412                            "New package not signed by keys specified by upgrade-keysets: "
12413                            + pkgName);
12414                    return;
12415                }
12416            } else {
12417                // default to original signature matching
12418                if (compareSignatures(oldPackage.mSignatures, pkg.mSignatures)
12419                    != PackageManager.SIGNATURE_MATCH) {
12420                    res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
12421                            "New package has a different signature: " + pkgName);
12422                    return;
12423                }
12424            }
12425
12426            // In case of rollback, remember per-user/profile install state
12427            allUsers = sUserManager.getUserIds();
12428            perUserInstalled = new boolean[allUsers.length];
12429            for (int i = 0; i < allUsers.length; i++) {
12430                perUserInstalled[i] = ps != null ? ps.getInstalled(allUsers[i]) : false;
12431            }
12432        }
12433
12434        boolean sysPkg = (isSystemApp(oldPackage));
12435        if (sysPkg) {
12436            replaceSystemPackageLI(oldPackage, pkg, parseFlags, scanFlags,
12437                    user, allUsers, perUserInstalled, installerPackageName, volumeUuid, res);
12438        } else {
12439            replaceNonSystemPackageLI(oldPackage, pkg, parseFlags, scanFlags,
12440                    user, allUsers, perUserInstalled, installerPackageName, volumeUuid, res);
12441        }
12442    }
12443
12444    private void replaceNonSystemPackageLI(PackageParser.Package deletedPackage,
12445            PackageParser.Package pkg, int parseFlags, int scanFlags, UserHandle user,
12446            int[] allUsers, boolean[] perUserInstalled, String installerPackageName,
12447            String volumeUuid, PackageInstalledInfo res) {
12448        String pkgName = deletedPackage.packageName;
12449        boolean deletedPkg = true;
12450        boolean updatedSettings = false;
12451
12452        if (DEBUG_INSTALL) Slog.d(TAG, "replaceNonSystemPackageLI: new=" + pkg + ", old="
12453                + deletedPackage);
12454        long origUpdateTime;
12455        if (pkg.mExtras != null) {
12456            origUpdateTime = ((PackageSetting)pkg.mExtras).lastUpdateTime;
12457        } else {
12458            origUpdateTime = 0;
12459        }
12460
12461        // First delete the existing package while retaining the data directory
12462        if (!deletePackageLI(pkgName, null, true, null, null, PackageManager.DELETE_KEEP_DATA,
12463                res.removedInfo, true)) {
12464            // If the existing package wasn't successfully deleted
12465            res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE, "replaceNonSystemPackageLI");
12466            deletedPkg = false;
12467        } else {
12468            // Successfully deleted the old package; proceed with replace.
12469
12470            // If deleted package lived in a container, give users a chance to
12471            // relinquish resources before killing.
12472            if (deletedPackage.isForwardLocked() || isExternal(deletedPackage)) {
12473                if (DEBUG_INSTALL) {
12474                    Slog.i(TAG, "upgrading pkg " + deletedPackage + " is ASEC-hosted -> UNAVAILABLE");
12475                }
12476                final int[] uidArray = new int[] { deletedPackage.applicationInfo.uid };
12477                final ArrayList<String> pkgList = new ArrayList<String>(1);
12478                pkgList.add(deletedPackage.applicationInfo.packageName);
12479                sendResourcesChangedBroadcast(false, true, pkgList, uidArray, null);
12480            }
12481
12482            deleteCodeCacheDirsLI(pkg.volumeUuid, pkgName);
12483            try {
12484                final PackageParser.Package newPackage = scanPackageTracedLI(pkg, parseFlags,
12485                        scanFlags | SCAN_UPDATE_TIME, System.currentTimeMillis(), user);
12486                updateSettingsLI(newPackage, installerPackageName, volumeUuid, allUsers,
12487                        perUserInstalled, res, user);
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                updatedSettings = true;
12620            }
12621
12622        } catch (PackageManagerException e) {
12623            res.setError("Package couldn't be installed in " + pkg.codePath, e);
12624        }
12625
12626        if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
12627            // Re installation failed. Restore old information
12628            // Remove new pkg information
12629            if (newPackage != null) {
12630                removeInstalledPackageLI(newPackage, true);
12631            }
12632            // Add back the old system package
12633            try {
12634                scanPackageTracedLI(oldPkg, parseFlags, SCAN_UPDATE_SIGNATURE, 0, user);
12635            } catch (PackageManagerException e) {
12636                Slog.e(TAG, "Failed to restore original package: " + e.getMessage());
12637            }
12638            // Restore the old system information in Settings
12639            synchronized (mPackages) {
12640                if (disabledSystem) {
12641                    mSettings.enableSystemPackageLPw(packageName);
12642                }
12643                if (updatedSettings) {
12644                    mSettings.setInstallerPackageName(packageName,
12645                            oldPkgSetting.installerPackageName);
12646                }
12647                mSettings.writeLPr();
12648            }
12649        }
12650    }
12651
12652    private int[] revokeUnusedSharedUserPermissionsLPw(SharedUserSetting su, int[] allUserIds) {
12653        // Collect all used permissions in the UID
12654        ArraySet<String> usedPermissions = new ArraySet<>();
12655        final int packageCount = su.packages.size();
12656        for (int i = 0; i < packageCount; i++) {
12657            PackageSetting ps = su.packages.valueAt(i);
12658            if (ps.pkg == null) {
12659                continue;
12660            }
12661            final int requestedPermCount = ps.pkg.requestedPermissions.size();
12662            for (int j = 0; j < requestedPermCount; j++) {
12663                String permission = ps.pkg.requestedPermissions.get(j);
12664                BasePermission bp = mSettings.mPermissions.get(permission);
12665                if (bp != null) {
12666                    usedPermissions.add(permission);
12667                }
12668            }
12669        }
12670
12671        PermissionsState permissionsState = su.getPermissionsState();
12672        // Prune install permissions
12673        List<PermissionState> installPermStates = permissionsState.getInstallPermissionStates();
12674        final int installPermCount = installPermStates.size();
12675        for (int i = installPermCount - 1; i >= 0;  i--) {
12676            PermissionState permissionState = installPermStates.get(i);
12677            if (!usedPermissions.contains(permissionState.getName())) {
12678                BasePermission bp = mSettings.mPermissions.get(permissionState.getName());
12679                if (bp != null) {
12680                    permissionsState.revokeInstallPermission(bp);
12681                    permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
12682                            PackageManager.MASK_PERMISSION_FLAGS, 0);
12683                }
12684            }
12685        }
12686
12687        int[] runtimePermissionChangedUserIds = EmptyArray.INT;
12688
12689        // Prune runtime permissions
12690        for (int userId : allUserIds) {
12691            List<PermissionState> runtimePermStates = permissionsState
12692                    .getRuntimePermissionStates(userId);
12693            final int runtimePermCount = runtimePermStates.size();
12694            for (int i = runtimePermCount - 1; i >= 0; i--) {
12695                PermissionState permissionState = runtimePermStates.get(i);
12696                if (!usedPermissions.contains(permissionState.getName())) {
12697                    BasePermission bp = mSettings.mPermissions.get(permissionState.getName());
12698                    if (bp != null) {
12699                        permissionsState.revokeRuntimePermission(bp, userId);
12700                        permissionsState.updatePermissionFlags(bp, userId,
12701                                PackageManager.MASK_PERMISSION_FLAGS, 0);
12702                        runtimePermissionChangedUserIds = ArrayUtils.appendInt(
12703                                runtimePermissionChangedUserIds, userId);
12704                    }
12705                }
12706            }
12707        }
12708
12709        return runtimePermissionChangedUserIds;
12710    }
12711
12712    private void updateSettingsLI(PackageParser.Package newPackage, String installerPackageName,
12713            String volumeUuid, int[] allUsers, boolean[] perUserInstalled, PackageInstalledInfo res,
12714            UserHandle user) {
12715        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");
12716
12717        String pkgName = newPackage.packageName;
12718        synchronized (mPackages) {
12719            //write settings. the installStatus will be incomplete at this stage.
12720            //note that the new package setting would have already been
12721            //added to mPackages. It hasn't been persisted yet.
12722            mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_INCOMPLETE);
12723            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings");
12724            mSettings.writeLPr();
12725            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
12726        }
12727
12728        if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + newPackage.codePath);
12729        synchronized (mPackages) {
12730            updatePermissionsLPw(newPackage.packageName, newPackage,
12731                    UPDATE_PERMISSIONS_REPLACE_PKG | (newPackage.permissions.size() > 0
12732                            ? UPDATE_PERMISSIONS_ALL : 0));
12733            // For system-bundled packages, we assume that installing an upgraded version
12734            // of the package implies that the user actually wants to run that new code,
12735            // so we enable the package.
12736            PackageSetting ps = mSettings.mPackages.get(pkgName);
12737            if (ps != null) {
12738                if (isSystemApp(newPackage)) {
12739                    // NB: implicit assumption that system package upgrades apply to all users
12740                    if (DEBUG_INSTALL) {
12741                        Slog.d(TAG, "Implicitly enabling system package on upgrade: " + pkgName);
12742                    }
12743                    if (res.origUsers != null) {
12744                        for (int userHandle : res.origUsers) {
12745                            ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT,
12746                                    userHandle, installerPackageName);
12747                        }
12748                    }
12749                    // Also convey the prior install/uninstall state
12750                    if (allUsers != null && perUserInstalled != null) {
12751                        for (int i = 0; i < allUsers.length; i++) {
12752                            if (DEBUG_INSTALL) {
12753                                Slog.d(TAG, "    user " + allUsers[i]
12754                                        + " => " + perUserInstalled[i]);
12755                            }
12756                            ps.setInstalled(perUserInstalled[i], allUsers[i]);
12757                        }
12758                        // these install state changes will be persisted in the
12759                        // upcoming call to mSettings.writeLPr().
12760                    }
12761                }
12762                // It's implied that when a user requests installation, they want the app to be
12763                // installed and enabled.
12764                int userId = user.getIdentifier();
12765                if (userId != UserHandle.USER_ALL) {
12766                    ps.setInstalled(true, userId);
12767                    ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, userId, installerPackageName);
12768                }
12769            }
12770            res.name = pkgName;
12771            res.uid = newPackage.applicationInfo.uid;
12772            res.pkg = newPackage;
12773            mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_COMPLETE);
12774            mSettings.setInstallerPackageName(pkgName, installerPackageName);
12775            res.returnCode = PackageManager.INSTALL_SUCCEEDED;
12776            //to update install status
12777            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings");
12778            mSettings.writeLPr();
12779            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
12780        }
12781
12782        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
12783    }
12784
12785    private void installPackageTracedLI(InstallArgs args, PackageInstalledInfo res) {
12786        try {
12787            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installPackage");
12788            installPackageLI(args, res);
12789        } finally {
12790            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
12791        }
12792    }
12793
12794    private void installPackageLI(InstallArgs args, PackageInstalledInfo res) {
12795        final int installFlags = args.installFlags;
12796        final String installerPackageName = args.installerPackageName;
12797        final String volumeUuid = args.volumeUuid;
12798        final File tmpPackageFile = new File(args.getCodePath());
12799        final boolean forwardLocked = ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0);
12800        final boolean onExternal = (((installFlags & PackageManager.INSTALL_EXTERNAL) != 0)
12801                || (args.volumeUuid != null));
12802        final boolean ephemeral = ((installFlags & PackageManager.INSTALL_EPHEMERAL) != 0);
12803        boolean replace = false;
12804        int scanFlags = SCAN_NEW_INSTALL | SCAN_UPDATE_SIGNATURE;
12805        if (args.move != null) {
12806            // moving a complete application; perfom an initial scan on the new install location
12807            scanFlags |= SCAN_INITIAL;
12808        }
12809        // Result object to be returned
12810        res.returnCode = PackageManager.INSTALL_SUCCEEDED;
12811
12812        if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile);
12813
12814        // Sanity check
12815        if (ephemeral && (forwardLocked || onExternal)) {
12816            Slog.i(TAG, "Incompatible ephemeral install; fwdLocked=" + forwardLocked
12817                    + " external=" + onExternal);
12818            res.returnCode = PackageManager.INSTALL_FAILED_EPHEMERAL_INVALID;
12819            return;
12820        }
12821
12822        // Retrieve PackageSettings and parse package
12823        final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY
12824                | PackageParser.PARSE_ENFORCE_CODE
12825                | (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0)
12826                | (onExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0)
12827                | (ephemeral ? PackageParser.PARSE_IS_EPHEMERAL : 0);
12828        PackageParser pp = new PackageParser();
12829        pp.setSeparateProcesses(mSeparateProcesses);
12830        pp.setDisplayMetrics(mMetrics);
12831
12832        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
12833        final PackageParser.Package pkg;
12834        try {
12835            pkg = pp.parsePackage(tmpPackageFile, parseFlags);
12836        } catch (PackageParserException e) {
12837            res.setError("Failed parse during installPackageLI", e);
12838            return;
12839        } finally {
12840            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
12841        }
12842
12843        // Mark that we have an install time CPU ABI override.
12844        pkg.cpuAbiOverride = args.abiOverride;
12845
12846        String pkgName = res.name = pkg.packageName;
12847        if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_TEST_ONLY) != 0) {
12848            if ((installFlags & PackageManager.INSTALL_ALLOW_TEST) == 0) {
12849                res.setError(INSTALL_FAILED_TEST_ONLY, "installPackageLI");
12850                return;
12851            }
12852        }
12853
12854        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "collectCertificates");
12855        try {
12856            pp.collectCertificates(pkg, parseFlags);
12857        } catch (PackageParserException e) {
12858            res.setError("Failed collect during installPackageLI", e);
12859            return;
12860        } finally {
12861            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
12862        }
12863
12864        // Get rid of all references to package scan path via parser.
12865        pp = null;
12866        String oldCodePath = null;
12867        boolean systemApp = false;
12868        synchronized (mPackages) {
12869            // Check if installing already existing package
12870            if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
12871                String oldName = mSettings.mRenamedPackages.get(pkgName);
12872                if (pkg.mOriginalPackages != null
12873                        && pkg.mOriginalPackages.contains(oldName)
12874                        && mPackages.containsKey(oldName)) {
12875                    // This package is derived from an original package,
12876                    // and this device has been updating from that original
12877                    // name.  We must continue using the original name, so
12878                    // rename the new package here.
12879                    pkg.setPackageName(oldName);
12880                    pkgName = pkg.packageName;
12881                    replace = true;
12882                    if (DEBUG_INSTALL) Slog.d(TAG, "Replacing existing renamed package: oldName="
12883                            + oldName + " pkgName=" + pkgName);
12884                } else if (mPackages.containsKey(pkgName)) {
12885                    // This package, under its official name, already exists
12886                    // on the device; we should replace it.
12887                    replace = true;
12888                    if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing pacakge: " + pkgName);
12889                }
12890
12891                // Prevent apps opting out from runtime permissions
12892                if (replace) {
12893                    PackageParser.Package oldPackage = mPackages.get(pkgName);
12894                    final int oldTargetSdk = oldPackage.applicationInfo.targetSdkVersion;
12895                    final int newTargetSdk = pkg.applicationInfo.targetSdkVersion;
12896                    if (oldTargetSdk > Build.VERSION_CODES.LOLLIPOP_MR1
12897                            && newTargetSdk <= Build.VERSION_CODES.LOLLIPOP_MR1) {
12898                        res.setError(PackageManager.INSTALL_FAILED_PERMISSION_MODEL_DOWNGRADE,
12899                                "Package " + pkg.packageName + " new target SDK " + newTargetSdk
12900                                        + " doesn't support runtime permissions but the old"
12901                                        + " target SDK " + oldTargetSdk + " does.");
12902                        return;
12903                    }
12904                }
12905            }
12906
12907            PackageSetting ps = mSettings.mPackages.get(pkgName);
12908            if (ps != null) {
12909                if (DEBUG_INSTALL) Slog.d(TAG, "Existing package: " + ps);
12910
12911                // Quick sanity check that we're signed correctly if updating;
12912                // we'll check this again later when scanning, but we want to
12913                // bail early here before tripping over redefined permissions.
12914                if (shouldCheckUpgradeKeySetLP(ps, scanFlags)) {
12915                    if (!checkUpgradeKeySetLP(ps, pkg)) {
12916                        res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
12917                                + pkg.packageName + " upgrade keys do not match the "
12918                                + "previously installed version");
12919                        return;
12920                    }
12921                } else {
12922                    try {
12923                        verifySignaturesLP(ps, pkg);
12924                    } catch (PackageManagerException e) {
12925                        res.setError(e.error, e.getMessage());
12926                        return;
12927                    }
12928                }
12929
12930                oldCodePath = mSettings.mPackages.get(pkgName).codePathString;
12931                if (ps.pkg != null && ps.pkg.applicationInfo != null) {
12932                    systemApp = (ps.pkg.applicationInfo.flags &
12933                            ApplicationInfo.FLAG_SYSTEM) != 0;
12934                }
12935                res.origUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
12936            }
12937
12938            // Check whether the newly-scanned package wants to define an already-defined perm
12939            int N = pkg.permissions.size();
12940            for (int i = N-1; i >= 0; i--) {
12941                PackageParser.Permission perm = pkg.permissions.get(i);
12942                BasePermission bp = mSettings.mPermissions.get(perm.info.name);
12943                if (bp != null) {
12944                    // If the defining package is signed with our cert, it's okay.  This
12945                    // also includes the "updating the same package" case, of course.
12946                    // "updating same package" could also involve key-rotation.
12947                    final boolean sigsOk;
12948                    if (bp.sourcePackage.equals(pkg.packageName)
12949                            && (bp.packageSetting instanceof PackageSetting)
12950                            && (shouldCheckUpgradeKeySetLP((PackageSetting) bp.packageSetting,
12951                                    scanFlags))) {
12952                        sigsOk = checkUpgradeKeySetLP((PackageSetting) bp.packageSetting, pkg);
12953                    } else {
12954                        sigsOk = compareSignatures(bp.packageSetting.signatures.mSignatures,
12955                                pkg.mSignatures) == PackageManager.SIGNATURE_MATCH;
12956                    }
12957                    if (!sigsOk) {
12958                        // If the owning package is the system itself, we log but allow
12959                        // install to proceed; we fail the install on all other permission
12960                        // redefinitions.
12961                        if (!bp.sourcePackage.equals("android")) {
12962                            res.setError(INSTALL_FAILED_DUPLICATE_PERMISSION, "Package "
12963                                    + pkg.packageName + " attempting to redeclare permission "
12964                                    + perm.info.name + " already owned by " + bp.sourcePackage);
12965                            res.origPermission = perm.info.name;
12966                            res.origPackage = bp.sourcePackage;
12967                            return;
12968                        } else {
12969                            Slog.w(TAG, "Package " + pkg.packageName
12970                                    + " attempting to redeclare system permission "
12971                                    + perm.info.name + "; ignoring new declaration");
12972                            pkg.permissions.remove(i);
12973                        }
12974                    }
12975                }
12976            }
12977
12978        }
12979
12980        if (systemApp) {
12981            if (onExternal) {
12982                // Abort update; system app can't be replaced with app on sdcard
12983                res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
12984                        "Cannot install updates to system apps on sdcard");
12985                return;
12986            } else if (ephemeral) {
12987                // Abort update; system app can't be replaced with an ephemeral app
12988                res.setError(INSTALL_FAILED_EPHEMERAL_INVALID,
12989                        "Cannot update a system app with an ephemeral app");
12990                return;
12991            }
12992        }
12993
12994        if (args.move != null) {
12995            // We did an in-place move, so dex is ready to roll
12996            scanFlags |= SCAN_NO_DEX;
12997            scanFlags |= SCAN_MOVE;
12998
12999            synchronized (mPackages) {
13000                final PackageSetting ps = mSettings.mPackages.get(pkgName);
13001                if (ps == null) {
13002                    res.setError(INSTALL_FAILED_INTERNAL_ERROR,
13003                            "Missing settings for moved package " + pkgName);
13004                }
13005
13006                // We moved the entire application as-is, so bring over the
13007                // previously derived ABI information.
13008                pkg.applicationInfo.primaryCpuAbi = ps.primaryCpuAbiString;
13009                pkg.applicationInfo.secondaryCpuAbi = ps.secondaryCpuAbiString;
13010            }
13011
13012        } else if (!forwardLocked && !pkg.applicationInfo.isExternalAsec()) {
13013            // Enable SCAN_NO_DEX flag to skip dexopt at a later stage
13014            scanFlags |= SCAN_NO_DEX;
13015
13016            try {
13017                derivePackageAbi(pkg, new File(pkg.codePath), args.abiOverride,
13018                        true /* extract libs */);
13019            } catch (PackageManagerException pme) {
13020                Slog.e(TAG, "Error deriving application ABI", pme);
13021                res.setError(INSTALL_FAILED_INTERNAL_ERROR, "Error deriving application ABI");
13022                return;
13023            }
13024        }
13025
13026        if (!args.doRename(res.returnCode, pkg, oldCodePath)) {
13027            res.setError(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename");
13028            return;
13029        }
13030
13031        startIntentFilterVerifications(args.user.getIdentifier(), replace, pkg);
13032
13033        if (replace) {
13034            replacePackageLI(pkg, parseFlags, scanFlags | SCAN_REPLACING, args.user,
13035                    installerPackageName, volumeUuid, res);
13036        } else {
13037            installNewPackageLI(pkg, parseFlags, scanFlags | SCAN_DELETE_DATA_ON_FAILURES,
13038                    args.user, installerPackageName, volumeUuid, res);
13039        }
13040        synchronized (mPackages) {
13041            final PackageSetting ps = mSettings.mPackages.get(pkgName);
13042            if (ps != null) {
13043                res.newUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
13044            }
13045        }
13046    }
13047
13048    private void startIntentFilterVerifications(int userId, boolean replacing,
13049            PackageParser.Package pkg) {
13050        if (mIntentFilterVerifierComponent == null) {
13051            Slog.w(TAG, "No IntentFilter verification will not be done as "
13052                    + "there is no IntentFilterVerifier available!");
13053            return;
13054        }
13055
13056        final int verifierUid = getPackageUid(
13057                mIntentFilterVerifierComponent.getPackageName(),
13058                (userId == UserHandle.USER_ALL) ? UserHandle.USER_SYSTEM : userId);
13059
13060        mHandler.removeMessages(START_INTENT_FILTER_VERIFICATIONS);
13061        final Message msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS);
13062        msg.obj = new IFVerificationParams(pkg, replacing, userId, verifierUid);
13063        mHandler.sendMessage(msg);
13064    }
13065
13066    private void verifyIntentFiltersIfNeeded(int userId, int verifierUid, boolean replacing,
13067            PackageParser.Package pkg) {
13068        int size = pkg.activities.size();
13069        if (size == 0) {
13070            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
13071                    "No activity, so no need to verify any IntentFilter!");
13072            return;
13073        }
13074
13075        final boolean hasDomainURLs = hasDomainURLs(pkg);
13076        if (!hasDomainURLs) {
13077            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
13078                    "No domain URLs, so no need to verify any IntentFilter!");
13079            return;
13080        }
13081
13082        if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Checking for userId:" + userId
13083                + " if any IntentFilter from the " + size
13084                + " Activities needs verification ...");
13085
13086        int count = 0;
13087        final String packageName = pkg.packageName;
13088
13089        synchronized (mPackages) {
13090            // If this is a new install and we see that we've already run verification for this
13091            // package, we have nothing to do: it means the state was restored from backup.
13092            if (!replacing) {
13093                IntentFilterVerificationInfo ivi =
13094                        mSettings.getIntentFilterVerificationLPr(packageName);
13095                if (ivi != null) {
13096                    if (DEBUG_DOMAIN_VERIFICATION) {
13097                        Slog.i(TAG, "Package " + packageName+ " already verified: status="
13098                                + ivi.getStatusString());
13099                    }
13100                    return;
13101                }
13102            }
13103
13104            // If any filters need to be verified, then all need to be.
13105            boolean needToVerify = false;
13106            for (PackageParser.Activity a : pkg.activities) {
13107                for (ActivityIntentInfo filter : a.intents) {
13108                    if (filter.needsVerification() && needsNetworkVerificationLPr(filter)) {
13109                        if (DEBUG_DOMAIN_VERIFICATION) {
13110                            Slog.d(TAG, "Intent filter needs verification, so processing all filters");
13111                        }
13112                        needToVerify = true;
13113                        break;
13114                    }
13115                }
13116            }
13117
13118            if (needToVerify) {
13119                final int verificationId = mIntentFilterVerificationToken++;
13120                for (PackageParser.Activity a : pkg.activities) {
13121                    for (ActivityIntentInfo filter : a.intents) {
13122                        if (filter.handlesWebUris(true) && needsNetworkVerificationLPr(filter)) {
13123                            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
13124                                    "Verification needed for IntentFilter:" + filter.toString());
13125                            mIntentFilterVerifier.addOneIntentFilterVerification(
13126                                    verifierUid, userId, verificationId, filter, packageName);
13127                            count++;
13128                        }
13129                    }
13130                }
13131            }
13132        }
13133
13134        if (count > 0) {
13135            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Starting " + count
13136                    + " IntentFilter verification" + (count > 1 ? "s" : "")
13137                    +  " for userId:" + userId);
13138            mIntentFilterVerifier.startVerifications(userId);
13139        } else {
13140            if (DEBUG_DOMAIN_VERIFICATION) {
13141                Slog.d(TAG, "No filters or not all autoVerify for " + packageName);
13142            }
13143        }
13144    }
13145
13146    private boolean needsNetworkVerificationLPr(ActivityIntentInfo filter) {
13147        final ComponentName cn  = filter.activity.getComponentName();
13148        final String packageName = cn.getPackageName();
13149
13150        IntentFilterVerificationInfo ivi = mSettings.getIntentFilterVerificationLPr(
13151                packageName);
13152        if (ivi == null) {
13153            return true;
13154        }
13155        int status = ivi.getStatus();
13156        switch (status) {
13157            case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED:
13158            case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK:
13159                return true;
13160
13161            default:
13162                // Nothing to do
13163                return false;
13164        }
13165    }
13166
13167    private static boolean isMultiArch(ApplicationInfo info) {
13168        return (info.flags & ApplicationInfo.FLAG_MULTIARCH) != 0;
13169    }
13170
13171    private static boolean isExternal(PackageParser.Package pkg) {
13172        return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
13173    }
13174
13175    private static boolean isExternal(PackageSetting ps) {
13176        return (ps.pkgFlags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
13177    }
13178
13179    private static boolean isEphemeral(PackageParser.Package pkg) {
13180        return pkg.applicationInfo.isEphemeralApp();
13181    }
13182
13183    private static boolean isEphemeral(PackageSetting ps) {
13184        return ps.pkg != null && isEphemeral(ps.pkg);
13185    }
13186
13187    private static boolean isSystemApp(PackageParser.Package pkg) {
13188        return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
13189    }
13190
13191    private static boolean isPrivilegedApp(PackageParser.Package pkg) {
13192        return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0;
13193    }
13194
13195    private static boolean hasDomainURLs(PackageParser.Package pkg) {
13196        return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) != 0;
13197    }
13198
13199    private static boolean isSystemApp(PackageSetting ps) {
13200        return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0;
13201    }
13202
13203    private static boolean isUpdatedSystemApp(PackageSetting ps) {
13204        return (ps.pkgFlags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
13205    }
13206
13207    private int packageFlagsToInstallFlags(PackageSetting ps) {
13208        int installFlags = 0;
13209        if (isEphemeral(ps)) {
13210            installFlags |= PackageManager.INSTALL_EPHEMERAL;
13211        }
13212        if (isExternal(ps) && TextUtils.isEmpty(ps.volumeUuid)) {
13213            // This existing package was an external ASEC install when we have
13214            // the external flag without a UUID
13215            installFlags |= PackageManager.INSTALL_EXTERNAL;
13216        }
13217        if (ps.isForwardLocked()) {
13218            installFlags |= PackageManager.INSTALL_FORWARD_LOCK;
13219        }
13220        return installFlags;
13221    }
13222
13223    private String getVolumeUuidForPackage(PackageParser.Package pkg) {
13224        if (isExternal(pkg)) {
13225            if (TextUtils.isEmpty(pkg.volumeUuid)) {
13226                return StorageManager.UUID_PRIMARY_PHYSICAL;
13227            } else {
13228                return pkg.volumeUuid;
13229            }
13230        } else {
13231            return StorageManager.UUID_PRIVATE_INTERNAL;
13232        }
13233    }
13234
13235    private VersionInfo getSettingsVersionForPackage(PackageParser.Package pkg) {
13236        if (isExternal(pkg)) {
13237            if (TextUtils.isEmpty(pkg.volumeUuid)) {
13238                return mSettings.getExternalVersion();
13239            } else {
13240                return mSettings.findOrCreateVersion(pkg.volumeUuid);
13241            }
13242        } else {
13243            return mSettings.getInternalVersion();
13244        }
13245    }
13246
13247    private void deleteTempPackageFiles() {
13248        final FilenameFilter filter = new FilenameFilter() {
13249            public boolean accept(File dir, String name) {
13250                return name.startsWith("vmdl") && name.endsWith(".tmp");
13251            }
13252        };
13253        for (File file : mDrmAppPrivateInstallDir.listFiles(filter)) {
13254            file.delete();
13255        }
13256    }
13257
13258    @Override
13259    public void deletePackageAsUser(String packageName, IPackageDeleteObserver observer, int userId,
13260            int flags) {
13261        deletePackage(packageName, new LegacyPackageDeleteObserver(observer).getBinder(), userId,
13262                flags);
13263    }
13264
13265    @Override
13266    public void deletePackage(final String packageName,
13267            final IPackageDeleteObserver2 observer, final int userId, final int flags) {
13268        mContext.enforceCallingOrSelfPermission(
13269                android.Manifest.permission.DELETE_PACKAGES, null);
13270        Preconditions.checkNotNull(packageName);
13271        Preconditions.checkNotNull(observer);
13272        final int uid = Binder.getCallingUid();
13273        final boolean deleteAllUsers = (flags & PackageManager.DELETE_ALL_USERS) != 0;
13274        final int[] users = deleteAllUsers ? sUserManager.getUserIds() : new int[]{ userId };
13275        if (UserHandle.getUserId(uid) != userId || (deleteAllUsers && users.length > 1)) {
13276            mContext.enforceCallingOrSelfPermission(
13277                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
13278                    "deletePackage for user " + userId);
13279        }
13280
13281        if (isUserRestricted(userId, UserManager.DISALLOW_UNINSTALL_APPS)) {
13282            try {
13283                observer.onPackageDeleted(packageName,
13284                        PackageManager.DELETE_FAILED_USER_RESTRICTED, null);
13285            } catch (RemoteException re) {
13286            }
13287            return;
13288        }
13289
13290        for (int currentUserId : users) {
13291            if (getBlockUninstallForUser(packageName, currentUserId)) {
13292                try {
13293                    observer.onPackageDeleted(packageName,
13294                            PackageManager.DELETE_FAILED_OWNER_BLOCKED, null);
13295                } catch (RemoteException re) {
13296                }
13297                return;
13298            }
13299        }
13300
13301        if (DEBUG_REMOVE) {
13302            Slog.d(TAG, "deletePackageAsUser: pkg=" + packageName + " user=" + userId);
13303        }
13304        // Queue up an async operation since the package deletion may take a little while.
13305        mHandler.post(new Runnable() {
13306            public void run() {
13307                mHandler.removeCallbacks(this);
13308                final int returnCode = deletePackageX(packageName, userId, flags);
13309                try {
13310                    observer.onPackageDeleted(packageName, returnCode, null);
13311                } catch (RemoteException e) {
13312                    Log.i(TAG, "Observer no longer exists.");
13313                } //end catch
13314            } //end run
13315        });
13316    }
13317
13318    private boolean isPackageDeviceAdmin(String packageName, int userId) {
13319        IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
13320                ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
13321        try {
13322            if (dpm != null) {
13323                final ComponentName deviceOwnerComponentName = dpm.getDeviceOwnerComponent(
13324                        /* callingUserOnly =*/ false);
13325                final String deviceOwnerPackageName = deviceOwnerComponentName == null ? null
13326                        : deviceOwnerComponentName.getPackageName();
13327                // Does the package contains the device owner?
13328                // TODO Do we have to do it even if userId != UserHandle.USER_ALL?  Otherwise,
13329                // this check is probably not needed, since DO should be registered as a device
13330                // admin on some user too. (Original bug for this: b/17657954)
13331                if (packageName.equals(deviceOwnerPackageName)) {
13332                    return true;
13333                }
13334                // Does it contain a device admin for any user?
13335                int[] users;
13336                if (userId == UserHandle.USER_ALL) {
13337                    users = sUserManager.getUserIds();
13338                } else {
13339                    users = new int[]{userId};
13340                }
13341                for (int i = 0; i < users.length; ++i) {
13342                    if (dpm.packageHasActiveAdmins(packageName, users[i])) {
13343                        return true;
13344                    }
13345                }
13346            }
13347        } catch (RemoteException e) {
13348        }
13349        return false;
13350    }
13351
13352    private boolean shouldKeepUninstalledPackageLPr(String packageName) {
13353        return mKeepUninstalledPackages != null && mKeepUninstalledPackages.contains(packageName);
13354    }
13355
13356    /**
13357     *  This method is an internal method that could be get invoked either
13358     *  to delete an installed package or to clean up a failed installation.
13359     *  After deleting an installed package, a broadcast is sent to notify any
13360     *  listeners that the package has been installed. For cleaning up a failed
13361     *  installation, the broadcast is not necessary since the package's
13362     *  installation wouldn't have sent the initial broadcast either
13363     *  The key steps in deleting a package are
13364     *  deleting the package information in internal structures like mPackages,
13365     *  deleting the packages base directories through installd
13366     *  updating mSettings to reflect current status
13367     *  persisting settings for later use
13368     *  sending a broadcast if necessary
13369     */
13370    private int deletePackageX(String packageName, int userId, int flags) {
13371        final PackageRemovedInfo info = new PackageRemovedInfo();
13372        final boolean res;
13373
13374        final UserHandle removeForUser = (flags & PackageManager.DELETE_ALL_USERS) != 0
13375                ? UserHandle.ALL : new UserHandle(userId);
13376
13377        if (isPackageDeviceAdmin(packageName, removeForUser.getIdentifier())) {
13378            Slog.w(TAG, "Not removing package " + packageName + ": has active device admin");
13379            return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER;
13380        }
13381
13382        boolean removedForAllUsers = false;
13383        boolean systemUpdate = false;
13384
13385        PackageParser.Package uninstalledPkg;
13386
13387        // for the uninstall-updates case and restricted profiles, remember the per-
13388        // userhandle installed state
13389        int[] allUsers;
13390        boolean[] perUserInstalled;
13391        synchronized (mPackages) {
13392            uninstalledPkg = mPackages.get(packageName);
13393            PackageSetting ps = mSettings.mPackages.get(packageName);
13394            allUsers = sUserManager.getUserIds();
13395            perUserInstalled = new boolean[allUsers.length];
13396            for (int i = 0; i < allUsers.length; i++) {
13397                perUserInstalled[i] = ps != null ? ps.getInstalled(allUsers[i]) : false;
13398            }
13399        }
13400
13401        synchronized (mInstallLock) {
13402            if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageX: pkg=" + packageName + " user=" + userId);
13403            res = deletePackageLI(packageName, removeForUser,
13404                    true, allUsers, perUserInstalled,
13405                    flags | REMOVE_CHATTY, info, true);
13406            systemUpdate = info.isRemovedPackageSystemUpdate;
13407            synchronized (mPackages) {
13408                if (res) {
13409                    if (!systemUpdate && mPackages.get(packageName) == null) {
13410                        removedForAllUsers = true;
13411                    }
13412                    mEphemeralApplicationRegistry.onPackageUninstalledLPw(uninstalledPkg);
13413                }
13414            }
13415            if (DEBUG_REMOVE) Slog.d(TAG, "delete res: systemUpdate=" + systemUpdate
13416                    + " removedForAllUsers=" + removedForAllUsers);
13417        }
13418
13419        if (res) {
13420            info.sendBroadcast(true, systemUpdate, removedForAllUsers);
13421
13422            // If the removed package was a system update, the old system package
13423            // was re-enabled; we need to broadcast this information
13424            if (systemUpdate) {
13425                Bundle extras = new Bundle(1);
13426                extras.putInt(Intent.EXTRA_UID, info.removedAppId >= 0
13427                        ? info.removedAppId : info.uid);
13428                extras.putBoolean(Intent.EXTRA_REPLACING, true);
13429
13430                sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
13431                        extras, 0, null, null, null);
13432                sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, packageName,
13433                        extras, 0, null, null, null);
13434                sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, null,
13435                        null, 0, packageName, null, null);
13436            }
13437        }
13438        // Force a gc here.
13439        Runtime.getRuntime().gc();
13440        // Delete the resources here after sending the broadcast to let
13441        // other processes clean up before deleting resources.
13442        if (info.args != null) {
13443            synchronized (mInstallLock) {
13444                info.args.doPostDeleteLI(true);
13445            }
13446        }
13447
13448        return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR;
13449    }
13450
13451    class PackageRemovedInfo {
13452        String removedPackage;
13453        int uid = -1;
13454        int removedAppId = -1;
13455        int[] removedUsers = null;
13456        boolean isRemovedPackageSystemUpdate = false;
13457        // Clean up resources deleted packages.
13458        InstallArgs args = null;
13459
13460        void sendBroadcast(boolean fullRemove, boolean replacing, boolean removedForAllUsers) {
13461            Bundle extras = new Bundle(1);
13462            extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid);
13463            extras.putBoolean(Intent.EXTRA_DATA_REMOVED, fullRemove);
13464            if (replacing) {
13465                extras.putBoolean(Intent.EXTRA_REPLACING, true);
13466            }
13467            extras.putBoolean(Intent.EXTRA_REMOVED_FOR_ALL_USERS, removedForAllUsers);
13468            if (removedPackage != null) {
13469                sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED, removedPackage,
13470                        extras, 0, null, null, removedUsers);
13471                if (fullRemove && !replacing) {
13472                    sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED, removedPackage,
13473                            extras, 0, null, null, removedUsers);
13474                }
13475            }
13476            if (removedAppId >= 0) {
13477                sendPackageBroadcast(Intent.ACTION_UID_REMOVED, null, extras, 0, null, null,
13478                        removedUsers);
13479            }
13480        }
13481    }
13482
13483    /*
13484     * This method deletes the package from internal data structures. If the DONT_DELETE_DATA
13485     * flag is not set, the data directory is removed as well.
13486     * make sure this flag is set for partially installed apps. If not its meaningless to
13487     * delete a partially installed application.
13488     */
13489    private void removePackageDataLI(PackageSetting ps,
13490            int[] allUserHandles, boolean[] perUserInstalled,
13491            PackageRemovedInfo outInfo, int flags, boolean writeSettings) {
13492        String packageName = ps.name;
13493        if (DEBUG_REMOVE) Slog.d(TAG, "removePackageDataLI: " + ps);
13494        removePackageLI(ps, (flags&REMOVE_CHATTY) != 0);
13495        // Retrieve object to delete permissions for shared user later on
13496        final PackageSetting deletedPs;
13497        // reader
13498        synchronized (mPackages) {
13499            deletedPs = mSettings.mPackages.get(packageName);
13500            if (outInfo != null) {
13501                outInfo.removedPackage = packageName;
13502                outInfo.removedUsers = deletedPs != null
13503                        ? deletedPs.queryInstalledUsers(sUserManager.getUserIds(), true)
13504                        : null;
13505            }
13506        }
13507        if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) {
13508            removeDataDirsLI(ps.volumeUuid, packageName);
13509            schedulePackageCleaning(packageName, UserHandle.USER_ALL, true);
13510        }
13511        // writer
13512        synchronized (mPackages) {
13513            if (deletedPs != null) {
13514                if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) {
13515                    clearIntentFilterVerificationsLPw(deletedPs.name, UserHandle.USER_ALL);
13516                    clearDefaultBrowserIfNeeded(packageName);
13517                    if (outInfo != null) {
13518                        mSettings.mKeySetManagerService.removeAppKeySetDataLPw(packageName);
13519                        outInfo.removedAppId = mSettings.removePackageLPw(packageName);
13520                    }
13521                    updatePermissionsLPw(deletedPs.name, null, 0);
13522                    if (deletedPs.sharedUser != null) {
13523                        // Remove permissions associated with package. Since runtime
13524                        // permissions are per user we have to kill the removed package
13525                        // or packages running under the shared user of the removed
13526                        // package if revoking the permissions requested only by the removed
13527                        // package is successful and this causes a change in gids.
13528                        for (int userId : UserManagerService.getInstance().getUserIds()) {
13529                            final int userIdToKill = mSettings.updateSharedUserPermsLPw(deletedPs,
13530                                    userId);
13531                            if (userIdToKill == UserHandle.USER_ALL
13532                                    || userIdToKill >= UserHandle.USER_SYSTEM) {
13533                                // If gids changed for this user, kill all affected packages.
13534                                mHandler.post(new Runnable() {
13535                                    @Override
13536                                    public void run() {
13537                                        // This has to happen with no lock held.
13538                                        killApplication(deletedPs.name, deletedPs.appId,
13539                                                KILL_APP_REASON_GIDS_CHANGED);
13540                                    }
13541                                });
13542                                break;
13543                            }
13544                        }
13545                    }
13546                    clearPackagePreferredActivitiesLPw(deletedPs.name, UserHandle.USER_ALL);
13547                }
13548                // make sure to preserve per-user disabled state if this removal was just
13549                // a downgrade of a system app to the factory package
13550                if (allUserHandles != null && perUserInstalled != null) {
13551                    if (DEBUG_REMOVE) {
13552                        Slog.d(TAG, "Propagating install state across downgrade");
13553                    }
13554                    for (int i = 0; i < allUserHandles.length; i++) {
13555                        if (DEBUG_REMOVE) {
13556                            Slog.d(TAG, "    user " + allUserHandles[i]
13557                                    + " => " + perUserInstalled[i]);
13558                        }
13559                        ps.setInstalled(perUserInstalled[i], allUserHandles[i]);
13560                    }
13561                }
13562            }
13563            // can downgrade to reader
13564            if (writeSettings) {
13565                // Save settings now
13566                mSettings.writeLPr();
13567            }
13568        }
13569        if (outInfo != null) {
13570            // A user ID was deleted here. Go through all users and remove it
13571            // from KeyStore.
13572            removeKeystoreDataIfNeeded(UserHandle.USER_ALL, outInfo.removedAppId);
13573        }
13574    }
13575
13576    static boolean locationIsPrivileged(File path) {
13577        try {
13578            final String privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app")
13579                    .getCanonicalPath();
13580            return path.getCanonicalPath().startsWith(privilegedAppDir);
13581        } catch (IOException e) {
13582            Slog.e(TAG, "Unable to access code path " + path);
13583        }
13584        return false;
13585    }
13586
13587    /*
13588     * Tries to delete system package.
13589     */
13590    private boolean deleteSystemPackageLI(PackageSetting newPs,
13591            int[] allUserHandles, boolean[] perUserInstalled,
13592            int flags, PackageRemovedInfo outInfo, boolean writeSettings) {
13593        final boolean applyUserRestrictions
13594                = (allUserHandles != null) && (perUserInstalled != null);
13595        PackageSetting disabledPs = null;
13596        // Confirm if the system package has been updated
13597        // An updated system app can be deleted. This will also have to restore
13598        // the system pkg from system partition
13599        // reader
13600        synchronized (mPackages) {
13601            disabledPs = mSettings.getDisabledSystemPkgLPr(newPs.name);
13602        }
13603        if (DEBUG_REMOVE) Slog.d(TAG, "deleteSystemPackageLI: newPs=" + newPs
13604                + " disabledPs=" + disabledPs);
13605        if (disabledPs == null) {
13606            Slog.w(TAG, "Attempt to delete unknown system package "+ newPs.name);
13607            return false;
13608        } else if (DEBUG_REMOVE) {
13609            Slog.d(TAG, "Deleting system pkg from data partition");
13610        }
13611        if (DEBUG_REMOVE) {
13612            if (applyUserRestrictions) {
13613                Slog.d(TAG, "Remembering install states:");
13614                for (int i = 0; i < allUserHandles.length; i++) {
13615                    Slog.d(TAG, "   u=" + allUserHandles[i] + " inst=" + perUserInstalled[i]);
13616                }
13617            }
13618        }
13619        // Delete the updated package
13620        outInfo.isRemovedPackageSystemUpdate = true;
13621        if (disabledPs.versionCode < newPs.versionCode) {
13622            // Delete data for downgrades
13623            flags &= ~PackageManager.DELETE_KEEP_DATA;
13624        } else {
13625            // Preserve data by setting flag
13626            flags |= PackageManager.DELETE_KEEP_DATA;
13627        }
13628        boolean ret = deleteInstalledPackageLI(newPs, true, flags,
13629                allUserHandles, perUserInstalled, outInfo, writeSettings);
13630        if (!ret) {
13631            return false;
13632        }
13633        // writer
13634        synchronized (mPackages) {
13635            // Reinstate the old system package
13636            mSettings.enableSystemPackageLPw(newPs.name);
13637            // Remove any native libraries from the upgraded package.
13638            NativeLibraryHelper.removeNativeBinariesLI(newPs.legacyNativeLibraryPathString);
13639        }
13640        // Install the system package
13641        if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs);
13642        int parseFlags = PackageParser.PARSE_MUST_BE_APK | PackageParser.PARSE_IS_SYSTEM;
13643        if (locationIsPrivileged(disabledPs.codePath)) {
13644            parseFlags |= PackageParser.PARSE_IS_PRIVILEGED;
13645        }
13646
13647        final PackageParser.Package newPkg;
13648        try {
13649            newPkg = scanPackageTracedLI(disabledPs.codePath, parseFlags, SCAN_NO_PATHS, 0, null);
13650        } catch (PackageManagerException e) {
13651            Slog.w(TAG, "Failed to restore system package " + newPs.name + ": " + e.getMessage());
13652            return false;
13653        }
13654
13655        // writer
13656        synchronized (mPackages) {
13657            PackageSetting ps = mSettings.mPackages.get(newPkg.packageName);
13658
13659            // Propagate the permissions state as we do not want to drop on the floor
13660            // runtime permissions. The update permissions method below will take
13661            // care of removing obsolete permissions and grant install permissions.
13662            ps.getPermissionsState().copyFrom(newPs.getPermissionsState());
13663            updatePermissionsLPw(newPkg.packageName, newPkg,
13664                    UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG);
13665
13666            if (applyUserRestrictions) {
13667                if (DEBUG_REMOVE) {
13668                    Slog.d(TAG, "Propagating install state across reinstall");
13669                }
13670                for (int i = 0; i < allUserHandles.length; i++) {
13671                    if (DEBUG_REMOVE) {
13672                        Slog.d(TAG, "    user " + allUserHandles[i]
13673                                + " => " + perUserInstalled[i]);
13674                    }
13675                    ps.setInstalled(perUserInstalled[i], allUserHandles[i]);
13676
13677                    mSettings.writeRuntimePermissionsForUserLPr(allUserHandles[i], false);
13678                }
13679                // Regardless of writeSettings we need to ensure that this restriction
13680                // state propagation is persisted
13681                mSettings.writeAllUsersPackageRestrictionsLPr();
13682            }
13683            // can downgrade to reader here
13684            if (writeSettings) {
13685                mSettings.writeLPr();
13686            }
13687        }
13688        return true;
13689    }
13690
13691    private boolean deleteInstalledPackageLI(PackageSetting ps,
13692            boolean deleteCodeAndResources, int flags,
13693            int[] allUserHandles, boolean[] perUserInstalled,
13694            PackageRemovedInfo outInfo, boolean writeSettings) {
13695        if (outInfo != null) {
13696            outInfo.uid = ps.appId;
13697        }
13698
13699        // Delete package data from internal structures and also remove data if flag is set
13700        removePackageDataLI(ps, allUserHandles, perUserInstalled, outInfo, flags, writeSettings);
13701
13702        // Delete application code and resources
13703        if (deleteCodeAndResources && (outInfo != null)) {
13704            outInfo.args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
13705                    ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
13706            if (DEBUG_SD_INSTALL) Slog.i(TAG, "args=" + outInfo.args);
13707        }
13708        return true;
13709    }
13710
13711    @Override
13712    public boolean setBlockUninstallForUser(String packageName, boolean blockUninstall,
13713            int userId) {
13714        mContext.enforceCallingOrSelfPermission(
13715                android.Manifest.permission.DELETE_PACKAGES, null);
13716        synchronized (mPackages) {
13717            PackageSetting ps = mSettings.mPackages.get(packageName);
13718            if (ps == null) {
13719                Log.i(TAG, "Package doesn't exist in set block uninstall " + packageName);
13720                return false;
13721            }
13722            if (!ps.getInstalled(userId)) {
13723                // Can't block uninstall for an app that is not installed or enabled.
13724                Log.i(TAG, "Package not installed in set block uninstall " + packageName);
13725                return false;
13726            }
13727            ps.setBlockUninstall(blockUninstall, userId);
13728            mSettings.writePackageRestrictionsLPr(userId);
13729        }
13730        return true;
13731    }
13732
13733    @Override
13734    public boolean getBlockUninstallForUser(String packageName, int userId) {
13735        synchronized (mPackages) {
13736            PackageSetting ps = mSettings.mPackages.get(packageName);
13737            if (ps == null) {
13738                Log.i(TAG, "Package doesn't exist in get block uninstall " + packageName);
13739                return false;
13740            }
13741            return ps.getBlockUninstall(userId);
13742        }
13743    }
13744
13745    @Override
13746    public boolean setRequiredForSystemUser(String packageName, boolean systemUserApp) {
13747        int callingUid = Binder.getCallingUid();
13748        if (callingUid != Process.SYSTEM_UID && callingUid != Process.ROOT_UID) {
13749            throw new SecurityException(
13750                    "setRequiredForSystemUser can only be run by the system or root");
13751        }
13752        synchronized (mPackages) {
13753            PackageSetting ps = mSettings.mPackages.get(packageName);
13754            if (ps == null) {
13755                Log.w(TAG, "Package doesn't exist: " + packageName);
13756                return false;
13757            }
13758            if (systemUserApp) {
13759                ps.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER;
13760            } else {
13761                ps.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER;
13762            }
13763            mSettings.writeLPr();
13764        }
13765        return true;
13766    }
13767
13768    /*
13769     * This method handles package deletion in general
13770     */
13771    private boolean deletePackageLI(String packageName, UserHandle user,
13772            boolean deleteCodeAndResources, int[] allUserHandles, boolean[] perUserInstalled,
13773            int flags, PackageRemovedInfo outInfo,
13774            boolean writeSettings) {
13775        if (packageName == null) {
13776            Slog.w(TAG, "Attempt to delete null packageName.");
13777            return false;
13778        }
13779        if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: " + packageName + " user " + user);
13780        PackageSetting ps;
13781        boolean dataOnly = false;
13782        int removeUser = -1;
13783        int appId = -1;
13784        synchronized (mPackages) {
13785            ps = mSettings.mPackages.get(packageName);
13786            if (ps == null) {
13787                Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
13788                return false;
13789            }
13790            if ((!isSystemApp(ps) || (flags&PackageManager.DELETE_SYSTEM_APP) != 0) && user != null
13791                    && user.getIdentifier() != UserHandle.USER_ALL) {
13792                // The caller is asking that the package only be deleted for a single
13793                // user.  To do this, we just mark its uninstalled state and delete
13794                // its data.  If this is a system app, we only allow this to happen if
13795                // they have set the special DELETE_SYSTEM_APP which requests different
13796                // semantics than normal for uninstalling system apps.
13797                if (DEBUG_REMOVE) Slog.d(TAG, "Only deleting for single user");
13798                final int userId = user.getIdentifier();
13799                ps.setUserState(userId,
13800                        COMPONENT_ENABLED_STATE_DEFAULT,
13801                        false, //installed
13802                        true,  //stopped
13803                        true,  //notLaunched
13804                        false, //hidden
13805                        false, //suspended
13806                        null, null, null,
13807                        false, // blockUninstall
13808                        ps.readUserState(userId).domainVerificationStatus, 0);
13809                if (!isSystemApp(ps)) {
13810                    // Do not uninstall the APK if an app should be cached
13811                    boolean keepUninstalledPackage = shouldKeepUninstalledPackageLPr(packageName);
13812                    if (ps.isAnyInstalled(sUserManager.getUserIds()) || keepUninstalledPackage) {
13813                        // Other user still have this package installed, so all
13814                        // we need to do is clear this user's data and save that
13815                        // it is uninstalled.
13816                        if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users");
13817                        removeUser = user.getIdentifier();
13818                        appId = ps.appId;
13819                        scheduleWritePackageRestrictionsLocked(removeUser);
13820                    } else {
13821                        // We need to set it back to 'installed' so the uninstall
13822                        // broadcasts will be sent correctly.
13823                        if (DEBUG_REMOVE) Slog.d(TAG, "Not installed by other users, full delete");
13824                        ps.setInstalled(true, user.getIdentifier());
13825                    }
13826                } else {
13827                    // This is a system app, so we assume that the
13828                    // other users still have this package installed, so all
13829                    // we need to do is clear this user's data and save that
13830                    // it is uninstalled.
13831                    if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app");
13832                    removeUser = user.getIdentifier();
13833                    appId = ps.appId;
13834                    scheduleWritePackageRestrictionsLocked(removeUser);
13835                }
13836            }
13837        }
13838
13839        if (removeUser >= 0) {
13840            // From above, we determined that we are deleting this only
13841            // for a single user.  Continue the work here.
13842            if (DEBUG_REMOVE) Slog.d(TAG, "Updating install state for user: " + removeUser);
13843            if (outInfo != null) {
13844                outInfo.removedPackage = packageName;
13845                outInfo.removedAppId = appId;
13846                outInfo.removedUsers = new int[] {removeUser};
13847            }
13848            mInstaller.clearUserData(ps.volumeUuid, packageName, removeUser);
13849            removeKeystoreDataIfNeeded(removeUser, appId);
13850            schedulePackageCleaning(packageName, removeUser, false);
13851            synchronized (mPackages) {
13852                if (clearPackagePreferredActivitiesLPw(packageName, removeUser)) {
13853                    scheduleWritePackageRestrictionsLocked(removeUser);
13854                }
13855                resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, removeUser);
13856            }
13857            return true;
13858        }
13859
13860        if (dataOnly) {
13861            // Delete application data first
13862            if (DEBUG_REMOVE) Slog.d(TAG, "Removing package data only");
13863            removePackageDataLI(ps, null, null, outInfo, flags, writeSettings);
13864            return true;
13865        }
13866
13867        boolean ret = false;
13868        if (isSystemApp(ps)) {
13869            if (DEBUG_REMOVE) Slog.d(TAG, "Removing system package: " + ps.name);
13870            // When an updated system application is deleted we delete the existing resources as well and
13871            // fall back to existing code in system partition
13872            ret = deleteSystemPackageLI(ps, allUserHandles, perUserInstalled,
13873                    flags, outInfo, writeSettings);
13874        } else {
13875            if (DEBUG_REMOVE) Slog.d(TAG, "Removing non-system package: " + ps.name);
13876            // Kill application pre-emptively especially for apps on sd.
13877            killApplication(packageName, ps.appId, "uninstall pkg");
13878            ret = deleteInstalledPackageLI(ps, deleteCodeAndResources, flags,
13879                    allUserHandles, perUserInstalled,
13880                    outInfo, writeSettings);
13881        }
13882
13883        return ret;
13884    }
13885
13886    private final static class ClearStorageConnection implements ServiceConnection {
13887        IMediaContainerService mContainerService;
13888
13889        @Override
13890        public void onServiceConnected(ComponentName name, IBinder service) {
13891            synchronized (this) {
13892                mContainerService = IMediaContainerService.Stub.asInterface(service);
13893                notifyAll();
13894            }
13895        }
13896
13897        @Override
13898        public void onServiceDisconnected(ComponentName name) {
13899        }
13900    }
13901
13902    private void clearExternalStorageDataSync(String packageName, int userId, boolean allData) {
13903        final boolean mounted;
13904        if (Environment.isExternalStorageEmulated()) {
13905            mounted = true;
13906        } else {
13907            final String status = Environment.getExternalStorageState();
13908
13909            mounted = status.equals(Environment.MEDIA_MOUNTED)
13910                    || status.equals(Environment.MEDIA_MOUNTED_READ_ONLY);
13911        }
13912
13913        if (!mounted) {
13914            return;
13915        }
13916
13917        final Intent containerIntent = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
13918        int[] users;
13919        if (userId == UserHandle.USER_ALL) {
13920            users = sUserManager.getUserIds();
13921        } else {
13922            users = new int[] { userId };
13923        }
13924        final ClearStorageConnection conn = new ClearStorageConnection();
13925        if (mContext.bindServiceAsUser(
13926                containerIntent, conn, Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) {
13927            try {
13928                for (int curUser : users) {
13929                    long timeout = SystemClock.uptimeMillis() + 5000;
13930                    synchronized (conn) {
13931                        long now = SystemClock.uptimeMillis();
13932                        while (conn.mContainerService == null && now < timeout) {
13933                            try {
13934                                conn.wait(timeout - now);
13935                            } catch (InterruptedException e) {
13936                            }
13937                        }
13938                    }
13939                    if (conn.mContainerService == null) {
13940                        return;
13941                    }
13942
13943                    final UserEnvironment userEnv = new UserEnvironment(curUser);
13944                    clearDirectory(conn.mContainerService,
13945                            userEnv.buildExternalStorageAppCacheDirs(packageName));
13946                    if (allData) {
13947                        clearDirectory(conn.mContainerService,
13948                                userEnv.buildExternalStorageAppDataDirs(packageName));
13949                        clearDirectory(conn.mContainerService,
13950                                userEnv.buildExternalStorageAppMediaDirs(packageName));
13951                    }
13952                }
13953            } finally {
13954                mContext.unbindService(conn);
13955            }
13956        }
13957    }
13958
13959    @Override
13960    public void clearApplicationUserData(final String packageName,
13961            final IPackageDataObserver observer, final int userId) {
13962        mContext.enforceCallingOrSelfPermission(
13963                android.Manifest.permission.CLEAR_APP_USER_DATA, null);
13964        enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, "clear application data");
13965        // Queue up an async operation since the package deletion may take a little while.
13966        mHandler.post(new Runnable() {
13967            public void run() {
13968                mHandler.removeCallbacks(this);
13969                final boolean succeeded;
13970                synchronized (mInstallLock) {
13971                    succeeded = clearApplicationUserDataLI(packageName, userId);
13972                }
13973                clearExternalStorageDataSync(packageName, userId, true);
13974                if (succeeded) {
13975                    // invoke DeviceStorageMonitor's update method to clear any notifications
13976                    DeviceStorageMonitorInternal
13977                            dsm = LocalServices.getService(DeviceStorageMonitorInternal.class);
13978                    if (dsm != null) {
13979                        dsm.checkMemory();
13980                    }
13981                }
13982                if(observer != null) {
13983                    try {
13984                        observer.onRemoveCompleted(packageName, succeeded);
13985                    } catch (RemoteException e) {
13986                        Log.i(TAG, "Observer no longer exists.");
13987                    }
13988                } //end if observer
13989            } //end run
13990        });
13991    }
13992
13993    private boolean clearApplicationUserDataLI(String packageName, int userId) {
13994        if (packageName == null) {
13995            Slog.w(TAG, "Attempt to delete null packageName.");
13996            return false;
13997        }
13998
13999        // Try finding details about the requested package
14000        PackageParser.Package pkg;
14001        synchronized (mPackages) {
14002            pkg = mPackages.get(packageName);
14003            if (pkg == null) {
14004                final PackageSetting ps = mSettings.mPackages.get(packageName);
14005                if (ps != null) {
14006                    pkg = ps.pkg;
14007                }
14008            }
14009
14010            if (pkg == null) {
14011                Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
14012                return false;
14013            }
14014
14015            PackageSetting ps = (PackageSetting) pkg.mExtras;
14016            resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
14017        }
14018
14019        // Always delete data directories for package, even if we found no other
14020        // record of app. This helps users recover from UID mismatches without
14021        // resorting to a full data wipe.
14022        int retCode = mInstaller.clearUserData(pkg.volumeUuid, packageName, userId);
14023        if (retCode < 0) {
14024            Slog.w(TAG, "Couldn't remove cache files for package " + packageName);
14025            return false;
14026        }
14027
14028        final int appId = pkg.applicationInfo.uid;
14029        removeKeystoreDataIfNeeded(userId, appId);
14030
14031        // Create a native library symlink only if we have native libraries
14032        // and if the native libraries are 32 bit libraries. We do not provide
14033        // this symlink for 64 bit libraries.
14034        if (pkg.applicationInfo.primaryCpuAbi != null &&
14035                !VMRuntime.is64BitAbi(pkg.applicationInfo.primaryCpuAbi)) {
14036            final String nativeLibPath = pkg.applicationInfo.nativeLibraryDir;
14037            if (mInstaller.linkNativeLibraryDirectory(pkg.volumeUuid, pkg.packageName,
14038                    nativeLibPath, userId) < 0) {
14039                Slog.w(TAG, "Failed linking native library dir");
14040                return false;
14041            }
14042        }
14043
14044        return true;
14045    }
14046
14047    /**
14048     * Reverts user permission state changes (permissions and flags) in
14049     * all packages for a given user.
14050     *
14051     * @param userId The device user for which to do a reset.
14052     */
14053    private void resetUserChangesToRuntimePermissionsAndFlagsLPw(int userId) {
14054        final int packageCount = mPackages.size();
14055        for (int i = 0; i < packageCount; i++) {
14056            PackageParser.Package pkg = mPackages.valueAt(i);
14057            PackageSetting ps = (PackageSetting) pkg.mExtras;
14058            resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
14059        }
14060    }
14061
14062    /**
14063     * Reverts user permission state changes (permissions and flags).
14064     *
14065     * @param ps The package for which to reset.
14066     * @param userId The device user for which to do a reset.
14067     */
14068    private void resetUserChangesToRuntimePermissionsAndFlagsLPw(
14069            final PackageSetting ps, final int userId) {
14070        if (ps.pkg == null) {
14071            return;
14072        }
14073
14074        // These are flags that can change base on user actions.
14075        final int userSettableMask = FLAG_PERMISSION_USER_SET
14076                | FLAG_PERMISSION_USER_FIXED
14077                | FLAG_PERMISSION_REVOKE_ON_UPGRADE
14078                | FLAG_PERMISSION_REVIEW_REQUIRED;
14079
14080        final int policyOrSystemFlags = FLAG_PERMISSION_SYSTEM_FIXED
14081                | FLAG_PERMISSION_POLICY_FIXED;
14082
14083        boolean writeInstallPermissions = false;
14084        boolean writeRuntimePermissions = false;
14085
14086        final int permissionCount = ps.pkg.requestedPermissions.size();
14087        for (int i = 0; i < permissionCount; i++) {
14088            String permission = ps.pkg.requestedPermissions.get(i);
14089
14090            BasePermission bp = mSettings.mPermissions.get(permission);
14091            if (bp == null) {
14092                continue;
14093            }
14094
14095            // If shared user we just reset the state to which only this app contributed.
14096            if (ps.sharedUser != null) {
14097                boolean used = false;
14098                final int packageCount = ps.sharedUser.packages.size();
14099                for (int j = 0; j < packageCount; j++) {
14100                    PackageSetting pkg = ps.sharedUser.packages.valueAt(j);
14101                    if (pkg.pkg != null && !pkg.pkg.packageName.equals(ps.pkg.packageName)
14102                            && pkg.pkg.requestedPermissions.contains(permission)) {
14103                        used = true;
14104                        break;
14105                    }
14106                }
14107                if (used) {
14108                    continue;
14109                }
14110            }
14111
14112            PermissionsState permissionsState = ps.getPermissionsState();
14113
14114            final int oldFlags = permissionsState.getPermissionFlags(bp.name, userId);
14115
14116            // Always clear the user settable flags.
14117            final boolean hasInstallState = permissionsState.getInstallPermissionState(
14118                    bp.name) != null;
14119            // If permission review is enabled and this is a legacy app, mark the
14120            // permission as requiring a review as this is the initial state.
14121            int flags = 0;
14122            if (Build.PERMISSIONS_REVIEW_REQUIRED
14123                    && ps.pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
14124                flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
14125            }
14126            if (permissionsState.updatePermissionFlags(bp, userId, userSettableMask, flags)) {
14127                if (hasInstallState) {
14128                    writeInstallPermissions = true;
14129                } else {
14130                    writeRuntimePermissions = true;
14131                }
14132            }
14133
14134            // Below is only runtime permission handling.
14135            if (!bp.isRuntime()) {
14136                continue;
14137            }
14138
14139            // Never clobber system or policy.
14140            if ((oldFlags & policyOrSystemFlags) != 0) {
14141                continue;
14142            }
14143
14144            // If this permission was granted by default, make sure it is.
14145            if ((oldFlags & FLAG_PERMISSION_GRANTED_BY_DEFAULT) != 0) {
14146                if (permissionsState.grantRuntimePermission(bp, userId)
14147                        != PERMISSION_OPERATION_FAILURE) {
14148                    writeRuntimePermissions = true;
14149                }
14150            // If permission review is enabled the permissions for a legacy apps
14151            // are represented as constantly granted runtime ones, so don't revoke.
14152            } else if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) {
14153                // Otherwise, reset the permission.
14154                final int revokeResult = permissionsState.revokeRuntimePermission(bp, userId);
14155                switch (revokeResult) {
14156                    case PERMISSION_OPERATION_SUCCESS: {
14157                        writeRuntimePermissions = true;
14158                    } break;
14159
14160                    case PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
14161                        writeRuntimePermissions = true;
14162                        final int appId = ps.appId;
14163                        mHandler.post(new Runnable() {
14164                            @Override
14165                            public void run() {
14166                                killUid(appId, userId, KILL_APP_REASON_GIDS_CHANGED);
14167                            }
14168                        });
14169                    } break;
14170                }
14171            }
14172        }
14173
14174        // Synchronously write as we are taking permissions away.
14175        if (writeRuntimePermissions) {
14176            mSettings.writeRuntimePermissionsForUserLPr(userId, true);
14177        }
14178
14179        // Synchronously write as we are taking permissions away.
14180        if (writeInstallPermissions) {
14181            mSettings.writeLPr();
14182        }
14183    }
14184
14185    /**
14186     * Remove entries from the keystore daemon. Will only remove it if the
14187     * {@code appId} is valid.
14188     */
14189    private static void removeKeystoreDataIfNeeded(int userId, int appId) {
14190        if (appId < 0) {
14191            return;
14192        }
14193
14194        final KeyStore keyStore = KeyStore.getInstance();
14195        if (keyStore != null) {
14196            if (userId == UserHandle.USER_ALL) {
14197                for (final int individual : sUserManager.getUserIds()) {
14198                    keyStore.clearUid(UserHandle.getUid(individual, appId));
14199                }
14200            } else {
14201                keyStore.clearUid(UserHandle.getUid(userId, appId));
14202            }
14203        } else {
14204            Slog.w(TAG, "Could not contact keystore to clear entries for app id " + appId);
14205        }
14206    }
14207
14208    @Override
14209    public void deleteApplicationCacheFiles(final String packageName,
14210            final IPackageDataObserver observer) {
14211        mContext.enforceCallingOrSelfPermission(
14212                android.Manifest.permission.DELETE_CACHE_FILES, null);
14213        // Queue up an async operation since the package deletion may take a little while.
14214        final int userId = UserHandle.getCallingUserId();
14215        mHandler.post(new Runnable() {
14216            public void run() {
14217                mHandler.removeCallbacks(this);
14218                final boolean succeded;
14219                synchronized (mInstallLock) {
14220                    succeded = deleteApplicationCacheFilesLI(packageName, userId);
14221                }
14222                clearExternalStorageDataSync(packageName, userId, false);
14223                if (observer != null) {
14224                    try {
14225                        observer.onRemoveCompleted(packageName, succeded);
14226                    } catch (RemoteException e) {
14227                        Log.i(TAG, "Observer no longer exists.");
14228                    }
14229                } //end if observer
14230            } //end run
14231        });
14232    }
14233
14234    private boolean deleteApplicationCacheFilesLI(String packageName, int userId) {
14235        if (packageName == null) {
14236            Slog.w(TAG, "Attempt to delete null packageName.");
14237            return false;
14238        }
14239        PackageParser.Package p;
14240        synchronized (mPackages) {
14241            p = mPackages.get(packageName);
14242        }
14243        if (p == null) {
14244            Slog.w(TAG, "Package named '" + packageName +"' doesn't exist.");
14245            return false;
14246        }
14247        final ApplicationInfo applicationInfo = p.applicationInfo;
14248        if (applicationInfo == null) {
14249            Slog.w(TAG, "Package " + packageName + " has no applicationInfo.");
14250            return false;
14251        }
14252        int retCode = mInstaller.deleteCacheFiles(p.volumeUuid, packageName, userId);
14253        if (retCode < 0) {
14254            Slog.w(TAG, "Couldn't remove cache files for package "
14255                       + packageName + " u" + userId);
14256            return false;
14257        }
14258        return true;
14259    }
14260
14261    @Override
14262    public void getPackageSizeInfo(final String packageName, int userHandle,
14263            final IPackageStatsObserver observer) {
14264        mContext.enforceCallingOrSelfPermission(
14265                android.Manifest.permission.GET_PACKAGE_SIZE, null);
14266        if (packageName == null) {
14267            throw new IllegalArgumentException("Attempt to get size of null packageName");
14268        }
14269
14270        PackageStats stats = new PackageStats(packageName, userHandle);
14271
14272        /*
14273         * Queue up an async operation since the package measurement may take a
14274         * little while.
14275         */
14276        Message msg = mHandler.obtainMessage(INIT_COPY);
14277        msg.obj = new MeasureParams(stats, observer);
14278        mHandler.sendMessage(msg);
14279    }
14280
14281    private boolean getPackageSizeInfoLI(String packageName, int userHandle,
14282            PackageStats pStats) {
14283        if (packageName == null) {
14284            Slog.w(TAG, "Attempt to get size of null packageName.");
14285            return false;
14286        }
14287        PackageParser.Package p;
14288        boolean dataOnly = false;
14289        String libDirRoot = null;
14290        String asecPath = null;
14291        PackageSetting ps = null;
14292        synchronized (mPackages) {
14293            p = mPackages.get(packageName);
14294            ps = mSettings.mPackages.get(packageName);
14295            if(p == null) {
14296                dataOnly = true;
14297                if((ps == null) || (ps.pkg == null)) {
14298                    Slog.w(TAG, "Package named '" + packageName +"' doesn't exist.");
14299                    return false;
14300                }
14301                p = ps.pkg;
14302            }
14303            if (ps != null) {
14304                libDirRoot = ps.legacyNativeLibraryPathString;
14305            }
14306            if (p != null && (p.isForwardLocked() || p.applicationInfo.isExternalAsec())) {
14307                final long token = Binder.clearCallingIdentity();
14308                try {
14309                    String secureContainerId = cidFromCodePath(p.applicationInfo.getBaseCodePath());
14310                    if (secureContainerId != null) {
14311                        asecPath = PackageHelper.getSdFilesystem(secureContainerId);
14312                    }
14313                } finally {
14314                    Binder.restoreCallingIdentity(token);
14315                }
14316            }
14317        }
14318        String publicSrcDir = null;
14319        if(!dataOnly) {
14320            final ApplicationInfo applicationInfo = p.applicationInfo;
14321            if (applicationInfo == null) {
14322                Slog.w(TAG, "Package " + packageName + " has no applicationInfo.");
14323                return false;
14324            }
14325            if (p.isForwardLocked()) {
14326                publicSrcDir = applicationInfo.getBaseResourcePath();
14327            }
14328        }
14329        // TODO: extend to measure size of split APKs
14330        // TODO(multiArch): Extend getSizeInfo to look at the full subdirectory tree,
14331        // not just the first level.
14332        // TODO(multiArch): Extend getSizeInfo to look at *all* instruction sets, not
14333        // just the primary.
14334        String[] dexCodeInstructionSets = getDexCodeInstructionSets(getAppDexInstructionSets(ps));
14335
14336        String apkPath;
14337        File packageDir = new File(p.codePath);
14338
14339        if (packageDir.isDirectory() && p.canHaveOatDir()) {
14340            apkPath = packageDir.getAbsolutePath();
14341            // If libDirRoot is inside a package dir, set it to null to avoid it being counted twice
14342            if (libDirRoot != null && libDirRoot.startsWith(apkPath)) {
14343                libDirRoot = null;
14344            }
14345        } else {
14346            apkPath = p.baseCodePath;
14347        }
14348
14349        int res = mInstaller.getSizeInfo(p.volumeUuid, packageName, userHandle, apkPath,
14350                libDirRoot, publicSrcDir, asecPath, dexCodeInstructionSets, pStats);
14351        if (res < 0) {
14352            return false;
14353        }
14354
14355        // Fix-up for forward-locked applications in ASEC containers.
14356        if (!isExternal(p)) {
14357            pStats.codeSize += pStats.externalCodeSize;
14358            pStats.externalCodeSize = 0L;
14359        }
14360
14361        return true;
14362    }
14363
14364
14365    @Override
14366    public void addPackageToPreferred(String packageName) {
14367        Slog.w(TAG, "addPackageToPreferred: this is now a no-op");
14368    }
14369
14370    @Override
14371    public void removePackageFromPreferred(String packageName) {
14372        Slog.w(TAG, "removePackageFromPreferred: this is now a no-op");
14373    }
14374
14375    @Override
14376    public List<PackageInfo> getPreferredPackages(int flags) {
14377        return new ArrayList<PackageInfo>();
14378    }
14379
14380    private int getUidTargetSdkVersionLockedLPr(int uid) {
14381        Object obj = mSettings.getUserIdLPr(uid);
14382        if (obj instanceof SharedUserSetting) {
14383            final SharedUserSetting sus = (SharedUserSetting) obj;
14384            int vers = Build.VERSION_CODES.CUR_DEVELOPMENT;
14385            final Iterator<PackageSetting> it = sus.packages.iterator();
14386            while (it.hasNext()) {
14387                final PackageSetting ps = it.next();
14388                if (ps.pkg != null) {
14389                    int v = ps.pkg.applicationInfo.targetSdkVersion;
14390                    if (v < vers) vers = v;
14391                }
14392            }
14393            return vers;
14394        } else if (obj instanceof PackageSetting) {
14395            final PackageSetting ps = (PackageSetting) obj;
14396            if (ps.pkg != null) {
14397                return ps.pkg.applicationInfo.targetSdkVersion;
14398            }
14399        }
14400        return Build.VERSION_CODES.CUR_DEVELOPMENT;
14401    }
14402
14403    @Override
14404    public void addPreferredActivity(IntentFilter filter, int match,
14405            ComponentName[] set, ComponentName activity, int userId) {
14406        addPreferredActivityInternal(filter, match, set, activity, true, userId,
14407                "Adding preferred");
14408    }
14409
14410    private void addPreferredActivityInternal(IntentFilter filter, int match,
14411            ComponentName[] set, ComponentName activity, boolean always, int userId,
14412            String opname) {
14413        // writer
14414        int callingUid = Binder.getCallingUid();
14415        enforceCrossUserPermission(callingUid, userId, true, false, "add preferred activity");
14416        if (filter.countActions() == 0) {
14417            Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
14418            return;
14419        }
14420        synchronized (mPackages) {
14421            if (mContext.checkCallingOrSelfPermission(
14422                    android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
14423                    != PackageManager.PERMISSION_GRANTED) {
14424                if (getUidTargetSdkVersionLockedLPr(callingUid)
14425                        < Build.VERSION_CODES.FROYO) {
14426                    Slog.w(TAG, "Ignoring addPreferredActivity() from uid "
14427                            + callingUid);
14428                    return;
14429                }
14430                mContext.enforceCallingOrSelfPermission(
14431                        android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
14432            }
14433
14434            PreferredIntentResolver pir = mSettings.editPreferredActivitiesLPw(userId);
14435            Slog.i(TAG, opname + " activity " + activity.flattenToShortString() + " for user "
14436                    + userId + ":");
14437            filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
14438            pir.addFilter(new PreferredActivity(filter, match, set, activity, always));
14439            scheduleWritePackageRestrictionsLocked(userId);
14440        }
14441    }
14442
14443    @Override
14444    public void replacePreferredActivity(IntentFilter filter, int match,
14445            ComponentName[] set, ComponentName activity, int userId) {
14446        if (filter.countActions() != 1) {
14447            throw new IllegalArgumentException(
14448                    "replacePreferredActivity expects filter to have only 1 action.");
14449        }
14450        if (filter.countDataAuthorities() != 0
14451                || filter.countDataPaths() != 0
14452                || filter.countDataSchemes() > 1
14453                || filter.countDataTypes() != 0) {
14454            throw new IllegalArgumentException(
14455                    "replacePreferredActivity expects filter to have no data authorities, " +
14456                    "paths, or types; and at most one scheme.");
14457        }
14458
14459        final int callingUid = Binder.getCallingUid();
14460        enforceCrossUserPermission(callingUid, userId, true, false, "replace preferred activity");
14461        synchronized (mPackages) {
14462            if (mContext.checkCallingOrSelfPermission(
14463                    android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
14464                    != PackageManager.PERMISSION_GRANTED) {
14465                if (getUidTargetSdkVersionLockedLPr(callingUid)
14466                        < Build.VERSION_CODES.FROYO) {
14467                    Slog.w(TAG, "Ignoring replacePreferredActivity() from uid "
14468                            + Binder.getCallingUid());
14469                    return;
14470                }
14471                mContext.enforceCallingOrSelfPermission(
14472                        android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
14473            }
14474
14475            PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
14476            if (pir != null) {
14477                // Get all of the existing entries that exactly match this filter.
14478                ArrayList<PreferredActivity> existing = pir.findFilters(filter);
14479                if (existing != null && existing.size() == 1) {
14480                    PreferredActivity cur = existing.get(0);
14481                    if (DEBUG_PREFERRED) {
14482                        Slog.i(TAG, "Checking replace of preferred:");
14483                        filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
14484                        if (!cur.mPref.mAlways) {
14485                            Slog.i(TAG, "  -- CUR; not mAlways!");
14486                        } else {
14487                            Slog.i(TAG, "  -- CUR: mMatch=" + cur.mPref.mMatch);
14488                            Slog.i(TAG, "  -- CUR: mSet="
14489                                    + Arrays.toString(cur.mPref.mSetComponents));
14490                            Slog.i(TAG, "  -- CUR: mComponent=" + cur.mPref.mShortComponent);
14491                            Slog.i(TAG, "  -- NEW: mMatch="
14492                                    + (match&IntentFilter.MATCH_CATEGORY_MASK));
14493                            Slog.i(TAG, "  -- CUR: mSet=" + Arrays.toString(set));
14494                            Slog.i(TAG, "  -- CUR: mComponent=" + activity.flattenToShortString());
14495                        }
14496                    }
14497                    if (cur.mPref.mAlways && cur.mPref.mComponent.equals(activity)
14498                            && cur.mPref.mMatch == (match&IntentFilter.MATCH_CATEGORY_MASK)
14499                            && cur.mPref.sameSet(set)) {
14500                        // Setting the preferred activity to what it happens to be already
14501                        if (DEBUG_PREFERRED) {
14502                            Slog.i(TAG, "Replacing with same preferred activity "
14503                                    + cur.mPref.mShortComponent + " for user "
14504                                    + userId + ":");
14505                            filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
14506                        }
14507                        return;
14508                    }
14509                }
14510
14511                if (existing != null) {
14512                    if (DEBUG_PREFERRED) {
14513                        Slog.i(TAG, existing.size() + " existing preferred matches for:");
14514                        filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
14515                    }
14516                    for (int i = 0; i < existing.size(); i++) {
14517                        PreferredActivity pa = existing.get(i);
14518                        if (DEBUG_PREFERRED) {
14519                            Slog.i(TAG, "Removing existing preferred activity "
14520                                    + pa.mPref.mComponent + ":");
14521                            pa.dump(new LogPrinter(Log.INFO, TAG), "  ");
14522                        }
14523                        pir.removeFilter(pa);
14524                    }
14525                }
14526            }
14527            addPreferredActivityInternal(filter, match, set, activity, true, userId,
14528                    "Replacing preferred");
14529        }
14530    }
14531
14532    @Override
14533    public void clearPackagePreferredActivities(String packageName) {
14534        final int uid = Binder.getCallingUid();
14535        // writer
14536        synchronized (mPackages) {
14537            PackageParser.Package pkg = mPackages.get(packageName);
14538            if (pkg == null || pkg.applicationInfo.uid != uid) {
14539                if (mContext.checkCallingOrSelfPermission(
14540                        android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
14541                        != PackageManager.PERMISSION_GRANTED) {
14542                    if (getUidTargetSdkVersionLockedLPr(Binder.getCallingUid())
14543                            < Build.VERSION_CODES.FROYO) {
14544                        Slog.w(TAG, "Ignoring clearPackagePreferredActivities() from uid "
14545                                + Binder.getCallingUid());
14546                        return;
14547                    }
14548                    mContext.enforceCallingOrSelfPermission(
14549                            android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
14550                }
14551            }
14552
14553            int user = UserHandle.getCallingUserId();
14554            if (clearPackagePreferredActivitiesLPw(packageName, user)) {
14555                scheduleWritePackageRestrictionsLocked(user);
14556            }
14557        }
14558    }
14559
14560    /** This method takes a specific user id as well as UserHandle.USER_ALL. */
14561    boolean clearPackagePreferredActivitiesLPw(String packageName, int userId) {
14562        ArrayList<PreferredActivity> removed = null;
14563        boolean changed = false;
14564        for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
14565            final int thisUserId = mSettings.mPreferredActivities.keyAt(i);
14566            PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
14567            if (userId != UserHandle.USER_ALL && userId != thisUserId) {
14568                continue;
14569            }
14570            Iterator<PreferredActivity> it = pir.filterIterator();
14571            while (it.hasNext()) {
14572                PreferredActivity pa = it.next();
14573                // Mark entry for removal only if it matches the package name
14574                // and the entry is of type "always".
14575                if (packageName == null ||
14576                        (pa.mPref.mComponent.getPackageName().equals(packageName)
14577                                && pa.mPref.mAlways)) {
14578                    if (removed == null) {
14579                        removed = new ArrayList<PreferredActivity>();
14580                    }
14581                    removed.add(pa);
14582                }
14583            }
14584            if (removed != null) {
14585                for (int j=0; j<removed.size(); j++) {
14586                    PreferredActivity pa = removed.get(j);
14587                    pir.removeFilter(pa);
14588                }
14589                changed = true;
14590            }
14591        }
14592        return changed;
14593    }
14594
14595    /** This method takes a specific user id as well as UserHandle.USER_ALL. */
14596    private void clearIntentFilterVerificationsLPw(int userId) {
14597        final int packageCount = mPackages.size();
14598        for (int i = 0; i < packageCount; i++) {
14599            PackageParser.Package pkg = mPackages.valueAt(i);
14600            clearIntentFilterVerificationsLPw(pkg.packageName, userId);
14601        }
14602    }
14603
14604    /** This method takes a specific user id as well as UserHandle.USER_ALL. */
14605    void clearIntentFilterVerificationsLPw(String packageName, int userId) {
14606        if (userId == UserHandle.USER_ALL) {
14607            if (mSettings.removeIntentFilterVerificationLPw(packageName,
14608                    sUserManager.getUserIds())) {
14609                for (int oneUserId : sUserManager.getUserIds()) {
14610                    scheduleWritePackageRestrictionsLocked(oneUserId);
14611                }
14612            }
14613        } else {
14614            if (mSettings.removeIntentFilterVerificationLPw(packageName, userId)) {
14615                scheduleWritePackageRestrictionsLocked(userId);
14616            }
14617        }
14618    }
14619
14620    void clearDefaultBrowserIfNeeded(String packageName) {
14621        for (int oneUserId : sUserManager.getUserIds()) {
14622            String defaultBrowserPackageName = getDefaultBrowserPackageName(oneUserId);
14623            if (TextUtils.isEmpty(defaultBrowserPackageName)) continue;
14624            if (packageName.equals(defaultBrowserPackageName)) {
14625                setDefaultBrowserPackageName(null, oneUserId);
14626            }
14627        }
14628    }
14629
14630    @Override
14631    public void resetApplicationPreferences(int userId) {
14632        mContext.enforceCallingOrSelfPermission(
14633                android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
14634        // writer
14635        synchronized (mPackages) {
14636            final long identity = Binder.clearCallingIdentity();
14637            try {
14638                clearPackagePreferredActivitiesLPw(null, userId);
14639                mSettings.applyDefaultPreferredAppsLPw(this, userId);
14640                // TODO: We have to reset the default SMS and Phone. This requires
14641                // significant refactoring to keep all default apps in the package
14642                // manager (cleaner but more work) or have the services provide
14643                // callbacks to the package manager to request a default app reset.
14644                applyFactoryDefaultBrowserLPw(userId);
14645                clearIntentFilterVerificationsLPw(userId);
14646                primeDomainVerificationsLPw(userId);
14647                resetUserChangesToRuntimePermissionsAndFlagsLPw(userId);
14648                scheduleWritePackageRestrictionsLocked(userId);
14649            } finally {
14650                Binder.restoreCallingIdentity(identity);
14651            }
14652        }
14653    }
14654
14655    @Override
14656    public int getPreferredActivities(List<IntentFilter> outFilters,
14657            List<ComponentName> outActivities, String packageName) {
14658
14659        int num = 0;
14660        final int userId = UserHandle.getCallingUserId();
14661        // reader
14662        synchronized (mPackages) {
14663            PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
14664            if (pir != null) {
14665                final Iterator<PreferredActivity> it = pir.filterIterator();
14666                while (it.hasNext()) {
14667                    final PreferredActivity pa = it.next();
14668                    if (packageName == null
14669                            || (pa.mPref.mComponent.getPackageName().equals(packageName)
14670                                    && pa.mPref.mAlways)) {
14671                        if (outFilters != null) {
14672                            outFilters.add(new IntentFilter(pa));
14673                        }
14674                        if (outActivities != null) {
14675                            outActivities.add(pa.mPref.mComponent);
14676                        }
14677                    }
14678                }
14679            }
14680        }
14681
14682        return num;
14683    }
14684
14685    @Override
14686    public void addPersistentPreferredActivity(IntentFilter filter, ComponentName activity,
14687            int userId) {
14688        int callingUid = Binder.getCallingUid();
14689        if (callingUid != Process.SYSTEM_UID) {
14690            throw new SecurityException(
14691                    "addPersistentPreferredActivity can only be run by the system");
14692        }
14693        if (filter.countActions() == 0) {
14694            Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
14695            return;
14696        }
14697        synchronized (mPackages) {
14698            Slog.i(TAG, "Adding persistent preferred activity " + activity + " for user " + userId +
14699                    ":");
14700            filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
14701            mSettings.editPersistentPreferredActivitiesLPw(userId).addFilter(
14702                    new PersistentPreferredActivity(filter, activity));
14703            scheduleWritePackageRestrictionsLocked(userId);
14704        }
14705    }
14706
14707    @Override
14708    public void clearPackagePersistentPreferredActivities(String packageName, int userId) {
14709        int callingUid = Binder.getCallingUid();
14710        if (callingUid != Process.SYSTEM_UID) {
14711            throw new SecurityException(
14712                    "clearPackagePersistentPreferredActivities can only be run by the system");
14713        }
14714        ArrayList<PersistentPreferredActivity> removed = null;
14715        boolean changed = false;
14716        synchronized (mPackages) {
14717            for (int i=0; i<mSettings.mPersistentPreferredActivities.size(); i++) {
14718                final int thisUserId = mSettings.mPersistentPreferredActivities.keyAt(i);
14719                PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
14720                        .valueAt(i);
14721                if (userId != thisUserId) {
14722                    continue;
14723                }
14724                Iterator<PersistentPreferredActivity> it = ppir.filterIterator();
14725                while (it.hasNext()) {
14726                    PersistentPreferredActivity ppa = it.next();
14727                    // Mark entry for removal only if it matches the package name.
14728                    if (ppa.mComponent.getPackageName().equals(packageName)) {
14729                        if (removed == null) {
14730                            removed = new ArrayList<PersistentPreferredActivity>();
14731                        }
14732                        removed.add(ppa);
14733                    }
14734                }
14735                if (removed != null) {
14736                    for (int j=0; j<removed.size(); j++) {
14737                        PersistentPreferredActivity ppa = removed.get(j);
14738                        ppir.removeFilter(ppa);
14739                    }
14740                    changed = true;
14741                }
14742            }
14743
14744            if (changed) {
14745                scheduleWritePackageRestrictionsLocked(userId);
14746            }
14747        }
14748    }
14749
14750    /**
14751     * Common machinery for picking apart a restored XML blob and passing
14752     * it to a caller-supplied functor to be applied to the running system.
14753     */
14754    private void restoreFromXml(XmlPullParser parser, int userId,
14755            String expectedStartTag, BlobXmlRestorer functor)
14756            throws IOException, XmlPullParserException {
14757        int type;
14758        while ((type = parser.next()) != XmlPullParser.START_TAG
14759                && type != XmlPullParser.END_DOCUMENT) {
14760        }
14761        if (type != XmlPullParser.START_TAG) {
14762            // oops didn't find a start tag?!
14763            if (DEBUG_BACKUP) {
14764                Slog.e(TAG, "Didn't find start tag during restore");
14765            }
14766            return;
14767        }
14768
14769        // this is supposed to be TAG_PREFERRED_BACKUP
14770        if (!expectedStartTag.equals(parser.getName())) {
14771            if (DEBUG_BACKUP) {
14772                Slog.e(TAG, "Found unexpected tag " + parser.getName());
14773            }
14774            return;
14775        }
14776
14777        // skip interfering stuff, then we're aligned with the backing implementation
14778        while ((type = parser.next()) == XmlPullParser.TEXT) { }
14779        functor.apply(parser, userId);
14780    }
14781
14782    private interface BlobXmlRestorer {
14783        public void apply(XmlPullParser parser, int userId) throws IOException, XmlPullParserException;
14784    }
14785
14786    /**
14787     * Non-Binder method, support for the backup/restore mechanism: write the
14788     * full set of preferred activities in its canonical XML format.  Returns the
14789     * XML output as a byte array, or null if there is none.
14790     */
14791    @Override
14792    public byte[] getPreferredActivityBackup(int userId) {
14793        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
14794            throw new SecurityException("Only the system may call getPreferredActivityBackup()");
14795        }
14796
14797        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
14798        try {
14799            final XmlSerializer serializer = new FastXmlSerializer();
14800            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
14801            serializer.startDocument(null, true);
14802            serializer.startTag(null, TAG_PREFERRED_BACKUP);
14803
14804            synchronized (mPackages) {
14805                mSettings.writePreferredActivitiesLPr(serializer, userId, true);
14806            }
14807
14808            serializer.endTag(null, TAG_PREFERRED_BACKUP);
14809            serializer.endDocument();
14810            serializer.flush();
14811        } catch (Exception e) {
14812            if (DEBUG_BACKUP) {
14813                Slog.e(TAG, "Unable to write preferred activities for backup", e);
14814            }
14815            return null;
14816        }
14817
14818        return dataStream.toByteArray();
14819    }
14820
14821    @Override
14822    public void restorePreferredActivities(byte[] backup, int userId) {
14823        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
14824            throw new SecurityException("Only the system may call restorePreferredActivities()");
14825        }
14826
14827        try {
14828            final XmlPullParser parser = Xml.newPullParser();
14829            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
14830            restoreFromXml(parser, userId, TAG_PREFERRED_BACKUP,
14831                    new BlobXmlRestorer() {
14832                        @Override
14833                        public void apply(XmlPullParser parser, int userId)
14834                                throws XmlPullParserException, IOException {
14835                            synchronized (mPackages) {
14836                                mSettings.readPreferredActivitiesLPw(parser, userId);
14837                            }
14838                        }
14839                    } );
14840        } catch (Exception e) {
14841            if (DEBUG_BACKUP) {
14842                Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
14843            }
14844        }
14845    }
14846
14847    /**
14848     * Non-Binder method, support for the backup/restore mechanism: write the
14849     * default browser (etc) settings in its canonical XML format.  Returns the default
14850     * browser XML representation as a byte array, or null if there is none.
14851     */
14852    @Override
14853    public byte[] getDefaultAppsBackup(int userId) {
14854        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
14855            throw new SecurityException("Only the system may call getDefaultAppsBackup()");
14856        }
14857
14858        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
14859        try {
14860            final XmlSerializer serializer = new FastXmlSerializer();
14861            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
14862            serializer.startDocument(null, true);
14863            serializer.startTag(null, TAG_DEFAULT_APPS);
14864
14865            synchronized (mPackages) {
14866                mSettings.writeDefaultAppsLPr(serializer, userId);
14867            }
14868
14869            serializer.endTag(null, TAG_DEFAULT_APPS);
14870            serializer.endDocument();
14871            serializer.flush();
14872        } catch (Exception e) {
14873            if (DEBUG_BACKUP) {
14874                Slog.e(TAG, "Unable to write default apps for backup", e);
14875            }
14876            return null;
14877        }
14878
14879        return dataStream.toByteArray();
14880    }
14881
14882    @Override
14883    public void restoreDefaultApps(byte[] backup, int userId) {
14884        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
14885            throw new SecurityException("Only the system may call restoreDefaultApps()");
14886        }
14887
14888        try {
14889            final XmlPullParser parser = Xml.newPullParser();
14890            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
14891            restoreFromXml(parser, userId, TAG_DEFAULT_APPS,
14892                    new BlobXmlRestorer() {
14893                        @Override
14894                        public void apply(XmlPullParser parser, int userId)
14895                                throws XmlPullParserException, IOException {
14896                            synchronized (mPackages) {
14897                                mSettings.readDefaultAppsLPw(parser, userId);
14898                            }
14899                        }
14900                    } );
14901        } catch (Exception e) {
14902            if (DEBUG_BACKUP) {
14903                Slog.e(TAG, "Exception restoring default apps: " + e.getMessage());
14904            }
14905        }
14906    }
14907
14908    @Override
14909    public byte[] getIntentFilterVerificationBackup(int userId) {
14910        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
14911            throw new SecurityException("Only the system may call getIntentFilterVerificationBackup()");
14912        }
14913
14914        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
14915        try {
14916            final XmlSerializer serializer = new FastXmlSerializer();
14917            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
14918            serializer.startDocument(null, true);
14919            serializer.startTag(null, TAG_INTENT_FILTER_VERIFICATION);
14920
14921            synchronized (mPackages) {
14922                mSettings.writeAllDomainVerificationsLPr(serializer, userId);
14923            }
14924
14925            serializer.endTag(null, TAG_INTENT_FILTER_VERIFICATION);
14926            serializer.endDocument();
14927            serializer.flush();
14928        } catch (Exception e) {
14929            if (DEBUG_BACKUP) {
14930                Slog.e(TAG, "Unable to write default apps for backup", e);
14931            }
14932            return null;
14933        }
14934
14935        return dataStream.toByteArray();
14936    }
14937
14938    @Override
14939    public void restoreIntentFilterVerification(byte[] backup, int userId) {
14940        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
14941            throw new SecurityException("Only the system may call restorePreferredActivities()");
14942        }
14943
14944        try {
14945            final XmlPullParser parser = Xml.newPullParser();
14946            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
14947            restoreFromXml(parser, userId, TAG_INTENT_FILTER_VERIFICATION,
14948                    new BlobXmlRestorer() {
14949                        @Override
14950                        public void apply(XmlPullParser parser, int userId)
14951                                throws XmlPullParserException, IOException {
14952                            synchronized (mPackages) {
14953                                mSettings.readAllDomainVerificationsLPr(parser, userId);
14954                                mSettings.writeLPr();
14955                            }
14956                        }
14957                    } );
14958        } catch (Exception e) {
14959            if (DEBUG_BACKUP) {
14960                Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
14961            }
14962        }
14963    }
14964
14965    @Override
14966    public void addCrossProfileIntentFilter(IntentFilter intentFilter, String ownerPackage,
14967            int sourceUserId, int targetUserId, int flags) {
14968        mContext.enforceCallingOrSelfPermission(
14969                        android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
14970        int callingUid = Binder.getCallingUid();
14971        enforceOwnerRights(ownerPackage, callingUid);
14972        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
14973        if (intentFilter.countActions() == 0) {
14974            Slog.w(TAG, "Cannot set a crossProfile intent filter with no filter actions");
14975            return;
14976        }
14977        synchronized (mPackages) {
14978            CrossProfileIntentFilter newFilter = new CrossProfileIntentFilter(intentFilter,
14979                    ownerPackage, targetUserId, flags);
14980            CrossProfileIntentResolver resolver =
14981                    mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
14982            ArrayList<CrossProfileIntentFilter> existing = resolver.findFilters(intentFilter);
14983            // We have all those whose filter is equal. Now checking if the rest is equal as well.
14984            if (existing != null) {
14985                int size = existing.size();
14986                for (int i = 0; i < size; i++) {
14987                    if (newFilter.equalsIgnoreFilter(existing.get(i))) {
14988                        return;
14989                    }
14990                }
14991            }
14992            resolver.addFilter(newFilter);
14993            scheduleWritePackageRestrictionsLocked(sourceUserId);
14994        }
14995    }
14996
14997    @Override
14998    public void clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage) {
14999        mContext.enforceCallingOrSelfPermission(
15000                        android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
15001        int callingUid = Binder.getCallingUid();
15002        enforceOwnerRights(ownerPackage, callingUid);
15003        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
15004        synchronized (mPackages) {
15005            CrossProfileIntentResolver resolver =
15006                    mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
15007            ArraySet<CrossProfileIntentFilter> set =
15008                    new ArraySet<CrossProfileIntentFilter>(resolver.filterSet());
15009            for (CrossProfileIntentFilter filter : set) {
15010                if (filter.getOwnerPackage().equals(ownerPackage)) {
15011                    resolver.removeFilter(filter);
15012                }
15013            }
15014            scheduleWritePackageRestrictionsLocked(sourceUserId);
15015        }
15016    }
15017
15018    // Enforcing that callingUid is owning pkg on userId
15019    private void enforceOwnerRights(String pkg, int callingUid) {
15020        // The system owns everything.
15021        if (UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) {
15022            return;
15023        }
15024        int callingUserId = UserHandle.getUserId(callingUid);
15025        PackageInfo pi = getPackageInfo(pkg, 0, callingUserId);
15026        if (pi == null) {
15027            throw new IllegalArgumentException("Unknown package " + pkg + " on user "
15028                    + callingUserId);
15029        }
15030        if (!UserHandle.isSameApp(pi.applicationInfo.uid, callingUid)) {
15031            throw new SecurityException("Calling uid " + callingUid
15032                    + " does not own package " + pkg);
15033        }
15034    }
15035
15036    @Override
15037    public ComponentName getHomeActivities(List<ResolveInfo> allHomeCandidates) {
15038        Intent intent = new Intent(Intent.ACTION_MAIN);
15039        intent.addCategory(Intent.CATEGORY_HOME);
15040
15041        final int callingUserId = UserHandle.getCallingUserId();
15042        List<ResolveInfo> list = queryIntentActivities(intent, null,
15043                PackageManager.GET_META_DATA, callingUserId);
15044        ResolveInfo preferred = findPreferredActivity(intent, null, 0, list, 0,
15045                true, false, false, callingUserId);
15046
15047        allHomeCandidates.clear();
15048        if (list != null) {
15049            for (ResolveInfo ri : list) {
15050                allHomeCandidates.add(ri);
15051            }
15052        }
15053        return (preferred == null || preferred.activityInfo == null)
15054                ? null
15055                : new ComponentName(preferred.activityInfo.packageName,
15056                        preferred.activityInfo.name);
15057    }
15058
15059    @Override
15060    public void setApplicationEnabledSetting(String appPackageName,
15061            int newState, int flags, int userId, String callingPackage) {
15062        if (!sUserManager.exists(userId)) return;
15063        if (callingPackage == null) {
15064            callingPackage = Integer.toString(Binder.getCallingUid());
15065        }
15066        setEnabledSetting(appPackageName, null, newState, flags, userId, callingPackage);
15067    }
15068
15069    @Override
15070    public void setComponentEnabledSetting(ComponentName componentName,
15071            int newState, int flags, int userId) {
15072        if (!sUserManager.exists(userId)) return;
15073        setEnabledSetting(componentName.getPackageName(),
15074                componentName.getClassName(), newState, flags, userId, null);
15075    }
15076
15077    private void setEnabledSetting(final String packageName, String className, int newState,
15078            final int flags, int userId, String callingPackage) {
15079        if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT
15080              || newState == COMPONENT_ENABLED_STATE_ENABLED
15081              || newState == COMPONENT_ENABLED_STATE_DISABLED
15082              || newState == COMPONENT_ENABLED_STATE_DISABLED_USER
15083              || newState == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED)) {
15084            throw new IllegalArgumentException("Invalid new component state: "
15085                    + newState);
15086        }
15087        PackageSetting pkgSetting;
15088        final int uid = Binder.getCallingUid();
15089        final int permission = mContext.checkCallingOrSelfPermission(
15090                android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
15091        enforceCrossUserPermission(uid, userId, false, true, "set enabled");
15092        final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
15093        boolean sendNow = false;
15094        boolean isApp = (className == null);
15095        String componentName = isApp ? packageName : className;
15096        int packageUid = -1;
15097        ArrayList<String> components;
15098
15099        // writer
15100        synchronized (mPackages) {
15101            pkgSetting = mSettings.mPackages.get(packageName);
15102            if (pkgSetting == null) {
15103                if (className == null) {
15104                    throw new IllegalArgumentException("Unknown package: " + packageName);
15105                }
15106                throw new IllegalArgumentException(
15107                        "Unknown component: " + packageName + "/" + className);
15108            }
15109            // Allow root and verify that userId is not being specified by a different user
15110            if (!allowedByPermission && !UserHandle.isSameApp(uid, pkgSetting.appId)) {
15111                throw new SecurityException(
15112                        "Permission Denial: attempt to change component state from pid="
15113                        + Binder.getCallingPid()
15114                        + ", uid=" + uid + ", package uid=" + pkgSetting.appId);
15115            }
15116            if (className == null) {
15117                // We're dealing with an application/package level state change
15118                if (pkgSetting.getEnabled(userId) == newState) {
15119                    // Nothing to do
15120                    return;
15121                }
15122                if (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
15123                    || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {
15124                    // Don't care about who enables an app.
15125                    callingPackage = null;
15126                }
15127                pkgSetting.setEnabled(newState, userId, callingPackage);
15128                // pkgSetting.pkg.mSetEnabled = newState;
15129            } else {
15130                // We're dealing with a component level state change
15131                // First, verify that this is a valid class name.
15132                PackageParser.Package pkg = pkgSetting.pkg;
15133                if (pkg == null || !pkg.hasComponentClassName(className)) {
15134                    if (pkg != null &&
15135                            pkg.applicationInfo.targetSdkVersion >=
15136                                    Build.VERSION_CODES.JELLY_BEAN) {
15137                        throw new IllegalArgumentException("Component class " + className
15138                                + " does not exist in " + packageName);
15139                    } else {
15140                        Slog.w(TAG, "Failed setComponentEnabledSetting: component class "
15141                                + className + " does not exist in " + packageName);
15142                    }
15143                }
15144                switch (newState) {
15145                case COMPONENT_ENABLED_STATE_ENABLED:
15146                    if (!pkgSetting.enableComponentLPw(className, userId)) {
15147                        return;
15148                    }
15149                    break;
15150                case COMPONENT_ENABLED_STATE_DISABLED:
15151                    if (!pkgSetting.disableComponentLPw(className, userId)) {
15152                        return;
15153                    }
15154                    break;
15155                case COMPONENT_ENABLED_STATE_DEFAULT:
15156                    if (!pkgSetting.restoreComponentLPw(className, userId)) {
15157                        return;
15158                    }
15159                    break;
15160                default:
15161                    Slog.e(TAG, "Invalid new component state: " + newState);
15162                    return;
15163                }
15164            }
15165            scheduleWritePackageRestrictionsLocked(userId);
15166            components = mPendingBroadcasts.get(userId, packageName);
15167            final boolean newPackage = components == null;
15168            if (newPackage) {
15169                components = new ArrayList<String>();
15170            }
15171            if (!components.contains(componentName)) {
15172                components.add(componentName);
15173            }
15174            if ((flags&PackageManager.DONT_KILL_APP) == 0) {
15175                sendNow = true;
15176                // Purge entry from pending broadcast list if another one exists already
15177                // since we are sending one right away.
15178                mPendingBroadcasts.remove(userId, packageName);
15179            } else {
15180                if (newPackage) {
15181                    mPendingBroadcasts.put(userId, packageName, components);
15182                }
15183                if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) {
15184                    // Schedule a message
15185                    mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, BROADCAST_DELAY);
15186                }
15187            }
15188        }
15189
15190        long callingId = Binder.clearCallingIdentity();
15191        try {
15192            if (sendNow) {
15193                packageUid = UserHandle.getUid(userId, pkgSetting.appId);
15194                sendPackageChangedBroadcast(packageName,
15195                        (flags&PackageManager.DONT_KILL_APP) != 0, components, packageUid);
15196            }
15197        } finally {
15198            Binder.restoreCallingIdentity(callingId);
15199        }
15200    }
15201
15202    private void sendPackageChangedBroadcast(String packageName,
15203            boolean killFlag, ArrayList<String> componentNames, int packageUid) {
15204        if (DEBUG_INSTALL)
15205            Log.v(TAG, "Sending package changed: package=" + packageName + " components="
15206                    + componentNames);
15207        Bundle extras = new Bundle(4);
15208        extras.putString(Intent.EXTRA_CHANGED_COMPONENT_NAME, componentNames.get(0));
15209        String nameList[] = new String[componentNames.size()];
15210        componentNames.toArray(nameList);
15211        extras.putStringArray(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST, nameList);
15212        extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, killFlag);
15213        extras.putInt(Intent.EXTRA_UID, packageUid);
15214        // If this is not reporting a change of the overall package, then only send it
15215        // to registered receivers.  We don't want to launch a swath of apps for every
15216        // little component state change.
15217        final int flags = !componentNames.contains(packageName)
15218                ? Intent.FLAG_RECEIVER_REGISTERED_ONLY : 0;
15219        sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED,  packageName, extras, flags, null, null,
15220                new int[] {UserHandle.getUserId(packageUid)});
15221    }
15222
15223    @Override
15224    public void setPackageStoppedState(String packageName, boolean stopped, int userId) {
15225        if (!sUserManager.exists(userId)) return;
15226        final int uid = Binder.getCallingUid();
15227        final int permission = mContext.checkCallingOrSelfPermission(
15228                android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
15229        final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
15230        enforceCrossUserPermission(uid, userId, true, true, "stop package");
15231        // writer
15232        synchronized (mPackages) {
15233            if (mSettings.setPackageStoppedStateLPw(this, packageName, stopped,
15234                    allowedByPermission, uid, userId)) {
15235                scheduleWritePackageRestrictionsLocked(userId);
15236            }
15237        }
15238    }
15239
15240    @Override
15241    public String getInstallerPackageName(String packageName) {
15242        // reader
15243        synchronized (mPackages) {
15244            return mSettings.getInstallerPackageNameLPr(packageName);
15245        }
15246    }
15247
15248    @Override
15249    public int getApplicationEnabledSetting(String packageName, int userId) {
15250        if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
15251        int uid = Binder.getCallingUid();
15252        enforceCrossUserPermission(uid, userId, false, false, "get enabled");
15253        // reader
15254        synchronized (mPackages) {
15255            return mSettings.getApplicationEnabledSettingLPr(packageName, userId);
15256        }
15257    }
15258
15259    @Override
15260    public int getComponentEnabledSetting(ComponentName componentName, int userId) {
15261        if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
15262        int uid = Binder.getCallingUid();
15263        enforceCrossUserPermission(uid, userId, false, false, "get component enabled");
15264        // reader
15265        synchronized (mPackages) {
15266            return mSettings.getComponentEnabledSettingLPr(componentName, userId);
15267        }
15268    }
15269
15270    @Override
15271    public void enterSafeMode() {
15272        enforceSystemOrRoot("Only the system can request entering safe mode");
15273
15274        if (!mSystemReady) {
15275            mSafeMode = true;
15276        }
15277    }
15278
15279    @Override
15280    public void systemReady() {
15281        mSystemReady = true;
15282
15283        // Read the compatibilty setting when the system is ready.
15284        boolean compatibilityModeEnabled = android.provider.Settings.Global.getInt(
15285                mContext.getContentResolver(),
15286                android.provider.Settings.Global.COMPATIBILITY_MODE, 1) == 1;
15287        PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled);
15288        if (DEBUG_SETTINGS) {
15289            Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled);
15290        }
15291
15292        int[] grantPermissionsUserIds = EMPTY_INT_ARRAY;
15293
15294        synchronized (mPackages) {
15295            // Verify that all of the preferred activity components actually
15296            // exist.  It is possible for applications to be updated and at
15297            // that point remove a previously declared activity component that
15298            // had been set as a preferred activity.  We try to clean this up
15299            // the next time we encounter that preferred activity, but it is
15300            // possible for the user flow to never be able to return to that
15301            // situation so here we do a sanity check to make sure we haven't
15302            // left any junk around.
15303            ArrayList<PreferredActivity> removed = new ArrayList<PreferredActivity>();
15304            for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
15305                PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
15306                removed.clear();
15307                for (PreferredActivity pa : pir.filterSet()) {
15308                    if (mActivities.mActivities.get(pa.mPref.mComponent) == null) {
15309                        removed.add(pa);
15310                    }
15311                }
15312                if (removed.size() > 0) {
15313                    for (int r=0; r<removed.size(); r++) {
15314                        PreferredActivity pa = removed.get(r);
15315                        Slog.w(TAG, "Removing dangling preferred activity: "
15316                                + pa.mPref.mComponent);
15317                        pir.removeFilter(pa);
15318                    }
15319                    mSettings.writePackageRestrictionsLPr(
15320                            mSettings.mPreferredActivities.keyAt(i));
15321                }
15322            }
15323
15324            for (int userId : UserManagerService.getInstance().getUserIds()) {
15325                if (!mSettings.areDefaultRuntimePermissionsGrantedLPr(userId)) {
15326                    grantPermissionsUserIds = ArrayUtils.appendInt(
15327                            grantPermissionsUserIds, userId);
15328                }
15329            }
15330        }
15331        sUserManager.systemReady();
15332
15333        // If we upgraded grant all default permissions before kicking off.
15334        for (int userId : grantPermissionsUserIds) {
15335            mDefaultPermissionPolicy.grantDefaultPermissions(userId);
15336        }
15337
15338        // Kick off any messages waiting for system ready
15339        if (mPostSystemReadyMessages != null) {
15340            for (Message msg : mPostSystemReadyMessages) {
15341                msg.sendToTarget();
15342            }
15343            mPostSystemReadyMessages = null;
15344        }
15345
15346        // Watch for external volumes that come and go over time
15347        final StorageManager storage = mContext.getSystemService(StorageManager.class);
15348        storage.registerListener(mStorageListener);
15349
15350        mInstallerService.systemReady();
15351        mPackageDexOptimizer.systemReady();
15352
15353        MountServiceInternal mountServiceInternal = LocalServices.getService(
15354                MountServiceInternal.class);
15355        mountServiceInternal.addExternalStoragePolicy(
15356                new MountServiceInternal.ExternalStorageMountPolicy() {
15357            @Override
15358            public int getMountMode(int uid, String packageName) {
15359                if (Process.isIsolated(uid)) {
15360                    return Zygote.MOUNT_EXTERNAL_NONE;
15361                }
15362                if (checkUidPermission(WRITE_MEDIA_STORAGE, uid) == PERMISSION_GRANTED) {
15363                    return Zygote.MOUNT_EXTERNAL_DEFAULT;
15364                }
15365                if (checkUidPermission(READ_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) {
15366                    return Zygote.MOUNT_EXTERNAL_DEFAULT;
15367                }
15368                if (checkUidPermission(WRITE_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) {
15369                    return Zygote.MOUNT_EXTERNAL_READ;
15370                }
15371                return Zygote.MOUNT_EXTERNAL_WRITE;
15372            }
15373
15374            @Override
15375            public boolean hasExternalStorage(int uid, String packageName) {
15376                return true;
15377            }
15378        });
15379    }
15380
15381    @Override
15382    public boolean isSafeMode() {
15383        return mSafeMode;
15384    }
15385
15386    @Override
15387    public boolean hasSystemUidErrors() {
15388        return mHasSystemUidErrors;
15389    }
15390
15391    static String arrayToString(int[] array) {
15392        StringBuffer buf = new StringBuffer(128);
15393        buf.append('[');
15394        if (array != null) {
15395            for (int i=0; i<array.length; i++) {
15396                if (i > 0) buf.append(", ");
15397                buf.append(array[i]);
15398            }
15399        }
15400        buf.append(']');
15401        return buf.toString();
15402    }
15403
15404    static class DumpState {
15405        public static final int DUMP_LIBS = 1 << 0;
15406        public static final int DUMP_FEATURES = 1 << 1;
15407        public static final int DUMP_ACTIVITY_RESOLVERS = 1 << 2;
15408        public static final int DUMP_SERVICE_RESOLVERS = 1 << 3;
15409        public static final int DUMP_RECEIVER_RESOLVERS = 1 << 4;
15410        public static final int DUMP_CONTENT_RESOLVERS = 1 << 5;
15411        public static final int DUMP_PERMISSIONS = 1 << 6;
15412        public static final int DUMP_PACKAGES = 1 << 7;
15413        public static final int DUMP_SHARED_USERS = 1 << 8;
15414        public static final int DUMP_MESSAGES = 1 << 9;
15415        public static final int DUMP_PROVIDERS = 1 << 10;
15416        public static final int DUMP_VERIFIERS = 1 << 11;
15417        public static final int DUMP_PREFERRED = 1 << 12;
15418        public static final int DUMP_PREFERRED_XML = 1 << 13;
15419        public static final int DUMP_KEYSETS = 1 << 14;
15420        public static final int DUMP_VERSION = 1 << 15;
15421        public static final int DUMP_INSTALLS = 1 << 16;
15422        public static final int DUMP_INTENT_FILTER_VERIFIERS = 1 << 17;
15423        public static final int DUMP_DOMAIN_PREFERRED = 1 << 18;
15424
15425        public static final int OPTION_SHOW_FILTERS = 1 << 0;
15426
15427        private int mTypes;
15428
15429        private int mOptions;
15430
15431        private boolean mTitlePrinted;
15432
15433        private SharedUserSetting mSharedUser;
15434
15435        public boolean isDumping(int type) {
15436            if (mTypes == 0 && type != DUMP_PREFERRED_XML) {
15437                return true;
15438            }
15439
15440            return (mTypes & type) != 0;
15441        }
15442
15443        public void setDump(int type) {
15444            mTypes |= type;
15445        }
15446
15447        public boolean isOptionEnabled(int option) {
15448            return (mOptions & option) != 0;
15449        }
15450
15451        public void setOptionEnabled(int option) {
15452            mOptions |= option;
15453        }
15454
15455        public boolean onTitlePrinted() {
15456            final boolean printed = mTitlePrinted;
15457            mTitlePrinted = true;
15458            return printed;
15459        }
15460
15461        public boolean getTitlePrinted() {
15462            return mTitlePrinted;
15463        }
15464
15465        public void setTitlePrinted(boolean enabled) {
15466            mTitlePrinted = enabled;
15467        }
15468
15469        public SharedUserSetting getSharedUser() {
15470            return mSharedUser;
15471        }
15472
15473        public void setSharedUser(SharedUserSetting user) {
15474            mSharedUser = user;
15475        }
15476    }
15477
15478    @Override
15479    public void onShellCommand(FileDescriptor in, FileDescriptor out,
15480            FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
15481        (new PackageManagerShellCommand(this)).exec(
15482                this, in, out, err, args, resultReceiver);
15483    }
15484
15485    @Override
15486    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
15487        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
15488                != PackageManager.PERMISSION_GRANTED) {
15489            pw.println("Permission Denial: can't dump ActivityManager from from pid="
15490                    + Binder.getCallingPid()
15491                    + ", uid=" + Binder.getCallingUid()
15492                    + " without permission "
15493                    + android.Manifest.permission.DUMP);
15494            return;
15495        }
15496
15497        DumpState dumpState = new DumpState();
15498        boolean fullPreferred = false;
15499        boolean checkin = false;
15500
15501        String packageName = null;
15502        ArraySet<String> permissionNames = null;
15503
15504        int opti = 0;
15505        while (opti < args.length) {
15506            String opt = args[opti];
15507            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15508                break;
15509            }
15510            opti++;
15511
15512            if ("-a".equals(opt)) {
15513                // Right now we only know how to print all.
15514            } else if ("-h".equals(opt)) {
15515                pw.println("Package manager dump options:");
15516                pw.println("  [-h] [-f] [--checkin] [cmd] ...");
15517                pw.println("    --checkin: dump for a checkin");
15518                pw.println("    -f: print details of intent filters");
15519                pw.println("    -h: print this help");
15520                pw.println("  cmd may be one of:");
15521                pw.println("    l[ibraries]: list known shared libraries");
15522                pw.println("    f[eatures]: list device features");
15523                pw.println("    k[eysets]: print known keysets");
15524                pw.println("    r[esolvers] [activity|service|receiver|content]: dump intent resolvers");
15525                pw.println("    perm[issions]: dump permissions");
15526                pw.println("    permission [name ...]: dump declaration and use of given permission");
15527                pw.println("    pref[erred]: print preferred package settings");
15528                pw.println("    preferred-xml [--full]: print preferred package settings as xml");
15529                pw.println("    prov[iders]: dump content providers");
15530                pw.println("    p[ackages]: dump installed packages");
15531                pw.println("    s[hared-users]: dump shared user IDs");
15532                pw.println("    m[essages]: print collected runtime messages");
15533                pw.println("    v[erifiers]: print package verifier info");
15534                pw.println("    d[omain-preferred-apps]: print domains preferred apps");
15535                pw.println("    i[ntent-filter-verifiers]|ifv: print intent filter verifier info");
15536                pw.println("    version: print database version info");
15537                pw.println("    write: write current settings now");
15538                pw.println("    installs: details about install sessions");
15539                pw.println("    check-permission <permission> <package> [<user>]: does pkg hold perm?");
15540                pw.println("    <package.name>: info about given package");
15541                return;
15542            } else if ("--checkin".equals(opt)) {
15543                checkin = true;
15544            } else if ("-f".equals(opt)) {
15545                dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
15546            } else {
15547                pw.println("Unknown argument: " + opt + "; use -h for help");
15548            }
15549        }
15550
15551        // Is the caller requesting to dump a particular piece of data?
15552        if (opti < args.length) {
15553            String cmd = args[opti];
15554            opti++;
15555            // Is this a package name?
15556            if ("android".equals(cmd) || cmd.contains(".")) {
15557                packageName = cmd;
15558                // When dumping a single package, we always dump all of its
15559                // filter information since the amount of data will be reasonable.
15560                dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
15561            } else if ("check-permission".equals(cmd)) {
15562                if (opti >= args.length) {
15563                    pw.println("Error: check-permission missing permission argument");
15564                    return;
15565                }
15566                String perm = args[opti];
15567                opti++;
15568                if (opti >= args.length) {
15569                    pw.println("Error: check-permission missing package argument");
15570                    return;
15571                }
15572                String pkg = args[opti];
15573                opti++;
15574                int user = UserHandle.getUserId(Binder.getCallingUid());
15575                if (opti < args.length) {
15576                    try {
15577                        user = Integer.parseInt(args[opti]);
15578                    } catch (NumberFormatException e) {
15579                        pw.println("Error: check-permission user argument is not a number: "
15580                                + args[opti]);
15581                        return;
15582                    }
15583                }
15584                pw.println(checkPermission(perm, pkg, user));
15585                return;
15586            } else if ("l".equals(cmd) || "libraries".equals(cmd)) {
15587                dumpState.setDump(DumpState.DUMP_LIBS);
15588            } else if ("f".equals(cmd) || "features".equals(cmd)) {
15589                dumpState.setDump(DumpState.DUMP_FEATURES);
15590            } else if ("r".equals(cmd) || "resolvers".equals(cmd)) {
15591                if (opti >= args.length) {
15592                    dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS
15593                            | DumpState.DUMP_SERVICE_RESOLVERS
15594                            | DumpState.DUMP_RECEIVER_RESOLVERS
15595                            | DumpState.DUMP_CONTENT_RESOLVERS);
15596                } else {
15597                    while (opti < args.length) {
15598                        String name = args[opti];
15599                        if ("a".equals(name) || "activity".equals(name)) {
15600                            dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS);
15601                        } else if ("s".equals(name) || "service".equals(name)) {
15602                            dumpState.setDump(DumpState.DUMP_SERVICE_RESOLVERS);
15603                        } else if ("r".equals(name) || "receiver".equals(name)) {
15604                            dumpState.setDump(DumpState.DUMP_RECEIVER_RESOLVERS);
15605                        } else if ("c".equals(name) || "content".equals(name)) {
15606                            dumpState.setDump(DumpState.DUMP_CONTENT_RESOLVERS);
15607                        } else {
15608                            pw.println("Error: unknown resolver table type: " + name);
15609                            return;
15610                        }
15611                        opti++;
15612                    }
15613                }
15614            } else if ("perm".equals(cmd) || "permissions".equals(cmd)) {
15615                dumpState.setDump(DumpState.DUMP_PERMISSIONS);
15616            } else if ("permission".equals(cmd)) {
15617                if (opti >= args.length) {
15618                    pw.println("Error: permission requires permission name");
15619                    return;
15620                }
15621                permissionNames = new ArraySet<>();
15622                while (opti < args.length) {
15623                    permissionNames.add(args[opti]);
15624                    opti++;
15625                }
15626                dumpState.setDump(DumpState.DUMP_PERMISSIONS
15627                        | DumpState.DUMP_PACKAGES | DumpState.DUMP_SHARED_USERS);
15628            } else if ("pref".equals(cmd) || "preferred".equals(cmd)) {
15629                dumpState.setDump(DumpState.DUMP_PREFERRED);
15630            } else if ("preferred-xml".equals(cmd)) {
15631                dumpState.setDump(DumpState.DUMP_PREFERRED_XML);
15632                if (opti < args.length && "--full".equals(args[opti])) {
15633                    fullPreferred = true;
15634                    opti++;
15635                }
15636            } else if ("d".equals(cmd) || "domain-preferred-apps".equals(cmd)) {
15637                dumpState.setDump(DumpState.DUMP_DOMAIN_PREFERRED);
15638            } else if ("p".equals(cmd) || "packages".equals(cmd)) {
15639                dumpState.setDump(DumpState.DUMP_PACKAGES);
15640            } else if ("s".equals(cmd) || "shared-users".equals(cmd)) {
15641                dumpState.setDump(DumpState.DUMP_SHARED_USERS);
15642            } else if ("prov".equals(cmd) || "providers".equals(cmd)) {
15643                dumpState.setDump(DumpState.DUMP_PROVIDERS);
15644            } else if ("m".equals(cmd) || "messages".equals(cmd)) {
15645                dumpState.setDump(DumpState.DUMP_MESSAGES);
15646            } else if ("v".equals(cmd) || "verifiers".equals(cmd)) {
15647                dumpState.setDump(DumpState.DUMP_VERIFIERS);
15648            } else if ("i".equals(cmd) || "ifv".equals(cmd)
15649                    || "intent-filter-verifiers".equals(cmd)) {
15650                dumpState.setDump(DumpState.DUMP_INTENT_FILTER_VERIFIERS);
15651            } else if ("version".equals(cmd)) {
15652                dumpState.setDump(DumpState.DUMP_VERSION);
15653            } else if ("k".equals(cmd) || "keysets".equals(cmd)) {
15654                dumpState.setDump(DumpState.DUMP_KEYSETS);
15655            } else if ("installs".equals(cmd)) {
15656                dumpState.setDump(DumpState.DUMP_INSTALLS);
15657            } else if ("write".equals(cmd)) {
15658                synchronized (mPackages) {
15659                    mSettings.writeLPr();
15660                    pw.println("Settings written.");
15661                    return;
15662                }
15663            }
15664        }
15665
15666        if (checkin) {
15667            pw.println("vers,1");
15668        }
15669
15670        // reader
15671        synchronized (mPackages) {
15672            if (dumpState.isDumping(DumpState.DUMP_VERSION) && packageName == null) {
15673                if (!checkin) {
15674                    if (dumpState.onTitlePrinted())
15675                        pw.println();
15676                    pw.println("Database versions:");
15677                    mSettings.dumpVersionLPr(new IndentingPrintWriter(pw, "  "));
15678                }
15679            }
15680
15681            if (dumpState.isDumping(DumpState.DUMP_VERIFIERS) && packageName == null) {
15682                if (!checkin) {
15683                    if (dumpState.onTitlePrinted())
15684                        pw.println();
15685                    pw.println("Verifiers:");
15686                    pw.print("  Required: ");
15687                    pw.print(mRequiredVerifierPackage);
15688                    pw.print(" (uid=");
15689                    pw.print(getPackageUid(mRequiredVerifierPackage, 0));
15690                    pw.println(")");
15691                } else if (mRequiredVerifierPackage != null) {
15692                    pw.print("vrfy,"); pw.print(mRequiredVerifierPackage);
15693                    pw.print(","); pw.println(getPackageUid(mRequiredVerifierPackage, 0));
15694                }
15695            }
15696
15697            if (dumpState.isDumping(DumpState.DUMP_INTENT_FILTER_VERIFIERS) &&
15698                    packageName == null) {
15699                if (mIntentFilterVerifierComponent != null) {
15700                    String verifierPackageName = mIntentFilterVerifierComponent.getPackageName();
15701                    if (!checkin) {
15702                        if (dumpState.onTitlePrinted())
15703                            pw.println();
15704                        pw.println("Intent Filter Verifier:");
15705                        pw.print("  Using: ");
15706                        pw.print(verifierPackageName);
15707                        pw.print(" (uid=");
15708                        pw.print(getPackageUid(verifierPackageName, 0));
15709                        pw.println(")");
15710                    } else if (verifierPackageName != null) {
15711                        pw.print("ifv,"); pw.print(verifierPackageName);
15712                        pw.print(","); pw.println(getPackageUid(verifierPackageName, 0));
15713                    }
15714                } else {
15715                    pw.println();
15716                    pw.println("No Intent Filter Verifier available!");
15717                }
15718            }
15719
15720            if (dumpState.isDumping(DumpState.DUMP_LIBS) && packageName == null) {
15721                boolean printedHeader = false;
15722                final Iterator<String> it = mSharedLibraries.keySet().iterator();
15723                while (it.hasNext()) {
15724                    String name = it.next();
15725                    SharedLibraryEntry ent = mSharedLibraries.get(name);
15726                    if (!checkin) {
15727                        if (!printedHeader) {
15728                            if (dumpState.onTitlePrinted())
15729                                pw.println();
15730                            pw.println("Libraries:");
15731                            printedHeader = true;
15732                        }
15733                        pw.print("  ");
15734                    } else {
15735                        pw.print("lib,");
15736                    }
15737                    pw.print(name);
15738                    if (!checkin) {
15739                        pw.print(" -> ");
15740                    }
15741                    if (ent.path != null) {
15742                        if (!checkin) {
15743                            pw.print("(jar) ");
15744                            pw.print(ent.path);
15745                        } else {
15746                            pw.print(",jar,");
15747                            pw.print(ent.path);
15748                        }
15749                    } else {
15750                        if (!checkin) {
15751                            pw.print("(apk) ");
15752                            pw.print(ent.apk);
15753                        } else {
15754                            pw.print(",apk,");
15755                            pw.print(ent.apk);
15756                        }
15757                    }
15758                    pw.println();
15759                }
15760            }
15761
15762            if (dumpState.isDumping(DumpState.DUMP_FEATURES) && packageName == null) {
15763                if (dumpState.onTitlePrinted())
15764                    pw.println();
15765                if (!checkin) {
15766                    pw.println("Features:");
15767                }
15768                Iterator<String> it = mAvailableFeatures.keySet().iterator();
15769                while (it.hasNext()) {
15770                    String name = it.next();
15771                    if (!checkin) {
15772                        pw.print("  ");
15773                    } else {
15774                        pw.print("feat,");
15775                    }
15776                    pw.println(name);
15777                }
15778            }
15779
15780            if (!checkin && dumpState.isDumping(DumpState.DUMP_ACTIVITY_RESOLVERS)) {
15781                if (mActivities.dump(pw, dumpState.getTitlePrinted() ? "\nActivity Resolver Table:"
15782                        : "Activity Resolver Table:", "  ", packageName,
15783                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
15784                    dumpState.setTitlePrinted(true);
15785                }
15786            }
15787            if (!checkin && dumpState.isDumping(DumpState.DUMP_RECEIVER_RESOLVERS)) {
15788                if (mReceivers.dump(pw, dumpState.getTitlePrinted() ? "\nReceiver Resolver Table:"
15789                        : "Receiver Resolver Table:", "  ", packageName,
15790                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
15791                    dumpState.setTitlePrinted(true);
15792                }
15793            }
15794            if (!checkin && dumpState.isDumping(DumpState.DUMP_SERVICE_RESOLVERS)) {
15795                if (mServices.dump(pw, dumpState.getTitlePrinted() ? "\nService Resolver Table:"
15796                        : "Service Resolver Table:", "  ", packageName,
15797                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
15798                    dumpState.setTitlePrinted(true);
15799                }
15800            }
15801            if (!checkin && dumpState.isDumping(DumpState.DUMP_CONTENT_RESOLVERS)) {
15802                if (mProviders.dump(pw, dumpState.getTitlePrinted() ? "\nProvider Resolver Table:"
15803                        : "Provider Resolver Table:", "  ", packageName,
15804                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
15805                    dumpState.setTitlePrinted(true);
15806                }
15807            }
15808
15809            if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED)) {
15810                for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
15811                    PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
15812                    int user = mSettings.mPreferredActivities.keyAt(i);
15813                    if (pir.dump(pw,
15814                            dumpState.getTitlePrinted()
15815                                ? "\nPreferred Activities User " + user + ":"
15816                                : "Preferred Activities User " + user + ":", "  ",
15817                            packageName, true, false)) {
15818                        dumpState.setTitlePrinted(true);
15819                    }
15820                }
15821            }
15822
15823            if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED_XML)) {
15824                pw.flush();
15825                FileOutputStream fout = new FileOutputStream(fd);
15826                BufferedOutputStream str = new BufferedOutputStream(fout);
15827                XmlSerializer serializer = new FastXmlSerializer();
15828                try {
15829                    serializer.setOutput(str, StandardCharsets.UTF_8.name());
15830                    serializer.startDocument(null, true);
15831                    serializer.setFeature(
15832                            "http://xmlpull.org/v1/doc/features.html#indent-output", true);
15833                    mSettings.writePreferredActivitiesLPr(serializer, 0, fullPreferred);
15834                    serializer.endDocument();
15835                    serializer.flush();
15836                } catch (IllegalArgumentException e) {
15837                    pw.println("Failed writing: " + e);
15838                } catch (IllegalStateException e) {
15839                    pw.println("Failed writing: " + e);
15840                } catch (IOException e) {
15841                    pw.println("Failed writing: " + e);
15842                }
15843            }
15844
15845            if (!checkin
15846                    && dumpState.isDumping(DumpState.DUMP_DOMAIN_PREFERRED)
15847                    && packageName == null) {
15848                pw.println();
15849                int count = mSettings.mPackages.size();
15850                if (count == 0) {
15851                    pw.println("No applications!");
15852                    pw.println();
15853                } else {
15854                    final String prefix = "  ";
15855                    Collection<PackageSetting> allPackageSettings = mSettings.mPackages.values();
15856                    if (allPackageSettings.size() == 0) {
15857                        pw.println("No domain preferred apps!");
15858                        pw.println();
15859                    } else {
15860                        pw.println("App verification status:");
15861                        pw.println();
15862                        count = 0;
15863                        for (PackageSetting ps : allPackageSettings) {
15864                            IntentFilterVerificationInfo ivi = ps.getIntentFilterVerificationInfo();
15865                            if (ivi == null || ivi.getPackageName() == null) continue;
15866                            pw.println(prefix + "Package: " + ivi.getPackageName());
15867                            pw.println(prefix + "Domains: " + ivi.getDomainsString());
15868                            pw.println(prefix + "Status:  " + ivi.getStatusString());
15869                            pw.println();
15870                            count++;
15871                        }
15872                        if (count == 0) {
15873                            pw.println(prefix + "No app verification established.");
15874                            pw.println();
15875                        }
15876                        for (int userId : sUserManager.getUserIds()) {
15877                            pw.println("App linkages for user " + userId + ":");
15878                            pw.println();
15879                            count = 0;
15880                            for (PackageSetting ps : allPackageSettings) {
15881                                final long status = ps.getDomainVerificationStatusForUser(userId);
15882                                if (status >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) {
15883                                    continue;
15884                                }
15885                                pw.println(prefix + "Package: " + ps.name);
15886                                pw.println(prefix + "Domains: " + dumpDomainString(ps.name));
15887                                String statusStr = IntentFilterVerificationInfo.
15888                                        getStatusStringFromValue(status);
15889                                pw.println(prefix + "Status:  " + statusStr);
15890                                pw.println();
15891                                count++;
15892                            }
15893                            if (count == 0) {
15894                                pw.println(prefix + "No configured app linkages.");
15895                                pw.println();
15896                            }
15897                        }
15898                    }
15899                }
15900            }
15901
15902            if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) {
15903                mSettings.dumpPermissionsLPr(pw, packageName, permissionNames, dumpState);
15904                if (packageName == null && permissionNames == null) {
15905                    for (int iperm=0; iperm<mAppOpPermissionPackages.size(); iperm++) {
15906                        if (iperm == 0) {
15907                            if (dumpState.onTitlePrinted())
15908                                pw.println();
15909                            pw.println("AppOp Permissions:");
15910                        }
15911                        pw.print("  AppOp Permission ");
15912                        pw.print(mAppOpPermissionPackages.keyAt(iperm));
15913                        pw.println(":");
15914                        ArraySet<String> pkgs = mAppOpPermissionPackages.valueAt(iperm);
15915                        for (int ipkg=0; ipkg<pkgs.size(); ipkg++) {
15916                            pw.print("    "); pw.println(pkgs.valueAt(ipkg));
15917                        }
15918                    }
15919                }
15920            }
15921
15922            if (!checkin && dumpState.isDumping(DumpState.DUMP_PROVIDERS)) {
15923                boolean printedSomething = false;
15924                for (PackageParser.Provider p : mProviders.mProviders.values()) {
15925                    if (packageName != null && !packageName.equals(p.info.packageName)) {
15926                        continue;
15927                    }
15928                    if (!printedSomething) {
15929                        if (dumpState.onTitlePrinted())
15930                            pw.println();
15931                        pw.println("Registered ContentProviders:");
15932                        printedSomething = true;
15933                    }
15934                    pw.print("  "); p.printComponentShortName(pw); pw.println(":");
15935                    pw.print("    "); pw.println(p.toString());
15936                }
15937                printedSomething = false;
15938                for (Map.Entry<String, PackageParser.Provider> entry :
15939                        mProvidersByAuthority.entrySet()) {
15940                    PackageParser.Provider p = entry.getValue();
15941                    if (packageName != null && !packageName.equals(p.info.packageName)) {
15942                        continue;
15943                    }
15944                    if (!printedSomething) {
15945                        if (dumpState.onTitlePrinted())
15946                            pw.println();
15947                        pw.println("ContentProvider Authorities:");
15948                        printedSomething = true;
15949                    }
15950                    pw.print("  ["); pw.print(entry.getKey()); pw.println("]:");
15951                    pw.print("    "); pw.println(p.toString());
15952                    if (p.info != null && p.info.applicationInfo != null) {
15953                        final String appInfo = p.info.applicationInfo.toString();
15954                        pw.print("      applicationInfo="); pw.println(appInfo);
15955                    }
15956                }
15957            }
15958
15959            if (!checkin && dumpState.isDumping(DumpState.DUMP_KEYSETS)) {
15960                mSettings.mKeySetManagerService.dumpLPr(pw, packageName, dumpState);
15961            }
15962
15963            if (dumpState.isDumping(DumpState.DUMP_PACKAGES)) {
15964                mSettings.dumpPackagesLPr(pw, packageName, permissionNames, dumpState, checkin);
15965            }
15966
15967            if (dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) {
15968                mSettings.dumpSharedUsersLPr(pw, packageName, permissionNames, dumpState, checkin);
15969            }
15970
15971            if (!checkin && dumpState.isDumping(DumpState.DUMP_INSTALLS) && packageName == null) {
15972                // XXX should handle packageName != null by dumping only install data that
15973                // the given package is involved with.
15974                if (dumpState.onTitlePrinted()) pw.println();
15975                mInstallerService.dump(new IndentingPrintWriter(pw, "  ", 120));
15976            }
15977
15978            if (!checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES) && packageName == null) {
15979                if (dumpState.onTitlePrinted()) pw.println();
15980                mSettings.dumpReadMessagesLPr(pw, dumpState);
15981
15982                pw.println();
15983                pw.println("Package warning messages:");
15984                BufferedReader in = null;
15985                String line = null;
15986                try {
15987                    in = new BufferedReader(new FileReader(getSettingsProblemFile()));
15988                    while ((line = in.readLine()) != null) {
15989                        if (line.contains("ignored: updated version")) continue;
15990                        pw.println(line);
15991                    }
15992                } catch (IOException ignored) {
15993                } finally {
15994                    IoUtils.closeQuietly(in);
15995                }
15996            }
15997
15998            if (checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES)) {
15999                BufferedReader in = null;
16000                String line = null;
16001                try {
16002                    in = new BufferedReader(new FileReader(getSettingsProblemFile()));
16003                    while ((line = in.readLine()) != null) {
16004                        if (line.contains("ignored: updated version")) continue;
16005                        pw.print("msg,");
16006                        pw.println(line);
16007                    }
16008                } catch (IOException ignored) {
16009                } finally {
16010                    IoUtils.closeQuietly(in);
16011                }
16012            }
16013        }
16014    }
16015
16016    private String dumpDomainString(String packageName) {
16017        List<IntentFilterVerificationInfo> iviList = getIntentFilterVerifications(packageName);
16018        List<IntentFilter> filters = getAllIntentFilters(packageName);
16019
16020        ArraySet<String> result = new ArraySet<>();
16021        if (iviList.size() > 0) {
16022            for (IntentFilterVerificationInfo ivi : iviList) {
16023                for (String host : ivi.getDomains()) {
16024                    result.add(host);
16025                }
16026            }
16027        }
16028        if (filters != null && filters.size() > 0) {
16029            for (IntentFilter filter : filters) {
16030                if (filter.hasCategory(Intent.CATEGORY_BROWSABLE)
16031                        && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) ||
16032                                filter.hasDataScheme(IntentFilter.SCHEME_HTTPS))) {
16033                    result.addAll(filter.getHostsList());
16034                }
16035            }
16036        }
16037
16038        StringBuilder sb = new StringBuilder(result.size() * 16);
16039        for (String domain : result) {
16040            if (sb.length() > 0) sb.append(" ");
16041            sb.append(domain);
16042        }
16043        return sb.toString();
16044    }
16045
16046    // ------- apps on sdcard specific code -------
16047    static final boolean DEBUG_SD_INSTALL = false;
16048
16049    private static final String SD_ENCRYPTION_KEYSTORE_NAME = "AppsOnSD";
16050
16051    private static final String SD_ENCRYPTION_ALGORITHM = "AES";
16052
16053    private boolean mMediaMounted = false;
16054
16055    static String getEncryptKey() {
16056        try {
16057            String sdEncKey = SystemKeyStore.getInstance().retrieveKeyHexString(
16058                    SD_ENCRYPTION_KEYSTORE_NAME);
16059            if (sdEncKey == null) {
16060                sdEncKey = SystemKeyStore.getInstance().generateNewKeyHexString(128,
16061                        SD_ENCRYPTION_ALGORITHM, SD_ENCRYPTION_KEYSTORE_NAME);
16062                if (sdEncKey == null) {
16063                    Slog.e(TAG, "Failed to create encryption keys");
16064                    return null;
16065                }
16066            }
16067            return sdEncKey;
16068        } catch (NoSuchAlgorithmException nsae) {
16069            Slog.e(TAG, "Failed to create encryption keys with exception: " + nsae);
16070            return null;
16071        } catch (IOException ioe) {
16072            Slog.e(TAG, "Failed to retrieve encryption keys with exception: " + ioe);
16073            return null;
16074        }
16075    }
16076
16077    /*
16078     * Update media status on PackageManager.
16079     */
16080    @Override
16081    public void updateExternalMediaStatus(final boolean mediaStatus, final boolean reportStatus) {
16082        int callingUid = Binder.getCallingUid();
16083        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
16084            throw new SecurityException("Media status can only be updated by the system");
16085        }
16086        // reader; this apparently protects mMediaMounted, but should probably
16087        // be a different lock in that case.
16088        synchronized (mPackages) {
16089            Log.i(TAG, "Updating external media status from "
16090                    + (mMediaMounted ? "mounted" : "unmounted") + " to "
16091                    + (mediaStatus ? "mounted" : "unmounted"));
16092            if (DEBUG_SD_INSTALL)
16093                Log.i(TAG, "updateExternalMediaStatus:: mediaStatus=" + mediaStatus
16094                        + ", mMediaMounted=" + mMediaMounted);
16095            if (mediaStatus == mMediaMounted) {
16096                final Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1
16097                        : 0, -1);
16098                mHandler.sendMessage(msg);
16099                return;
16100            }
16101            mMediaMounted = mediaStatus;
16102        }
16103        // Queue up an async operation since the package installation may take a
16104        // little while.
16105        mHandler.post(new Runnable() {
16106            public void run() {
16107                updateExternalMediaStatusInner(mediaStatus, reportStatus, true);
16108            }
16109        });
16110    }
16111
16112    /**
16113     * Called by MountService when the initial ASECs to scan are available.
16114     * Should block until all the ASEC containers are finished being scanned.
16115     */
16116    public void scanAvailableAsecs() {
16117        updateExternalMediaStatusInner(true, false, false);
16118        if (mShouldRestoreconData) {
16119            SELinuxMMAC.setRestoreconDone();
16120            mShouldRestoreconData = false;
16121        }
16122    }
16123
16124    /*
16125     * Collect information of applications on external media, map them against
16126     * existing containers and update information based on current mount status.
16127     * Please note that we always have to report status if reportStatus has been
16128     * set to true especially when unloading packages.
16129     */
16130    private void updateExternalMediaStatusInner(boolean isMounted, boolean reportStatus,
16131            boolean externalStorage) {
16132        ArrayMap<AsecInstallArgs, String> processCids = new ArrayMap<>();
16133        int[] uidArr = EmptyArray.INT;
16134
16135        final String[] list = PackageHelper.getSecureContainerList();
16136        if (ArrayUtils.isEmpty(list)) {
16137            Log.i(TAG, "No secure containers found");
16138        } else {
16139            // Process list of secure containers and categorize them
16140            // as active or stale based on their package internal state.
16141
16142            // reader
16143            synchronized (mPackages) {
16144                for (String cid : list) {
16145                    // Leave stages untouched for now; installer service owns them
16146                    if (PackageInstallerService.isStageName(cid)) continue;
16147
16148                    if (DEBUG_SD_INSTALL)
16149                        Log.i(TAG, "Processing container " + cid);
16150                    String pkgName = getAsecPackageName(cid);
16151                    if (pkgName == null) {
16152                        Slog.i(TAG, "Found stale container " + cid + " with no package name");
16153                        continue;
16154                    }
16155                    if (DEBUG_SD_INSTALL)
16156                        Log.i(TAG, "Looking for pkg : " + pkgName);
16157
16158                    final PackageSetting ps = mSettings.mPackages.get(pkgName);
16159                    if (ps == null) {
16160                        Slog.i(TAG, "Found stale container " + cid + " with no matching settings");
16161                        continue;
16162                    }
16163
16164                    /*
16165                     * Skip packages that are not external if we're unmounting
16166                     * external storage.
16167                     */
16168                    if (externalStorage && !isMounted && !isExternal(ps)) {
16169                        continue;
16170                    }
16171
16172                    final AsecInstallArgs args = new AsecInstallArgs(cid,
16173                            getAppDexInstructionSets(ps), ps.isForwardLocked());
16174                    // The package status is changed only if the code path
16175                    // matches between settings and the container id.
16176                    if (ps.codePathString != null
16177                            && ps.codePathString.startsWith(args.getCodePath())) {
16178                        if (DEBUG_SD_INSTALL) {
16179                            Log.i(TAG, "Container : " + cid + " corresponds to pkg : " + pkgName
16180                                    + " at code path: " + ps.codePathString);
16181                        }
16182
16183                        // We do have a valid package installed on sdcard
16184                        processCids.put(args, ps.codePathString);
16185                        final int uid = ps.appId;
16186                        if (uid != -1) {
16187                            uidArr = ArrayUtils.appendInt(uidArr, uid);
16188                        }
16189                    } else {
16190                        Slog.i(TAG, "Found stale container " + cid + ": expected codePath="
16191                                + ps.codePathString);
16192                    }
16193                }
16194            }
16195
16196            Arrays.sort(uidArr);
16197        }
16198
16199        // Process packages with valid entries.
16200        if (isMounted) {
16201            if (DEBUG_SD_INSTALL)
16202                Log.i(TAG, "Loading packages");
16203            loadMediaPackages(processCids, uidArr, externalStorage);
16204            startCleaningPackages();
16205            mInstallerService.onSecureContainersAvailable();
16206        } else {
16207            if (DEBUG_SD_INSTALL)
16208                Log.i(TAG, "Unloading packages");
16209            unloadMediaPackages(processCids, uidArr, reportStatus);
16210        }
16211    }
16212
16213    private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
16214            ArrayList<ApplicationInfo> infos, IIntentReceiver finishedReceiver) {
16215        final int size = infos.size();
16216        final String[] packageNames = new String[size];
16217        final int[] packageUids = new int[size];
16218        for (int i = 0; i < size; i++) {
16219            final ApplicationInfo info = infos.get(i);
16220            packageNames[i] = info.packageName;
16221            packageUids[i] = info.uid;
16222        }
16223        sendResourcesChangedBroadcast(mediaStatus, replacing, packageNames, packageUids,
16224                finishedReceiver);
16225    }
16226
16227    private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
16228            ArrayList<String> pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
16229        sendResourcesChangedBroadcast(mediaStatus, replacing,
16230                pkgList.toArray(new String[pkgList.size()]), uidArr, finishedReceiver);
16231    }
16232
16233    private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
16234            String[] pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
16235        int size = pkgList.length;
16236        if (size > 0) {
16237            // Send broadcasts here
16238            Bundle extras = new Bundle();
16239            extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
16240            if (uidArr != null) {
16241                extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidArr);
16242            }
16243            if (replacing) {
16244                extras.putBoolean(Intent.EXTRA_REPLACING, replacing);
16245            }
16246            String action = mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE
16247                    : Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE;
16248            sendPackageBroadcast(action, null, extras, 0, null, finishedReceiver, null);
16249        }
16250    }
16251
16252   /*
16253     * Look at potentially valid container ids from processCids If package
16254     * information doesn't match the one on record or package scanning fails,
16255     * the cid is added to list of removeCids. We currently don't delete stale
16256     * containers.
16257     */
16258    private void loadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int[] uidArr,
16259            boolean externalStorage) {
16260        ArrayList<String> pkgList = new ArrayList<String>();
16261        Set<AsecInstallArgs> keys = processCids.keySet();
16262
16263        for (AsecInstallArgs args : keys) {
16264            String codePath = processCids.get(args);
16265            if (DEBUG_SD_INSTALL)
16266                Log.i(TAG, "Loading container : " + args.cid);
16267            int retCode = PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
16268            try {
16269                // Make sure there are no container errors first.
16270                if (args.doPreInstall(PackageManager.INSTALL_SUCCEEDED) != PackageManager.INSTALL_SUCCEEDED) {
16271                    Slog.e(TAG, "Failed to mount cid : " + args.cid
16272                            + " when installing from sdcard");
16273                    continue;
16274                }
16275                // Check code path here.
16276                if (codePath == null || !codePath.startsWith(args.getCodePath())) {
16277                    Slog.e(TAG, "Container " + args.cid + " cachepath " + args.getCodePath()
16278                            + " does not match one in settings " + codePath);
16279                    continue;
16280                }
16281                // Parse package
16282                int parseFlags = mDefParseFlags;
16283                if (args.isExternalAsec()) {
16284                    parseFlags |= PackageParser.PARSE_EXTERNAL_STORAGE;
16285                }
16286                if (args.isFwdLocked()) {
16287                    parseFlags |= PackageParser.PARSE_FORWARD_LOCK;
16288                }
16289
16290                synchronized (mInstallLock) {
16291                    PackageParser.Package pkg = null;
16292                    try {
16293                        pkg = scanPackageTracedLI(new File(codePath), parseFlags, 0, 0, null);
16294                    } catch (PackageManagerException e) {
16295                        Slog.w(TAG, "Failed to scan " + codePath + ": " + e.getMessage());
16296                    }
16297                    // Scan the package
16298                    if (pkg != null) {
16299                        /*
16300                         * TODO why is the lock being held? doPostInstall is
16301                         * called in other places without the lock. This needs
16302                         * to be straightened out.
16303                         */
16304                        // writer
16305                        synchronized (mPackages) {
16306                            retCode = PackageManager.INSTALL_SUCCEEDED;
16307                            pkgList.add(pkg.packageName);
16308                            // Post process args
16309                            args.doPostInstall(PackageManager.INSTALL_SUCCEEDED,
16310                                    pkg.applicationInfo.uid);
16311                        }
16312                    } else {
16313                        Slog.i(TAG, "Failed to install pkg from  " + codePath + " from sdcard");
16314                    }
16315                }
16316
16317            } finally {
16318                if (retCode != PackageManager.INSTALL_SUCCEEDED) {
16319                    Log.w(TAG, "Container " + args.cid + " is stale, retCode=" + retCode);
16320                }
16321            }
16322        }
16323        // writer
16324        synchronized (mPackages) {
16325            // If the platform SDK has changed since the last time we booted,
16326            // we need to re-grant app permission to catch any new ones that
16327            // appear. This is really a hack, and means that apps can in some
16328            // cases get permissions that the user didn't initially explicitly
16329            // allow... it would be nice to have some better way to handle
16330            // this situation.
16331            final VersionInfo ver = externalStorage ? mSettings.getExternalVersion()
16332                    : mSettings.getInternalVersion();
16333            final String volumeUuid = externalStorage ? StorageManager.UUID_PRIMARY_PHYSICAL
16334                    : StorageManager.UUID_PRIVATE_INTERNAL;
16335
16336            int updateFlags = UPDATE_PERMISSIONS_ALL;
16337            if (ver.sdkVersion != mSdkVersion) {
16338                logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to "
16339                        + mSdkVersion + "; regranting permissions for external");
16340                updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
16341            }
16342            updatePermissionsLPw(null, null, volumeUuid, updateFlags);
16343
16344            // Yay, everything is now upgraded
16345            ver.forceCurrent();
16346
16347            // can downgrade to reader
16348            // Persist settings
16349            mSettings.writeLPr();
16350        }
16351        // Send a broadcast to let everyone know we are done processing
16352        if (pkgList.size() > 0) {
16353            sendResourcesChangedBroadcast(true, false, pkgList, uidArr, null);
16354        }
16355    }
16356
16357   /*
16358     * Utility method to unload a list of specified containers
16359     */
16360    private void unloadAllContainers(Set<AsecInstallArgs> cidArgs) {
16361        // Just unmount all valid containers.
16362        for (AsecInstallArgs arg : cidArgs) {
16363            synchronized (mInstallLock) {
16364                arg.doPostDeleteLI(false);
16365           }
16366       }
16367   }
16368
16369    /*
16370     * Unload packages mounted on external media. This involves deleting package
16371     * data from internal structures, sending broadcasts about diabled packages,
16372     * gc'ing to free up references, unmounting all secure containers
16373     * corresponding to packages on external media, and posting a
16374     * UPDATED_MEDIA_STATUS message if status has been requested. Please note
16375     * that we always have to post this message if status has been requested no
16376     * matter what.
16377     */
16378    private void unloadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int uidArr[],
16379            final boolean reportStatus) {
16380        if (DEBUG_SD_INSTALL)
16381            Log.i(TAG, "unloading media packages");
16382        ArrayList<String> pkgList = new ArrayList<String>();
16383        ArrayList<AsecInstallArgs> failedList = new ArrayList<AsecInstallArgs>();
16384        final Set<AsecInstallArgs> keys = processCids.keySet();
16385        for (AsecInstallArgs args : keys) {
16386            String pkgName = args.getPackageName();
16387            if (DEBUG_SD_INSTALL)
16388                Log.i(TAG, "Trying to unload pkg : " + pkgName);
16389            // Delete package internally
16390            PackageRemovedInfo outInfo = new PackageRemovedInfo();
16391            synchronized (mInstallLock) {
16392                boolean res = deletePackageLI(pkgName, null, false, null, null,
16393                        PackageManager.DELETE_KEEP_DATA, outInfo, false);
16394                if (res) {
16395                    pkgList.add(pkgName);
16396                } else {
16397                    Slog.e(TAG, "Failed to delete pkg from sdcard : " + pkgName);
16398                    failedList.add(args);
16399                }
16400            }
16401        }
16402
16403        // reader
16404        synchronized (mPackages) {
16405            // We didn't update the settings after removing each package;
16406            // write them now for all packages.
16407            mSettings.writeLPr();
16408        }
16409
16410        // We have to absolutely send UPDATED_MEDIA_STATUS only
16411        // after confirming that all the receivers processed the ordered
16412        // broadcast when packages get disabled, force a gc to clean things up.
16413        // and unload all the containers.
16414        if (pkgList.size() > 0) {
16415            sendResourcesChangedBroadcast(false, false, pkgList, uidArr,
16416                    new IIntentReceiver.Stub() {
16417                public void performReceive(Intent intent, int resultCode, String data,
16418                        Bundle extras, boolean ordered, boolean sticky,
16419                        int sendingUser) throws RemoteException {
16420                    Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS,
16421                            reportStatus ? 1 : 0, 1, keys);
16422                    mHandler.sendMessage(msg);
16423                }
16424            });
16425        } else {
16426            Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1 : 0, -1,
16427                    keys);
16428            mHandler.sendMessage(msg);
16429        }
16430    }
16431
16432    private void loadPrivatePackages(final VolumeInfo vol) {
16433        mHandler.post(new Runnable() {
16434            @Override
16435            public void run() {
16436                loadPrivatePackagesInner(vol);
16437            }
16438        });
16439    }
16440
16441    private void loadPrivatePackagesInner(VolumeInfo vol) {
16442        final ArrayList<ApplicationInfo> loaded = new ArrayList<>();
16443        final int parseFlags = mDefParseFlags | PackageParser.PARSE_EXTERNAL_STORAGE;
16444
16445        final VersionInfo ver;
16446        final List<PackageSetting> packages;
16447        synchronized (mPackages) {
16448            ver = mSettings.findOrCreateVersion(vol.fsUuid);
16449            packages = mSettings.getVolumePackagesLPr(vol.fsUuid);
16450        }
16451
16452        for (PackageSetting ps : packages) {
16453            synchronized (mInstallLock) {
16454                final PackageParser.Package pkg;
16455                try {
16456                    pkg = scanPackageTracedLI(ps.codePath, parseFlags, SCAN_INITIAL, 0, null);
16457                    loaded.add(pkg.applicationInfo);
16458                } catch (PackageManagerException e) {
16459                    Slog.w(TAG, "Failed to scan " + ps.codePath + ": " + e.getMessage());
16460                }
16461
16462                if (!Build.FINGERPRINT.equals(ver.fingerprint)) {
16463                    deleteCodeCacheDirsLI(ps.volumeUuid, ps.name);
16464                }
16465            }
16466        }
16467
16468        synchronized (mPackages) {
16469            int updateFlags = UPDATE_PERMISSIONS_ALL;
16470            if (ver.sdkVersion != mSdkVersion) {
16471                logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to "
16472                        + mSdkVersion + "; regranting permissions for " + vol.fsUuid);
16473                updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
16474            }
16475            updatePermissionsLPw(null, null, vol.fsUuid, updateFlags);
16476
16477            // Yay, everything is now upgraded
16478            ver.forceCurrent();
16479
16480            mSettings.writeLPr();
16481        }
16482
16483        if (DEBUG_INSTALL) Slog.d(TAG, "Loaded packages " + loaded);
16484        sendResourcesChangedBroadcast(true, false, loaded, null);
16485    }
16486
16487    private void unloadPrivatePackages(final VolumeInfo vol) {
16488        mHandler.post(new Runnable() {
16489            @Override
16490            public void run() {
16491                unloadPrivatePackagesInner(vol);
16492            }
16493        });
16494    }
16495
16496    private void unloadPrivatePackagesInner(VolumeInfo vol) {
16497        final ArrayList<ApplicationInfo> unloaded = new ArrayList<>();
16498        synchronized (mInstallLock) {
16499        synchronized (mPackages) {
16500            final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(vol.fsUuid);
16501            for (PackageSetting ps : packages) {
16502                if (ps.pkg == null) continue;
16503
16504                final ApplicationInfo info = ps.pkg.applicationInfo;
16505                final PackageRemovedInfo outInfo = new PackageRemovedInfo();
16506                if (deletePackageLI(ps.name, null, false, null, null,
16507                        PackageManager.DELETE_KEEP_DATA, outInfo, false)) {
16508                    unloaded.add(info);
16509                } else {
16510                    Slog.w(TAG, "Failed to unload " + ps.codePath);
16511                }
16512            }
16513
16514            mSettings.writeLPr();
16515        }
16516        }
16517
16518        if (DEBUG_INSTALL) Slog.d(TAG, "Unloaded packages " + unloaded);
16519        sendResourcesChangedBroadcast(false, false, unloaded, null);
16520    }
16521
16522    /**
16523     * Examine all users present on given mounted volume, and destroy data
16524     * belonging to users that are no longer valid, or whose user ID has been
16525     * recycled.
16526     */
16527    private void reconcileUsers(String volumeUuid) {
16528        final File[] files = FileUtils
16529                .listFilesOrEmpty(Environment.getDataUserDirectory(volumeUuid));
16530        for (File file : files) {
16531            if (!file.isDirectory()) continue;
16532
16533            final int userId;
16534            final UserInfo info;
16535            try {
16536                userId = Integer.parseInt(file.getName());
16537                info = sUserManager.getUserInfo(userId);
16538            } catch (NumberFormatException e) {
16539                Slog.w(TAG, "Invalid user directory " + file);
16540                continue;
16541            }
16542
16543            boolean destroyUser = false;
16544            if (info == null) {
16545                logCriticalInfo(Log.WARN, "Destroying user directory " + file
16546                        + " because no matching user was found");
16547                destroyUser = true;
16548            } else {
16549                try {
16550                    UserManagerService.enforceSerialNumber(file, info.serialNumber);
16551                } catch (IOException e) {
16552                    logCriticalInfo(Log.WARN, "Destroying user directory " + file
16553                            + " because we failed to enforce serial number: " + e);
16554                    destroyUser = true;
16555                }
16556            }
16557
16558            if (destroyUser) {
16559                synchronized (mInstallLock) {
16560                    mInstaller.removeUserDataDirs(volumeUuid, userId);
16561                }
16562            }
16563        }
16564
16565        final StorageManager sm = mContext.getSystemService(StorageManager.class);
16566        final UserManager um = mContext.getSystemService(UserManager.class);
16567        for (UserInfo user : um.getUsers()) {
16568            final File userDir = Environment.getDataUserDirectory(volumeUuid, user.id);
16569            if (userDir.exists()) continue;
16570
16571            try {
16572                sm.prepareUserStorage(volumeUuid, user.id, user.serialNumber, user.isEphemeral());
16573                UserManagerService.enforceSerialNumber(userDir, user.serialNumber);
16574            } catch (IOException e) {
16575                Log.wtf(TAG, "Failed to create user directory on " + volumeUuid, e);
16576            }
16577        }
16578    }
16579
16580    /**
16581     * Examine all apps present on given mounted volume, and destroy apps that
16582     * aren't expected, either due to uninstallation or reinstallation on
16583     * another volume.
16584     */
16585    private void reconcileApps(String volumeUuid) {
16586        final File[] files = FileUtils
16587                .listFilesOrEmpty(Environment.getDataAppDirectory(volumeUuid));
16588        for (File file : files) {
16589            final boolean isPackage = (isApkFile(file) || file.isDirectory())
16590                    && !PackageInstallerService.isStageName(file.getName());
16591            if (!isPackage) {
16592                // Ignore entries which are not packages
16593                continue;
16594            }
16595
16596            boolean destroyApp = false;
16597            String packageName = null;
16598            try {
16599                final PackageLite pkg = PackageParser.parsePackageLite(file,
16600                        PackageParser.PARSE_MUST_BE_APK);
16601                packageName = pkg.packageName;
16602
16603                synchronized (mPackages) {
16604                    final PackageSetting ps = mSettings.mPackages.get(packageName);
16605                    if (ps == null) {
16606                        logCriticalInfo(Log.WARN, "Destroying " + packageName + " on + "
16607                                + volumeUuid + " because we found no install record");
16608                        destroyApp = true;
16609                    } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) {
16610                        logCriticalInfo(Log.WARN, "Destroying " + packageName + " on "
16611                                + volumeUuid + " because we expected it on " + ps.volumeUuid);
16612                        destroyApp = true;
16613                    }
16614                }
16615
16616            } catch (PackageParserException e) {
16617                logCriticalInfo(Log.WARN, "Destroying " + file + " due to parse failure: " + e);
16618                destroyApp = true;
16619            }
16620
16621            if (destroyApp) {
16622                synchronized (mInstallLock) {
16623                    if (packageName != null) {
16624                        removeDataDirsLI(volumeUuid, packageName);
16625                    }
16626                    if (file.isDirectory()) {
16627                        mInstaller.rmPackageDir(file.getAbsolutePath());
16628                    } else {
16629                        file.delete();
16630                    }
16631                }
16632            }
16633        }
16634    }
16635
16636    private void unfreezePackage(String packageName) {
16637        synchronized (mPackages) {
16638            final PackageSetting ps = mSettings.mPackages.get(packageName);
16639            if (ps != null) {
16640                ps.frozen = false;
16641            }
16642        }
16643    }
16644
16645    @Override
16646    public int movePackage(final String packageName, final String volumeUuid) {
16647        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
16648
16649        final int moveId = mNextMoveId.getAndIncrement();
16650        mHandler.post(new Runnable() {
16651            @Override
16652            public void run() {
16653                try {
16654                    movePackageInternal(packageName, volumeUuid, moveId);
16655                } catch (PackageManagerException e) {
16656                    Slog.w(TAG, "Failed to move " + packageName, e);
16657                    mMoveCallbacks.notifyStatusChanged(moveId,
16658                            PackageManager.MOVE_FAILED_INTERNAL_ERROR);
16659                }
16660            }
16661        });
16662        return moveId;
16663    }
16664
16665    private void movePackageInternal(final String packageName, final String volumeUuid,
16666            final int moveId) throws PackageManagerException {
16667        final UserHandle user = new UserHandle(UserHandle.getCallingUserId());
16668        final StorageManager storage = mContext.getSystemService(StorageManager.class);
16669        final PackageManager pm = mContext.getPackageManager();
16670
16671        final boolean currentAsec;
16672        final String currentVolumeUuid;
16673        final File codeFile;
16674        final String installerPackageName;
16675        final String packageAbiOverride;
16676        final int appId;
16677        final String seinfo;
16678        final String label;
16679
16680        // reader
16681        synchronized (mPackages) {
16682            final PackageParser.Package pkg = mPackages.get(packageName);
16683            final PackageSetting ps = mSettings.mPackages.get(packageName);
16684            if (pkg == null || ps == null) {
16685                throw new PackageManagerException(MOVE_FAILED_DOESNT_EXIST, "Missing package");
16686            }
16687
16688            if (pkg.applicationInfo.isSystemApp()) {
16689                throw new PackageManagerException(MOVE_FAILED_SYSTEM_PACKAGE,
16690                        "Cannot move system application");
16691            }
16692
16693            if (pkg.applicationInfo.isExternalAsec()) {
16694                currentAsec = true;
16695                currentVolumeUuid = StorageManager.UUID_PRIMARY_PHYSICAL;
16696            } else if (pkg.applicationInfo.isForwardLocked()) {
16697                currentAsec = true;
16698                currentVolumeUuid = "forward_locked";
16699            } else {
16700                currentAsec = false;
16701                currentVolumeUuid = ps.volumeUuid;
16702
16703                final File probe = new File(pkg.codePath);
16704                final File probeOat = new File(probe, "oat");
16705                if (!probe.isDirectory() || !probeOat.isDirectory()) {
16706                    throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
16707                            "Move only supported for modern cluster style installs");
16708                }
16709            }
16710
16711            if (Objects.equals(currentVolumeUuid, volumeUuid)) {
16712                throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
16713                        "Package already moved to " + volumeUuid);
16714            }
16715
16716            if (ps.frozen) {
16717                throw new PackageManagerException(MOVE_FAILED_OPERATION_PENDING,
16718                        "Failed to move already frozen package");
16719            }
16720            ps.frozen = true;
16721
16722            codeFile = new File(pkg.codePath);
16723            installerPackageName = ps.installerPackageName;
16724            packageAbiOverride = ps.cpuAbiOverrideString;
16725            appId = UserHandle.getAppId(pkg.applicationInfo.uid);
16726            seinfo = pkg.applicationInfo.seinfo;
16727            label = String.valueOf(pm.getApplicationLabel(pkg.applicationInfo));
16728        }
16729
16730        // Now that we're guarded by frozen state, kill app during move
16731        final long token = Binder.clearCallingIdentity();
16732        try {
16733            killApplication(packageName, appId, "move pkg");
16734        } finally {
16735            Binder.restoreCallingIdentity(token);
16736        }
16737
16738        final Bundle extras = new Bundle();
16739        extras.putString(Intent.EXTRA_PACKAGE_NAME, packageName);
16740        extras.putString(Intent.EXTRA_TITLE, label);
16741        mMoveCallbacks.notifyCreated(moveId, extras);
16742
16743        int installFlags;
16744        final boolean moveCompleteApp;
16745        final File measurePath;
16746
16747        if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, volumeUuid)) {
16748            installFlags = INSTALL_INTERNAL;
16749            moveCompleteApp = !currentAsec;
16750            measurePath = Environment.getDataAppDirectory(volumeUuid);
16751        } else if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, volumeUuid)) {
16752            installFlags = INSTALL_EXTERNAL;
16753            moveCompleteApp = false;
16754            measurePath = storage.getPrimaryPhysicalVolume().getPath();
16755        } else {
16756            final VolumeInfo volume = storage.findVolumeByUuid(volumeUuid);
16757            if (volume == null || volume.getType() != VolumeInfo.TYPE_PRIVATE
16758                    || !volume.isMountedWritable()) {
16759                unfreezePackage(packageName);
16760                throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
16761                        "Move location not mounted private volume");
16762            }
16763
16764            Preconditions.checkState(!currentAsec);
16765
16766            installFlags = INSTALL_INTERNAL;
16767            moveCompleteApp = true;
16768            measurePath = Environment.getDataAppDirectory(volumeUuid);
16769        }
16770
16771        final PackageStats stats = new PackageStats(null, -1);
16772        synchronized (mInstaller) {
16773            if (!getPackageSizeInfoLI(packageName, -1, stats)) {
16774                unfreezePackage(packageName);
16775                throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
16776                        "Failed to measure package size");
16777            }
16778        }
16779
16780        if (DEBUG_INSTALL) Slog.d(TAG, "Measured code size " + stats.codeSize + ", data size "
16781                + stats.dataSize);
16782
16783        final long startFreeBytes = measurePath.getFreeSpace();
16784        final long sizeBytes;
16785        if (moveCompleteApp) {
16786            sizeBytes = stats.codeSize + stats.dataSize;
16787        } else {
16788            sizeBytes = stats.codeSize;
16789        }
16790
16791        if (sizeBytes > storage.getStorageBytesUntilLow(measurePath)) {
16792            unfreezePackage(packageName);
16793            throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
16794                    "Not enough free space to move");
16795        }
16796
16797        mMoveCallbacks.notifyStatusChanged(moveId, 10);
16798
16799        final CountDownLatch installedLatch = new CountDownLatch(1);
16800        final IPackageInstallObserver2 installObserver = new IPackageInstallObserver2.Stub() {
16801            @Override
16802            public void onUserActionRequired(Intent intent) throws RemoteException {
16803                throw new IllegalStateException();
16804            }
16805
16806            @Override
16807            public void onPackageInstalled(String basePackageName, int returnCode, String msg,
16808                    Bundle extras) throws RemoteException {
16809                if (DEBUG_INSTALL) Slog.d(TAG, "Install result for move: "
16810                        + PackageManager.installStatusToString(returnCode, msg));
16811
16812                installedLatch.countDown();
16813
16814                // Regardless of success or failure of the move operation,
16815                // always unfreeze the package
16816                unfreezePackage(packageName);
16817
16818                final int status = PackageManager.installStatusToPublicStatus(returnCode);
16819                switch (status) {
16820                    case PackageInstaller.STATUS_SUCCESS:
16821                        mMoveCallbacks.notifyStatusChanged(moveId,
16822                                PackageManager.MOVE_SUCCEEDED);
16823                        break;
16824                    case PackageInstaller.STATUS_FAILURE_STORAGE:
16825                        mMoveCallbacks.notifyStatusChanged(moveId,
16826                                PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE);
16827                        break;
16828                    default:
16829                        mMoveCallbacks.notifyStatusChanged(moveId,
16830                                PackageManager.MOVE_FAILED_INTERNAL_ERROR);
16831                        break;
16832                }
16833            }
16834        };
16835
16836        final MoveInfo move;
16837        if (moveCompleteApp) {
16838            // Kick off a thread to report progress estimates
16839            new Thread() {
16840                @Override
16841                public void run() {
16842                    while (true) {
16843                        try {
16844                            if (installedLatch.await(1, TimeUnit.SECONDS)) {
16845                                break;
16846                            }
16847                        } catch (InterruptedException ignored) {
16848                        }
16849
16850                        final long deltaFreeBytes = startFreeBytes - measurePath.getFreeSpace();
16851                        final int progress = 10 + (int) MathUtils.constrain(
16852                                ((deltaFreeBytes * 80) / sizeBytes), 0, 80);
16853                        mMoveCallbacks.notifyStatusChanged(moveId, progress);
16854                    }
16855                }
16856            }.start();
16857
16858            final String dataAppName = codeFile.getName();
16859            move = new MoveInfo(moveId, currentVolumeUuid, volumeUuid, packageName,
16860                    dataAppName, appId, seinfo);
16861        } else {
16862            move = null;
16863        }
16864
16865        installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
16866
16867        final Message msg = mHandler.obtainMessage(INIT_COPY);
16868        final OriginInfo origin = OriginInfo.fromExistingFile(codeFile);
16869        final InstallParams params = new InstallParams(origin, move, installObserver, installFlags,
16870                installerPackageName, volumeUuid, null, user, packageAbiOverride, null);
16871        params.setTraceMethod("movePackage").setTraceCookie(System.identityHashCode(params));
16872        msg.obj = params;
16873
16874        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "movePackage",
16875                System.identityHashCode(msg.obj));
16876        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
16877                System.identityHashCode(msg.obj));
16878
16879        mHandler.sendMessage(msg);
16880    }
16881
16882    @Override
16883    public int movePrimaryStorage(String volumeUuid) throws RemoteException {
16884        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
16885
16886        final int realMoveId = mNextMoveId.getAndIncrement();
16887        final Bundle extras = new Bundle();
16888        extras.putString(VolumeRecord.EXTRA_FS_UUID, volumeUuid);
16889        mMoveCallbacks.notifyCreated(realMoveId, extras);
16890
16891        final IPackageMoveObserver callback = new IPackageMoveObserver.Stub() {
16892            @Override
16893            public void onCreated(int moveId, Bundle extras) {
16894                // Ignored
16895            }
16896
16897            @Override
16898            public void onStatusChanged(int moveId, int status, long estMillis) {
16899                mMoveCallbacks.notifyStatusChanged(realMoveId, status, estMillis);
16900            }
16901        };
16902
16903        final StorageManager storage = mContext.getSystemService(StorageManager.class);
16904        storage.setPrimaryStorageUuid(volumeUuid, callback);
16905        return realMoveId;
16906    }
16907
16908    @Override
16909    public int getMoveStatus(int moveId) {
16910        mContext.enforceCallingOrSelfPermission(
16911                android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
16912        return mMoveCallbacks.mLastStatus.get(moveId);
16913    }
16914
16915    @Override
16916    public void registerMoveCallback(IPackageMoveObserver callback) {
16917        mContext.enforceCallingOrSelfPermission(
16918                android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
16919        mMoveCallbacks.register(callback);
16920    }
16921
16922    @Override
16923    public void unregisterMoveCallback(IPackageMoveObserver callback) {
16924        mContext.enforceCallingOrSelfPermission(
16925                android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
16926        mMoveCallbacks.unregister(callback);
16927    }
16928
16929    @Override
16930    public boolean setInstallLocation(int loc) {
16931        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS,
16932                null);
16933        if (getInstallLocation() == loc) {
16934            return true;
16935        }
16936        if (loc == PackageHelper.APP_INSTALL_AUTO || loc == PackageHelper.APP_INSTALL_INTERNAL
16937                || loc == PackageHelper.APP_INSTALL_EXTERNAL) {
16938            android.provider.Settings.Global.putInt(mContext.getContentResolver(),
16939                    android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, loc);
16940            return true;
16941        }
16942        return false;
16943   }
16944
16945    @Override
16946    public int getInstallLocation() {
16947        return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
16948                android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION,
16949                PackageHelper.APP_INSTALL_AUTO);
16950    }
16951
16952    /** Called by UserManagerService */
16953    void cleanUpUser(UserManagerService userManager, int userHandle) {
16954        synchronized (mPackages) {
16955            mDirtyUsers.remove(userHandle);
16956            mUserNeedsBadging.delete(userHandle);
16957            mSettings.removeUserLPw(userHandle);
16958            mPendingBroadcasts.remove(userHandle);
16959            mEphemeralApplicationRegistry.onUserRemovedLPw(userHandle);
16960        }
16961        synchronized (mInstallLock) {
16962            final StorageManager storage = mContext.getSystemService(StorageManager.class);
16963            for (VolumeInfo vol : storage.getWritablePrivateVolumes()) {
16964                final String volumeUuid = vol.getFsUuid();
16965                if (DEBUG_INSTALL) Slog.d(TAG, "Removing user data on volume " + volumeUuid);
16966                mInstaller.removeUserDataDirs(volumeUuid, userHandle);
16967            }
16968            synchronized (mPackages) {
16969                removeUnusedPackagesLILPw(userManager, userHandle);
16970            }
16971        }
16972    }
16973
16974    /**
16975     * We're removing userHandle and would like to remove any downloaded packages
16976     * that are no longer in use by any other user.
16977     * @param userHandle the user being removed
16978     */
16979    private void removeUnusedPackagesLILPw(UserManagerService userManager, final int userHandle) {
16980        final boolean DEBUG_CLEAN_APKS = false;
16981        int [] users = userManager.getUserIds();
16982        Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
16983        while (psit.hasNext()) {
16984            PackageSetting ps = psit.next();
16985            if (ps.pkg == null) {
16986                continue;
16987            }
16988            final String packageName = ps.pkg.packageName;
16989            // Skip over if system app
16990            if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) {
16991                continue;
16992            }
16993            if (DEBUG_CLEAN_APKS) {
16994                Slog.i(TAG, "Checking package " + packageName);
16995            }
16996            boolean keep = shouldKeepUninstalledPackageLPr(packageName);
16997            if (keep) {
16998                if (DEBUG_CLEAN_APKS) {
16999                    Slog.i(TAG, "  Keeping package " + packageName + " - requested by DO");
17000                }
17001            } else {
17002                for (int i = 0; i < users.length; i++) {
17003                    if (users[i] != userHandle && ps.getInstalled(users[i])) {
17004                        keep = true;
17005                        if (DEBUG_CLEAN_APKS) {
17006                            Slog.i(TAG, "  Keeping package " + packageName + " for user "
17007                                    + users[i]);
17008                        }
17009                        break;
17010                    }
17011                }
17012            }
17013            if (!keep) {
17014                if (DEBUG_CLEAN_APKS) {
17015                    Slog.i(TAG, "  Removing package " + packageName);
17016                }
17017                mHandler.post(new Runnable() {
17018                    public void run() {
17019                        deletePackageX(packageName, userHandle, 0);
17020                    } //end run
17021                });
17022            }
17023        }
17024    }
17025
17026    /** Called by UserManagerService */
17027    void createNewUser(int userHandle) {
17028        synchronized (mInstallLock) {
17029            mInstaller.createUserConfig(userHandle);
17030            mSettings.createNewUserLI(this, mInstaller, userHandle);
17031        }
17032        synchronized (mPackages) {
17033            applyFactoryDefaultBrowserLPw(userHandle);
17034            primeDomainVerificationsLPw(userHandle);
17035        }
17036    }
17037
17038    void newUserCreated(final int userHandle) {
17039        mDefaultPermissionPolicy.grantDefaultPermissions(userHandle);
17040        // If permission review for legacy apps is required, we represent
17041        // dagerous permissions for such apps as always granted runtime
17042        // permissions to keep per user flag state whether review is needed.
17043        // Hence, if a new user is added we have to propagate dangerous
17044        // permission grants for these legacy apps.
17045        if (Build.PERMISSIONS_REVIEW_REQUIRED) {
17046            updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL
17047                    | UPDATE_PERMISSIONS_REPLACE_ALL);
17048        }
17049    }
17050
17051    @Override
17052    public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException {
17053        mContext.enforceCallingOrSelfPermission(
17054                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
17055                "Only package verification agents can read the verifier device identity");
17056
17057        synchronized (mPackages) {
17058            return mSettings.getVerifierDeviceIdentityLPw();
17059        }
17060    }
17061
17062    @Override
17063    public void setPermissionEnforced(String permission, boolean enforced) {
17064        // TODO: Now that we no longer change GID for storage, this should to away.
17065        mContext.enforceCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
17066                "setPermissionEnforced");
17067        if (READ_EXTERNAL_STORAGE.equals(permission)) {
17068            synchronized (mPackages) {
17069                if (mSettings.mReadExternalStorageEnforced == null
17070                        || mSettings.mReadExternalStorageEnforced != enforced) {
17071                    mSettings.mReadExternalStorageEnforced = enforced;
17072                    mSettings.writeLPr();
17073                }
17074            }
17075            // kill any non-foreground processes so we restart them and
17076            // grant/revoke the GID.
17077            final IActivityManager am = ActivityManagerNative.getDefault();
17078            if (am != null) {
17079                final long token = Binder.clearCallingIdentity();
17080                try {
17081                    am.killProcessesBelowForeground("setPermissionEnforcement");
17082                } catch (RemoteException e) {
17083                } finally {
17084                    Binder.restoreCallingIdentity(token);
17085                }
17086            }
17087        } else {
17088            throw new IllegalArgumentException("No selective enforcement for " + permission);
17089        }
17090    }
17091
17092    @Override
17093    @Deprecated
17094    public boolean isPermissionEnforced(String permission) {
17095        return true;
17096    }
17097
17098    @Override
17099    public boolean isStorageLow() {
17100        final long token = Binder.clearCallingIdentity();
17101        try {
17102            final DeviceStorageMonitorInternal
17103                    dsm = LocalServices.getService(DeviceStorageMonitorInternal.class);
17104            if (dsm != null) {
17105                return dsm.isMemoryLow();
17106            } else {
17107                return false;
17108            }
17109        } finally {
17110            Binder.restoreCallingIdentity(token);
17111        }
17112    }
17113
17114    @Override
17115    public IPackageInstaller getPackageInstaller() {
17116        return mInstallerService;
17117    }
17118
17119    private boolean userNeedsBadging(int userId) {
17120        int index = mUserNeedsBadging.indexOfKey(userId);
17121        if (index < 0) {
17122            final UserInfo userInfo;
17123            final long token = Binder.clearCallingIdentity();
17124            try {
17125                userInfo = sUserManager.getUserInfo(userId);
17126            } finally {
17127                Binder.restoreCallingIdentity(token);
17128            }
17129            final boolean b;
17130            if (userInfo != null && userInfo.isManagedProfile()) {
17131                b = true;
17132            } else {
17133                b = false;
17134            }
17135            mUserNeedsBadging.put(userId, b);
17136            return b;
17137        }
17138        return mUserNeedsBadging.valueAt(index);
17139    }
17140
17141    @Override
17142    public KeySet getKeySetByAlias(String packageName, String alias) {
17143        if (packageName == null || alias == null) {
17144            return null;
17145        }
17146        synchronized(mPackages) {
17147            final PackageParser.Package pkg = mPackages.get(packageName);
17148            if (pkg == null) {
17149                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
17150                throw new IllegalArgumentException("Unknown package: " + packageName);
17151            }
17152            KeySetManagerService ksms = mSettings.mKeySetManagerService;
17153            return new KeySet(ksms.getKeySetByAliasAndPackageNameLPr(packageName, alias));
17154        }
17155    }
17156
17157    @Override
17158    public KeySet getSigningKeySet(String packageName) {
17159        if (packageName == null) {
17160            return null;
17161        }
17162        synchronized(mPackages) {
17163            final PackageParser.Package pkg = mPackages.get(packageName);
17164            if (pkg == null) {
17165                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
17166                throw new IllegalArgumentException("Unknown package: " + packageName);
17167            }
17168            if (pkg.applicationInfo.uid != Binder.getCallingUid()
17169                    && Process.SYSTEM_UID != Binder.getCallingUid()) {
17170                throw new SecurityException("May not access signing KeySet of other apps.");
17171            }
17172            KeySetManagerService ksms = mSettings.mKeySetManagerService;
17173            return new KeySet(ksms.getSigningKeySetByPackageNameLPr(packageName));
17174        }
17175    }
17176
17177    @Override
17178    public boolean isPackageSignedByKeySet(String packageName, KeySet ks) {
17179        if (packageName == null || ks == null) {
17180            return false;
17181        }
17182        synchronized(mPackages) {
17183            final PackageParser.Package pkg = mPackages.get(packageName);
17184            if (pkg == null) {
17185                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
17186                throw new IllegalArgumentException("Unknown package: " + packageName);
17187            }
17188            IBinder ksh = ks.getToken();
17189            if (ksh instanceof KeySetHandle) {
17190                KeySetManagerService ksms = mSettings.mKeySetManagerService;
17191                return ksms.packageIsSignedByLPr(packageName, (KeySetHandle) ksh);
17192            }
17193            return false;
17194        }
17195    }
17196
17197    @Override
17198    public boolean isPackageSignedByKeySetExactly(String packageName, KeySet ks) {
17199        if (packageName == null || ks == null) {
17200            return false;
17201        }
17202        synchronized(mPackages) {
17203            final PackageParser.Package pkg = mPackages.get(packageName);
17204            if (pkg == null) {
17205                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
17206                throw new IllegalArgumentException("Unknown package: " + packageName);
17207            }
17208            IBinder ksh = ks.getToken();
17209            if (ksh instanceof KeySetHandle) {
17210                KeySetManagerService ksms = mSettings.mKeySetManagerService;
17211                return ksms.packageIsSignedByExactlyLPr(packageName, (KeySetHandle) ksh);
17212            }
17213            return false;
17214        }
17215    }
17216
17217    private void deletePackageIfUnusedLPr(final String packageName) {
17218        PackageSetting ps = mSettings.mPackages.get(packageName);
17219        if (ps == null) {
17220            return;
17221        }
17222        if (!ps.isAnyInstalled(sUserManager.getUserIds())) {
17223            // TODO Implement atomic delete if package is unused
17224            // It is currently possible that the package will be deleted even if it is installed
17225            // after this method returns.
17226            mHandler.post(new Runnable() {
17227                public void run() {
17228                    deletePackageX(packageName, 0, PackageManager.DELETE_ALL_USERS);
17229                }
17230            });
17231        }
17232    }
17233
17234    /**
17235     * Check and throw if the given before/after packages would be considered a
17236     * downgrade.
17237     */
17238    private static void checkDowngrade(PackageParser.Package before, PackageInfoLite after)
17239            throws PackageManagerException {
17240        if (after.versionCode < before.mVersionCode) {
17241            throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
17242                    "Update version code " + after.versionCode + " is older than current "
17243                    + before.mVersionCode);
17244        } else if (after.versionCode == before.mVersionCode) {
17245            if (after.baseRevisionCode < before.baseRevisionCode) {
17246                throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
17247                        "Update base revision code " + after.baseRevisionCode
17248                        + " is older than current " + before.baseRevisionCode);
17249            }
17250
17251            if (!ArrayUtils.isEmpty(after.splitNames)) {
17252                for (int i = 0; i < after.splitNames.length; i++) {
17253                    final String splitName = after.splitNames[i];
17254                    final int j = ArrayUtils.indexOf(before.splitNames, splitName);
17255                    if (j != -1) {
17256                        if (after.splitRevisionCodes[i] < before.splitRevisionCodes[j]) {
17257                            throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
17258                                    "Update split " + splitName + " revision code "
17259                                    + after.splitRevisionCodes[i] + " is older than current "
17260                                    + before.splitRevisionCodes[j]);
17261                        }
17262                    }
17263                }
17264            }
17265        }
17266    }
17267
17268    private static class MoveCallbacks extends Handler {
17269        private static final int MSG_CREATED = 1;
17270        private static final int MSG_STATUS_CHANGED = 2;
17271
17272        private final RemoteCallbackList<IPackageMoveObserver>
17273                mCallbacks = new RemoteCallbackList<>();
17274
17275        private final SparseIntArray mLastStatus = new SparseIntArray();
17276
17277        public MoveCallbacks(Looper looper) {
17278            super(looper);
17279        }
17280
17281        public void register(IPackageMoveObserver callback) {
17282            mCallbacks.register(callback);
17283        }
17284
17285        public void unregister(IPackageMoveObserver callback) {
17286            mCallbacks.unregister(callback);
17287        }
17288
17289        @Override
17290        public void handleMessage(Message msg) {
17291            final SomeArgs args = (SomeArgs) msg.obj;
17292            final int n = mCallbacks.beginBroadcast();
17293            for (int i = 0; i < n; i++) {
17294                final IPackageMoveObserver callback = mCallbacks.getBroadcastItem(i);
17295                try {
17296                    invokeCallback(callback, msg.what, args);
17297                } catch (RemoteException ignored) {
17298                }
17299            }
17300            mCallbacks.finishBroadcast();
17301            args.recycle();
17302        }
17303
17304        private void invokeCallback(IPackageMoveObserver callback, int what, SomeArgs args)
17305                throws RemoteException {
17306            switch (what) {
17307                case MSG_CREATED: {
17308                    callback.onCreated(args.argi1, (Bundle) args.arg2);
17309                    break;
17310                }
17311                case MSG_STATUS_CHANGED: {
17312                    callback.onStatusChanged(args.argi1, args.argi2, (long) args.arg3);
17313                    break;
17314                }
17315            }
17316        }
17317
17318        private void notifyCreated(int moveId, Bundle extras) {
17319            Slog.v(TAG, "Move " + moveId + " created " + extras.toString());
17320
17321            final SomeArgs args = SomeArgs.obtain();
17322            args.argi1 = moveId;
17323            args.arg2 = extras;
17324            obtainMessage(MSG_CREATED, args).sendToTarget();
17325        }
17326
17327        private void notifyStatusChanged(int moveId, int status) {
17328            notifyStatusChanged(moveId, status, -1);
17329        }
17330
17331        private void notifyStatusChanged(int moveId, int status, long estMillis) {
17332            Slog.v(TAG, "Move " + moveId + " status " + status);
17333
17334            final SomeArgs args = SomeArgs.obtain();
17335            args.argi1 = moveId;
17336            args.argi2 = status;
17337            args.arg3 = estMillis;
17338            obtainMessage(MSG_STATUS_CHANGED, args).sendToTarget();
17339
17340            synchronized (mLastStatus) {
17341                mLastStatus.put(moveId, status);
17342            }
17343        }
17344    }
17345
17346    private final static class OnPermissionChangeListeners extends Handler {
17347        private static final int MSG_ON_PERMISSIONS_CHANGED = 1;
17348
17349        private final RemoteCallbackList<IOnPermissionsChangeListener> mPermissionListeners =
17350                new RemoteCallbackList<>();
17351
17352        public OnPermissionChangeListeners(Looper looper) {
17353            super(looper);
17354        }
17355
17356        @Override
17357        public void handleMessage(Message msg) {
17358            switch (msg.what) {
17359                case MSG_ON_PERMISSIONS_CHANGED: {
17360                    final int uid = msg.arg1;
17361                    handleOnPermissionsChanged(uid);
17362                } break;
17363            }
17364        }
17365
17366        public void addListenerLocked(IOnPermissionsChangeListener listener) {
17367            mPermissionListeners.register(listener);
17368
17369        }
17370
17371        public void removeListenerLocked(IOnPermissionsChangeListener listener) {
17372            mPermissionListeners.unregister(listener);
17373        }
17374
17375        public void onPermissionsChanged(int uid) {
17376            if (mPermissionListeners.getRegisteredCallbackCount() > 0) {
17377                obtainMessage(MSG_ON_PERMISSIONS_CHANGED, uid, 0).sendToTarget();
17378            }
17379        }
17380
17381        private void handleOnPermissionsChanged(int uid) {
17382            final int count = mPermissionListeners.beginBroadcast();
17383            try {
17384                for (int i = 0; i < count; i++) {
17385                    IOnPermissionsChangeListener callback = mPermissionListeners
17386                            .getBroadcastItem(i);
17387                    try {
17388                        callback.onPermissionsChanged(uid);
17389                    } catch (RemoteException e) {
17390                        Log.e(TAG, "Permission listener is dead", e);
17391                    }
17392                }
17393            } finally {
17394                mPermissionListeners.finishBroadcast();
17395            }
17396        }
17397    }
17398
17399    private class PackageManagerInternalImpl extends PackageManagerInternal {
17400        @Override
17401        public void setLocationPackagesProvider(PackagesProvider provider) {
17402            synchronized (mPackages) {
17403                mDefaultPermissionPolicy.setLocationPackagesProviderLPw(provider);
17404            }
17405        }
17406
17407        @Override
17408        public void setImePackagesProvider(PackagesProvider provider) {
17409            synchronized (mPackages) {
17410                mDefaultPermissionPolicy.setImePackagesProviderLPr(provider);
17411            }
17412        }
17413
17414        @Override
17415        public void setVoiceInteractionPackagesProvider(PackagesProvider provider) {
17416            synchronized (mPackages) {
17417                mDefaultPermissionPolicy.setVoiceInteractionPackagesProviderLPw(provider);
17418            }
17419        }
17420
17421        @Override
17422        public void setSmsAppPackagesProvider(PackagesProvider provider) {
17423            synchronized (mPackages) {
17424                mDefaultPermissionPolicy.setSmsAppPackagesProviderLPw(provider);
17425            }
17426        }
17427
17428        @Override
17429        public void setDialerAppPackagesProvider(PackagesProvider provider) {
17430            synchronized (mPackages) {
17431                mDefaultPermissionPolicy.setDialerAppPackagesProviderLPw(provider);
17432            }
17433        }
17434
17435        @Override
17436        public void setSimCallManagerPackagesProvider(PackagesProvider provider) {
17437            synchronized (mPackages) {
17438                mDefaultPermissionPolicy.setSimCallManagerPackagesProviderLPw(provider);
17439            }
17440        }
17441
17442        @Override
17443        public void setSyncAdapterPackagesprovider(SyncAdapterPackagesProvider provider) {
17444            synchronized (mPackages) {
17445                mDefaultPermissionPolicy.setSyncAdapterPackagesProviderLPw(provider);
17446            }
17447        }
17448
17449        @Override
17450        public void grantDefaultPermissionsToDefaultSmsApp(String packageName, int userId) {
17451            synchronized (mPackages) {
17452                mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSmsAppLPr(
17453                        packageName, userId);
17454            }
17455        }
17456
17457        @Override
17458        public void grantDefaultPermissionsToDefaultDialerApp(String packageName, int userId) {
17459            synchronized (mPackages) {
17460                mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultDialerAppLPr(
17461                        packageName, userId);
17462            }
17463        }
17464
17465        @Override
17466        public void grantDefaultPermissionsToDefaultSimCallManager(String packageName, int userId) {
17467            synchronized (mPackages) {
17468                mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSimCallManagerLPr(
17469                        packageName, userId);
17470            }
17471        }
17472
17473        @Override
17474        public void setKeepUninstalledPackages(final List<String> packageList) {
17475            Preconditions.checkNotNull(packageList);
17476            List<String> removedFromList = null;
17477            synchronized (mPackages) {
17478                if (mKeepUninstalledPackages != null) {
17479                    final int packagesCount = mKeepUninstalledPackages.size();
17480                    for (int i = 0; i < packagesCount; i++) {
17481                        String oldPackage = mKeepUninstalledPackages.get(i);
17482                        if (packageList != null && packageList.contains(oldPackage)) {
17483                            continue;
17484                        }
17485                        if (removedFromList == null) {
17486                            removedFromList = new ArrayList<>();
17487                        }
17488                        removedFromList.add(oldPackage);
17489                    }
17490                }
17491                mKeepUninstalledPackages = new ArrayList<>(packageList);
17492                if (removedFromList != null) {
17493                    final int removedCount = removedFromList.size();
17494                    for (int i = 0; i < removedCount; i++) {
17495                        deletePackageIfUnusedLPr(removedFromList.get(i));
17496                    }
17497                }
17498            }
17499        }
17500
17501        @Override
17502        public boolean isPermissionsReviewRequired(String packageName, int userId) {
17503            synchronized (mPackages) {
17504                // If we do not support permission review, done.
17505                if (!Build.PERMISSIONS_REVIEW_REQUIRED) {
17506                    return false;
17507                }
17508
17509                PackageSetting packageSetting = mSettings.mPackages.get(packageName);
17510                if (packageSetting == null) {
17511                    return false;
17512                }
17513
17514                // Permission review applies only to apps not supporting the new permission model.
17515                if (packageSetting.pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.M) {
17516                    return false;
17517                }
17518
17519                // Legacy apps have the permission and get user consent on launch.
17520                PermissionsState permissionsState = packageSetting.getPermissionsState();
17521                return permissionsState.isPermissionReviewRequired(userId);
17522            }
17523        }
17524    }
17525
17526    @Override
17527    public void grantDefaultPermissionsToEnabledCarrierApps(String[] packageNames, int userId) {
17528        enforceSystemOrPhoneCaller("grantPermissionsToEnabledCarrierApps");
17529        synchronized (mPackages) {
17530            final long identity = Binder.clearCallingIdentity();
17531            try {
17532                mDefaultPermissionPolicy.grantDefaultPermissionsToEnabledCarrierAppsLPr(
17533                        packageNames, userId);
17534            } finally {
17535                Binder.restoreCallingIdentity(identity);
17536            }
17537        }
17538    }
17539
17540    private static void enforceSystemOrPhoneCaller(String tag) {
17541        int callingUid = Binder.getCallingUid();
17542        if (callingUid != Process.PHONE_UID && callingUid != Process.SYSTEM_UID) {
17543            throw new SecurityException(
17544                    "Cannot call " + tag + " from UID " + callingUid);
17545        }
17546    }
17547}
17548