PackageManagerService.java revision e46fbfaf2e5759b54091dd62e2e9cf14a8545fcf
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 = getRequiredVerifierLPr();
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 @NonNull String getRequiredVerifierLPr() {
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            throw new RuntimeException("There must be exactly one verifier; found " + matches);
2450        }
2451    }
2452
2453    private @NonNull String getRequiredInstallerLPr() {
2454        final Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
2455        intent.addCategory(Intent.CATEGORY_DEFAULT);
2456        intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE);
2457
2458        final List<ResolveInfo> matches = queryIntentActivities(intent, PACKAGE_MIME_TYPE,
2459                MATCH_SYSTEM_ONLY | MATCH_ENCRYPTION_AWARE_AND_UNAWARE, UserHandle.USER_SYSTEM);
2460        if (matches.size() == 1) {
2461            return matches.get(0).getComponentInfo().packageName;
2462        } else {
2463            throw new RuntimeException("There must be exactly one installer; found " + matches);
2464        }
2465    }
2466
2467    private @NonNull ComponentName getIntentFilterVerifierComponentNameLPr() {
2468        final Intent intent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION);
2469
2470        final List<ResolveInfo> matches = queryIntentReceivers(intent, PACKAGE_MIME_TYPE,
2471                MATCH_SYSTEM_ONLY | MATCH_ENCRYPTION_AWARE_AND_UNAWARE, UserHandle.USER_SYSTEM);
2472        ResolveInfo best = null;
2473        final int N = matches.size();
2474        for (int i = 0; i < N; i++) {
2475            final ResolveInfo cur = matches.get(i);
2476            final String packageName = cur.getComponentInfo().packageName;
2477            if (checkPermission(android.Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT,
2478                    packageName, UserHandle.USER_SYSTEM) != PackageManager.PERMISSION_GRANTED) {
2479                continue;
2480            }
2481
2482            if (best == null || cur.priority > best.priority) {
2483                best = cur;
2484            }
2485        }
2486
2487        if (best != null) {
2488            return best.getComponentInfo().getComponentName();
2489        } else {
2490            throw new RuntimeException("There must be at least one intent filter verifier");
2491        }
2492    }
2493
2494    private @Nullable ComponentName getEphemeralResolverLPr() {
2495        final String[] packageArray =
2496                mContext.getResources().getStringArray(R.array.config_ephemeralResolverPackage);
2497        if (packageArray.length == 0) {
2498            if (DEBUG_EPHEMERAL) {
2499                Slog.d(TAG, "Ephemeral resolver NOT found; empty package list");
2500            }
2501            return null;
2502        }
2503
2504        final Intent resolverIntent = new Intent(Intent.ACTION_RESOLVE_EPHEMERAL_PACKAGE);
2505        final List<ResolveInfo> resolvers = queryIntentServices(resolverIntent, null,
2506                MATCH_SYSTEM_ONLY | MATCH_ENCRYPTION_AWARE_AND_UNAWARE, UserHandle.USER_SYSTEM);
2507
2508        final int N = resolvers.size();
2509        if (N == 0) {
2510            if (DEBUG_EPHEMERAL) {
2511                Slog.d(TAG, "Ephemeral resolver NOT found; no matching intent filters");
2512            }
2513            return null;
2514        }
2515
2516        final Set<String> possiblePackages = new ArraySet<>(Arrays.asList(packageArray));
2517        for (int i = 0; i < N; i++) {
2518            final ResolveInfo info = resolvers.get(i);
2519
2520            if (info.serviceInfo == null) {
2521                continue;
2522            }
2523
2524            final String packageName = info.serviceInfo.packageName;
2525            if (!possiblePackages.contains(packageName)) {
2526                if (DEBUG_EPHEMERAL) {
2527                    Slog.d(TAG, "Ephemeral resolver not in allowed package list;"
2528                            + " pkg: " + packageName + ", info:" + info);
2529                }
2530                continue;
2531            }
2532
2533            if (DEBUG_EPHEMERAL) {
2534                Slog.v(TAG, "Ephemeral resolver found;"
2535                        + " pkg: " + packageName + ", info:" + info);
2536            }
2537            return new ComponentName(packageName, info.serviceInfo.name);
2538        }
2539        if (DEBUG_EPHEMERAL) {
2540            Slog.v(TAG, "Ephemeral resolver NOT found");
2541        }
2542        return null;
2543    }
2544
2545    private @Nullable ComponentName getEphemeralInstallerLPr() {
2546        final Intent intent = new Intent(Intent.ACTION_INSTALL_EPHEMERAL_PACKAGE);
2547        intent.addCategory(Intent.CATEGORY_DEFAULT);
2548        intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE);
2549
2550        final List<ResolveInfo> matches = queryIntentActivities(intent, PACKAGE_MIME_TYPE,
2551                MATCH_SYSTEM_ONLY | MATCH_ENCRYPTION_AWARE_AND_UNAWARE, UserHandle.USER_SYSTEM);
2552        if (matches.size() == 0) {
2553            return null;
2554        } else if (matches.size() == 1) {
2555            return matches.get(0).getComponentInfo().getComponentName();
2556        } else {
2557            throw new RuntimeException(
2558                    "There must be at most one ephemeral installer; found " + matches);
2559        }
2560    }
2561
2562    private void primeDomainVerificationsLPw(int userId) {
2563        if (DEBUG_DOMAIN_VERIFICATION) {
2564            Slog.d(TAG, "Priming domain verifications in user " + userId);
2565        }
2566
2567        SystemConfig systemConfig = SystemConfig.getInstance();
2568        ArraySet<String> packages = systemConfig.getLinkedApps();
2569        ArraySet<String> domains = new ArraySet<String>();
2570
2571        for (String packageName : packages) {
2572            PackageParser.Package pkg = mPackages.get(packageName);
2573            if (pkg != null) {
2574                if (!pkg.isSystemApp()) {
2575                    Slog.w(TAG, "Non-system app '" + packageName + "' in sysconfig <app-link>");
2576                    continue;
2577                }
2578
2579                domains.clear();
2580                for (PackageParser.Activity a : pkg.activities) {
2581                    for (ActivityIntentInfo filter : a.intents) {
2582                        if (hasValidDomains(filter)) {
2583                            domains.addAll(filter.getHostsList());
2584                        }
2585                    }
2586                }
2587
2588                if (domains.size() > 0) {
2589                    if (DEBUG_DOMAIN_VERIFICATION) {
2590                        Slog.v(TAG, "      + " + packageName);
2591                    }
2592                    // 'Undefined' in the global IntentFilterVerificationInfo, i.e. the usual
2593                    // state w.r.t. the formal app-linkage "no verification attempted" state;
2594                    // and then 'always' in the per-user state actually used for intent resolution.
2595                    final IntentFilterVerificationInfo ivi;
2596                    ivi = mSettings.createIntentFilterVerificationIfNeededLPw(packageName,
2597                            new ArrayList<String>(domains));
2598                    ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED);
2599                    mSettings.updateIntentFilterVerificationStatusLPw(packageName,
2600                            INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS, userId);
2601                } else {
2602                    Slog.w(TAG, "Sysconfig <app-link> package '" + packageName
2603                            + "' does not handle web links");
2604                }
2605            } else {
2606                Slog.w(TAG, "Unknown package " + packageName + " in sysconfig <app-link>");
2607            }
2608        }
2609
2610        scheduleWritePackageRestrictionsLocked(userId);
2611        scheduleWriteSettingsLocked();
2612    }
2613
2614    private void applyFactoryDefaultBrowserLPw(int userId) {
2615        // The default browser app's package name is stored in a string resource,
2616        // with a product-specific overlay used for vendor customization.
2617        String browserPkg = mContext.getResources().getString(
2618                com.android.internal.R.string.default_browser);
2619        if (!TextUtils.isEmpty(browserPkg)) {
2620            // non-empty string => required to be a known package
2621            PackageSetting ps = mSettings.mPackages.get(browserPkg);
2622            if (ps == null) {
2623                Slog.e(TAG, "Product default browser app does not exist: " + browserPkg);
2624                browserPkg = null;
2625            } else {
2626                mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId);
2627            }
2628        }
2629
2630        // Nothing valid explicitly set? Make the factory-installed browser the explicit
2631        // default.  If there's more than one, just leave everything alone.
2632        if (browserPkg == null) {
2633            calculateDefaultBrowserLPw(userId);
2634        }
2635    }
2636
2637    private void calculateDefaultBrowserLPw(int userId) {
2638        List<String> allBrowsers = resolveAllBrowserApps(userId);
2639        final String browserPkg = (allBrowsers.size() == 1) ? allBrowsers.get(0) : null;
2640        mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId);
2641    }
2642
2643    private List<String> resolveAllBrowserApps(int userId) {
2644        // Resolve the canonical browser intent and check that the handleAllWebDataURI boolean is set
2645        List<ResolveInfo> list = queryIntentActivities(sBrowserIntent, null,
2646                PackageManager.MATCH_ALL, userId);
2647
2648        final int count = list.size();
2649        List<String> result = new ArrayList<String>(count);
2650        for (int i=0; i<count; i++) {
2651            ResolveInfo info = list.get(i);
2652            if (info.activityInfo == null
2653                    || !info.handleAllWebDataURI
2654                    || (info.activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0
2655                    || result.contains(info.activityInfo.packageName)) {
2656                continue;
2657            }
2658            result.add(info.activityInfo.packageName);
2659        }
2660
2661        return result;
2662    }
2663
2664    private boolean packageIsBrowser(String packageName, int userId) {
2665        List<ResolveInfo> list = queryIntentActivities(sBrowserIntent, null,
2666                PackageManager.MATCH_ALL, userId);
2667        final int N = list.size();
2668        for (int i = 0; i < N; i++) {
2669            ResolveInfo info = list.get(i);
2670            if (packageName.equals(info.activityInfo.packageName)) {
2671                return true;
2672            }
2673        }
2674        return false;
2675    }
2676
2677    private void checkDefaultBrowser() {
2678        final int myUserId = UserHandle.myUserId();
2679        final String packageName = getDefaultBrowserPackageName(myUserId);
2680        if (packageName != null) {
2681            PackageInfo info = getPackageInfo(packageName, 0, myUserId);
2682            if (info == null) {
2683                Slog.w(TAG, "Default browser no longer installed: " + packageName);
2684                synchronized (mPackages) {
2685                    applyFactoryDefaultBrowserLPw(myUserId);    // leaves ambiguous when > 1
2686                }
2687            }
2688        }
2689    }
2690
2691    @Override
2692    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2693            throws RemoteException {
2694        try {
2695            return super.onTransact(code, data, reply, flags);
2696        } catch (RuntimeException e) {
2697            if (!(e instanceof SecurityException) && !(e instanceof IllegalArgumentException)) {
2698                Slog.wtf(TAG, "Package Manager Crash", e);
2699            }
2700            throw e;
2701        }
2702    }
2703
2704    void cleanupInstallFailedPackage(PackageSetting ps) {
2705        logCriticalInfo(Log.WARN, "Cleaning up incompletely installed app: " + ps.name);
2706
2707        removeDataDirsLI(ps.volumeUuid, ps.name);
2708        if (ps.codePath != null) {
2709            if (ps.codePath.isDirectory()) {
2710                mInstaller.rmPackageDir(ps.codePath.getAbsolutePath());
2711            } else {
2712                ps.codePath.delete();
2713            }
2714        }
2715        if (ps.resourcePath != null && !ps.resourcePath.equals(ps.codePath)) {
2716            if (ps.resourcePath.isDirectory()) {
2717                FileUtils.deleteContents(ps.resourcePath);
2718            }
2719            ps.resourcePath.delete();
2720        }
2721        mSettings.removePackageLPw(ps.name);
2722    }
2723
2724    static int[] appendInts(int[] cur, int[] add) {
2725        if (add == null) return cur;
2726        if (cur == null) return add;
2727        final int N = add.length;
2728        for (int i=0; i<N; i++) {
2729            cur = appendInt(cur, add[i]);
2730        }
2731        return cur;
2732    }
2733
2734    PackageInfo generatePackageInfo(PackageParser.Package p, int flags, int userId) {
2735        if (!sUserManager.exists(userId)) return null;
2736        final PackageSetting ps = (PackageSetting) p.mExtras;
2737        if (ps == null) {
2738            return null;
2739        }
2740
2741        final PermissionsState permissionsState = ps.getPermissionsState();
2742
2743        final int[] gids = permissionsState.computeGids(userId);
2744        final Set<String> permissions = permissionsState.getPermissions(userId);
2745        final PackageUserState state = ps.readUserState(userId);
2746
2747        return PackageParser.generatePackageInfo(p, gids, flags,
2748                ps.firstInstallTime, ps.lastUpdateTime, permissions, state, userId);
2749    }
2750
2751    @Override
2752    public void checkPackageStartable(String packageName, int userId) {
2753        final boolean userKeyUnlocked = isUserKeyUnlocked(userId);
2754
2755        synchronized (mPackages) {
2756            final PackageSetting ps = mSettings.mPackages.get(packageName);
2757            if (ps == null) {
2758                throw new SecurityException("Package " + packageName + " was not found!");
2759            }
2760
2761            if (ps.frozen) {
2762                throw new SecurityException("Package " + packageName + " is currently frozen!");
2763            }
2764
2765            if (!userKeyUnlocked && !(ps.pkg.applicationInfo.isEncryptionAware()
2766                    || ps.pkg.applicationInfo.isPartiallyEncryptionAware())) {
2767                throw new SecurityException("Package " + packageName + " is not encryption aware!");
2768            }
2769        }
2770    }
2771
2772    @Override
2773    public boolean isPackageAvailable(String packageName, int userId) {
2774        if (!sUserManager.exists(userId)) return false;
2775        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "is package available");
2776        synchronized (mPackages) {
2777            PackageParser.Package p = mPackages.get(packageName);
2778            if (p != null) {
2779                final PackageSetting ps = (PackageSetting) p.mExtras;
2780                if (ps != null) {
2781                    final PackageUserState state = ps.readUserState(userId);
2782                    if (state != null) {
2783                        return PackageParser.isAvailable(state);
2784                    }
2785                }
2786            }
2787        }
2788        return false;
2789    }
2790
2791    @Override
2792    public PackageInfo getPackageInfo(String packageName, int flags, int userId) {
2793        if (!sUserManager.exists(userId)) return null;
2794        flags = updateFlagsForPackage(flags, userId, packageName);
2795        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get package info");
2796        // reader
2797        synchronized (mPackages) {
2798            PackageParser.Package p = mPackages.get(packageName);
2799            if (DEBUG_PACKAGE_INFO)
2800                Log.v(TAG, "getPackageInfo " + packageName + ": " + p);
2801            if (p != null) {
2802                return generatePackageInfo(p, flags, userId);
2803            }
2804            if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0) {
2805                return generatePackageInfoFromSettingsLPw(packageName, flags, userId);
2806            }
2807        }
2808        return null;
2809    }
2810
2811    @Override
2812    public String[] currentToCanonicalPackageNames(String[] names) {
2813        String[] out = new String[names.length];
2814        // reader
2815        synchronized (mPackages) {
2816            for (int i=names.length-1; i>=0; i--) {
2817                PackageSetting ps = mSettings.mPackages.get(names[i]);
2818                out[i] = ps != null && ps.realName != null ? ps.realName : names[i];
2819            }
2820        }
2821        return out;
2822    }
2823
2824    @Override
2825    public String[] canonicalToCurrentPackageNames(String[] names) {
2826        String[] out = new String[names.length];
2827        // reader
2828        synchronized (mPackages) {
2829            for (int i=names.length-1; i>=0; i--) {
2830                String cur = mSettings.mRenamedPackages.get(names[i]);
2831                out[i] = cur != null ? cur : names[i];
2832            }
2833        }
2834        return out;
2835    }
2836
2837    @Override
2838    public int getPackageUid(String packageName, int userId) {
2839        return getPackageUidEtc(packageName, 0, userId);
2840    }
2841
2842    @Override
2843    public int getPackageUidEtc(String packageName, int flags, int userId) {
2844        if (!sUserManager.exists(userId)) return -1;
2845        flags = updateFlagsForPackage(flags, userId, packageName);
2846        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get package uid");
2847
2848        // reader
2849        synchronized (mPackages) {
2850            final PackageParser.Package p = mPackages.get(packageName);
2851            if (p != null) {
2852                return UserHandle.getUid(userId, p.applicationInfo.uid);
2853            }
2854            if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0) {
2855                final PackageSetting ps = mSettings.mPackages.get(packageName);
2856                if (ps != null) {
2857                    return UserHandle.getUid(userId, ps.appId);
2858                }
2859            }
2860        }
2861
2862        return -1;
2863    }
2864
2865    @Override
2866    public int[] getPackageGids(String packageName, int userId) {
2867        return getPackageGidsEtc(packageName, 0, userId);
2868    }
2869
2870    @Override
2871    public int[] getPackageGidsEtc(String packageName, int flags, int userId) {
2872        if (!sUserManager.exists(userId)) return null;
2873        flags = updateFlagsForPackage(flags, userId, packageName);
2874        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false,
2875                "getPackageGids");
2876
2877        // reader
2878        synchronized (mPackages) {
2879            final PackageParser.Package p = mPackages.get(packageName);
2880            if (p != null) {
2881                PackageSetting ps = (PackageSetting) p.mExtras;
2882                return ps.getPermissionsState().computeGids(userId);
2883            }
2884            if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0) {
2885                final PackageSetting ps = mSettings.mPackages.get(packageName);
2886                if (ps != null) {
2887                    return ps.getPermissionsState().computeGids(userId);
2888                }
2889            }
2890        }
2891
2892        return null;
2893    }
2894
2895    static PermissionInfo generatePermissionInfo(BasePermission bp, int flags) {
2896        if (bp.perm != null) {
2897            return PackageParser.generatePermissionInfo(bp.perm, flags);
2898        }
2899        PermissionInfo pi = new PermissionInfo();
2900        pi.name = bp.name;
2901        pi.packageName = bp.sourcePackage;
2902        pi.nonLocalizedLabel = bp.name;
2903        pi.protectionLevel = bp.protectionLevel;
2904        return pi;
2905    }
2906
2907    @Override
2908    public PermissionInfo getPermissionInfo(String name, int flags) {
2909        // reader
2910        synchronized (mPackages) {
2911            final BasePermission p = mSettings.mPermissions.get(name);
2912            if (p != null) {
2913                return generatePermissionInfo(p, flags);
2914            }
2915            return null;
2916        }
2917    }
2918
2919    @Override
2920    public List<PermissionInfo> queryPermissionsByGroup(String group, int flags) {
2921        // reader
2922        synchronized (mPackages) {
2923            ArrayList<PermissionInfo> out = new ArrayList<PermissionInfo>(10);
2924            for (BasePermission p : mSettings.mPermissions.values()) {
2925                if (group == null) {
2926                    if (p.perm == null || p.perm.info.group == null) {
2927                        out.add(generatePermissionInfo(p, flags));
2928                    }
2929                } else {
2930                    if (p.perm != null && group.equals(p.perm.info.group)) {
2931                        out.add(PackageParser.generatePermissionInfo(p.perm, flags));
2932                    }
2933                }
2934            }
2935
2936            if (out.size() > 0) {
2937                return out;
2938            }
2939            return mPermissionGroups.containsKey(group) ? out : null;
2940        }
2941    }
2942
2943    @Override
2944    public PermissionGroupInfo getPermissionGroupInfo(String name, int flags) {
2945        // reader
2946        synchronized (mPackages) {
2947            return PackageParser.generatePermissionGroupInfo(
2948                    mPermissionGroups.get(name), flags);
2949        }
2950    }
2951
2952    @Override
2953    public List<PermissionGroupInfo> getAllPermissionGroups(int flags) {
2954        // reader
2955        synchronized (mPackages) {
2956            final int N = mPermissionGroups.size();
2957            ArrayList<PermissionGroupInfo> out
2958                    = new ArrayList<PermissionGroupInfo>(N);
2959            for (PackageParser.PermissionGroup pg : mPermissionGroups.values()) {
2960                out.add(PackageParser.generatePermissionGroupInfo(pg, flags));
2961            }
2962            return out;
2963        }
2964    }
2965
2966    private ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName, int flags,
2967            int userId) {
2968        if (!sUserManager.exists(userId)) return null;
2969        PackageSetting ps = mSettings.mPackages.get(packageName);
2970        if (ps != null) {
2971            if (ps.pkg == null) {
2972                PackageInfo pInfo = generatePackageInfoFromSettingsLPw(packageName,
2973                        flags, userId);
2974                if (pInfo != null) {
2975                    return pInfo.applicationInfo;
2976                }
2977                return null;
2978            }
2979            return PackageParser.generateApplicationInfo(ps.pkg, flags,
2980                    ps.readUserState(userId), userId);
2981        }
2982        return null;
2983    }
2984
2985    private PackageInfo generatePackageInfoFromSettingsLPw(String packageName, int flags,
2986            int userId) {
2987        if (!sUserManager.exists(userId)) return null;
2988        PackageSetting ps = mSettings.mPackages.get(packageName);
2989        if (ps != null) {
2990            PackageParser.Package pkg = ps.pkg;
2991            if (pkg == null) {
2992                if ((flags & MATCH_UNINSTALLED_PACKAGES) == 0) {
2993                    return null;
2994                }
2995                // Only data remains, so we aren't worried about code paths
2996                pkg = new PackageParser.Package(packageName);
2997                pkg.applicationInfo.packageName = packageName;
2998                pkg.applicationInfo.flags = ps.pkgFlags | ApplicationInfo.FLAG_IS_DATA_ONLY;
2999                pkg.applicationInfo.privateFlags = ps.pkgPrivateFlags;
3000                pkg.applicationInfo.uid = ps.appId;
3001                pkg.applicationInfo.initForUser(userId);
3002                pkg.applicationInfo.primaryCpuAbi = ps.primaryCpuAbiString;
3003                pkg.applicationInfo.secondaryCpuAbi = ps.secondaryCpuAbiString;
3004            }
3005            return generatePackageInfo(pkg, flags, userId);
3006        }
3007        return null;
3008    }
3009
3010    @Override
3011    public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) {
3012        if (!sUserManager.exists(userId)) return null;
3013        flags = updateFlagsForApplication(flags, userId, packageName);
3014        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get application info");
3015        // writer
3016        synchronized (mPackages) {
3017            PackageParser.Package p = mPackages.get(packageName);
3018            if (DEBUG_PACKAGE_INFO) Log.v(
3019                    TAG, "getApplicationInfo " + packageName
3020                    + ": " + p);
3021            if (p != null) {
3022                PackageSetting ps = mSettings.mPackages.get(packageName);
3023                if (ps == null) return null;
3024                // Note: isEnabledLP() does not apply here - always return info
3025                return PackageParser.generateApplicationInfo(
3026                        p, flags, ps.readUserState(userId), userId);
3027            }
3028            if ("android".equals(packageName)||"system".equals(packageName)) {
3029                return mAndroidApplication;
3030            }
3031            if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0) {
3032                return generateApplicationInfoFromSettingsLPw(packageName, flags, userId);
3033            }
3034        }
3035        return null;
3036    }
3037
3038    @Override
3039    public void freeStorageAndNotify(final String volumeUuid, final long freeStorageSize,
3040            final IPackageDataObserver observer) {
3041        mContext.enforceCallingOrSelfPermission(
3042                android.Manifest.permission.CLEAR_APP_CACHE, null);
3043        // Queue up an async operation since clearing cache may take a little while.
3044        mHandler.post(new Runnable() {
3045            public void run() {
3046                mHandler.removeCallbacks(this);
3047                int retCode = -1;
3048                synchronized (mInstallLock) {
3049                    retCode = mInstaller.freeCache(volumeUuid, freeStorageSize);
3050                    if (retCode < 0) {
3051                        Slog.w(TAG, "Couldn't clear application caches");
3052                    }
3053                }
3054                if (observer != null) {
3055                    try {
3056                        observer.onRemoveCompleted(null, (retCode >= 0));
3057                    } catch (RemoteException e) {
3058                        Slog.w(TAG, "RemoveException when invoking call back");
3059                    }
3060                }
3061            }
3062        });
3063    }
3064
3065    @Override
3066    public void freeStorage(final String volumeUuid, final long freeStorageSize,
3067            final IntentSender pi) {
3068        mContext.enforceCallingOrSelfPermission(
3069                android.Manifest.permission.CLEAR_APP_CACHE, null);
3070        // Queue up an async operation since clearing cache may take a little while.
3071        mHandler.post(new Runnable() {
3072            public void run() {
3073                mHandler.removeCallbacks(this);
3074                int retCode = -1;
3075                synchronized (mInstallLock) {
3076                    retCode = mInstaller.freeCache(volumeUuid, freeStorageSize);
3077                    if (retCode < 0) {
3078                        Slog.w(TAG, "Couldn't clear application caches");
3079                    }
3080                }
3081                if(pi != null) {
3082                    try {
3083                        // Callback via pending intent
3084                        int code = (retCode >= 0) ? 1 : 0;
3085                        pi.sendIntent(null, code, null,
3086                                null, null);
3087                    } catch (SendIntentException e1) {
3088                        Slog.i(TAG, "Failed to send pending intent");
3089                    }
3090                }
3091            }
3092        });
3093    }
3094
3095    void freeStorage(String volumeUuid, long freeStorageSize) throws IOException {
3096        synchronized (mInstallLock) {
3097            if (mInstaller.freeCache(volumeUuid, freeStorageSize) < 0) {
3098                throw new IOException("Failed to free enough space");
3099            }
3100        }
3101    }
3102
3103    /**
3104     * Return if the user key is currently unlocked.
3105     */
3106    private boolean isUserKeyUnlocked(int userId) {
3107        if (StorageManager.isFileBasedEncryptionEnabled()) {
3108            final IMountService mount = IMountService.Stub
3109                    .asInterface(ServiceManager.getService("mount"));
3110            if (mount == null) {
3111                Slog.w(TAG, "Early during boot, assuming locked");
3112                return false;
3113            }
3114            final long token = Binder.clearCallingIdentity();
3115            try {
3116                return mount.isUserKeyUnlocked(userId);
3117            } catch (RemoteException e) {
3118                throw e.rethrowAsRuntimeException();
3119            } finally {
3120                Binder.restoreCallingIdentity(token);
3121            }
3122        } else {
3123            return true;
3124        }
3125    }
3126
3127    /**
3128     * Update given flags based on encryption status of current user.
3129     */
3130    private int updateFlagsForEncryption(int flags, int userId) {
3131        if ((flags & (PackageManager.MATCH_ENCRYPTION_UNAWARE
3132                | PackageManager.MATCH_ENCRYPTION_AWARE)) != 0) {
3133            // Caller expressed an explicit opinion about what encryption
3134            // aware/unaware components they want to see, so fall through and
3135            // give them what they want
3136        } else {
3137            // Caller expressed no opinion, so match based on user state
3138            if (isUserKeyUnlocked(userId)) {
3139                flags |= PackageManager.MATCH_ENCRYPTION_AWARE_AND_UNAWARE;
3140            } else {
3141                flags |= PackageManager.MATCH_ENCRYPTION_AWARE;
3142            }
3143        }
3144        return flags;
3145    }
3146
3147    /**
3148     * Update given flags when being used to request {@link PackageInfo}.
3149     */
3150    private int updateFlagsForPackage(int flags, int userId, Object cookie) {
3151        boolean triaged = true;
3152        if ((flags & PackageManager.GET_ACTIVITIES | PackageManager.GET_RECEIVERS
3153                | PackageManager.GET_SERVICES | PackageManager.GET_PROVIDERS) != 0) {
3154            // Caller is asking for component details, so they'd better be
3155            // asking for specific encryption matching behavior, or be triaged
3156            if ((flags & (PackageManager.MATCH_ENCRYPTION_UNAWARE
3157                    | PackageManager.MATCH_ENCRYPTION_AWARE
3158                    | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
3159                triaged = false;
3160            }
3161        }
3162        if ((flags & (PackageManager.MATCH_UNINSTALLED_PACKAGES
3163                | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
3164            triaged = false;
3165        }
3166        if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) {
3167            Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie,
3168                    new Throwable());
3169        }
3170        return updateFlagsForEncryption(flags, userId);
3171    }
3172
3173    /**
3174     * Update given flags when being used to request {@link ApplicationInfo}.
3175     */
3176    private int updateFlagsForApplication(int flags, int userId, Object cookie) {
3177        return updateFlagsForPackage(flags, userId, cookie);
3178    }
3179
3180    /**
3181     * Update given flags when being used to request {@link ComponentInfo}.
3182     */
3183    private int updateFlagsForComponent(int flags, int userId, Object cookie) {
3184        boolean triaged = true;
3185        // Caller is asking for component details, so they'd better be
3186        // asking for specific encryption matching behavior, or be triaged
3187        if ((flags & (PackageManager.MATCH_ENCRYPTION_UNAWARE
3188                | PackageManager.MATCH_ENCRYPTION_AWARE
3189                | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
3190            triaged = false;
3191        }
3192        if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) {
3193            Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie,
3194                    new Throwable());
3195        }
3196        return updateFlagsForEncryption(flags, userId);
3197    }
3198
3199    /**
3200     * Update given flags when being used to request {@link ResolveInfo}.
3201     */
3202    private int updateFlagsForResolve(int flags, int userId, Object cookie) {
3203        return updateFlagsForComponent(flags, userId, cookie);
3204    }
3205
3206    @Override
3207    public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) {
3208        if (!sUserManager.exists(userId)) return null;
3209        flags = updateFlagsForComponent(flags, userId, component);
3210        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get activity info");
3211        synchronized (mPackages) {
3212            PackageParser.Activity a = mActivities.mActivities.get(component);
3213
3214            if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a);
3215            if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) {
3216                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
3217                if (ps == null) return null;
3218                return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId),
3219                        userId);
3220            }
3221            if (mResolveComponentName.equals(component)) {
3222                return PackageParser.generateActivityInfo(mResolveActivity, flags,
3223                        new PackageUserState(), userId);
3224            }
3225        }
3226        return null;
3227    }
3228
3229    @Override
3230    public boolean activitySupportsIntent(ComponentName component, Intent intent,
3231            String resolvedType) {
3232        synchronized (mPackages) {
3233            if (component.equals(mResolveComponentName)) {
3234                // The resolver supports EVERYTHING!
3235                return true;
3236            }
3237            PackageParser.Activity a = mActivities.mActivities.get(component);
3238            if (a == null) {
3239                return false;
3240            }
3241            for (int i=0; i<a.intents.size(); i++) {
3242                if (a.intents.get(i).match(intent.getAction(), resolvedType, intent.getScheme(),
3243                        intent.getData(), intent.getCategories(), TAG) >= 0) {
3244                    return true;
3245                }
3246            }
3247            return false;
3248        }
3249    }
3250
3251    @Override
3252    public ActivityInfo getReceiverInfo(ComponentName component, int flags, int userId) {
3253        if (!sUserManager.exists(userId)) return null;
3254        flags = updateFlagsForComponent(flags, userId, component);
3255        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get receiver info");
3256        synchronized (mPackages) {
3257            PackageParser.Activity a = mReceivers.mActivities.get(component);
3258            if (DEBUG_PACKAGE_INFO) Log.v(
3259                TAG, "getReceiverInfo " + component + ": " + a);
3260            if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) {
3261                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
3262                if (ps == null) return null;
3263                return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId),
3264                        userId);
3265            }
3266        }
3267        return null;
3268    }
3269
3270    @Override
3271    public ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) {
3272        if (!sUserManager.exists(userId)) return null;
3273        flags = updateFlagsForComponent(flags, userId, component);
3274        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get service info");
3275        synchronized (mPackages) {
3276            PackageParser.Service s = mServices.mServices.get(component);
3277            if (DEBUG_PACKAGE_INFO) Log.v(
3278                TAG, "getServiceInfo " + component + ": " + s);
3279            if (s != null && mSettings.isEnabledAndMatchLPr(s.info, flags, userId)) {
3280                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
3281                if (ps == null) return null;
3282                return PackageParser.generateServiceInfo(s, flags, ps.readUserState(userId),
3283                        userId);
3284            }
3285        }
3286        return null;
3287    }
3288
3289    @Override
3290    public ProviderInfo getProviderInfo(ComponentName component, int flags, int userId) {
3291        if (!sUserManager.exists(userId)) return null;
3292        flags = updateFlagsForComponent(flags, userId, component);
3293        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get provider info");
3294        synchronized (mPackages) {
3295            PackageParser.Provider p = mProviders.mProviders.get(component);
3296            if (DEBUG_PACKAGE_INFO) Log.v(
3297                TAG, "getProviderInfo " + component + ": " + p);
3298            if (p != null && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) {
3299                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
3300                if (ps == null) return null;
3301                return PackageParser.generateProviderInfo(p, flags, ps.readUserState(userId),
3302                        userId);
3303            }
3304        }
3305        return null;
3306    }
3307
3308    @Override
3309    public String[] getSystemSharedLibraryNames() {
3310        Set<String> libSet;
3311        synchronized (mPackages) {
3312            libSet = mSharedLibraries.keySet();
3313            int size = libSet.size();
3314            if (size > 0) {
3315                String[] libs = new String[size];
3316                libSet.toArray(libs);
3317                return libs;
3318            }
3319        }
3320        return null;
3321    }
3322
3323    /**
3324     * @hide
3325     */
3326    PackageParser.Package findSharedNonSystemLibrary(String libName) {
3327        synchronized (mPackages) {
3328            PackageManagerService.SharedLibraryEntry lib = mSharedLibraries.get(libName);
3329            if (lib != null && lib.apk != null) {
3330                return mPackages.get(lib.apk);
3331            }
3332        }
3333        return null;
3334    }
3335
3336    @Override
3337    public FeatureInfo[] getSystemAvailableFeatures() {
3338        Collection<FeatureInfo> featSet;
3339        synchronized (mPackages) {
3340            featSet = mAvailableFeatures.values();
3341            int size = featSet.size();
3342            if (size > 0) {
3343                FeatureInfo[] features = new FeatureInfo[size+1];
3344                featSet.toArray(features);
3345                FeatureInfo fi = new FeatureInfo();
3346                fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version",
3347                        FeatureInfo.GL_ES_VERSION_UNDEFINED);
3348                features[size] = fi;
3349                return features;
3350            }
3351        }
3352        return null;
3353    }
3354
3355    @Override
3356    public boolean hasSystemFeature(String name) {
3357        synchronized (mPackages) {
3358            return mAvailableFeatures.containsKey(name);
3359        }
3360    }
3361
3362    @Override
3363    public int checkPermission(String permName, String pkgName, int userId) {
3364        if (!sUserManager.exists(userId)) {
3365            return PackageManager.PERMISSION_DENIED;
3366        }
3367
3368        synchronized (mPackages) {
3369            final PackageParser.Package p = mPackages.get(pkgName);
3370            if (p != null && p.mExtras != null) {
3371                final PackageSetting ps = (PackageSetting) p.mExtras;
3372                final PermissionsState permissionsState = ps.getPermissionsState();
3373                if (permissionsState.hasPermission(permName, userId)) {
3374                    return PackageManager.PERMISSION_GRANTED;
3375                }
3376                // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION
3377                if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState
3378                        .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) {
3379                    return PackageManager.PERMISSION_GRANTED;
3380                }
3381            }
3382        }
3383
3384        return PackageManager.PERMISSION_DENIED;
3385    }
3386
3387    @Override
3388    public int checkUidPermission(String permName, int uid) {
3389        final int userId = UserHandle.getUserId(uid);
3390
3391        if (!sUserManager.exists(userId)) {
3392            return PackageManager.PERMISSION_DENIED;
3393        }
3394
3395        synchronized (mPackages) {
3396            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
3397            if (obj != null) {
3398                final SettingBase ps = (SettingBase) obj;
3399                final PermissionsState permissionsState = ps.getPermissionsState();
3400                if (permissionsState.hasPermission(permName, userId)) {
3401                    return PackageManager.PERMISSION_GRANTED;
3402                }
3403                // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION
3404                if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState
3405                        .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) {
3406                    return PackageManager.PERMISSION_GRANTED;
3407                }
3408            } else {
3409                ArraySet<String> perms = mSystemPermissions.get(uid);
3410                if (perms != null) {
3411                    if (perms.contains(permName)) {
3412                        return PackageManager.PERMISSION_GRANTED;
3413                    }
3414                    if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && perms
3415                            .contains(Manifest.permission.ACCESS_FINE_LOCATION)) {
3416                        return PackageManager.PERMISSION_GRANTED;
3417                    }
3418                }
3419            }
3420        }
3421
3422        return PackageManager.PERMISSION_DENIED;
3423    }
3424
3425    @Override
3426    public boolean isPermissionRevokedByPolicy(String permission, String packageName, int userId) {
3427        if (UserHandle.getCallingUserId() != userId) {
3428            mContext.enforceCallingPermission(
3429                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
3430                    "isPermissionRevokedByPolicy for user " + userId);
3431        }
3432
3433        if (checkPermission(permission, packageName, userId)
3434                == PackageManager.PERMISSION_GRANTED) {
3435            return false;
3436        }
3437
3438        final long identity = Binder.clearCallingIdentity();
3439        try {
3440            final int flags = getPermissionFlags(permission, packageName, userId);
3441            return (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0;
3442        } finally {
3443            Binder.restoreCallingIdentity(identity);
3444        }
3445    }
3446
3447    @Override
3448    public String getPermissionControllerPackageName() {
3449        synchronized (mPackages) {
3450            return mRequiredInstallerPackage;
3451        }
3452    }
3453
3454    /**
3455     * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS
3456     * or INTERACT_ACROSS_USERS_FULL permissions, if the userid is not for the caller.
3457     * @param checkShell TODO(yamasani):
3458     * @param message the message to log on security exception
3459     */
3460    void enforceCrossUserPermission(int callingUid, int userId, boolean requireFullPermission,
3461            boolean checkShell, String message) {
3462        if (userId < 0) {
3463            throw new IllegalArgumentException("Invalid userId " + userId);
3464        }
3465        if (checkShell) {
3466            enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId);
3467        }
3468        if (userId == UserHandle.getUserId(callingUid)) return;
3469        if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
3470            if (requireFullPermission) {
3471                mContext.enforceCallingOrSelfPermission(
3472                        android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
3473            } else {
3474                try {
3475                    mContext.enforceCallingOrSelfPermission(
3476                            android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
3477                } catch (SecurityException se) {
3478                    mContext.enforceCallingOrSelfPermission(
3479                            android.Manifest.permission.INTERACT_ACROSS_USERS, message);
3480                }
3481            }
3482        }
3483    }
3484
3485    void enforceShellRestriction(String restriction, int callingUid, int userHandle) {
3486        if (callingUid == Process.SHELL_UID) {
3487            if (userHandle >= 0
3488                    && sUserManager.hasUserRestriction(restriction, userHandle)) {
3489                throw new SecurityException("Shell does not have permission to access user "
3490                        + userHandle);
3491            } else if (userHandle < 0) {
3492                Slog.e(TAG, "Unable to check shell permission for user " + userHandle + "\n\t"
3493                        + Debug.getCallers(3));
3494            }
3495        }
3496    }
3497
3498    private BasePermission findPermissionTreeLP(String permName) {
3499        for(BasePermission bp : mSettings.mPermissionTrees.values()) {
3500            if (permName.startsWith(bp.name) &&
3501                    permName.length() > bp.name.length() &&
3502                    permName.charAt(bp.name.length()) == '.') {
3503                return bp;
3504            }
3505        }
3506        return null;
3507    }
3508
3509    private BasePermission checkPermissionTreeLP(String permName) {
3510        if (permName != null) {
3511            BasePermission bp = findPermissionTreeLP(permName);
3512            if (bp != null) {
3513                if (bp.uid == UserHandle.getAppId(Binder.getCallingUid())) {
3514                    return bp;
3515                }
3516                throw new SecurityException("Calling uid "
3517                        + Binder.getCallingUid()
3518                        + " is not allowed to add to permission tree "
3519                        + bp.name + " owned by uid " + bp.uid);
3520            }
3521        }
3522        throw new SecurityException("No permission tree found for " + permName);
3523    }
3524
3525    static boolean compareStrings(CharSequence s1, CharSequence s2) {
3526        if (s1 == null) {
3527            return s2 == null;
3528        }
3529        if (s2 == null) {
3530            return false;
3531        }
3532        if (s1.getClass() != s2.getClass()) {
3533            return false;
3534        }
3535        return s1.equals(s2);
3536    }
3537
3538    static boolean comparePermissionInfos(PermissionInfo pi1, PermissionInfo pi2) {
3539        if (pi1.icon != pi2.icon) return false;
3540        if (pi1.logo != pi2.logo) return false;
3541        if (pi1.protectionLevel != pi2.protectionLevel) return false;
3542        if (!compareStrings(pi1.name, pi2.name)) return false;
3543        if (!compareStrings(pi1.nonLocalizedLabel, pi2.nonLocalizedLabel)) return false;
3544        // We'll take care of setting this one.
3545        if (!compareStrings(pi1.packageName, pi2.packageName)) return false;
3546        // These are not currently stored in settings.
3547        //if (!compareStrings(pi1.group, pi2.group)) return false;
3548        //if (!compareStrings(pi1.nonLocalizedDescription, pi2.nonLocalizedDescription)) return false;
3549        //if (pi1.labelRes != pi2.labelRes) return false;
3550        //if (pi1.descriptionRes != pi2.descriptionRes) return false;
3551        return true;
3552    }
3553
3554    int permissionInfoFootprint(PermissionInfo info) {
3555        int size = info.name.length();
3556        if (info.nonLocalizedLabel != null) size += info.nonLocalizedLabel.length();
3557        if (info.nonLocalizedDescription != null) size += info.nonLocalizedDescription.length();
3558        return size;
3559    }
3560
3561    int calculateCurrentPermissionFootprintLocked(BasePermission tree) {
3562        int size = 0;
3563        for (BasePermission perm : mSettings.mPermissions.values()) {
3564            if (perm.uid == tree.uid) {
3565                size += perm.name.length() + permissionInfoFootprint(perm.perm.info);
3566            }
3567        }
3568        return size;
3569    }
3570
3571    void enforcePermissionCapLocked(PermissionInfo info, BasePermission tree) {
3572        // We calculate the max size of permissions defined by this uid and throw
3573        // if that plus the size of 'info' would exceed our stated maximum.
3574        if (tree.uid != Process.SYSTEM_UID) {
3575            final int curTreeSize = calculateCurrentPermissionFootprintLocked(tree);
3576            if (curTreeSize + permissionInfoFootprint(info) > MAX_PERMISSION_TREE_FOOTPRINT) {
3577                throw new SecurityException("Permission tree size cap exceeded");
3578            }
3579        }
3580    }
3581
3582    boolean addPermissionLocked(PermissionInfo info, boolean async) {
3583        if (info.labelRes == 0 && info.nonLocalizedLabel == null) {
3584            throw new SecurityException("Label must be specified in permission");
3585        }
3586        BasePermission tree = checkPermissionTreeLP(info.name);
3587        BasePermission bp = mSettings.mPermissions.get(info.name);
3588        boolean added = bp == null;
3589        boolean changed = true;
3590        int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel);
3591        if (added) {
3592            enforcePermissionCapLocked(info, tree);
3593            bp = new BasePermission(info.name, tree.sourcePackage,
3594                    BasePermission.TYPE_DYNAMIC);
3595        } else if (bp.type != BasePermission.TYPE_DYNAMIC) {
3596            throw new SecurityException(
3597                    "Not allowed to modify non-dynamic permission "
3598                    + info.name);
3599        } else {
3600            if (bp.protectionLevel == fixedLevel
3601                    && bp.perm.owner.equals(tree.perm.owner)
3602                    && bp.uid == tree.uid
3603                    && comparePermissionInfos(bp.perm.info, info)) {
3604                changed = false;
3605            }
3606        }
3607        bp.protectionLevel = fixedLevel;
3608        info = new PermissionInfo(info);
3609        info.protectionLevel = fixedLevel;
3610        bp.perm = new PackageParser.Permission(tree.perm.owner, info);
3611        bp.perm.info.packageName = tree.perm.info.packageName;
3612        bp.uid = tree.uid;
3613        if (added) {
3614            mSettings.mPermissions.put(info.name, bp);
3615        }
3616        if (changed) {
3617            if (!async) {
3618                mSettings.writeLPr();
3619            } else {
3620                scheduleWriteSettingsLocked();
3621            }
3622        }
3623        return added;
3624    }
3625
3626    @Override
3627    public boolean addPermission(PermissionInfo info) {
3628        synchronized (mPackages) {
3629            return addPermissionLocked(info, false);
3630        }
3631    }
3632
3633    @Override
3634    public boolean addPermissionAsync(PermissionInfo info) {
3635        synchronized (mPackages) {
3636            return addPermissionLocked(info, true);
3637        }
3638    }
3639
3640    @Override
3641    public void removePermission(String name) {
3642        synchronized (mPackages) {
3643            checkPermissionTreeLP(name);
3644            BasePermission bp = mSettings.mPermissions.get(name);
3645            if (bp != null) {
3646                if (bp.type != BasePermission.TYPE_DYNAMIC) {
3647                    throw new SecurityException(
3648                            "Not allowed to modify non-dynamic permission "
3649                            + name);
3650                }
3651                mSettings.mPermissions.remove(name);
3652                mSettings.writeLPr();
3653            }
3654        }
3655    }
3656
3657    private static void enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(PackageParser.Package pkg,
3658            BasePermission bp) {
3659        int index = pkg.requestedPermissions.indexOf(bp.name);
3660        if (index == -1) {
3661            throw new SecurityException("Package " + pkg.packageName
3662                    + " has not requested permission " + bp.name);
3663        }
3664        if (!bp.isRuntime() && !bp.isDevelopment()) {
3665            throw new SecurityException("Permission " + bp.name
3666                    + " is not a changeable permission type");
3667        }
3668    }
3669
3670    @Override
3671    public void grantRuntimePermission(String packageName, String name, final int userId) {
3672        if (!sUserManager.exists(userId)) {
3673            Log.e(TAG, "No such user:" + userId);
3674            return;
3675        }
3676
3677        mContext.enforceCallingOrSelfPermission(
3678                android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
3679                "grantRuntimePermission");
3680
3681        enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false,
3682                "grantRuntimePermission");
3683
3684        final int uid;
3685        final SettingBase sb;
3686
3687        synchronized (mPackages) {
3688            final PackageParser.Package pkg = mPackages.get(packageName);
3689            if (pkg == null) {
3690                throw new IllegalArgumentException("Unknown package: " + packageName);
3691            }
3692
3693            final BasePermission bp = mSettings.mPermissions.get(name);
3694            if (bp == null) {
3695                throw new IllegalArgumentException("Unknown permission: " + name);
3696            }
3697
3698            enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(pkg, bp);
3699
3700            // If a permission review is required for legacy apps we represent
3701            // their permissions as always granted runtime ones since we need
3702            // to keep the review required permission flag per user while an
3703            // install permission's state is shared across all users.
3704            if (Build.PERMISSIONS_REVIEW_REQUIRED
3705                    && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
3706                    && bp.isRuntime()) {
3707                return;
3708            }
3709
3710            uid = UserHandle.getUid(userId, pkg.applicationInfo.uid);
3711            sb = (SettingBase) pkg.mExtras;
3712            if (sb == null) {
3713                throw new IllegalArgumentException("Unknown package: " + packageName);
3714            }
3715
3716            final PermissionsState permissionsState = sb.getPermissionsState();
3717
3718            final int flags = permissionsState.getPermissionFlags(name, userId);
3719            if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
3720                throw new SecurityException("Cannot grant system fixed permission "
3721                        + name + " for package " + packageName);
3722            }
3723
3724            if (bp.isDevelopment()) {
3725                // Development permissions must be handled specially, since they are not
3726                // normal runtime permissions.  For now they apply to all users.
3727                if (permissionsState.grantInstallPermission(bp) !=
3728                        PermissionsState.PERMISSION_OPERATION_FAILURE) {
3729                    scheduleWriteSettingsLocked();
3730                }
3731                return;
3732            }
3733
3734            if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
3735                Slog.w(TAG, "Cannot grant runtime permission to a legacy app");
3736                return;
3737            }
3738
3739            final int result = permissionsState.grantRuntimePermission(bp, userId);
3740            switch (result) {
3741                case PermissionsState.PERMISSION_OPERATION_FAILURE: {
3742                    return;
3743                }
3744
3745                case PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
3746                    final int appId = UserHandle.getAppId(pkg.applicationInfo.uid);
3747                    mHandler.post(new Runnable() {
3748                        @Override
3749                        public void run() {
3750                            killUid(appId, userId, KILL_APP_REASON_GIDS_CHANGED);
3751                        }
3752                    });
3753                }
3754                break;
3755            }
3756
3757            mOnPermissionChangeListeners.onPermissionsChanged(uid);
3758
3759            // Not critical if that is lost - app has to request again.
3760            mSettings.writeRuntimePermissionsForUserLPr(userId, false);
3761        }
3762
3763        // Only need to do this if user is initialized. Otherwise it's a new user
3764        // and there are no processes running as the user yet and there's no need
3765        // to make an expensive call to remount processes for the changed permissions.
3766        if (READ_EXTERNAL_STORAGE.equals(name)
3767                || WRITE_EXTERNAL_STORAGE.equals(name)) {
3768            final long token = Binder.clearCallingIdentity();
3769            try {
3770                if (sUserManager.isInitialized(userId)) {
3771                    MountServiceInternal mountServiceInternal = LocalServices.getService(
3772                            MountServiceInternal.class);
3773                    mountServiceInternal.onExternalStoragePolicyChanged(uid, packageName);
3774                }
3775            } finally {
3776                Binder.restoreCallingIdentity(token);
3777            }
3778        }
3779    }
3780
3781    @Override
3782    public void revokeRuntimePermission(String packageName, String name, int userId) {
3783        if (!sUserManager.exists(userId)) {
3784            Log.e(TAG, "No such user:" + userId);
3785            return;
3786        }
3787
3788        mContext.enforceCallingOrSelfPermission(
3789                android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
3790                "revokeRuntimePermission");
3791
3792        enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false,
3793                "revokeRuntimePermission");
3794
3795        final int appId;
3796
3797        synchronized (mPackages) {
3798            final PackageParser.Package pkg = mPackages.get(packageName);
3799            if (pkg == null) {
3800                throw new IllegalArgumentException("Unknown package: " + packageName);
3801            }
3802
3803            final BasePermission bp = mSettings.mPermissions.get(name);
3804            if (bp == null) {
3805                throw new IllegalArgumentException("Unknown permission: " + name);
3806            }
3807
3808            enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(pkg, bp);
3809
3810            // If a permission review is required for legacy apps we represent
3811            // their permissions as always granted runtime ones since we need
3812            // to keep the review required permission flag per user while an
3813            // install permission's state is shared across all users.
3814            if (Build.PERMISSIONS_REVIEW_REQUIRED
3815                    && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
3816                    && bp.isRuntime()) {
3817                return;
3818            }
3819
3820            SettingBase sb = (SettingBase) pkg.mExtras;
3821            if (sb == null) {
3822                throw new IllegalArgumentException("Unknown package: " + packageName);
3823            }
3824
3825            final PermissionsState permissionsState = sb.getPermissionsState();
3826
3827            final int flags = permissionsState.getPermissionFlags(name, userId);
3828            if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
3829                throw new SecurityException("Cannot revoke system fixed permission "
3830                        + name + " for package " + packageName);
3831            }
3832
3833            if (bp.isDevelopment()) {
3834                // Development permissions must be handled specially, since they are not
3835                // normal runtime permissions.  For now they apply to all users.
3836                if (permissionsState.revokeInstallPermission(bp) !=
3837                        PermissionsState.PERMISSION_OPERATION_FAILURE) {
3838                    scheduleWriteSettingsLocked();
3839                }
3840                return;
3841            }
3842
3843            if (permissionsState.revokeRuntimePermission(bp, userId) ==
3844                    PermissionsState.PERMISSION_OPERATION_FAILURE) {
3845                return;
3846            }
3847
3848            mOnPermissionChangeListeners.onPermissionsChanged(pkg.applicationInfo.uid);
3849
3850            // Critical, after this call app should never have the permission.
3851            mSettings.writeRuntimePermissionsForUserLPr(userId, true);
3852
3853            appId = UserHandle.getAppId(pkg.applicationInfo.uid);
3854        }
3855
3856        killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED);
3857    }
3858
3859    @Override
3860    public void resetRuntimePermissions() {
3861        mContext.enforceCallingOrSelfPermission(
3862                android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
3863                "revokeRuntimePermission");
3864
3865        int callingUid = Binder.getCallingUid();
3866        if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
3867            mContext.enforceCallingOrSelfPermission(
3868                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
3869                    "resetRuntimePermissions");
3870        }
3871
3872        synchronized (mPackages) {
3873            updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL);
3874            for (int userId : UserManagerService.getInstance().getUserIds()) {
3875                final int packageCount = mPackages.size();
3876                for (int i = 0; i < packageCount; i++) {
3877                    PackageParser.Package pkg = mPackages.valueAt(i);
3878                    if (!(pkg.mExtras instanceof PackageSetting)) {
3879                        continue;
3880                    }
3881                    PackageSetting ps = (PackageSetting) pkg.mExtras;
3882                    resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
3883                }
3884            }
3885        }
3886    }
3887
3888    @Override
3889    public int getPermissionFlags(String name, String packageName, int userId) {
3890        if (!sUserManager.exists(userId)) {
3891            return 0;
3892        }
3893
3894        enforceGrantRevokeRuntimePermissionPermissions("getPermissionFlags");
3895
3896        enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false,
3897                "getPermissionFlags");
3898
3899        synchronized (mPackages) {
3900            final PackageParser.Package pkg = mPackages.get(packageName);
3901            if (pkg == null) {
3902                throw new IllegalArgumentException("Unknown package: " + packageName);
3903            }
3904
3905            final BasePermission bp = mSettings.mPermissions.get(name);
3906            if (bp == null) {
3907                throw new IllegalArgumentException("Unknown permission: " + name);
3908            }
3909
3910            SettingBase sb = (SettingBase) pkg.mExtras;
3911            if (sb == null) {
3912                throw new IllegalArgumentException("Unknown package: " + packageName);
3913            }
3914
3915            PermissionsState permissionsState = sb.getPermissionsState();
3916            return permissionsState.getPermissionFlags(name, userId);
3917        }
3918    }
3919
3920    @Override
3921    public void updatePermissionFlags(String name, String packageName, int flagMask,
3922            int flagValues, int userId) {
3923        if (!sUserManager.exists(userId)) {
3924            return;
3925        }
3926
3927        enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlags");
3928
3929        enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false,
3930                "updatePermissionFlags");
3931
3932        // Only the system can change these flags and nothing else.
3933        if (getCallingUid() != Process.SYSTEM_UID) {
3934            flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
3935            flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
3936            flagMask &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
3937            flagValues &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
3938            flagValues &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
3939        }
3940
3941        synchronized (mPackages) {
3942            final PackageParser.Package pkg = mPackages.get(packageName);
3943            if (pkg == null) {
3944                throw new IllegalArgumentException("Unknown package: " + packageName);
3945            }
3946
3947            final BasePermission bp = mSettings.mPermissions.get(name);
3948            if (bp == null) {
3949                throw new IllegalArgumentException("Unknown permission: " + name);
3950            }
3951
3952            SettingBase sb = (SettingBase) pkg.mExtras;
3953            if (sb == null) {
3954                throw new IllegalArgumentException("Unknown package: " + packageName);
3955            }
3956
3957            PermissionsState permissionsState = sb.getPermissionsState();
3958
3959            boolean hadState = permissionsState.getRuntimePermissionState(name, userId) != null;
3960
3961            if (permissionsState.updatePermissionFlags(bp, userId, flagMask, flagValues)) {
3962                // Install and runtime permissions are stored in different places,
3963                // so figure out what permission changed and persist the change.
3964                if (permissionsState.getInstallPermissionState(name) != null) {
3965                    scheduleWriteSettingsLocked();
3966                } else if (permissionsState.getRuntimePermissionState(name, userId) != null
3967                        || hadState) {
3968                    mSettings.writeRuntimePermissionsForUserLPr(userId, false);
3969                }
3970            }
3971        }
3972    }
3973
3974    /**
3975     * Update the permission flags for all packages and runtime permissions of a user in order
3976     * to allow device or profile owner to remove POLICY_FIXED.
3977     */
3978    @Override
3979    public void updatePermissionFlagsForAllApps(int flagMask, int flagValues, int userId) {
3980        if (!sUserManager.exists(userId)) {
3981            return;
3982        }
3983
3984        enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlagsForAllApps");
3985
3986        enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false,
3987                "updatePermissionFlagsForAllApps");
3988
3989        // Only the system can change system fixed flags.
3990        if (getCallingUid() != Process.SYSTEM_UID) {
3991            flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
3992            flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
3993        }
3994
3995        synchronized (mPackages) {
3996            boolean changed = false;
3997            final int packageCount = mPackages.size();
3998            for (int pkgIndex = 0; pkgIndex < packageCount; pkgIndex++) {
3999                final PackageParser.Package pkg = mPackages.valueAt(pkgIndex);
4000                SettingBase sb = (SettingBase) pkg.mExtras;
4001                if (sb == null) {
4002                    continue;
4003                }
4004                PermissionsState permissionsState = sb.getPermissionsState();
4005                changed |= permissionsState.updatePermissionFlagsForAllPermissions(
4006                        userId, flagMask, flagValues);
4007            }
4008            if (changed) {
4009                mSettings.writeRuntimePermissionsForUserLPr(userId, false);
4010            }
4011        }
4012    }
4013
4014    private void enforceGrantRevokeRuntimePermissionPermissions(String message) {
4015        if (mContext.checkCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS)
4016                != PackageManager.PERMISSION_GRANTED
4017            && mContext.checkCallingOrSelfPermission(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS)
4018                != PackageManager.PERMISSION_GRANTED) {
4019            throw new SecurityException(message + " requires "
4020                    + Manifest.permission.GRANT_RUNTIME_PERMISSIONS + " or "
4021                    + Manifest.permission.REVOKE_RUNTIME_PERMISSIONS);
4022        }
4023    }
4024
4025    @Override
4026    public boolean shouldShowRequestPermissionRationale(String permissionName,
4027            String packageName, int userId) {
4028        if (UserHandle.getCallingUserId() != userId) {
4029            mContext.enforceCallingPermission(
4030                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
4031                    "canShowRequestPermissionRationale for user " + userId);
4032        }
4033
4034        final int uid = getPackageUid(packageName, userId);
4035        if (UserHandle.getAppId(getCallingUid()) != UserHandle.getAppId(uid)) {
4036            return false;
4037        }
4038
4039        if (checkPermission(permissionName, packageName, userId)
4040                == PackageManager.PERMISSION_GRANTED) {
4041            return false;
4042        }
4043
4044        final int flags;
4045
4046        final long identity = Binder.clearCallingIdentity();
4047        try {
4048            flags = getPermissionFlags(permissionName,
4049                    packageName, userId);
4050        } finally {
4051            Binder.restoreCallingIdentity(identity);
4052        }
4053
4054        final int fixedFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
4055                | PackageManager.FLAG_PERMISSION_POLICY_FIXED
4056                | PackageManager.FLAG_PERMISSION_USER_FIXED;
4057
4058        if ((flags & fixedFlags) != 0) {
4059            return false;
4060        }
4061
4062        return (flags & PackageManager.FLAG_PERMISSION_USER_SET) != 0;
4063    }
4064
4065    @Override
4066    public void addOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
4067        mContext.enforceCallingOrSelfPermission(
4068                Manifest.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS,
4069                "addOnPermissionsChangeListener");
4070
4071        synchronized (mPackages) {
4072            mOnPermissionChangeListeners.addListenerLocked(listener);
4073        }
4074    }
4075
4076    @Override
4077    public void removeOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
4078        synchronized (mPackages) {
4079            mOnPermissionChangeListeners.removeListenerLocked(listener);
4080        }
4081    }
4082
4083    @Override
4084    public boolean isProtectedBroadcast(String actionName) {
4085        synchronized (mPackages) {
4086            if (mProtectedBroadcasts.contains(actionName)) {
4087                return true;
4088            } else if (actionName != null) {
4089                // TODO: remove these terrible hacks
4090                if (actionName.startsWith("android.net.netmon.lingerExpired")
4091                        || actionName.startsWith("com.android.server.sip.SipWakeupTimer")) {
4092                    return true;
4093                }
4094            }
4095        }
4096        return false;
4097    }
4098
4099    @Override
4100    public int checkSignatures(String pkg1, String pkg2) {
4101        synchronized (mPackages) {
4102            final PackageParser.Package p1 = mPackages.get(pkg1);
4103            final PackageParser.Package p2 = mPackages.get(pkg2);
4104            if (p1 == null || p1.mExtras == null
4105                    || p2 == null || p2.mExtras == null) {
4106                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
4107            }
4108            return compareSignatures(p1.mSignatures, p2.mSignatures);
4109        }
4110    }
4111
4112    @Override
4113    public int checkUidSignatures(int uid1, int uid2) {
4114        // Map to base uids.
4115        uid1 = UserHandle.getAppId(uid1);
4116        uid2 = UserHandle.getAppId(uid2);
4117        // reader
4118        synchronized (mPackages) {
4119            Signature[] s1;
4120            Signature[] s2;
4121            Object obj = mSettings.getUserIdLPr(uid1);
4122            if (obj != null) {
4123                if (obj instanceof SharedUserSetting) {
4124                    s1 = ((SharedUserSetting)obj).signatures.mSignatures;
4125                } else if (obj instanceof PackageSetting) {
4126                    s1 = ((PackageSetting)obj).signatures.mSignatures;
4127                } else {
4128                    return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
4129                }
4130            } else {
4131                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
4132            }
4133            obj = mSettings.getUserIdLPr(uid2);
4134            if (obj != null) {
4135                if (obj instanceof SharedUserSetting) {
4136                    s2 = ((SharedUserSetting)obj).signatures.mSignatures;
4137                } else if (obj instanceof PackageSetting) {
4138                    s2 = ((PackageSetting)obj).signatures.mSignatures;
4139                } else {
4140                    return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
4141                }
4142            } else {
4143                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
4144            }
4145            return compareSignatures(s1, s2);
4146        }
4147    }
4148
4149    private void killUid(int appId, int userId, String reason) {
4150        final long identity = Binder.clearCallingIdentity();
4151        try {
4152            IActivityManager am = ActivityManagerNative.getDefault();
4153            if (am != null) {
4154                try {
4155                    am.killUid(appId, userId, reason);
4156                } catch (RemoteException e) {
4157                    /* ignore - same process */
4158                }
4159            }
4160        } finally {
4161            Binder.restoreCallingIdentity(identity);
4162        }
4163    }
4164
4165    /**
4166     * Compares two sets of signatures. Returns:
4167     * <br />
4168     * {@link PackageManager#SIGNATURE_NEITHER_SIGNED}: if both signature sets are null,
4169     * <br />
4170     * {@link PackageManager#SIGNATURE_FIRST_NOT_SIGNED}: if the first signature set is null,
4171     * <br />
4172     * {@link PackageManager#SIGNATURE_SECOND_NOT_SIGNED}: if the second signature set is null,
4173     * <br />
4174     * {@link PackageManager#SIGNATURE_MATCH}: if the two signature sets are identical,
4175     * <br />
4176     * {@link PackageManager#SIGNATURE_NO_MATCH}: if the two signature sets differ.
4177     */
4178    static int compareSignatures(Signature[] s1, Signature[] s2) {
4179        if (s1 == null) {
4180            return s2 == null
4181                    ? PackageManager.SIGNATURE_NEITHER_SIGNED
4182                    : PackageManager.SIGNATURE_FIRST_NOT_SIGNED;
4183        }
4184
4185        if (s2 == null) {
4186            return PackageManager.SIGNATURE_SECOND_NOT_SIGNED;
4187        }
4188
4189        if (s1.length != s2.length) {
4190            return PackageManager.SIGNATURE_NO_MATCH;
4191        }
4192
4193        // Since both signature sets are of size 1, we can compare without HashSets.
4194        if (s1.length == 1) {
4195            return s1[0].equals(s2[0]) ?
4196                    PackageManager.SIGNATURE_MATCH :
4197                    PackageManager.SIGNATURE_NO_MATCH;
4198        }
4199
4200        ArraySet<Signature> set1 = new ArraySet<Signature>();
4201        for (Signature sig : s1) {
4202            set1.add(sig);
4203        }
4204        ArraySet<Signature> set2 = new ArraySet<Signature>();
4205        for (Signature sig : s2) {
4206            set2.add(sig);
4207        }
4208        // Make sure s2 contains all signatures in s1.
4209        if (set1.equals(set2)) {
4210            return PackageManager.SIGNATURE_MATCH;
4211        }
4212        return PackageManager.SIGNATURE_NO_MATCH;
4213    }
4214
4215    /**
4216     * If the database version for this type of package (internal storage or
4217     * external storage) is less than the version where package signatures
4218     * were updated, return true.
4219     */
4220    private boolean isCompatSignatureUpdateNeeded(PackageParser.Package scannedPkg) {
4221        final VersionInfo ver = getSettingsVersionForPackage(scannedPkg);
4222        return ver.databaseVersion < DatabaseVersion.SIGNATURE_END_ENTITY;
4223    }
4224
4225    /**
4226     * Used for backward compatibility to make sure any packages with
4227     * certificate chains get upgraded to the new style. {@code existingSigs}
4228     * will be in the old format (since they were stored on disk from before the
4229     * system upgrade) and {@code scannedSigs} will be in the newer format.
4230     */
4231    private int compareSignaturesCompat(PackageSignatures existingSigs,
4232            PackageParser.Package scannedPkg) {
4233        if (!isCompatSignatureUpdateNeeded(scannedPkg)) {
4234            return PackageManager.SIGNATURE_NO_MATCH;
4235        }
4236
4237        ArraySet<Signature> existingSet = new ArraySet<Signature>();
4238        for (Signature sig : existingSigs.mSignatures) {
4239            existingSet.add(sig);
4240        }
4241        ArraySet<Signature> scannedCompatSet = new ArraySet<Signature>();
4242        for (Signature sig : scannedPkg.mSignatures) {
4243            try {
4244                Signature[] chainSignatures = sig.getChainSignatures();
4245                for (Signature chainSig : chainSignatures) {
4246                    scannedCompatSet.add(chainSig);
4247                }
4248            } catch (CertificateEncodingException e) {
4249                scannedCompatSet.add(sig);
4250            }
4251        }
4252        /*
4253         * Make sure the expanded scanned set contains all signatures in the
4254         * existing one.
4255         */
4256        if (scannedCompatSet.equals(existingSet)) {
4257            // Migrate the old signatures to the new scheme.
4258            existingSigs.assignSignatures(scannedPkg.mSignatures);
4259            // The new KeySets will be re-added later in the scanning process.
4260            synchronized (mPackages) {
4261                mSettings.mKeySetManagerService.removeAppKeySetDataLPw(scannedPkg.packageName);
4262            }
4263            return PackageManager.SIGNATURE_MATCH;
4264        }
4265        return PackageManager.SIGNATURE_NO_MATCH;
4266    }
4267
4268    private boolean isRecoverSignatureUpdateNeeded(PackageParser.Package scannedPkg) {
4269        final VersionInfo ver = getSettingsVersionForPackage(scannedPkg);
4270        return ver.databaseVersion < DatabaseVersion.SIGNATURE_MALFORMED_RECOVER;
4271    }
4272
4273    private int compareSignaturesRecover(PackageSignatures existingSigs,
4274            PackageParser.Package scannedPkg) {
4275        if (!isRecoverSignatureUpdateNeeded(scannedPkg)) {
4276            return PackageManager.SIGNATURE_NO_MATCH;
4277        }
4278
4279        String msg = null;
4280        try {
4281            if (Signature.areEffectiveMatch(existingSigs.mSignatures, scannedPkg.mSignatures)) {
4282                logCriticalInfo(Log.INFO, "Recovered effectively matching certificates for "
4283                        + scannedPkg.packageName);
4284                return PackageManager.SIGNATURE_MATCH;
4285            }
4286        } catch (CertificateException e) {
4287            msg = e.getMessage();
4288        }
4289
4290        logCriticalInfo(Log.INFO,
4291                "Failed to recover certificates for " + scannedPkg.packageName + ": " + msg);
4292        return PackageManager.SIGNATURE_NO_MATCH;
4293    }
4294
4295    @Override
4296    public String[] getPackagesForUid(int uid) {
4297        uid = UserHandle.getAppId(uid);
4298        // reader
4299        synchronized (mPackages) {
4300            Object obj = mSettings.getUserIdLPr(uid);
4301            if (obj instanceof SharedUserSetting) {
4302                final SharedUserSetting sus = (SharedUserSetting) obj;
4303                final int N = sus.packages.size();
4304                final String[] res = new String[N];
4305                final Iterator<PackageSetting> it = sus.packages.iterator();
4306                int i = 0;
4307                while (it.hasNext()) {
4308                    res[i++] = it.next().name;
4309                }
4310                return res;
4311            } else if (obj instanceof PackageSetting) {
4312                final PackageSetting ps = (PackageSetting) obj;
4313                return new String[] { ps.name };
4314            }
4315        }
4316        return null;
4317    }
4318
4319    @Override
4320    public String getNameForUid(int uid) {
4321        // reader
4322        synchronized (mPackages) {
4323            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
4324            if (obj instanceof SharedUserSetting) {
4325                final SharedUserSetting sus = (SharedUserSetting) obj;
4326                return sus.name + ":" + sus.userId;
4327            } else if (obj instanceof PackageSetting) {
4328                final PackageSetting ps = (PackageSetting) obj;
4329                return ps.name;
4330            }
4331        }
4332        return null;
4333    }
4334
4335    @Override
4336    public int getUidForSharedUser(String sharedUserName) {
4337        if(sharedUserName == null) {
4338            return -1;
4339        }
4340        // reader
4341        synchronized (mPackages) {
4342            final SharedUserSetting suid = mSettings.getSharedUserLPw(sharedUserName, 0, 0, false);
4343            if (suid == null) {
4344                return -1;
4345            }
4346            return suid.userId;
4347        }
4348    }
4349
4350    @Override
4351    public int getFlagsForUid(int uid) {
4352        synchronized (mPackages) {
4353            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
4354            if (obj instanceof SharedUserSetting) {
4355                final SharedUserSetting sus = (SharedUserSetting) obj;
4356                return sus.pkgFlags;
4357            } else if (obj instanceof PackageSetting) {
4358                final PackageSetting ps = (PackageSetting) obj;
4359                return ps.pkgFlags;
4360            }
4361        }
4362        return 0;
4363    }
4364
4365    @Override
4366    public int getPrivateFlagsForUid(int uid) {
4367        synchronized (mPackages) {
4368            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
4369            if (obj instanceof SharedUserSetting) {
4370                final SharedUserSetting sus = (SharedUserSetting) obj;
4371                return sus.pkgPrivateFlags;
4372            } else if (obj instanceof PackageSetting) {
4373                final PackageSetting ps = (PackageSetting) obj;
4374                return ps.pkgPrivateFlags;
4375            }
4376        }
4377        return 0;
4378    }
4379
4380    @Override
4381    public boolean isUidPrivileged(int uid) {
4382        uid = UserHandle.getAppId(uid);
4383        // reader
4384        synchronized (mPackages) {
4385            Object obj = mSettings.getUserIdLPr(uid);
4386            if (obj instanceof SharedUserSetting) {
4387                final SharedUserSetting sus = (SharedUserSetting) obj;
4388                final Iterator<PackageSetting> it = sus.packages.iterator();
4389                while (it.hasNext()) {
4390                    if (it.next().isPrivileged()) {
4391                        return true;
4392                    }
4393                }
4394            } else if (obj instanceof PackageSetting) {
4395                final PackageSetting ps = (PackageSetting) obj;
4396                return ps.isPrivileged();
4397            }
4398        }
4399        return false;
4400    }
4401
4402    @Override
4403    public String[] getAppOpPermissionPackages(String permissionName) {
4404        synchronized (mPackages) {
4405            ArraySet<String> pkgs = mAppOpPermissionPackages.get(permissionName);
4406            if (pkgs == null) {
4407                return null;
4408            }
4409            return pkgs.toArray(new String[pkgs.size()]);
4410        }
4411    }
4412
4413    @Override
4414    public ResolveInfo resolveIntent(Intent intent, String resolvedType,
4415            int flags, int userId) {
4416        if (!sUserManager.exists(userId)) return null;
4417        flags = updateFlagsForResolve(flags, userId, intent);
4418        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "resolve intent");
4419        List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId);
4420        final ResolveInfo bestChoice =
4421                chooseBestActivity(intent, resolvedType, flags, query, userId);
4422
4423        if (isEphemeralAllowed(intent, query, userId)) {
4424            final EphemeralResolveInfo ai =
4425                    getEphemeralResolveInfo(intent, resolvedType, userId);
4426            if (ai != null) {
4427                if (DEBUG_EPHEMERAL) {
4428                    Slog.v(TAG, "Returning an EphemeralResolveInfo");
4429                }
4430                bestChoice.ephemeralInstaller = mEphemeralInstallerInfo;
4431                bestChoice.ephemeralResolveInfo = ai;
4432            }
4433        }
4434        return bestChoice;
4435    }
4436
4437    @Override
4438    public void setLastChosenActivity(Intent intent, String resolvedType, int flags,
4439            IntentFilter filter, int match, ComponentName activity) {
4440        final int userId = UserHandle.getCallingUserId();
4441        if (DEBUG_PREFERRED) {
4442            Log.v(TAG, "setLastChosenActivity intent=" + intent
4443                + " resolvedType=" + resolvedType
4444                + " flags=" + flags
4445                + " filter=" + filter
4446                + " match=" + match
4447                + " activity=" + activity);
4448            filter.dump(new PrintStreamPrinter(System.out), "    ");
4449        }
4450        intent.setComponent(null);
4451        List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId);
4452        // Find any earlier preferred or last chosen entries and nuke them
4453        findPreferredActivity(intent, resolvedType,
4454                flags, query, 0, false, true, false, userId);
4455        // Add the new activity as the last chosen for this filter
4456        addPreferredActivityInternal(filter, match, null, activity, false, userId,
4457                "Setting last chosen");
4458    }
4459
4460    @Override
4461    public ResolveInfo getLastChosenActivity(Intent intent, String resolvedType, int flags) {
4462        final int userId = UserHandle.getCallingUserId();
4463        if (DEBUG_PREFERRED) Log.v(TAG, "Querying last chosen activity for " + intent);
4464        List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId);
4465        return findPreferredActivity(intent, resolvedType, flags, query, 0,
4466                false, false, false, userId);
4467    }
4468
4469
4470    private boolean isEphemeralAllowed(
4471            Intent intent, List<ResolveInfo> resolvedActivites, int userId) {
4472        // Short circuit and return early if possible.
4473        final int callingUser = UserHandle.getCallingUserId();
4474        if (callingUser != UserHandle.USER_SYSTEM) {
4475            return false;
4476        }
4477        if (mEphemeralResolverConnection == null) {
4478            return false;
4479        }
4480        if (intent.getComponent() != null) {
4481            return false;
4482        }
4483        if (intent.getPackage() != null) {
4484            return false;
4485        }
4486        final boolean isWebUri = hasWebURI(intent);
4487        if (!isWebUri) {
4488            return false;
4489        }
4490        // Deny ephemeral apps if the user chose _ALWAYS or _ALWAYS_ASK for intent resolution.
4491        synchronized (mPackages) {
4492            final int count = resolvedActivites.size();
4493            for (int n = 0; n < count; n++) {
4494                ResolveInfo info = resolvedActivites.get(n);
4495                String packageName = info.activityInfo.packageName;
4496                PackageSetting ps = mSettings.mPackages.get(packageName);
4497                if (ps != null) {
4498                    // Try to get the status from User settings first
4499                    long packedStatus = getDomainVerificationStatusLPr(ps, userId);
4500                    int status = (int) (packedStatus >> 32);
4501                    if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS
4502                            || status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
4503                        if (DEBUG_EPHEMERAL) {
4504                            Slog.v(TAG, "DENY ephemeral apps;"
4505                                + " pkg: " + packageName + ", status: " + status);
4506                        }
4507                        return false;
4508                    }
4509                }
4510            }
4511        }
4512        // We've exhausted all ways to deny ephemeral application; let the system look for them.
4513        return true;
4514    }
4515
4516    private EphemeralResolveInfo getEphemeralResolveInfo(Intent intent, String resolvedType,
4517            int userId) {
4518        MessageDigest digest = null;
4519        try {
4520            digest = MessageDigest.getInstance(EphemeralResolveInfo.SHA_ALGORITHM);
4521        } catch (NoSuchAlgorithmException e) {
4522            // If we can't create a digest, ignore ephemeral apps.
4523            return null;
4524        }
4525
4526        final byte[] hostBytes = intent.getData().getHost().getBytes();
4527        final byte[] digestBytes = digest.digest(hostBytes);
4528        int shaPrefix =
4529                digestBytes[0] << 24
4530                | digestBytes[1] << 16
4531                | digestBytes[2] << 8
4532                | digestBytes[3] << 0;
4533        final List<EphemeralResolveInfo> ephemeralResolveInfoList =
4534                mEphemeralResolverConnection.getEphemeralResolveInfoList(shaPrefix);
4535        if (ephemeralResolveInfoList == null || ephemeralResolveInfoList.size() == 0) {
4536            // No hash prefix match; there are no ephemeral apps for this domain.
4537            return null;
4538        }
4539        for (int i = ephemeralResolveInfoList.size() - 1; i >= 0; --i) {
4540            EphemeralResolveInfo ephemeralApplication = ephemeralResolveInfoList.get(i);
4541            if (!Arrays.equals(digestBytes, ephemeralApplication.getDigestBytes())) {
4542                continue;
4543            }
4544            final List<IntentFilter> filters = ephemeralApplication.getFilters();
4545            // No filters; this should never happen.
4546            if (filters.isEmpty()) {
4547                continue;
4548            }
4549            // We have a domain match; resolve the filters to see if anything matches.
4550            final EphemeralIntentResolver ephemeralResolver = new EphemeralIntentResolver();
4551            for (int j = filters.size() - 1; j >= 0; --j) {
4552                final EphemeralResolveIntentInfo intentInfo =
4553                        new EphemeralResolveIntentInfo(filters.get(j), ephemeralApplication);
4554                ephemeralResolver.addFilter(intentInfo);
4555            }
4556            List<EphemeralResolveInfo> matchedResolveInfoList = ephemeralResolver.queryIntent(
4557                    intent, resolvedType, false /*defaultOnly*/, userId);
4558            if (!matchedResolveInfoList.isEmpty()) {
4559                return matchedResolveInfoList.get(0);
4560            }
4561        }
4562        // Hash or filter mis-match; no ephemeral apps for this domain.
4563        return null;
4564    }
4565
4566    private ResolveInfo chooseBestActivity(Intent intent, String resolvedType,
4567            int flags, List<ResolveInfo> query, int userId) {
4568        if (query != null) {
4569            final int N = query.size();
4570            if (N == 1) {
4571                return query.get(0);
4572            } else if (N > 1) {
4573                final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4574                // If there is more than one activity with the same priority,
4575                // then let the user decide between them.
4576                ResolveInfo r0 = query.get(0);
4577                ResolveInfo r1 = query.get(1);
4578                if (DEBUG_INTENT_MATCHING || debug) {
4579                    Slog.v(TAG, r0.activityInfo.name + "=" + r0.priority + " vs "
4580                            + r1.activityInfo.name + "=" + r1.priority);
4581                }
4582                // If the first activity has a higher priority, or a different
4583                // default, then it is always desirable to pick it.
4584                if (r0.priority != r1.priority
4585                        || r0.preferredOrder != r1.preferredOrder
4586                        || r0.isDefault != r1.isDefault) {
4587                    return query.get(0);
4588                }
4589                // If we have saved a preference for a preferred activity for
4590                // this Intent, use that.
4591                ResolveInfo ri = findPreferredActivity(intent, resolvedType,
4592                        flags, query, r0.priority, true, false, debug, userId);
4593                if (ri != null) {
4594                    return ri;
4595                }
4596                ri = new ResolveInfo(mResolveInfo);
4597                ri.activityInfo = new ActivityInfo(ri.activityInfo);
4598                ri.activityInfo.applicationInfo = new ApplicationInfo(
4599                        ri.activityInfo.applicationInfo);
4600                if (userId != 0) {
4601                    ri.activityInfo.applicationInfo.uid = UserHandle.getUid(userId,
4602                            UserHandle.getAppId(ri.activityInfo.applicationInfo.uid));
4603                }
4604                // Make sure that the resolver is displayable in car mode
4605                if (ri.activityInfo.metaData == null) ri.activityInfo.metaData = new Bundle();
4606                ri.activityInfo.metaData.putBoolean(Intent.METADATA_DOCK_HOME, true);
4607                return ri;
4608            }
4609        }
4610        return null;
4611    }
4612
4613    private ResolveInfo findPersistentPreferredActivityLP(Intent intent, String resolvedType,
4614            int flags, List<ResolveInfo> query, boolean debug, int userId) {
4615        final int N = query.size();
4616        PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
4617                .get(userId);
4618        // Get the list of persistent preferred activities that handle the intent
4619        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for presistent preferred activities...");
4620        List<PersistentPreferredActivity> pprefs = ppir != null
4621                ? ppir.queryIntent(intent, resolvedType,
4622                        (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId)
4623                : null;
4624        if (pprefs != null && pprefs.size() > 0) {
4625            final int M = pprefs.size();
4626            for (int i=0; i<M; i++) {
4627                final PersistentPreferredActivity ppa = pprefs.get(i);
4628                if (DEBUG_PREFERRED || debug) {
4629                    Slog.v(TAG, "Checking PersistentPreferredActivity ds="
4630                            + (ppa.countDataSchemes() > 0 ? ppa.getDataScheme(0) : "<none>")
4631                            + "\n  component=" + ppa.mComponent);
4632                    ppa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
4633                }
4634                final ActivityInfo ai = getActivityInfo(ppa.mComponent,
4635                        flags | MATCH_DISABLED_COMPONENTS, userId);
4636                if (DEBUG_PREFERRED || debug) {
4637                    Slog.v(TAG, "Found persistent preferred activity:");
4638                    if (ai != null) {
4639                        ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
4640                    } else {
4641                        Slog.v(TAG, "  null");
4642                    }
4643                }
4644                if (ai == null) {
4645                    // This previously registered persistent preferred activity
4646                    // component is no longer known. Ignore it and do NOT remove it.
4647                    continue;
4648                }
4649                for (int j=0; j<N; j++) {
4650                    final ResolveInfo ri = query.get(j);
4651                    if (!ri.activityInfo.applicationInfo.packageName
4652                            .equals(ai.applicationInfo.packageName)) {
4653                        continue;
4654                    }
4655                    if (!ri.activityInfo.name.equals(ai.name)) {
4656                        continue;
4657                    }
4658                    //  Found a persistent preference that can handle the intent.
4659                    if (DEBUG_PREFERRED || debug) {
4660                        Slog.v(TAG, "Returning persistent preferred activity: " +
4661                                ri.activityInfo.packageName + "/" + ri.activityInfo.name);
4662                    }
4663                    return ri;
4664                }
4665            }
4666        }
4667        return null;
4668    }
4669
4670    // TODO: handle preferred activities missing while user has amnesia
4671    ResolveInfo findPreferredActivity(Intent intent, String resolvedType, int flags,
4672            List<ResolveInfo> query, int priority, boolean always,
4673            boolean removeMatches, boolean debug, int userId) {
4674        if (!sUserManager.exists(userId)) return null;
4675        flags = updateFlagsForResolve(flags, userId, intent);
4676        // writer
4677        synchronized (mPackages) {
4678            if (intent.getSelector() != null) {
4679                intent = intent.getSelector();
4680            }
4681            if (DEBUG_PREFERRED) intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION);
4682
4683            // Try to find a matching persistent preferred activity.
4684            ResolveInfo pri = findPersistentPreferredActivityLP(intent, resolvedType, flags, query,
4685                    debug, userId);
4686
4687            // If a persistent preferred activity matched, use it.
4688            if (pri != null) {
4689                return pri;
4690            }
4691
4692            PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
4693            // Get the list of preferred activities that handle the intent
4694            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for preferred activities...");
4695            List<PreferredActivity> prefs = pir != null
4696                    ? pir.queryIntent(intent, resolvedType,
4697                            (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId)
4698                    : null;
4699            if (prefs != null && prefs.size() > 0) {
4700                boolean changed = false;
4701                try {
4702                    // First figure out how good the original match set is.
4703                    // We will only allow preferred activities that came
4704                    // from the same match quality.
4705                    int match = 0;
4706
4707                    if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Figuring out best match...");
4708
4709                    final int N = query.size();
4710                    for (int j=0; j<N; j++) {
4711                        final ResolveInfo ri = query.get(j);
4712                        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Match for " + ri.activityInfo
4713                                + ": 0x" + Integer.toHexString(match));
4714                        if (ri.match > match) {
4715                            match = ri.match;
4716                        }
4717                    }
4718
4719                    if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Best match: 0x"
4720                            + Integer.toHexString(match));
4721
4722                    match &= IntentFilter.MATCH_CATEGORY_MASK;
4723                    final int M = prefs.size();
4724                    for (int i=0; i<M; i++) {
4725                        final PreferredActivity pa = prefs.get(i);
4726                        if (DEBUG_PREFERRED || debug) {
4727                            Slog.v(TAG, "Checking PreferredActivity ds="
4728                                    + (pa.countDataSchemes() > 0 ? pa.getDataScheme(0) : "<none>")
4729                                    + "\n  component=" + pa.mPref.mComponent);
4730                            pa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
4731                        }
4732                        if (pa.mPref.mMatch != match) {
4733                            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping bad match "
4734                                    + Integer.toHexString(pa.mPref.mMatch));
4735                            continue;
4736                        }
4737                        // If it's not an "always" type preferred activity and that's what we're
4738                        // looking for, skip it.
4739                        if (always && !pa.mPref.mAlways) {
4740                            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping mAlways=false entry");
4741                            continue;
4742                        }
4743                        final ActivityInfo ai = getActivityInfo(pa.mPref.mComponent,
4744                                flags | MATCH_DISABLED_COMPONENTS, userId);
4745                        if (DEBUG_PREFERRED || debug) {
4746                            Slog.v(TAG, "Found preferred activity:");
4747                            if (ai != null) {
4748                                ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
4749                            } else {
4750                                Slog.v(TAG, "  null");
4751                            }
4752                        }
4753                        if (ai == null) {
4754                            // This previously registered preferred activity
4755                            // component is no longer known.  Most likely an update
4756                            // to the app was installed and in the new version this
4757                            // component no longer exists.  Clean it up by removing
4758                            // it from the preferred activities list, and skip it.
4759                            Slog.w(TAG, "Removing dangling preferred activity: "
4760                                    + pa.mPref.mComponent);
4761                            pir.removeFilter(pa);
4762                            changed = true;
4763                            continue;
4764                        }
4765                        for (int j=0; j<N; j++) {
4766                            final ResolveInfo ri = query.get(j);
4767                            if (!ri.activityInfo.applicationInfo.packageName
4768                                    .equals(ai.applicationInfo.packageName)) {
4769                                continue;
4770                            }
4771                            if (!ri.activityInfo.name.equals(ai.name)) {
4772                                continue;
4773                            }
4774
4775                            if (removeMatches) {
4776                                pir.removeFilter(pa);
4777                                changed = true;
4778                                if (DEBUG_PREFERRED) {
4779                                    Slog.v(TAG, "Removing match " + pa.mPref.mComponent);
4780                                }
4781                                break;
4782                            }
4783
4784                            // Okay we found a previously set preferred or last chosen app.
4785                            // If the result set is different from when this
4786                            // was created, we need to clear it and re-ask the
4787                            // user their preference, if we're looking for an "always" type entry.
4788                            if (always && !pa.mPref.sameSet(query)) {
4789                                Slog.i(TAG, "Result set changed, dropping preferred activity for "
4790                                        + intent + " type " + resolvedType);
4791                                if (DEBUG_PREFERRED) {
4792                                    Slog.v(TAG, "Removing preferred activity since set changed "
4793                                            + pa.mPref.mComponent);
4794                                }
4795                                pir.removeFilter(pa);
4796                                // Re-add the filter as a "last chosen" entry (!always)
4797                                PreferredActivity lastChosen = new PreferredActivity(
4798                                        pa, pa.mPref.mMatch, null, pa.mPref.mComponent, false);
4799                                pir.addFilter(lastChosen);
4800                                changed = true;
4801                                return null;
4802                            }
4803
4804                            // Yay! Either the set matched or we're looking for the last chosen
4805                            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Returning preferred activity: "
4806                                    + ri.activityInfo.packageName + "/" + ri.activityInfo.name);
4807                            return ri;
4808                        }
4809                    }
4810                } finally {
4811                    if (changed) {
4812                        if (DEBUG_PREFERRED) {
4813                            Slog.v(TAG, "Preferred activity bookkeeping changed; writing restrictions");
4814                        }
4815                        scheduleWritePackageRestrictionsLocked(userId);
4816                    }
4817                }
4818            }
4819        }
4820        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "No preferred activity to return");
4821        return null;
4822    }
4823
4824    /*
4825     * Returns if intent can be forwarded from the sourceUserId to the targetUserId
4826     */
4827    @Override
4828    public boolean canForwardTo(Intent intent, String resolvedType, int sourceUserId,
4829            int targetUserId) {
4830        mContext.enforceCallingOrSelfPermission(
4831                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
4832        List<CrossProfileIntentFilter> matches =
4833                getMatchingCrossProfileIntentFilters(intent, resolvedType, sourceUserId);
4834        if (matches != null) {
4835            int size = matches.size();
4836            for (int i = 0; i < size; i++) {
4837                if (matches.get(i).getTargetUserId() == targetUserId) return true;
4838            }
4839        }
4840        if (hasWebURI(intent)) {
4841            // cross-profile app linking works only towards the parent.
4842            final UserInfo parent = getProfileParent(sourceUserId);
4843            synchronized(mPackages) {
4844                CrossProfileDomainInfo xpDomainInfo = getCrossProfileDomainPreferredLpr(
4845                        intent, resolvedType, 0, sourceUserId, parent.id);
4846                return xpDomainInfo != null;
4847            }
4848        }
4849        return false;
4850    }
4851
4852    private UserInfo getProfileParent(int userId) {
4853        final long identity = Binder.clearCallingIdentity();
4854        try {
4855            return sUserManager.getProfileParent(userId);
4856        } finally {
4857            Binder.restoreCallingIdentity(identity);
4858        }
4859    }
4860
4861    private List<CrossProfileIntentFilter> getMatchingCrossProfileIntentFilters(Intent intent,
4862            String resolvedType, int userId) {
4863        CrossProfileIntentResolver resolver = mSettings.mCrossProfileIntentResolvers.get(userId);
4864        if (resolver != null) {
4865            return resolver.queryIntent(intent, resolvedType, false, userId);
4866        }
4867        return null;
4868    }
4869
4870    @Override
4871    public List<ResolveInfo> queryIntentActivities(Intent intent,
4872            String resolvedType, int flags, int userId) {
4873        if (!sUserManager.exists(userId)) return Collections.emptyList();
4874        flags = updateFlagsForResolve(flags, userId, intent);
4875        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "query intent activities");
4876        ComponentName comp = intent.getComponent();
4877        if (comp == null) {
4878            if (intent.getSelector() != null) {
4879                intent = intent.getSelector();
4880                comp = intent.getComponent();
4881            }
4882        }
4883
4884        if (comp != null) {
4885            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
4886            final ActivityInfo ai = getActivityInfo(comp, flags, userId);
4887            if (ai != null) {
4888                final ResolveInfo ri = new ResolveInfo();
4889                ri.activityInfo = ai;
4890                list.add(ri);
4891            }
4892            return list;
4893        }
4894
4895        // reader
4896        synchronized (mPackages) {
4897            final String pkgName = intent.getPackage();
4898            if (pkgName == null) {
4899                List<CrossProfileIntentFilter> matchingFilters =
4900                        getMatchingCrossProfileIntentFilters(intent, resolvedType, userId);
4901                // Check for results that need to skip the current profile.
4902                ResolveInfo xpResolveInfo  = querySkipCurrentProfileIntents(matchingFilters, intent,
4903                        resolvedType, flags, userId);
4904                if (xpResolveInfo != null) {
4905                    List<ResolveInfo> result = new ArrayList<ResolveInfo>(1);
4906                    result.add(xpResolveInfo);
4907                    return filterIfNotSystemUser(result, userId);
4908                }
4909
4910                // Check for results in the current profile.
4911                List<ResolveInfo> result = mActivities.queryIntent(
4912                        intent, resolvedType, flags, userId);
4913                result = filterIfNotSystemUser(result, userId);
4914
4915                // Check for cross profile results.
4916                boolean hasNonNegativePriorityResult = hasNonNegativePriority(result);
4917                xpResolveInfo = queryCrossProfileIntents(
4918                        matchingFilters, intent, resolvedType, flags, userId,
4919                        hasNonNegativePriorityResult);
4920                if (xpResolveInfo != null && isUserEnabled(xpResolveInfo.targetUserId)) {
4921                    boolean isVisibleToUser = filterIfNotSystemUser(
4922                            Collections.singletonList(xpResolveInfo), userId).size() > 0;
4923                    if (isVisibleToUser) {
4924                        result.add(xpResolveInfo);
4925                        Collections.sort(result, mResolvePrioritySorter);
4926                    }
4927                }
4928                if (hasWebURI(intent)) {
4929                    CrossProfileDomainInfo xpDomainInfo = null;
4930                    final UserInfo parent = getProfileParent(userId);
4931                    if (parent != null) {
4932                        xpDomainInfo = getCrossProfileDomainPreferredLpr(intent, resolvedType,
4933                                flags, userId, parent.id);
4934                    }
4935                    if (xpDomainInfo != null) {
4936                        if (xpResolveInfo != null) {
4937                            // If we didn't remove it, the cross-profile ResolveInfo would be twice
4938                            // in the result.
4939                            result.remove(xpResolveInfo);
4940                        }
4941                        if (result.size() == 0) {
4942                            result.add(xpDomainInfo.resolveInfo);
4943                            return result;
4944                        }
4945                    } else if (result.size() <= 1) {
4946                        return result;
4947                    }
4948                    result = filterCandidatesWithDomainPreferredActivitiesLPr(intent, flags, result,
4949                            xpDomainInfo, userId);
4950                    Collections.sort(result, mResolvePrioritySorter);
4951                }
4952                return result;
4953            }
4954            final PackageParser.Package pkg = mPackages.get(pkgName);
4955            if (pkg != null) {
4956                return filterIfNotSystemUser(
4957                        mActivities.queryIntentForPackage(
4958                                intent, resolvedType, flags, pkg.activities, userId),
4959                        userId);
4960            }
4961            return new ArrayList<ResolveInfo>();
4962        }
4963    }
4964
4965    private static class CrossProfileDomainInfo {
4966        /* ResolveInfo for IntentForwarderActivity to send the intent to the other profile */
4967        ResolveInfo resolveInfo;
4968        /* Best domain verification status of the activities found in the other profile */
4969        int bestDomainVerificationStatus;
4970    }
4971
4972    private CrossProfileDomainInfo getCrossProfileDomainPreferredLpr(Intent intent,
4973            String resolvedType, int flags, int sourceUserId, int parentUserId) {
4974        if (!sUserManager.hasUserRestriction(UserManager.ALLOW_PARENT_PROFILE_APP_LINKING,
4975                sourceUserId)) {
4976            return null;
4977        }
4978        List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent,
4979                resolvedType, flags, parentUserId);
4980
4981        if (resultTargetUser == null || resultTargetUser.isEmpty()) {
4982            return null;
4983        }
4984        CrossProfileDomainInfo result = null;
4985        int size = resultTargetUser.size();
4986        for (int i = 0; i < size; i++) {
4987            ResolveInfo riTargetUser = resultTargetUser.get(i);
4988            // Intent filter verification is only for filters that specify a host. So don't return
4989            // those that handle all web uris.
4990            if (riTargetUser.handleAllWebDataURI) {
4991                continue;
4992            }
4993            String packageName = riTargetUser.activityInfo.packageName;
4994            PackageSetting ps = mSettings.mPackages.get(packageName);
4995            if (ps == null) {
4996                continue;
4997            }
4998            long verificationState = getDomainVerificationStatusLPr(ps, parentUserId);
4999            int status = (int)(verificationState >> 32);
5000            if (result == null) {
5001                result = new CrossProfileDomainInfo();
5002                result.resolveInfo = createForwardingResolveInfoUnchecked(new IntentFilter(),
5003                        sourceUserId, parentUserId);
5004                result.bestDomainVerificationStatus = status;
5005            } else {
5006                result.bestDomainVerificationStatus = bestDomainVerificationStatus(status,
5007                        result.bestDomainVerificationStatus);
5008            }
5009        }
5010        // Don't consider matches with status NEVER across profiles.
5011        if (result != null && result.bestDomainVerificationStatus
5012                == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
5013            return null;
5014        }
5015        return result;
5016    }
5017
5018    /**
5019     * Verification statuses are ordered from the worse to the best, except for
5020     * INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER, which is the worse.
5021     */
5022    private int bestDomainVerificationStatus(int status1, int status2) {
5023        if (status1 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
5024            return status2;
5025        }
5026        if (status2 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
5027            return status1;
5028        }
5029        return (int) MathUtils.max(status1, status2);
5030    }
5031
5032    private boolean isUserEnabled(int userId) {
5033        long callingId = Binder.clearCallingIdentity();
5034        try {
5035            UserInfo userInfo = sUserManager.getUserInfo(userId);
5036            return userInfo != null && userInfo.isEnabled();
5037        } finally {
5038            Binder.restoreCallingIdentity(callingId);
5039        }
5040    }
5041
5042    /**
5043     * Filter out activities with systemUserOnly flag set, when current user is not System.
5044     *
5045     * @return filtered list
5046     */
5047    private List<ResolveInfo> filterIfNotSystemUser(List<ResolveInfo> resolveInfos, int userId) {
5048        if (userId == UserHandle.USER_SYSTEM) {
5049            return resolveInfos;
5050        }
5051        for (int i = resolveInfos.size() - 1; i >= 0; i--) {
5052            ResolveInfo info = resolveInfos.get(i);
5053            if ((info.activityInfo.flags & ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
5054                resolveInfos.remove(i);
5055            }
5056        }
5057        return resolveInfos;
5058    }
5059
5060    /**
5061     * @param resolveInfos list of resolve infos in descending priority order
5062     * @return if the list contains a resolve info with non-negative priority
5063     */
5064    private boolean hasNonNegativePriority(List<ResolveInfo> resolveInfos) {
5065        return resolveInfos.size() > 0 && resolveInfos.get(0).priority >= 0;
5066    }
5067
5068    private static boolean hasWebURI(Intent intent) {
5069        if (intent.getData() == null) {
5070            return false;
5071        }
5072        final String scheme = intent.getScheme();
5073        if (TextUtils.isEmpty(scheme)) {
5074            return false;
5075        }
5076        return scheme.equals(IntentFilter.SCHEME_HTTP) || scheme.equals(IntentFilter.SCHEME_HTTPS);
5077    }
5078
5079    private List<ResolveInfo> filterCandidatesWithDomainPreferredActivitiesLPr(Intent intent,
5080            int matchFlags, List<ResolveInfo> candidates, CrossProfileDomainInfo xpDomainInfo,
5081            int userId) {
5082        final boolean debug = (intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0;
5083
5084        if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) {
5085            Slog.v(TAG, "Filtering results with preferred activities. Candidates count: " +
5086                    candidates.size());
5087        }
5088
5089        ArrayList<ResolveInfo> result = new ArrayList<ResolveInfo>();
5090        ArrayList<ResolveInfo> alwaysList = new ArrayList<ResolveInfo>();
5091        ArrayList<ResolveInfo> undefinedList = new ArrayList<ResolveInfo>();
5092        ArrayList<ResolveInfo> alwaysAskList = new ArrayList<ResolveInfo>();
5093        ArrayList<ResolveInfo> neverList = new ArrayList<ResolveInfo>();
5094        ArrayList<ResolveInfo> matchAllList = new ArrayList<ResolveInfo>();
5095
5096        synchronized (mPackages) {
5097            final int count = candidates.size();
5098            // First, try to use linked apps. Partition the candidates into four lists:
5099            // one for the final results, one for the "do not use ever", one for "undefined status"
5100            // and finally one for "browser app type".
5101            for (int n=0; n<count; n++) {
5102                ResolveInfo info = candidates.get(n);
5103                String packageName = info.activityInfo.packageName;
5104                PackageSetting ps = mSettings.mPackages.get(packageName);
5105                if (ps != null) {
5106                    // Add to the special match all list (Browser use case)
5107                    if (info.handleAllWebDataURI) {
5108                        matchAllList.add(info);
5109                        continue;
5110                    }
5111                    // Try to get the status from User settings first
5112                    long packedStatus = getDomainVerificationStatusLPr(ps, userId);
5113                    int status = (int)(packedStatus >> 32);
5114                    int linkGeneration = (int)(packedStatus & 0xFFFFFFFF);
5115                    if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) {
5116                        if (DEBUG_DOMAIN_VERIFICATION) {
5117                            Slog.i(TAG, "  + always: " + info.activityInfo.packageName
5118                                    + " : linkgen=" + linkGeneration);
5119                        }
5120                        // Use link-enabled generation as preferredOrder, i.e.
5121                        // prefer newly-enabled over earlier-enabled.
5122                        info.preferredOrder = linkGeneration;
5123                        alwaysList.add(info);
5124                    } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
5125                        if (DEBUG_DOMAIN_VERIFICATION) {
5126                            Slog.i(TAG, "  + never: " + info.activityInfo.packageName);
5127                        }
5128                        neverList.add(info);
5129                    } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
5130                        if (DEBUG_DOMAIN_VERIFICATION) {
5131                            Slog.i(TAG, "  + always-ask: " + info.activityInfo.packageName);
5132                        }
5133                        alwaysAskList.add(info);
5134                    } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED ||
5135                            status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK) {
5136                        if (DEBUG_DOMAIN_VERIFICATION) {
5137                            Slog.i(TAG, "  + ask: " + info.activityInfo.packageName);
5138                        }
5139                        undefinedList.add(info);
5140                    }
5141                }
5142            }
5143
5144            // We'll want to include browser possibilities in a few cases
5145            boolean includeBrowser = false;
5146
5147            // First try to add the "always" resolution(s) for the current user, if any
5148            if (alwaysList.size() > 0) {
5149                result.addAll(alwaysList);
5150            } else {
5151                // Add all undefined apps as we want them to appear in the disambiguation dialog.
5152                result.addAll(undefinedList);
5153                // Maybe add one for the other profile.
5154                if (xpDomainInfo != null && (
5155                        xpDomainInfo.bestDomainVerificationStatus
5156                        != INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER)) {
5157                    result.add(xpDomainInfo.resolveInfo);
5158                }
5159                includeBrowser = true;
5160            }
5161
5162            // The presence of any 'always ask' alternatives means we'll also offer browsers.
5163            // If there were 'always' entries their preferred order has been set, so we also
5164            // back that off to make the alternatives equivalent
5165            if (alwaysAskList.size() > 0) {
5166                for (ResolveInfo i : result) {
5167                    i.preferredOrder = 0;
5168                }
5169                result.addAll(alwaysAskList);
5170                includeBrowser = true;
5171            }
5172
5173            if (includeBrowser) {
5174                // Also add browsers (all of them or only the default one)
5175                if (DEBUG_DOMAIN_VERIFICATION) {
5176                    Slog.v(TAG, "   ...including browsers in candidate set");
5177                }
5178                if ((matchFlags & MATCH_ALL) != 0) {
5179                    result.addAll(matchAllList);
5180                } else {
5181                    // Browser/generic handling case.  If there's a default browser, go straight
5182                    // to that (but only if there is no other higher-priority match).
5183                    final String defaultBrowserPackageName = getDefaultBrowserPackageName(userId);
5184                    int maxMatchPrio = 0;
5185                    ResolveInfo defaultBrowserMatch = null;
5186                    final int numCandidates = matchAllList.size();
5187                    for (int n = 0; n < numCandidates; n++) {
5188                        ResolveInfo info = matchAllList.get(n);
5189                        // track the highest overall match priority...
5190                        if (info.priority > maxMatchPrio) {
5191                            maxMatchPrio = info.priority;
5192                        }
5193                        // ...and the highest-priority default browser match
5194                        if (info.activityInfo.packageName.equals(defaultBrowserPackageName)) {
5195                            if (defaultBrowserMatch == null
5196                                    || (defaultBrowserMatch.priority < info.priority)) {
5197                                if (debug) {
5198                                    Slog.v(TAG, "Considering default browser match " + info);
5199                                }
5200                                defaultBrowserMatch = info;
5201                            }
5202                        }
5203                    }
5204                    if (defaultBrowserMatch != null
5205                            && defaultBrowserMatch.priority >= maxMatchPrio
5206                            && !TextUtils.isEmpty(defaultBrowserPackageName))
5207                    {
5208                        if (debug) {
5209                            Slog.v(TAG, "Default browser match " + defaultBrowserMatch);
5210                        }
5211                        result.add(defaultBrowserMatch);
5212                    } else {
5213                        result.addAll(matchAllList);
5214                    }
5215                }
5216
5217                // If there is nothing selected, add all candidates and remove the ones that the user
5218                // has explicitly put into the INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER state
5219                if (result.size() == 0) {
5220                    result.addAll(candidates);
5221                    result.removeAll(neverList);
5222                }
5223            }
5224        }
5225        if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) {
5226            Slog.v(TAG, "Filtered results with preferred activities. New candidates count: " +
5227                    result.size());
5228            for (ResolveInfo info : result) {
5229                Slog.v(TAG, "  + " + info.activityInfo);
5230            }
5231        }
5232        return result;
5233    }
5234
5235    // Returns a packed value as a long:
5236    //
5237    // high 'int'-sized word: link status: undefined/ask/never/always.
5238    // low 'int'-sized word: relative priority among 'always' results.
5239    private long getDomainVerificationStatusLPr(PackageSetting ps, int userId) {
5240        long result = ps.getDomainVerificationStatusForUser(userId);
5241        // if none available, get the master status
5242        if (result >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) {
5243            if (ps.getIntentFilterVerificationInfo() != null) {
5244                result = ((long)ps.getIntentFilterVerificationInfo().getStatus()) << 32;
5245            }
5246        }
5247        return result;
5248    }
5249
5250    private ResolveInfo querySkipCurrentProfileIntents(
5251            List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
5252            int flags, int sourceUserId) {
5253        if (matchingFilters != null) {
5254            int size = matchingFilters.size();
5255            for (int i = 0; i < size; i ++) {
5256                CrossProfileIntentFilter filter = matchingFilters.get(i);
5257                if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0) {
5258                    // Checking if there are activities in the target user that can handle the
5259                    // intent.
5260                    ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent,
5261                            resolvedType, flags, sourceUserId);
5262                    if (resolveInfo != null) {
5263                        return resolveInfo;
5264                    }
5265                }
5266            }
5267        }
5268        return null;
5269    }
5270
5271    // Return matching ResolveInfo in target user if any.
5272    private ResolveInfo queryCrossProfileIntents(
5273            List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
5274            int flags, int sourceUserId, boolean matchInCurrentProfile) {
5275        if (matchingFilters != null) {
5276            // Two {@link CrossProfileIntentFilter}s can have the same targetUserId and
5277            // match the same intent. For performance reasons, it is better not to
5278            // run queryIntent twice for the same userId
5279            SparseBooleanArray alreadyTriedUserIds = new SparseBooleanArray();
5280            int size = matchingFilters.size();
5281            for (int i = 0; i < size; i++) {
5282                CrossProfileIntentFilter filter = matchingFilters.get(i);
5283                int targetUserId = filter.getTargetUserId();
5284                boolean skipCurrentProfile =
5285                        (filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0;
5286                boolean skipCurrentProfileIfNoMatchFound =
5287                        (filter.getFlags() & PackageManager.ONLY_IF_NO_MATCH_FOUND) != 0;
5288                if (!skipCurrentProfile && !alreadyTriedUserIds.get(targetUserId)
5289                        && (!skipCurrentProfileIfNoMatchFound || !matchInCurrentProfile)) {
5290                    // Checking if there are activities in the target user that can handle the
5291                    // intent.
5292                    ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent,
5293                            resolvedType, flags, sourceUserId);
5294                    if (resolveInfo != null) return resolveInfo;
5295                    alreadyTriedUserIds.put(targetUserId, true);
5296                }
5297            }
5298        }
5299        return null;
5300    }
5301
5302    /**
5303     * If the filter's target user can handle the intent and is enabled: returns a ResolveInfo that
5304     * will forward the intent to the filter's target user.
5305     * Otherwise, returns null.
5306     */
5307    private ResolveInfo createForwardingResolveInfo(CrossProfileIntentFilter filter, Intent intent,
5308            String resolvedType, int flags, int sourceUserId) {
5309        int targetUserId = filter.getTargetUserId();
5310        List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent,
5311                resolvedType, flags, targetUserId);
5312        if (resultTargetUser != null && !resultTargetUser.isEmpty()
5313                && isUserEnabled(targetUserId)) {
5314            return createForwardingResolveInfoUnchecked(filter, sourceUserId, targetUserId);
5315        }
5316        return null;
5317    }
5318
5319    private ResolveInfo createForwardingResolveInfoUnchecked(IntentFilter filter,
5320            int sourceUserId, int targetUserId) {
5321        ResolveInfo forwardingResolveInfo = new ResolveInfo();
5322        long ident = Binder.clearCallingIdentity();
5323        boolean targetIsProfile;
5324        try {
5325            targetIsProfile = sUserManager.getUserInfo(targetUserId).isManagedProfile();
5326        } finally {
5327            Binder.restoreCallingIdentity(ident);
5328        }
5329        String className;
5330        if (targetIsProfile) {
5331            className = FORWARD_INTENT_TO_MANAGED_PROFILE;
5332        } else {
5333            className = FORWARD_INTENT_TO_PARENT;
5334        }
5335        ComponentName forwardingActivityComponentName = new ComponentName(
5336                mAndroidApplication.packageName, className);
5337        ActivityInfo forwardingActivityInfo = getActivityInfo(forwardingActivityComponentName, 0,
5338                sourceUserId);
5339        if (!targetIsProfile) {
5340            forwardingActivityInfo.showUserIcon = targetUserId;
5341            forwardingResolveInfo.noResourceId = true;
5342        }
5343        forwardingResolveInfo.activityInfo = forwardingActivityInfo;
5344        forwardingResolveInfo.priority = 0;
5345        forwardingResolveInfo.preferredOrder = 0;
5346        forwardingResolveInfo.match = 0;
5347        forwardingResolveInfo.isDefault = true;
5348        forwardingResolveInfo.filter = filter;
5349        forwardingResolveInfo.targetUserId = targetUserId;
5350        return forwardingResolveInfo;
5351    }
5352
5353    @Override
5354    public List<ResolveInfo> queryIntentActivityOptions(ComponentName caller,
5355            Intent[] specifics, String[] specificTypes, Intent intent,
5356            String resolvedType, int flags, int userId) {
5357        if (!sUserManager.exists(userId)) return Collections.emptyList();
5358        flags = updateFlagsForResolve(flags, userId, intent);
5359        enforceCrossUserPermission(Binder.getCallingUid(), userId, false,
5360                false, "query intent activity options");
5361        final String resultsAction = intent.getAction();
5362
5363        List<ResolveInfo> results = queryIntentActivities(intent, resolvedType, flags
5364                | PackageManager.GET_RESOLVED_FILTER, userId);
5365
5366        if (DEBUG_INTENT_MATCHING) {
5367            Log.v(TAG, "Query " + intent + ": " + results);
5368        }
5369
5370        int specificsPos = 0;
5371        int N;
5372
5373        // todo: note that the algorithm used here is O(N^2).  This
5374        // isn't a problem in our current environment, but if we start running
5375        // into situations where we have more than 5 or 10 matches then this
5376        // should probably be changed to something smarter...
5377
5378        // First we go through and resolve each of the specific items
5379        // that were supplied, taking care of removing any corresponding
5380        // duplicate items in the generic resolve list.
5381        if (specifics != null) {
5382            for (int i=0; i<specifics.length; i++) {
5383                final Intent sintent = specifics[i];
5384                if (sintent == null) {
5385                    continue;
5386                }
5387
5388                if (DEBUG_INTENT_MATCHING) {
5389                    Log.v(TAG, "Specific #" + i + ": " + sintent);
5390                }
5391
5392                String action = sintent.getAction();
5393                if (resultsAction != null && resultsAction.equals(action)) {
5394                    // If this action was explicitly requested, then don't
5395                    // remove things that have it.
5396                    action = null;
5397                }
5398
5399                ResolveInfo ri = null;
5400                ActivityInfo ai = null;
5401
5402                ComponentName comp = sintent.getComponent();
5403                if (comp == null) {
5404                    ri = resolveIntent(
5405                        sintent,
5406                        specificTypes != null ? specificTypes[i] : null,
5407                            flags, userId);
5408                    if (ri == null) {
5409                        continue;
5410                    }
5411                    if (ri == mResolveInfo) {
5412                        // ACK!  Must do something better with this.
5413                    }
5414                    ai = ri.activityInfo;
5415                    comp = new ComponentName(ai.applicationInfo.packageName,
5416                            ai.name);
5417                } else {
5418                    ai = getActivityInfo(comp, flags, userId);
5419                    if (ai == null) {
5420                        continue;
5421                    }
5422                }
5423
5424                // Look for any generic query activities that are duplicates
5425                // of this specific one, and remove them from the results.
5426                if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Specific #" + i + ": " + ai);
5427                N = results.size();
5428                int j;
5429                for (j=specificsPos; j<N; j++) {
5430                    ResolveInfo sri = results.get(j);
5431                    if ((sri.activityInfo.name.equals(comp.getClassName())
5432                            && sri.activityInfo.applicationInfo.packageName.equals(
5433                                    comp.getPackageName()))
5434                        || (action != null && sri.filter.matchAction(action))) {
5435                        results.remove(j);
5436                        if (DEBUG_INTENT_MATCHING) Log.v(
5437                            TAG, "Removing duplicate item from " + j
5438                            + " due to specific " + specificsPos);
5439                        if (ri == null) {
5440                            ri = sri;
5441                        }
5442                        j--;
5443                        N--;
5444                    }
5445                }
5446
5447                // Add this specific item to its proper place.
5448                if (ri == null) {
5449                    ri = new ResolveInfo();
5450                    ri.activityInfo = ai;
5451                }
5452                results.add(specificsPos, ri);
5453                ri.specificIndex = i;
5454                specificsPos++;
5455            }
5456        }
5457
5458        // Now we go through the remaining generic results and remove any
5459        // duplicate actions that are found here.
5460        N = results.size();
5461        for (int i=specificsPos; i<N-1; i++) {
5462            final ResolveInfo rii = results.get(i);
5463            if (rii.filter == null) {
5464                continue;
5465            }
5466
5467            // Iterate over all of the actions of this result's intent
5468            // filter...  typically this should be just one.
5469            final Iterator<String> it = rii.filter.actionsIterator();
5470            if (it == null) {
5471                continue;
5472            }
5473            while (it.hasNext()) {
5474                final String action = it.next();
5475                if (resultsAction != null && resultsAction.equals(action)) {
5476                    // If this action was explicitly requested, then don't
5477                    // remove things that have it.
5478                    continue;
5479                }
5480                for (int j=i+1; j<N; j++) {
5481                    final ResolveInfo rij = results.get(j);
5482                    if (rij.filter != null && rij.filter.hasAction(action)) {
5483                        results.remove(j);
5484                        if (DEBUG_INTENT_MATCHING) Log.v(
5485                            TAG, "Removing duplicate item from " + j
5486                            + " due to action " + action + " at " + i);
5487                        j--;
5488                        N--;
5489                    }
5490                }
5491            }
5492
5493            // If the caller didn't request filter information, drop it now
5494            // so we don't have to marshall/unmarshall it.
5495            if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
5496                rii.filter = null;
5497            }
5498        }
5499
5500        // Filter out the caller activity if so requested.
5501        if (caller != null) {
5502            N = results.size();
5503            for (int i=0; i<N; i++) {
5504                ActivityInfo ainfo = results.get(i).activityInfo;
5505                if (caller.getPackageName().equals(ainfo.applicationInfo.packageName)
5506                        && caller.getClassName().equals(ainfo.name)) {
5507                    results.remove(i);
5508                    break;
5509                }
5510            }
5511        }
5512
5513        // If the caller didn't request filter information,
5514        // drop them now so we don't have to
5515        // marshall/unmarshall it.
5516        if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
5517            N = results.size();
5518            for (int i=0; i<N; i++) {
5519                results.get(i).filter = null;
5520            }
5521        }
5522
5523        if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Result: " + results);
5524        return results;
5525    }
5526
5527    @Override
5528    public List<ResolveInfo> queryIntentReceivers(Intent intent, String resolvedType, int flags,
5529            int userId) {
5530        if (!sUserManager.exists(userId)) return Collections.emptyList();
5531        flags = updateFlagsForResolve(flags, userId, intent);
5532        ComponentName comp = intent.getComponent();
5533        if (comp == null) {
5534            if (intent.getSelector() != null) {
5535                intent = intent.getSelector();
5536                comp = intent.getComponent();
5537            }
5538        }
5539        if (comp != null) {
5540            List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
5541            ActivityInfo ai = getReceiverInfo(comp, flags, userId);
5542            if (ai != null) {
5543                ResolveInfo ri = new ResolveInfo();
5544                ri.activityInfo = ai;
5545                list.add(ri);
5546            }
5547            return list;
5548        }
5549
5550        // reader
5551        synchronized (mPackages) {
5552            String pkgName = intent.getPackage();
5553            if (pkgName == null) {
5554                return mReceivers.queryIntent(intent, resolvedType, flags, userId);
5555            }
5556            final PackageParser.Package pkg = mPackages.get(pkgName);
5557            if (pkg != null) {
5558                return mReceivers.queryIntentForPackage(intent, resolvedType, flags, pkg.receivers,
5559                        userId);
5560            }
5561            return null;
5562        }
5563    }
5564
5565    @Override
5566    public ResolveInfo resolveService(Intent intent, String resolvedType, int flags, int userId) {
5567        if (!sUserManager.exists(userId)) return null;
5568        flags = updateFlagsForResolve(flags, userId, intent);
5569        List<ResolveInfo> query = queryIntentServices(intent, resolvedType, flags, userId);
5570        if (query != null) {
5571            if (query.size() >= 1) {
5572                // If there is more than one service with the same priority,
5573                // just arbitrarily pick the first one.
5574                return query.get(0);
5575            }
5576        }
5577        return null;
5578    }
5579
5580    @Override
5581    public List<ResolveInfo> queryIntentServices(Intent intent, String resolvedType, int flags,
5582            int userId) {
5583        if (!sUserManager.exists(userId)) return Collections.emptyList();
5584        flags = updateFlagsForResolve(flags, userId, intent);
5585        ComponentName comp = intent.getComponent();
5586        if (comp == null) {
5587            if (intent.getSelector() != null) {
5588                intent = intent.getSelector();
5589                comp = intent.getComponent();
5590            }
5591        }
5592        if (comp != null) {
5593            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
5594            final ServiceInfo si = getServiceInfo(comp, flags, userId);
5595            if (si != null) {
5596                final ResolveInfo ri = new ResolveInfo();
5597                ri.serviceInfo = si;
5598                list.add(ri);
5599            }
5600            return list;
5601        }
5602
5603        // reader
5604        synchronized (mPackages) {
5605            String pkgName = intent.getPackage();
5606            if (pkgName == null) {
5607                return mServices.queryIntent(intent, resolvedType, flags, userId);
5608            }
5609            final PackageParser.Package pkg = mPackages.get(pkgName);
5610            if (pkg != null) {
5611                return mServices.queryIntentForPackage(intent, resolvedType, flags, pkg.services,
5612                        userId);
5613            }
5614            return null;
5615        }
5616    }
5617
5618    @Override
5619    public List<ResolveInfo> queryIntentContentProviders(
5620            Intent intent, String resolvedType, int flags, int userId) {
5621        if (!sUserManager.exists(userId)) return Collections.emptyList();
5622        flags = updateFlagsForResolve(flags, userId, intent);
5623        ComponentName comp = intent.getComponent();
5624        if (comp == null) {
5625            if (intent.getSelector() != null) {
5626                intent = intent.getSelector();
5627                comp = intent.getComponent();
5628            }
5629        }
5630        if (comp != null) {
5631            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
5632            final ProviderInfo pi = getProviderInfo(comp, flags, userId);
5633            if (pi != null) {
5634                final ResolveInfo ri = new ResolveInfo();
5635                ri.providerInfo = pi;
5636                list.add(ri);
5637            }
5638            return list;
5639        }
5640
5641        // reader
5642        synchronized (mPackages) {
5643            String pkgName = intent.getPackage();
5644            if (pkgName == null) {
5645                return mProviders.queryIntent(intent, resolvedType, flags, userId);
5646            }
5647            final PackageParser.Package pkg = mPackages.get(pkgName);
5648            if (pkg != null) {
5649                return mProviders.queryIntentForPackage(
5650                        intent, resolvedType, flags, pkg.providers, userId);
5651            }
5652            return null;
5653        }
5654    }
5655
5656    @Override
5657    public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) {
5658        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
5659        flags = updateFlagsForPackage(flags, userId, null);
5660        final boolean listUninstalled = (flags & MATCH_UNINSTALLED_PACKAGES) != 0;
5661        enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, "get installed packages");
5662
5663        // writer
5664        synchronized (mPackages) {
5665            ArrayList<PackageInfo> list;
5666            if (listUninstalled) {
5667                list = new ArrayList<PackageInfo>(mSettings.mPackages.size());
5668                for (PackageSetting ps : mSettings.mPackages.values()) {
5669                    PackageInfo pi;
5670                    if (ps.pkg != null) {
5671                        pi = generatePackageInfo(ps.pkg, flags, userId);
5672                    } else {
5673                        pi = generatePackageInfoFromSettingsLPw(ps.name, flags, userId);
5674                    }
5675                    if (pi != null) {
5676                        list.add(pi);
5677                    }
5678                }
5679            } else {
5680                list = new ArrayList<PackageInfo>(mPackages.size());
5681                for (PackageParser.Package p : mPackages.values()) {
5682                    PackageInfo pi = generatePackageInfo(p, flags, userId);
5683                    if (pi != null) {
5684                        list.add(pi);
5685                    }
5686                }
5687            }
5688
5689            return new ParceledListSlice<PackageInfo>(list);
5690        }
5691    }
5692
5693    private void addPackageHoldingPermissions(ArrayList<PackageInfo> list, PackageSetting ps,
5694            String[] permissions, boolean[] tmp, int flags, int userId) {
5695        int numMatch = 0;
5696        final PermissionsState permissionsState = ps.getPermissionsState();
5697        for (int i=0; i<permissions.length; i++) {
5698            final String permission = permissions[i];
5699            if (permissionsState.hasPermission(permission, userId)) {
5700                tmp[i] = true;
5701                numMatch++;
5702            } else {
5703                tmp[i] = false;
5704            }
5705        }
5706        if (numMatch == 0) {
5707            return;
5708        }
5709        PackageInfo pi;
5710        if (ps.pkg != null) {
5711            pi = generatePackageInfo(ps.pkg, flags, userId);
5712        } else {
5713            pi = generatePackageInfoFromSettingsLPw(ps.name, flags, userId);
5714        }
5715        // The above might return null in cases of uninstalled apps or install-state
5716        // skew across users/profiles.
5717        if (pi != null) {
5718            if ((flags&PackageManager.GET_PERMISSIONS) == 0) {
5719                if (numMatch == permissions.length) {
5720                    pi.requestedPermissions = permissions;
5721                } else {
5722                    pi.requestedPermissions = new String[numMatch];
5723                    numMatch = 0;
5724                    for (int i=0; i<permissions.length; i++) {
5725                        if (tmp[i]) {
5726                            pi.requestedPermissions[numMatch] = permissions[i];
5727                            numMatch++;
5728                        }
5729                    }
5730                }
5731            }
5732            list.add(pi);
5733        }
5734    }
5735
5736    @Override
5737    public ParceledListSlice<PackageInfo> getPackagesHoldingPermissions(
5738            String[] permissions, int flags, int userId) {
5739        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
5740        flags = updateFlagsForPackage(flags, userId, permissions);
5741        final boolean listUninstalled = (flags & MATCH_UNINSTALLED_PACKAGES) != 0;
5742
5743        // writer
5744        synchronized (mPackages) {
5745            ArrayList<PackageInfo> list = new ArrayList<PackageInfo>();
5746            boolean[] tmpBools = new boolean[permissions.length];
5747            if (listUninstalled) {
5748                for (PackageSetting ps : mSettings.mPackages.values()) {
5749                    addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags, userId);
5750                }
5751            } else {
5752                for (PackageParser.Package pkg : mPackages.values()) {
5753                    PackageSetting ps = (PackageSetting)pkg.mExtras;
5754                    if (ps != null) {
5755                        addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags,
5756                                userId);
5757                    }
5758                }
5759            }
5760
5761            return new ParceledListSlice<PackageInfo>(list);
5762        }
5763    }
5764
5765    @Override
5766    public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags, int userId) {
5767        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
5768        flags = updateFlagsForApplication(flags, userId, null);
5769        final boolean listUninstalled = (flags & MATCH_UNINSTALLED_PACKAGES) != 0;
5770
5771        // writer
5772        synchronized (mPackages) {
5773            ArrayList<ApplicationInfo> list;
5774            if (listUninstalled) {
5775                list = new ArrayList<ApplicationInfo>(mSettings.mPackages.size());
5776                for (PackageSetting ps : mSettings.mPackages.values()) {
5777                    ApplicationInfo ai;
5778                    if (ps.pkg != null) {
5779                        ai = PackageParser.generateApplicationInfo(ps.pkg, flags,
5780                                ps.readUserState(userId), userId);
5781                    } else {
5782                        ai = generateApplicationInfoFromSettingsLPw(ps.name, flags, userId);
5783                    }
5784                    if (ai != null) {
5785                        list.add(ai);
5786                    }
5787                }
5788            } else {
5789                list = new ArrayList<ApplicationInfo>(mPackages.size());
5790                for (PackageParser.Package p : mPackages.values()) {
5791                    if (p.mExtras != null) {
5792                        ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
5793                                ((PackageSetting)p.mExtras).readUserState(userId), userId);
5794                        if (ai != null) {
5795                            list.add(ai);
5796                        }
5797                    }
5798                }
5799            }
5800
5801            return new ParceledListSlice<ApplicationInfo>(list);
5802        }
5803    }
5804
5805    @Override
5806    public ParceledListSlice<EphemeralApplicationInfo> getEphemeralApplications(int userId) {
5807        mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_EPHEMERAL_APPS,
5808                "getEphemeralApplications");
5809        enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false,
5810                "getEphemeralApplications");
5811        synchronized (mPackages) {
5812            List<EphemeralApplicationInfo> ephemeralApps = mEphemeralApplicationRegistry
5813                    .getEphemeralApplicationsLPw(userId);
5814            if (ephemeralApps != null) {
5815                return new ParceledListSlice<>(ephemeralApps);
5816            }
5817        }
5818        return null;
5819    }
5820
5821    @Override
5822    public boolean isEphemeralApplication(String packageName, int userId) {
5823        enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false,
5824                "isEphemeral");
5825        if (!isCallerSameApp(packageName)) {
5826            return false;
5827        }
5828        synchronized (mPackages) {
5829            PackageParser.Package pkg = mPackages.get(packageName);
5830            if (pkg != null) {
5831                return pkg.applicationInfo.isEphemeralApp();
5832            }
5833        }
5834        return false;
5835    }
5836
5837    @Override
5838    public byte[] getEphemeralApplicationCookie(String packageName, int userId) {
5839        enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false,
5840                "getCookie");
5841        if (!isCallerSameApp(packageName)) {
5842            return null;
5843        }
5844        synchronized (mPackages) {
5845            return mEphemeralApplicationRegistry.getEphemeralApplicationCookieLPw(
5846                    packageName, userId);
5847        }
5848    }
5849
5850    @Override
5851    public boolean setEphemeralApplicationCookie(String packageName, byte[] cookie, int userId) {
5852        enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false,
5853                "setCookie");
5854        if (!isCallerSameApp(packageName)) {
5855            return false;
5856        }
5857        synchronized (mPackages) {
5858            return mEphemeralApplicationRegistry.setEphemeralApplicationCookieLPw(
5859                    packageName, cookie, userId);
5860        }
5861    }
5862
5863    @Override
5864    public Bitmap getEphemeralApplicationIcon(String packageName, int userId) {
5865        mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_EPHEMERAL_APPS,
5866                "getEphemeralApplicationIcon");
5867        enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false,
5868                "getEphemeralApplicationIcon");
5869        synchronized (mPackages) {
5870            return mEphemeralApplicationRegistry.getEphemeralApplicationIconLPw(
5871                    packageName, userId);
5872        }
5873    }
5874
5875    private boolean isCallerSameApp(String packageName) {
5876        PackageParser.Package pkg = mPackages.get(packageName);
5877        return pkg != null
5878                && UserHandle.getAppId(Binder.getCallingUid()) == pkg.applicationInfo.uid;
5879    }
5880
5881    public List<ApplicationInfo> getPersistentApplications(int flags) {
5882        final ArrayList<ApplicationInfo> finalList = new ArrayList<ApplicationInfo>();
5883
5884        // reader
5885        synchronized (mPackages) {
5886            final Iterator<PackageParser.Package> i = mPackages.values().iterator();
5887            final int userId = UserHandle.getCallingUserId();
5888            while (i.hasNext()) {
5889                final PackageParser.Package p = i.next();
5890                if (p.applicationInfo != null
5891                        && (p.applicationInfo.flags&ApplicationInfo.FLAG_PERSISTENT) != 0
5892                        && (!mSafeMode || isSystemApp(p))) {
5893                    PackageSetting ps = mSettings.mPackages.get(p.packageName);
5894                    if (ps != null) {
5895                        ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
5896                                ps.readUserState(userId), userId);
5897                        if (ai != null) {
5898                            finalList.add(ai);
5899                        }
5900                    }
5901                }
5902            }
5903        }
5904
5905        return finalList;
5906    }
5907
5908    @Override
5909    public ProviderInfo resolveContentProvider(String name, int flags, int userId) {
5910        if (!sUserManager.exists(userId)) return null;
5911        flags = updateFlagsForComponent(flags, userId, name);
5912        // reader
5913        synchronized (mPackages) {
5914            final PackageParser.Provider provider = mProvidersByAuthority.get(name);
5915            PackageSetting ps = provider != null
5916                    ? mSettings.mPackages.get(provider.owner.packageName)
5917                    : null;
5918            return ps != null
5919                    && mSettings.isEnabledAndMatchLPr(provider.info, flags, userId)
5920                    && (!mSafeMode || (provider.info.applicationInfo.flags
5921                            &ApplicationInfo.FLAG_SYSTEM) != 0)
5922                    ? PackageParser.generateProviderInfo(provider, flags,
5923                            ps.readUserState(userId), userId)
5924                    : null;
5925        }
5926    }
5927
5928    /**
5929     * @deprecated
5930     */
5931    @Deprecated
5932    public void querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo) {
5933        // reader
5934        synchronized (mPackages) {
5935            final Iterator<Map.Entry<String, PackageParser.Provider>> i = mProvidersByAuthority
5936                    .entrySet().iterator();
5937            final int userId = UserHandle.getCallingUserId();
5938            while (i.hasNext()) {
5939                Map.Entry<String, PackageParser.Provider> entry = i.next();
5940                PackageParser.Provider p = entry.getValue();
5941                PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
5942
5943                if (ps != null && p.syncable
5944                        && (!mSafeMode || (p.info.applicationInfo.flags
5945                                &ApplicationInfo.FLAG_SYSTEM) != 0)) {
5946                    ProviderInfo info = PackageParser.generateProviderInfo(p, 0,
5947                            ps.readUserState(userId), userId);
5948                    if (info != null) {
5949                        outNames.add(entry.getKey());
5950                        outInfo.add(info);
5951                    }
5952                }
5953            }
5954        }
5955    }
5956
5957    @Override
5958    public ParceledListSlice<ProviderInfo> queryContentProviders(String processName,
5959            int uid, int flags) {
5960        final int userId = processName != null ? UserHandle.getUserId(uid)
5961                : UserHandle.getCallingUserId();
5962        if (!sUserManager.exists(userId)) return null;
5963        flags = updateFlagsForComponent(flags, userId, processName);
5964
5965        ArrayList<ProviderInfo> finalList = null;
5966        // reader
5967        synchronized (mPackages) {
5968            final Iterator<PackageParser.Provider> i = mProviders.mProviders.values().iterator();
5969            while (i.hasNext()) {
5970                final PackageParser.Provider p = i.next();
5971                PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
5972                if (ps != null && p.info.authority != null
5973                        && (processName == null
5974                                || (p.info.processName.equals(processName)
5975                                        && UserHandle.isSameApp(p.info.applicationInfo.uid, uid)))
5976                        && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)
5977                        && (!mSafeMode
5978                                || (p.info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0)) {
5979                    if (finalList == null) {
5980                        finalList = new ArrayList<ProviderInfo>(3);
5981                    }
5982                    ProviderInfo info = PackageParser.generateProviderInfo(p, flags,
5983                            ps.readUserState(userId), userId);
5984                    if (info != null) {
5985                        finalList.add(info);
5986                    }
5987                }
5988            }
5989        }
5990
5991        if (finalList != null) {
5992            Collections.sort(finalList, mProviderInitOrderSorter);
5993            return new ParceledListSlice<ProviderInfo>(finalList);
5994        }
5995
5996        return null;
5997    }
5998
5999    @Override
6000    public InstrumentationInfo getInstrumentationInfo(ComponentName name, int flags) {
6001        // reader
6002        synchronized (mPackages) {
6003            final PackageParser.Instrumentation i = mInstrumentation.get(name);
6004            return PackageParser.generateInstrumentationInfo(i, flags);
6005        }
6006    }
6007
6008    @Override
6009    public List<InstrumentationInfo> queryInstrumentation(String targetPackage,
6010            int flags) {
6011        ArrayList<InstrumentationInfo> finalList =
6012            new ArrayList<InstrumentationInfo>();
6013
6014        // reader
6015        synchronized (mPackages) {
6016            final Iterator<PackageParser.Instrumentation> i = mInstrumentation.values().iterator();
6017            while (i.hasNext()) {
6018                final PackageParser.Instrumentation p = i.next();
6019                if (targetPackage == null
6020                        || targetPackage.equals(p.info.targetPackage)) {
6021                    InstrumentationInfo ii = PackageParser.generateInstrumentationInfo(p,
6022                            flags);
6023                    if (ii != null) {
6024                        finalList.add(ii);
6025                    }
6026                }
6027            }
6028        }
6029
6030        return finalList;
6031    }
6032
6033    private void createIdmapsForPackageLI(PackageParser.Package pkg) {
6034        ArrayMap<String, PackageParser.Package> overlays = mOverlays.get(pkg.packageName);
6035        if (overlays == null) {
6036            Slog.w(TAG, "Unable to create idmap for " + pkg.packageName + ": no overlay packages");
6037            return;
6038        }
6039        for (PackageParser.Package opkg : overlays.values()) {
6040            // Not much to do if idmap fails: we already logged the error
6041            // and we certainly don't want to abort installation of pkg simply
6042            // because an overlay didn't fit properly. For these reasons,
6043            // ignore the return value of createIdmapForPackagePairLI.
6044            createIdmapForPackagePairLI(pkg, opkg);
6045        }
6046    }
6047
6048    private boolean createIdmapForPackagePairLI(PackageParser.Package pkg,
6049            PackageParser.Package opkg) {
6050        if (!opkg.mTrustedOverlay) {
6051            Slog.w(TAG, "Skipping target and overlay pair " + pkg.baseCodePath + " and " +
6052                    opkg.baseCodePath + ": overlay not trusted");
6053            return false;
6054        }
6055        ArrayMap<String, PackageParser.Package> overlaySet = mOverlays.get(pkg.packageName);
6056        if (overlaySet == null) {
6057            Slog.e(TAG, "was about to create idmap for " + pkg.baseCodePath + " and " +
6058                    opkg.baseCodePath + " but target package has no known overlays");
6059            return false;
6060        }
6061        final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
6062        // TODO: generate idmap for split APKs
6063        if (mInstaller.idmap(pkg.baseCodePath, opkg.baseCodePath, sharedGid) != 0) {
6064            Slog.e(TAG, "Failed to generate idmap for " + pkg.baseCodePath + " and "
6065                    + opkg.baseCodePath);
6066            return false;
6067        }
6068        PackageParser.Package[] overlayArray =
6069            overlaySet.values().toArray(new PackageParser.Package[0]);
6070        Comparator<PackageParser.Package> cmp = new Comparator<PackageParser.Package>() {
6071            public int compare(PackageParser.Package p1, PackageParser.Package p2) {
6072                return p1.mOverlayPriority - p2.mOverlayPriority;
6073            }
6074        };
6075        Arrays.sort(overlayArray, cmp);
6076
6077        pkg.applicationInfo.resourceDirs = new String[overlayArray.length];
6078        int i = 0;
6079        for (PackageParser.Package p : overlayArray) {
6080            pkg.applicationInfo.resourceDirs[i++] = p.baseCodePath;
6081        }
6082        return true;
6083    }
6084
6085    private void scanDirTracedLI(File dir, int parseFlags, int scanFlags, long currentTime) {
6086        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanDir");
6087        try {
6088            scanDirLI(dir, parseFlags, scanFlags, currentTime);
6089        } finally {
6090            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
6091        }
6092    }
6093
6094    private void scanDirLI(File dir, int parseFlags, int scanFlags, long currentTime) {
6095        final File[] files = dir.listFiles();
6096        if (ArrayUtils.isEmpty(files)) {
6097            Log.d(TAG, "No files in app dir " + dir);
6098            return;
6099        }
6100
6101        if (DEBUG_PACKAGE_SCANNING) {
6102            Log.d(TAG, "Scanning app dir " + dir + " scanFlags=" + scanFlags
6103                    + " flags=0x" + Integer.toHexString(parseFlags));
6104        }
6105
6106        for (File file : files) {
6107            final boolean isPackage = (isApkFile(file) || file.isDirectory())
6108                    && !PackageInstallerService.isStageName(file.getName());
6109            if (!isPackage) {
6110                // Ignore entries which are not packages
6111                continue;
6112            }
6113            try {
6114                scanPackageTracedLI(file, parseFlags | PackageParser.PARSE_MUST_BE_APK,
6115                        scanFlags, currentTime, null);
6116            } catch (PackageManagerException e) {
6117                Slog.w(TAG, "Failed to parse " + file + ": " + e.getMessage());
6118
6119                // Delete invalid userdata apps
6120                if ((parseFlags & PackageParser.PARSE_IS_SYSTEM) == 0 &&
6121                        e.error == PackageManager.INSTALL_FAILED_INVALID_APK) {
6122                    logCriticalInfo(Log.WARN, "Deleting invalid package at " + file);
6123                    if (file.isDirectory()) {
6124                        mInstaller.rmPackageDir(file.getAbsolutePath());
6125                    } else {
6126                        file.delete();
6127                    }
6128                }
6129            }
6130        }
6131    }
6132
6133    private static File getSettingsProblemFile() {
6134        File dataDir = Environment.getDataDirectory();
6135        File systemDir = new File(dataDir, "system");
6136        File fname = new File(systemDir, "uiderrors.txt");
6137        return fname;
6138    }
6139
6140    static void reportSettingsProblem(int priority, String msg) {
6141        logCriticalInfo(priority, msg);
6142    }
6143
6144    static void logCriticalInfo(int priority, String msg) {
6145        Slog.println(priority, TAG, msg);
6146        EventLogTags.writePmCriticalInfo(msg);
6147        try {
6148            File fname = getSettingsProblemFile();
6149            FileOutputStream out = new FileOutputStream(fname, true);
6150            PrintWriter pw = new FastPrintWriter(out);
6151            SimpleDateFormat formatter = new SimpleDateFormat();
6152            String dateString = formatter.format(new Date(System.currentTimeMillis()));
6153            pw.println(dateString + ": " + msg);
6154            pw.close();
6155            FileUtils.setPermissions(
6156                    fname.toString(),
6157                    FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IROTH,
6158                    -1, -1);
6159        } catch (java.io.IOException e) {
6160        }
6161    }
6162
6163    private void collectCertificatesLI(PackageParser pp, PackageSetting ps,
6164            PackageParser.Package pkg, File srcFile, int parseFlags)
6165            throws PackageManagerException {
6166        if (ps != null
6167                && ps.codePath.equals(srcFile)
6168                && ps.timeStamp == srcFile.lastModified()
6169                && !isCompatSignatureUpdateNeeded(pkg)
6170                && !isRecoverSignatureUpdateNeeded(pkg)) {
6171            long mSigningKeySetId = ps.keySetData.getProperSigningKeySet();
6172            KeySetManagerService ksms = mSettings.mKeySetManagerService;
6173            ArraySet<PublicKey> signingKs;
6174            synchronized (mPackages) {
6175                signingKs = ksms.getPublicKeysFromKeySetLPr(mSigningKeySetId);
6176            }
6177            if (ps.signatures.mSignatures != null
6178                    && ps.signatures.mSignatures.length != 0
6179                    && signingKs != null) {
6180                // Optimization: reuse the existing cached certificates
6181                // if the package appears to be unchanged.
6182                pkg.mSignatures = ps.signatures.mSignatures;
6183                pkg.mSigningKeys = signingKs;
6184                return;
6185            }
6186
6187            Slog.w(TAG, "PackageSetting for " + ps.name
6188                    + " is missing signatures.  Collecting certs again to recover them.");
6189        } else {
6190            Log.i(TAG, srcFile.toString() + " changed; collecting certs");
6191        }
6192
6193        try {
6194            pp.collectCertificates(pkg, parseFlags);
6195        } catch (PackageParserException e) {
6196            throw PackageManagerException.from(e);
6197        }
6198    }
6199
6200    /**
6201     *  Traces a package scan.
6202     *  @see #scanPackageLI(File, int, int, long, UserHandle)
6203     */
6204    private PackageParser.Package scanPackageTracedLI(File scanFile, int parseFlags, int scanFlags,
6205            long currentTime, UserHandle user) throws PackageManagerException {
6206        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage");
6207        try {
6208            return scanPackageLI(scanFile, parseFlags, scanFlags, currentTime, user);
6209        } finally {
6210            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
6211        }
6212    }
6213
6214    /**
6215     *  Scans a package and returns the newly parsed package.
6216     *  Returns {@code null} in case of errors and the error code is stored in mLastScanError
6217     */
6218    private PackageParser.Package scanPackageLI(File scanFile, int parseFlags, int scanFlags,
6219            long currentTime, UserHandle user) throws PackageManagerException {
6220        if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanFile);
6221        parseFlags |= mDefParseFlags;
6222        PackageParser pp = new PackageParser();
6223        pp.setSeparateProcesses(mSeparateProcesses);
6224        pp.setOnlyCoreApps(mOnlyCore);
6225        pp.setDisplayMetrics(mMetrics);
6226
6227        if ((scanFlags & SCAN_TRUSTED_OVERLAY) != 0) {
6228            parseFlags |= PackageParser.PARSE_TRUSTED_OVERLAY;
6229        }
6230
6231        final PackageParser.Package pkg;
6232        try {
6233            pkg = pp.parsePackage(scanFile, parseFlags);
6234        } catch (PackageParserException e) {
6235            throw PackageManagerException.from(e);
6236        }
6237
6238        PackageSetting ps = null;
6239        PackageSetting updatedPkg;
6240        // reader
6241        synchronized (mPackages) {
6242            // Look to see if we already know about this package.
6243            String oldName = mSettings.mRenamedPackages.get(pkg.packageName);
6244            if (pkg.mOriginalPackages != null && pkg.mOriginalPackages.contains(oldName)) {
6245                // This package has been renamed to its original name.  Let's
6246                // use that.
6247                ps = mSettings.peekPackageLPr(oldName);
6248            }
6249            // If there was no original package, see one for the real package name.
6250            if (ps == null) {
6251                ps = mSettings.peekPackageLPr(pkg.packageName);
6252            }
6253            // Check to see if this package could be hiding/updating a system
6254            // package.  Must look for it either under the original or real
6255            // package name depending on our state.
6256            updatedPkg = mSettings.getDisabledSystemPkgLPr(ps != null ? ps.name : pkg.packageName);
6257            if (DEBUG_INSTALL && updatedPkg != null) Slog.d(TAG, "updatedPkg = " + updatedPkg);
6258        }
6259        boolean updatedPkgBetter = false;
6260        // First check if this is a system package that may involve an update
6261        if (updatedPkg != null && (parseFlags & PackageParser.PARSE_IS_SYSTEM) != 0) {
6262            // If new package is not located in "/system/priv-app" (e.g. due to an OTA),
6263            // it needs to drop FLAG_PRIVILEGED.
6264            if (locationIsPrivileged(scanFile)) {
6265                updatedPkg.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
6266            } else {
6267                updatedPkg.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
6268            }
6269
6270            if (ps != null && !ps.codePath.equals(scanFile)) {
6271                // The path has changed from what was last scanned...  check the
6272                // version of the new path against what we have stored to determine
6273                // what to do.
6274                if (DEBUG_INSTALL) Slog.d(TAG, "Path changing from " + ps.codePath);
6275                if (pkg.mVersionCode <= ps.versionCode) {
6276                    // The system package has been updated and the code path does not match
6277                    // Ignore entry. Skip it.
6278                    if (DEBUG_INSTALL) Slog.i(TAG, "Package " + ps.name + " at " + scanFile
6279                            + " ignored: updated version " + ps.versionCode
6280                            + " better than this " + pkg.mVersionCode);
6281                    if (!updatedPkg.codePath.equals(scanFile)) {
6282                        Slog.w(PackageManagerService.TAG, "Code path for hidden system pkg "
6283                                + ps.name + " changing from " + updatedPkg.codePathString
6284                                + " to " + scanFile);
6285                        updatedPkg.codePath = scanFile;
6286                        updatedPkg.codePathString = scanFile.toString();
6287                        updatedPkg.resourcePath = scanFile;
6288                        updatedPkg.resourcePathString = scanFile.toString();
6289                    }
6290                    updatedPkg.pkg = pkg;
6291                    throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
6292                            "Package " + ps.name + " at " + scanFile
6293                                    + " ignored: updated version " + ps.versionCode
6294                                    + " better than this " + pkg.mVersionCode);
6295                } else {
6296                    // The current app on the system partition is better than
6297                    // what we have updated to on the data partition; switch
6298                    // back to the system partition version.
6299                    // At this point, its safely assumed that package installation for
6300                    // apps in system partition will go through. If not there won't be a working
6301                    // version of the app
6302                    // writer
6303                    synchronized (mPackages) {
6304                        // Just remove the loaded entries from package lists.
6305                        mPackages.remove(ps.name);
6306                    }
6307
6308                    logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile
6309                            + " reverting from " + ps.codePathString
6310                            + ": new version " + pkg.mVersionCode
6311                            + " better than installed " + ps.versionCode);
6312
6313                    InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
6314                            ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
6315                    synchronized (mInstallLock) {
6316                        args.cleanUpResourcesLI();
6317                    }
6318                    synchronized (mPackages) {
6319                        mSettings.enableSystemPackageLPw(ps.name);
6320                    }
6321                    updatedPkgBetter = true;
6322                }
6323            }
6324        }
6325
6326        if (updatedPkg != null) {
6327            // An updated system app will not have the PARSE_IS_SYSTEM flag set
6328            // initially
6329            parseFlags |= PackageParser.PARSE_IS_SYSTEM;
6330
6331            // An updated privileged app will not have the PARSE_IS_PRIVILEGED
6332            // flag set initially
6333            if ((updatedPkg.pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0) {
6334                parseFlags |= PackageParser.PARSE_IS_PRIVILEGED;
6335            }
6336        }
6337
6338        // Verify certificates against what was last scanned
6339        collectCertificatesLI(pp, ps, pkg, scanFile, parseFlags);
6340
6341        /*
6342         * A new system app appeared, but we already had a non-system one of the
6343         * same name installed earlier.
6344         */
6345        boolean shouldHideSystemApp = false;
6346        if (updatedPkg == null && ps != null
6347                && (parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0 && !isSystemApp(ps)) {
6348            /*
6349             * Check to make sure the signatures match first. If they don't,
6350             * wipe the installed application and its data.
6351             */
6352            if (compareSignatures(ps.signatures.mSignatures, pkg.mSignatures)
6353                    != PackageManager.SIGNATURE_MATCH) {
6354                logCriticalInfo(Log.WARN, "Package " + ps.name + " appeared on system, but"
6355                        + " signatures don't match existing userdata copy; removing");
6356                deletePackageLI(pkg.packageName, null, true, null, null, 0, null, false);
6357                ps = null;
6358            } else {
6359                /*
6360                 * If the newly-added system app is an older version than the
6361                 * already installed version, hide it. It will be scanned later
6362                 * and re-added like an update.
6363                 */
6364                if (pkg.mVersionCode <= ps.versionCode) {
6365                    shouldHideSystemApp = true;
6366                    logCriticalInfo(Log.INFO, "Package " + ps.name + " appeared at " + scanFile
6367                            + " but new version " + pkg.mVersionCode + " better than installed "
6368                            + ps.versionCode + "; hiding system");
6369                } else {
6370                    /*
6371                     * The newly found system app is a newer version that the
6372                     * one previously installed. Simply remove the
6373                     * already-installed application and replace it with our own
6374                     * while keeping the application data.
6375                     */
6376                    logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile
6377                            + " reverting from " + ps.codePathString + ": new version "
6378                            + pkg.mVersionCode + " better than installed " + ps.versionCode);
6379                    InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
6380                            ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
6381                    synchronized (mInstallLock) {
6382                        args.cleanUpResourcesLI();
6383                    }
6384                }
6385            }
6386        }
6387
6388        // The apk is forward locked (not public) if its code and resources
6389        // are kept in different files. (except for app in either system or
6390        // vendor path).
6391        // TODO grab this value from PackageSettings
6392        if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
6393            if (ps != null && !ps.codePath.equals(ps.resourcePath)) {
6394                parseFlags |= PackageParser.PARSE_FORWARD_LOCK;
6395            }
6396        }
6397
6398        // TODO: extend to support forward-locked splits
6399        String resourcePath = null;
6400        String baseResourcePath = null;
6401        if ((parseFlags & PackageParser.PARSE_FORWARD_LOCK) != 0 && !updatedPkgBetter) {
6402            if (ps != null && ps.resourcePathString != null) {
6403                resourcePath = ps.resourcePathString;
6404                baseResourcePath = ps.resourcePathString;
6405            } else {
6406                // Should not happen at all. Just log an error.
6407                Slog.e(TAG, "Resource path not set for package " + pkg.packageName);
6408            }
6409        } else {
6410            resourcePath = pkg.codePath;
6411            baseResourcePath = pkg.baseCodePath;
6412        }
6413
6414        // Set application objects path explicitly.
6415        pkg.applicationInfo.volumeUuid = pkg.volumeUuid;
6416        pkg.applicationInfo.setCodePath(pkg.codePath);
6417        pkg.applicationInfo.setBaseCodePath(pkg.baseCodePath);
6418        pkg.applicationInfo.setSplitCodePaths(pkg.splitCodePaths);
6419        pkg.applicationInfo.setResourcePath(resourcePath);
6420        pkg.applicationInfo.setBaseResourcePath(baseResourcePath);
6421        pkg.applicationInfo.setSplitResourcePaths(pkg.splitCodePaths);
6422
6423        // Note that we invoke the following method only if we are about to unpack an application
6424        PackageParser.Package scannedPkg = scanPackageLI(pkg, parseFlags, scanFlags
6425                | SCAN_UPDATE_SIGNATURE, currentTime, user);
6426
6427        /*
6428         * If the system app should be overridden by a previously installed
6429         * data, hide the system app now and let the /data/app scan pick it up
6430         * again.
6431         */
6432        if (shouldHideSystemApp) {
6433            synchronized (mPackages) {
6434                mSettings.disableSystemPackageLPw(pkg.packageName);
6435            }
6436        }
6437
6438        return scannedPkg;
6439    }
6440
6441    private static String fixProcessName(String defProcessName,
6442            String processName, int uid) {
6443        if (processName == null) {
6444            return defProcessName;
6445        }
6446        return processName;
6447    }
6448
6449    private void verifySignaturesLP(PackageSetting pkgSetting, PackageParser.Package pkg)
6450            throws PackageManagerException {
6451        if (pkgSetting.signatures.mSignatures != null) {
6452            // Already existing package. Make sure signatures match
6453            boolean match = compareSignatures(pkgSetting.signatures.mSignatures, pkg.mSignatures)
6454                    == PackageManager.SIGNATURE_MATCH;
6455            if (!match) {
6456                match = compareSignaturesCompat(pkgSetting.signatures, pkg)
6457                        == PackageManager.SIGNATURE_MATCH;
6458            }
6459            if (!match) {
6460                match = compareSignaturesRecover(pkgSetting.signatures, pkg)
6461                        == PackageManager.SIGNATURE_MATCH;
6462            }
6463            if (!match) {
6464                throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
6465                        + pkg.packageName + " signatures do not match the "
6466                        + "previously installed version; ignoring!");
6467            }
6468        }
6469
6470        // Check for shared user signatures
6471        if (pkgSetting.sharedUser != null && pkgSetting.sharedUser.signatures.mSignatures != null) {
6472            // Already existing package. Make sure signatures match
6473            boolean match = compareSignatures(pkgSetting.sharedUser.signatures.mSignatures,
6474                    pkg.mSignatures) == PackageManager.SIGNATURE_MATCH;
6475            if (!match) {
6476                match = compareSignaturesCompat(pkgSetting.sharedUser.signatures, pkg)
6477                        == PackageManager.SIGNATURE_MATCH;
6478            }
6479            if (!match) {
6480                match = compareSignaturesRecover(pkgSetting.sharedUser.signatures, pkg)
6481                        == PackageManager.SIGNATURE_MATCH;
6482            }
6483            if (!match) {
6484                throw new PackageManagerException(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
6485                        "Package " + pkg.packageName
6486                        + " has no signatures that match those in shared user "
6487                        + pkgSetting.sharedUser.name + "; ignoring!");
6488            }
6489        }
6490    }
6491
6492    /**
6493     * Enforces that only the system UID or root's UID can call a method exposed
6494     * via Binder.
6495     *
6496     * @param message used as message if SecurityException is thrown
6497     * @throws SecurityException if the caller is not system or root
6498     */
6499    private static final void enforceSystemOrRoot(String message) {
6500        final int uid = Binder.getCallingUid();
6501        if (uid != Process.SYSTEM_UID && uid != 0) {
6502            throw new SecurityException(message);
6503        }
6504    }
6505
6506    @Override
6507    public void performFstrimIfNeeded() {
6508        enforceSystemOrRoot("Only the system can request fstrim");
6509
6510        // Before everything else, see whether we need to fstrim.
6511        try {
6512            IMountService ms = PackageHelper.getMountService();
6513            if (ms != null) {
6514                final boolean isUpgrade = isUpgrade();
6515                boolean doTrim = isUpgrade;
6516                if (doTrim) {
6517                    Slog.w(TAG, "Running disk maintenance immediately due to system update");
6518                } else {
6519                    final long interval = android.provider.Settings.Global.getLong(
6520                            mContext.getContentResolver(),
6521                            android.provider.Settings.Global.FSTRIM_MANDATORY_INTERVAL,
6522                            DEFAULT_MANDATORY_FSTRIM_INTERVAL);
6523                    if (interval > 0) {
6524                        final long timeSinceLast = System.currentTimeMillis() - ms.lastMaintenance();
6525                        if (timeSinceLast > interval) {
6526                            doTrim = true;
6527                            Slog.w(TAG, "No disk maintenance in " + timeSinceLast
6528                                    + "; running immediately");
6529                        }
6530                    }
6531                }
6532                if (doTrim) {
6533                    if (!isFirstBoot()) {
6534                        try {
6535                            ActivityManagerNative.getDefault().showBootMessage(
6536                                    mContext.getResources().getString(
6537                                            R.string.android_upgrading_fstrim), true);
6538                        } catch (RemoteException e) {
6539                        }
6540                    }
6541                    ms.runMaintenance();
6542                }
6543            } else {
6544                Slog.e(TAG, "Mount service unavailable!");
6545            }
6546        } catch (RemoteException e) {
6547            // Can't happen; MountService is local
6548        }
6549    }
6550
6551    private ArraySet<String> getPackageNamesForIntent(Intent intent, int userId) {
6552        List<ResolveInfo> ris = null;
6553        try {
6554            ris = AppGlobals.getPackageManager().queryIntentReceivers(
6555                    intent, null, 0, userId);
6556        } catch (RemoteException e) {
6557        }
6558        ArraySet<String> pkgNames = new ArraySet<String>();
6559        if (ris != null) {
6560            for (ResolveInfo ri : ris) {
6561                pkgNames.add(ri.activityInfo.packageName);
6562            }
6563        }
6564        return pkgNames;
6565    }
6566
6567    @Override
6568    public void notifyPackageUse(String packageName) {
6569        synchronized (mPackages) {
6570            PackageParser.Package p = mPackages.get(packageName);
6571            if (p == null) {
6572                return;
6573            }
6574            p.mLastPackageUsageTimeInMills = System.currentTimeMillis();
6575        }
6576    }
6577
6578    @Override
6579    public boolean performDexOptIfNeeded(String packageName, String instructionSet) {
6580        return performDexOptTraced(packageName, instructionSet);
6581    }
6582
6583    public boolean performDexOpt(String packageName, String instructionSet) {
6584        return performDexOptTraced(packageName, instructionSet);
6585    }
6586
6587    private boolean performDexOptTraced(String packageName, String instructionSet) {
6588        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
6589        try {
6590            return performDexOptInternal(packageName, instructionSet);
6591        } finally {
6592            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
6593        }
6594    }
6595
6596    private boolean performDexOptInternal(String packageName, String instructionSet) {
6597        PackageParser.Package p;
6598        final String targetInstructionSet;
6599        synchronized (mPackages) {
6600            p = mPackages.get(packageName);
6601            if (p == null) {
6602                return false;
6603            }
6604            mPackageUsage.write(false);
6605
6606            targetInstructionSet = instructionSet != null ? instructionSet :
6607                    getPrimaryInstructionSet(p.applicationInfo);
6608            if (p.mDexOptPerformed.contains(targetInstructionSet)) {
6609                return false;
6610            }
6611        }
6612        long callingId = Binder.clearCallingIdentity();
6613        try {
6614            synchronized (mInstallLock) {
6615                final String[] instructionSets = new String[] { targetInstructionSet };
6616                int result = mPackageDexOptimizer.performDexOpt(p, instructionSets,
6617                        true /* inclDependencies */);
6618                return result == PackageDexOptimizer.DEX_OPT_PERFORMED;
6619            }
6620        } finally {
6621            Binder.restoreCallingIdentity(callingId);
6622        }
6623    }
6624
6625    public ArraySet<String> getPackagesThatNeedDexOpt() {
6626        ArraySet<String> pkgs = null;
6627        synchronized (mPackages) {
6628            for (PackageParser.Package p : mPackages.values()) {
6629                if (DEBUG_DEXOPT) {
6630                    Log.i(TAG, p.packageName + " mDexOptPerformed=" + p.mDexOptPerformed.toArray());
6631                }
6632                if (!p.mDexOptPerformed.isEmpty()) {
6633                    continue;
6634                }
6635                if (pkgs == null) {
6636                    pkgs = new ArraySet<String>();
6637                }
6638                pkgs.add(p.packageName);
6639            }
6640        }
6641        return pkgs;
6642    }
6643
6644    public void shutdown() {
6645        mPackageUsage.write(true);
6646    }
6647
6648    @Override
6649    public void forceDexOpt(String packageName) {
6650        enforceSystemOrRoot("forceDexOpt");
6651
6652        PackageParser.Package pkg;
6653        synchronized (mPackages) {
6654            pkg = mPackages.get(packageName);
6655            if (pkg == null) {
6656                throw new IllegalArgumentException("Unknown package: " + packageName);
6657            }
6658        }
6659
6660        synchronized (mInstallLock) {
6661            final String[] instructionSets = new String[] {
6662                    getPrimaryInstructionSet(pkg.applicationInfo) };
6663
6664            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
6665
6666            final int res = mPackageDexOptimizer.performDexOpt(pkg, instructionSets,
6667                    true /* inclDependencies */);
6668
6669            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
6670            if (res != PackageDexOptimizer.DEX_OPT_PERFORMED) {
6671                throw new IllegalStateException("Failed to dexopt: " + res);
6672            }
6673        }
6674    }
6675
6676    private boolean verifyPackageUpdateLPr(PackageSetting oldPkg, PackageParser.Package newPkg) {
6677        if ((oldPkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) {
6678            Slog.w(TAG, "Unable to update from " + oldPkg.name
6679                    + " to " + newPkg.packageName
6680                    + ": old package not in system partition");
6681            return false;
6682        } else if (mPackages.get(oldPkg.name) != null) {
6683            Slog.w(TAG, "Unable to update from " + oldPkg.name
6684                    + " to " + newPkg.packageName
6685                    + ": old package still exists");
6686            return false;
6687        }
6688        return true;
6689    }
6690
6691    private void createDataDirsLI(String volumeUuid, String packageName, int uid, String seinfo)
6692            throws PackageManagerException {
6693        int res = mInstaller.install(volumeUuid, packageName, uid, uid, seinfo);
6694        if (res != 0) {
6695            throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE,
6696                    "Failed to install " + packageName + ": " + res);
6697        }
6698
6699        final int[] users = sUserManager.getUserIds();
6700        for (int user : users) {
6701            if (user != 0) {
6702                res = mInstaller.createUserData(volumeUuid, packageName,
6703                        UserHandle.getUid(user, uid), user, seinfo);
6704                if (res != 0) {
6705                    throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE,
6706                            "Failed to createUserData " + packageName + ": " + res);
6707                }
6708            }
6709        }
6710    }
6711
6712    private int removeDataDirsLI(String volumeUuid, String packageName) {
6713        int[] users = sUserManager.getUserIds();
6714        int res = 0;
6715        for (int user : users) {
6716            int resInner = mInstaller.remove(volumeUuid, packageName, user);
6717            if (resInner < 0) {
6718                res = resInner;
6719            }
6720        }
6721
6722        return res;
6723    }
6724
6725    private int deleteCodeCacheDirsLI(String volumeUuid, String packageName) {
6726        int[] users = sUserManager.getUserIds();
6727        int res = 0;
6728        for (int user : users) {
6729            int resInner = mInstaller.deleteCodeCacheFiles(volumeUuid, packageName, user);
6730            if (resInner < 0) {
6731                res = resInner;
6732            }
6733        }
6734        return res;
6735    }
6736
6737    private void addSharedLibraryLPw(ArraySet<String> usesLibraryFiles, SharedLibraryEntry file,
6738            PackageParser.Package changingLib) {
6739        if (file.path != null) {
6740            usesLibraryFiles.add(file.path);
6741            return;
6742        }
6743        PackageParser.Package p = mPackages.get(file.apk);
6744        if (changingLib != null && changingLib.packageName.equals(file.apk)) {
6745            // If we are doing this while in the middle of updating a library apk,
6746            // then we need to make sure to use that new apk for determining the
6747            // dependencies here.  (We haven't yet finished committing the new apk
6748            // to the package manager state.)
6749            if (p == null || p.packageName.equals(changingLib.packageName)) {
6750                p = changingLib;
6751            }
6752        }
6753        if (p != null) {
6754            usesLibraryFiles.addAll(p.getAllCodePaths());
6755        }
6756    }
6757
6758    private void updateSharedLibrariesLPw(PackageParser.Package pkg,
6759            PackageParser.Package changingLib) throws PackageManagerException {
6760        if (pkg.usesLibraries != null || pkg.usesOptionalLibraries != null) {
6761            final ArraySet<String> usesLibraryFiles = new ArraySet<>();
6762            int N = pkg.usesLibraries != null ? pkg.usesLibraries.size() : 0;
6763            for (int i=0; i<N; i++) {
6764                final SharedLibraryEntry file = mSharedLibraries.get(pkg.usesLibraries.get(i));
6765                if (file == null) {
6766                    throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
6767                            "Package " + pkg.packageName + " requires unavailable shared library "
6768                            + pkg.usesLibraries.get(i) + "; failing!");
6769                }
6770                addSharedLibraryLPw(usesLibraryFiles, file, changingLib);
6771            }
6772            N = pkg.usesOptionalLibraries != null ? pkg.usesOptionalLibraries.size() : 0;
6773            for (int i=0; i<N; i++) {
6774                final SharedLibraryEntry file = mSharedLibraries.get(pkg.usesOptionalLibraries.get(i));
6775                if (file == null) {
6776                    Slog.w(TAG, "Package " + pkg.packageName
6777                            + " desires unavailable shared library "
6778                            + pkg.usesOptionalLibraries.get(i) + "; ignoring!");
6779                } else {
6780                    addSharedLibraryLPw(usesLibraryFiles, file, changingLib);
6781                }
6782            }
6783            N = usesLibraryFiles.size();
6784            if (N > 0) {
6785                pkg.usesLibraryFiles = usesLibraryFiles.toArray(new String[N]);
6786            } else {
6787                pkg.usesLibraryFiles = null;
6788            }
6789        }
6790    }
6791
6792    private static boolean hasString(List<String> list, List<String> which) {
6793        if (list == null) {
6794            return false;
6795        }
6796        for (int i=list.size()-1; i>=0; i--) {
6797            for (int j=which.size()-1; j>=0; j--) {
6798                if (which.get(j).equals(list.get(i))) {
6799                    return true;
6800                }
6801            }
6802        }
6803        return false;
6804    }
6805
6806    private void updateAllSharedLibrariesLPw() {
6807        for (PackageParser.Package pkg : mPackages.values()) {
6808            try {
6809                updateSharedLibrariesLPw(pkg, null);
6810            } catch (PackageManagerException e) {
6811                Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
6812            }
6813        }
6814    }
6815
6816    private ArrayList<PackageParser.Package> updateAllSharedLibrariesLPw(
6817            PackageParser.Package changingPkg) {
6818        ArrayList<PackageParser.Package> res = null;
6819        for (PackageParser.Package pkg : mPackages.values()) {
6820            if (hasString(pkg.usesLibraries, changingPkg.libraryNames)
6821                    || hasString(pkg.usesOptionalLibraries, changingPkg.libraryNames)) {
6822                if (res == null) {
6823                    res = new ArrayList<PackageParser.Package>();
6824                }
6825                res.add(pkg);
6826                try {
6827                    updateSharedLibrariesLPw(pkg, changingPkg);
6828                } catch (PackageManagerException e) {
6829                    Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
6830                }
6831            }
6832        }
6833        return res;
6834    }
6835
6836    /**
6837     * Derive the value of the {@code cpuAbiOverride} based on the provided
6838     * value and an optional stored value from the package settings.
6839     */
6840    private static String deriveAbiOverride(String abiOverride, PackageSetting settings) {
6841        String cpuAbiOverride = null;
6842
6843        if (NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(abiOverride)) {
6844            cpuAbiOverride = null;
6845        } else if (abiOverride != null) {
6846            cpuAbiOverride = abiOverride;
6847        } else if (settings != null) {
6848            cpuAbiOverride = settings.cpuAbiOverrideString;
6849        }
6850
6851        return cpuAbiOverride;
6852    }
6853
6854    private PackageParser.Package scanPackageTracedLI(PackageParser.Package pkg, int parseFlags,
6855            int scanFlags, long currentTime, UserHandle user) throws PackageManagerException {
6856        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage");
6857        try {
6858            return scanPackageLI(pkg, parseFlags, scanFlags, currentTime, user);
6859        } finally {
6860            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
6861        }
6862    }
6863
6864    private PackageParser.Package scanPackageLI(PackageParser.Package pkg, int parseFlags,
6865            int scanFlags, long currentTime, UserHandle user) throws PackageManagerException {
6866        boolean success = false;
6867        try {
6868            final PackageParser.Package res = scanPackageDirtyLI(pkg, parseFlags, scanFlags,
6869                    currentTime, user);
6870            success = true;
6871            return res;
6872        } finally {
6873            if (!success && (scanFlags & SCAN_DELETE_DATA_ON_FAILURES) != 0) {
6874                removeDataDirsLI(pkg.volumeUuid, pkg.packageName);
6875            }
6876        }
6877    }
6878
6879    private PackageParser.Package scanPackageDirtyLI(PackageParser.Package pkg, int parseFlags,
6880            int scanFlags, long currentTime, UserHandle user) throws PackageManagerException {
6881        final File scanFile = new File(pkg.codePath);
6882        if (pkg.applicationInfo.getCodePath() == null ||
6883                pkg.applicationInfo.getResourcePath() == null) {
6884            // Bail out. The resource and code paths haven't been set.
6885            throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
6886                    "Code and resource paths haven't been set correctly");
6887        }
6888
6889        if ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) {
6890            pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
6891        } else {
6892            // Only allow system apps to be flagged as core apps.
6893            pkg.coreApp = false;
6894        }
6895
6896        if ((parseFlags&PackageParser.PARSE_IS_PRIVILEGED) != 0) {
6897            pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
6898        }
6899
6900        if (mCustomResolverComponentName != null &&
6901                mCustomResolverComponentName.getPackageName().equals(pkg.packageName)) {
6902            setUpCustomResolverActivity(pkg);
6903        }
6904
6905        if (pkg.packageName.equals("android")) {
6906            synchronized (mPackages) {
6907                if (mAndroidApplication != null) {
6908                    Slog.w(TAG, "*************************************************");
6909                    Slog.w(TAG, "Core android package being redefined.  Skipping.");
6910                    Slog.w(TAG, " file=" + scanFile);
6911                    Slog.w(TAG, "*************************************************");
6912                    throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
6913                            "Core android package being redefined.  Skipping.");
6914                }
6915
6916                // Set up information for our fall-back user intent resolution activity.
6917                mPlatformPackage = pkg;
6918                pkg.mVersionCode = mSdkVersion;
6919                mAndroidApplication = pkg.applicationInfo;
6920
6921                if (!mResolverReplaced) {
6922                    mResolveActivity.applicationInfo = mAndroidApplication;
6923                    mResolveActivity.name = ResolverActivity.class.getName();
6924                    mResolveActivity.packageName = mAndroidApplication.packageName;
6925                    mResolveActivity.processName = "system:ui";
6926                    mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
6927                    mResolveActivity.documentLaunchMode = ActivityInfo.DOCUMENT_LAUNCH_NEVER;
6928                    mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS;
6929                    mResolveActivity.theme = R.style.Theme_Holo_Dialog_Alert;
6930                    mResolveActivity.exported = true;
6931                    mResolveActivity.enabled = true;
6932                    mResolveInfo.activityInfo = mResolveActivity;
6933                    mResolveInfo.priority = 0;
6934                    mResolveInfo.preferredOrder = 0;
6935                    mResolveInfo.match = 0;
6936                    mResolveComponentName = new ComponentName(
6937                            mAndroidApplication.packageName, mResolveActivity.name);
6938                }
6939            }
6940        }
6941
6942        if (DEBUG_PACKAGE_SCANNING) {
6943            if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
6944                Log.d(TAG, "Scanning package " + pkg.packageName);
6945        }
6946
6947        if (mPackages.containsKey(pkg.packageName)
6948                || mSharedLibraries.containsKey(pkg.packageName)) {
6949            throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
6950                    "Application package " + pkg.packageName
6951                    + " already installed.  Skipping duplicate.");
6952        }
6953
6954        // If we're only installing presumed-existing packages, require that the
6955        // scanned APK is both already known and at the path previously established
6956        // for it.  Previously unknown packages we pick up normally, but if we have an
6957        // a priori expectation about this package's install presence, enforce it.
6958        // With a singular exception for new system packages. When an OTA contains
6959        // a new system package, we allow the codepath to change from a system location
6960        // to the user-installed location. If we don't allow this change, any newer,
6961        // user-installed version of the application will be ignored.
6962        if ((scanFlags & SCAN_REQUIRE_KNOWN) != 0) {
6963            if (mExpectingBetter.containsKey(pkg.packageName)) {
6964                logCriticalInfo(Log.WARN,
6965                        "Relax SCAN_REQUIRE_KNOWN requirement for package " + pkg.packageName);
6966            } else {
6967                PackageSetting known = mSettings.peekPackageLPr(pkg.packageName);
6968                if (known != null) {
6969                    if (DEBUG_PACKAGE_SCANNING) {
6970                        Log.d(TAG, "Examining " + pkg.codePath
6971                                + " and requiring known paths " + known.codePathString
6972                                + " & " + known.resourcePathString);
6973                    }
6974                    if (!pkg.applicationInfo.getCodePath().equals(known.codePathString)
6975                            || !pkg.applicationInfo.getResourcePath().equals(known.resourcePathString)) {
6976                        throw new PackageManagerException(INSTALL_FAILED_PACKAGE_CHANGED,
6977                                "Application package " + pkg.packageName
6978                                + " found at " + pkg.applicationInfo.getCodePath()
6979                                + " but expected at " + known.codePathString + "; ignoring.");
6980                    }
6981                }
6982            }
6983        }
6984
6985        // Initialize package source and resource directories
6986        File destCodeFile = new File(pkg.applicationInfo.getCodePath());
6987        File destResourceFile = new File(pkg.applicationInfo.getResourcePath());
6988
6989        SharedUserSetting suid = null;
6990        PackageSetting pkgSetting = null;
6991
6992        if (!isSystemApp(pkg)) {
6993            // Only system apps can use these features.
6994            pkg.mOriginalPackages = null;
6995            pkg.mRealPackage = null;
6996            pkg.mAdoptPermissions = null;
6997        }
6998
6999        // writer
7000        synchronized (mPackages) {
7001            if (pkg.mSharedUserId != null) {
7002                suid = mSettings.getSharedUserLPw(pkg.mSharedUserId, 0, 0, true);
7003                if (suid == null) {
7004                    throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE,
7005                            "Creating application package " + pkg.packageName
7006                            + " for shared user failed");
7007                }
7008                if (DEBUG_PACKAGE_SCANNING) {
7009                    if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
7010                        Log.d(TAG, "Shared UserID " + pkg.mSharedUserId + " (uid=" + suid.userId
7011                                + "): packages=" + suid.packages);
7012                }
7013            }
7014
7015            // Check if we are renaming from an original package name.
7016            PackageSetting origPackage = null;
7017            String realName = null;
7018            if (pkg.mOriginalPackages != null) {
7019                // This package may need to be renamed to a previously
7020                // installed name.  Let's check on that...
7021                final String renamed = mSettings.mRenamedPackages.get(pkg.mRealPackage);
7022                if (pkg.mOriginalPackages.contains(renamed)) {
7023                    // This package had originally been installed as the
7024                    // original name, and we have already taken care of
7025                    // transitioning to the new one.  Just update the new
7026                    // one to continue using the old name.
7027                    realName = pkg.mRealPackage;
7028                    if (!pkg.packageName.equals(renamed)) {
7029                        // Callers into this function may have already taken
7030                        // care of renaming the package; only do it here if
7031                        // it is not already done.
7032                        pkg.setPackageName(renamed);
7033                    }
7034
7035                } else {
7036                    for (int i=pkg.mOriginalPackages.size()-1; i>=0; i--) {
7037                        if ((origPackage = mSettings.peekPackageLPr(
7038                                pkg.mOriginalPackages.get(i))) != null) {
7039                            // We do have the package already installed under its
7040                            // original name...  should we use it?
7041                            if (!verifyPackageUpdateLPr(origPackage, pkg)) {
7042                                // New package is not compatible with original.
7043                                origPackage = null;
7044                                continue;
7045                            } else if (origPackage.sharedUser != null) {
7046                                // Make sure uid is compatible between packages.
7047                                if (!origPackage.sharedUser.name.equals(pkg.mSharedUserId)) {
7048                                    Slog.w(TAG, "Unable to migrate data from " + origPackage.name
7049                                            + " to " + pkg.packageName + ": old uid "
7050                                            + origPackage.sharedUser.name
7051                                            + " differs from " + pkg.mSharedUserId);
7052                                    origPackage = null;
7053                                    continue;
7054                                }
7055                            } else {
7056                                if (DEBUG_UPGRADE) Log.v(TAG, "Renaming new package "
7057                                        + pkg.packageName + " to old name " + origPackage.name);
7058                            }
7059                            break;
7060                        }
7061                    }
7062                }
7063            }
7064
7065            if (mTransferedPackages.contains(pkg.packageName)) {
7066                Slog.w(TAG, "Package " + pkg.packageName
7067                        + " was transferred to another, but its .apk remains");
7068            }
7069
7070            // Just create the setting, don't add it yet. For already existing packages
7071            // the PkgSetting exists already and doesn't have to be created.
7072            pkgSetting = mSettings.getPackageLPw(pkg, origPackage, realName, suid, destCodeFile,
7073                    destResourceFile, pkg.applicationInfo.nativeLibraryRootDir,
7074                    pkg.applicationInfo.primaryCpuAbi,
7075                    pkg.applicationInfo.secondaryCpuAbi,
7076                    pkg.applicationInfo.flags, pkg.applicationInfo.privateFlags,
7077                    user, false);
7078            if (pkgSetting == null) {
7079                throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE,
7080                        "Creating application package " + pkg.packageName + " failed");
7081            }
7082
7083            if (pkgSetting.origPackage != null) {
7084                // If we are first transitioning from an original package,
7085                // fix up the new package's name now.  We need to do this after
7086                // looking up the package under its new name, so getPackageLP
7087                // can take care of fiddling things correctly.
7088                pkg.setPackageName(origPackage.name);
7089
7090                // File a report about this.
7091                String msg = "New package " + pkgSetting.realName
7092                        + " renamed to replace old package " + pkgSetting.name;
7093                reportSettingsProblem(Log.WARN, msg);
7094
7095                // Make a note of it.
7096                mTransferedPackages.add(origPackage.name);
7097
7098                // No longer need to retain this.
7099                pkgSetting.origPackage = null;
7100            }
7101
7102            if (realName != null) {
7103                // Make a note of it.
7104                mTransferedPackages.add(pkg.packageName);
7105            }
7106
7107            if (mSettings.isDisabledSystemPackageLPr(pkg.packageName)) {
7108                pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
7109            }
7110
7111            if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
7112                // Check all shared libraries and map to their actual file path.
7113                // We only do this here for apps not on a system dir, because those
7114                // are the only ones that can fail an install due to this.  We
7115                // will take care of the system apps by updating all of their
7116                // library paths after the scan is done.
7117                updateSharedLibrariesLPw(pkg, null);
7118            }
7119
7120            if (mFoundPolicyFile) {
7121                SELinuxMMAC.assignSeinfoValue(pkg);
7122            }
7123
7124            pkg.applicationInfo.uid = pkgSetting.appId;
7125            pkg.mExtras = pkgSetting;
7126            if (shouldCheckUpgradeKeySetLP(pkgSetting, scanFlags)) {
7127                if (checkUpgradeKeySetLP(pkgSetting, pkg)) {
7128                    // We just determined the app is signed correctly, so bring
7129                    // over the latest parsed certs.
7130                    pkgSetting.signatures.mSignatures = pkg.mSignatures;
7131                } else {
7132                    if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
7133                        throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
7134                                "Package " + pkg.packageName + " upgrade keys do not match the "
7135                                + "previously installed version");
7136                    } else {
7137                        pkgSetting.signatures.mSignatures = pkg.mSignatures;
7138                        String msg = "System package " + pkg.packageName
7139                            + " signature changed; retaining data.";
7140                        reportSettingsProblem(Log.WARN, msg);
7141                    }
7142                }
7143            } else {
7144                try {
7145                    verifySignaturesLP(pkgSetting, pkg);
7146                    // We just determined the app is signed correctly, so bring
7147                    // over the latest parsed certs.
7148                    pkgSetting.signatures.mSignatures = pkg.mSignatures;
7149                } catch (PackageManagerException e) {
7150                    if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
7151                        throw e;
7152                    }
7153                    // The signature has changed, but this package is in the system
7154                    // image...  let's recover!
7155                    pkgSetting.signatures.mSignatures = pkg.mSignatures;
7156                    // However...  if this package is part of a shared user, but it
7157                    // doesn't match the signature of the shared user, let's fail.
7158                    // What this means is that you can't change the signatures
7159                    // associated with an overall shared user, which doesn't seem all
7160                    // that unreasonable.
7161                    if (pkgSetting.sharedUser != null) {
7162                        if (compareSignatures(pkgSetting.sharedUser.signatures.mSignatures,
7163                                              pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) {
7164                            throw new PackageManagerException(
7165                                    INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES,
7166                                            "Signature mismatch for shared user: "
7167                                            + pkgSetting.sharedUser);
7168                        }
7169                    }
7170                    // File a report about this.
7171                    String msg = "System package " + pkg.packageName
7172                        + " signature changed; retaining data.";
7173                    reportSettingsProblem(Log.WARN, msg);
7174                }
7175            }
7176            // Verify that this new package doesn't have any content providers
7177            // that conflict with existing packages.  Only do this if the
7178            // package isn't already installed, since we don't want to break
7179            // things that are installed.
7180            if ((scanFlags & SCAN_NEW_INSTALL) != 0) {
7181                final int N = pkg.providers.size();
7182                int i;
7183                for (i=0; i<N; i++) {
7184                    PackageParser.Provider p = pkg.providers.get(i);
7185                    if (p.info.authority != null) {
7186                        String names[] = p.info.authority.split(";");
7187                        for (int j = 0; j < names.length; j++) {
7188                            if (mProvidersByAuthority.containsKey(names[j])) {
7189                                PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
7190                                final String otherPackageName =
7191                                        ((other != null && other.getComponentName() != null) ?
7192                                                other.getComponentName().getPackageName() : "?");
7193                                throw new PackageManagerException(
7194                                        INSTALL_FAILED_CONFLICTING_PROVIDER,
7195                                                "Can't install because provider name " + names[j]
7196                                                + " (in package " + pkg.applicationInfo.packageName
7197                                                + ") is already used by " + otherPackageName);
7198                            }
7199                        }
7200                    }
7201                }
7202            }
7203
7204            if (pkg.mAdoptPermissions != null) {
7205                // This package wants to adopt ownership of permissions from
7206                // another package.
7207                for (int i = pkg.mAdoptPermissions.size() - 1; i >= 0; i--) {
7208                    final String origName = pkg.mAdoptPermissions.get(i);
7209                    final PackageSetting orig = mSettings.peekPackageLPr(origName);
7210                    if (orig != null) {
7211                        if (verifyPackageUpdateLPr(orig, pkg)) {
7212                            Slog.i(TAG, "Adopting permissions from " + origName + " to "
7213                                    + pkg.packageName);
7214                            mSettings.transferPermissionsLPw(origName, pkg.packageName);
7215                        }
7216                    }
7217                }
7218            }
7219        }
7220
7221        final String pkgName = pkg.packageName;
7222
7223        final long scanFileTime = scanFile.lastModified();
7224        final boolean forceDex = (scanFlags & SCAN_FORCE_DEX) != 0;
7225        pkg.applicationInfo.processName = fixProcessName(
7226                pkg.applicationInfo.packageName,
7227                pkg.applicationInfo.processName,
7228                pkg.applicationInfo.uid);
7229
7230        if (pkg != mPlatformPackage) {
7231            // This is a normal package, need to make its data directory.
7232            final File dataPath = Environment.getDataUserCredentialEncryptedPackageDirectory(
7233                    pkg.volumeUuid, UserHandle.USER_SYSTEM, pkg.packageName);
7234
7235            boolean uidError = false;
7236            if (dataPath.exists()) {
7237                int currentUid = 0;
7238                try {
7239                    StructStat stat = Os.stat(dataPath.getPath());
7240                    currentUid = stat.st_uid;
7241                } catch (ErrnoException e) {
7242                    Slog.e(TAG, "Couldn't stat path " + dataPath.getPath(), e);
7243                }
7244
7245                // If we have mismatched owners for the data path, we have a problem.
7246                if (currentUid != pkg.applicationInfo.uid) {
7247                    boolean recovered = false;
7248                    if (currentUid == 0) {
7249                        // The directory somehow became owned by root.  Wow.
7250                        // This is probably because the system was stopped while
7251                        // installd was in the middle of messing with its libs
7252                        // directory.  Ask installd to fix that.
7253                        int ret = mInstaller.fixUid(pkg.volumeUuid, pkgName,
7254                                pkg.applicationInfo.uid, pkg.applicationInfo.uid);
7255                        if (ret >= 0) {
7256                            recovered = true;
7257                            String msg = "Package " + pkg.packageName
7258                                    + " unexpectedly changed to uid 0; recovered to " +
7259                                    + pkg.applicationInfo.uid;
7260                            reportSettingsProblem(Log.WARN, msg);
7261                        }
7262                    }
7263                    if (!recovered && ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0
7264                            || (scanFlags&SCAN_BOOTING) != 0)) {
7265                        // If this is a system app, we can at least delete its
7266                        // current data so the application will still work.
7267                        int ret = removeDataDirsLI(pkg.volumeUuid, pkgName);
7268                        if (ret >= 0) {
7269                            // TODO: Kill the processes first
7270                            // Old data gone!
7271                            String prefix = (parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0
7272                                    ? "System package " : "Third party package ";
7273                            String msg = prefix + pkg.packageName
7274                                    + " has changed from uid: "
7275                                    + currentUid + " to "
7276                                    + pkg.applicationInfo.uid + "; old data erased";
7277                            reportSettingsProblem(Log.WARN, msg);
7278                            recovered = true;
7279                        }
7280                        if (!recovered) {
7281                            mHasSystemUidErrors = true;
7282                        }
7283                    } else if (!recovered) {
7284                        // If we allow this install to proceed, we will be broken.
7285                        // Abort, abort!
7286                        throw new PackageManagerException(INSTALL_FAILED_UID_CHANGED,
7287                                "scanPackageLI");
7288                    }
7289                    if (!recovered) {
7290                        pkg.applicationInfo.dataDir = "/mismatched_uid/settings_"
7291                            + pkg.applicationInfo.uid + "/fs_"
7292                            + currentUid;
7293                        pkg.applicationInfo.nativeLibraryDir = pkg.applicationInfo.dataDir;
7294                        pkg.applicationInfo.nativeLibraryRootDir = pkg.applicationInfo.dataDir;
7295                        String msg = "Package " + pkg.packageName
7296                                + " has mismatched uid: "
7297                                + currentUid + " on disk, "
7298                                + pkg.applicationInfo.uid + " in settings";
7299                        // writer
7300                        synchronized (mPackages) {
7301                            mSettings.mReadMessages.append(msg);
7302                            mSettings.mReadMessages.append('\n');
7303                            uidError = true;
7304                            if (!pkgSetting.uidError) {
7305                                reportSettingsProblem(Log.ERROR, msg);
7306                            }
7307                        }
7308                    }
7309                }
7310
7311                // Ensure that directories are prepared
7312                createDataDirsLI(pkg.volumeUuid, pkgName, pkg.applicationInfo.uid,
7313                        pkg.applicationInfo.seinfo);
7314
7315                if (mShouldRestoreconData) {
7316                    Slog.i(TAG, "SELinux relabeling of " + pkg.packageName + " issued.");
7317                    mInstaller.restoreconData(pkg.volumeUuid, pkg.packageName,
7318                            pkg.applicationInfo.seinfo, pkg.applicationInfo.uid);
7319                }
7320            } else {
7321                if (DEBUG_PACKAGE_SCANNING) {
7322                    if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
7323                        Log.v(TAG, "Want this data dir: " + dataPath);
7324                }
7325                createDataDirsLI(pkg.volumeUuid, pkgName, pkg.applicationInfo.uid,
7326                        pkg.applicationInfo.seinfo);
7327            }
7328
7329            // Get all of our default paths setup
7330            pkg.applicationInfo.initForUser(UserHandle.USER_SYSTEM);
7331
7332            pkgSetting.uidError = uidError;
7333        }
7334
7335        final String path = scanFile.getPath();
7336        final String cpuAbiOverride = deriveAbiOverride(pkg.cpuAbiOverride, pkgSetting);
7337
7338        if ((scanFlags & SCAN_NEW_INSTALL) == 0) {
7339            derivePackageAbi(pkg, scanFile, cpuAbiOverride, true /* extract libs */);
7340
7341            // Some system apps still use directory structure for native libraries
7342            // in which case we might end up not detecting abi solely based on apk
7343            // structure. Try to detect abi based on directory structure.
7344            if (isSystemApp(pkg) && !pkg.isUpdatedSystemApp() &&
7345                    pkg.applicationInfo.primaryCpuAbi == null) {
7346                setBundledAppAbisAndRoots(pkg, pkgSetting);
7347                setNativeLibraryPaths(pkg);
7348            }
7349
7350        } else {
7351            if ((scanFlags & SCAN_MOVE) != 0) {
7352                // We haven't run dex-opt for this move (since we've moved the compiled output too)
7353                // but we already have this packages package info in the PackageSetting. We just
7354                // use that and derive the native library path based on the new codepath.
7355                pkg.applicationInfo.primaryCpuAbi = pkgSetting.primaryCpuAbiString;
7356                pkg.applicationInfo.secondaryCpuAbi = pkgSetting.secondaryCpuAbiString;
7357            }
7358
7359            // Set native library paths again. For moves, the path will be updated based on the
7360            // ABIs we've determined above. For non-moves, the path will be updated based on the
7361            // ABIs we determined during compilation, but the path will depend on the final
7362            // package path (after the rename away from the stage path).
7363            setNativeLibraryPaths(pkg);
7364        }
7365
7366        if (DEBUG_INSTALL) Slog.i(TAG, "Linking native library dir for " + path);
7367        final int[] userIds = sUserManager.getUserIds();
7368        synchronized (mInstallLock) {
7369            // Make sure all user data directories are ready to roll; we're okay
7370            // if they already exist
7371            if (!TextUtils.isEmpty(pkg.volumeUuid)) {
7372                for (int userId : userIds) {
7373                    if (userId != UserHandle.USER_SYSTEM) {
7374                        mInstaller.createUserData(pkg.volumeUuid, pkg.packageName,
7375                                UserHandle.getUid(userId, pkg.applicationInfo.uid), userId,
7376                                pkg.applicationInfo.seinfo);
7377                    }
7378                }
7379            }
7380
7381            // Create a native library symlink only if we have native libraries
7382            // and if the native libraries are 32 bit libraries. We do not provide
7383            // this symlink for 64 bit libraries.
7384            if (pkg.applicationInfo.primaryCpuAbi != null &&
7385                    !VMRuntime.is64BitAbi(pkg.applicationInfo.primaryCpuAbi)) {
7386                Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "linkNativeLib");
7387                try {
7388                    final String nativeLibPath = pkg.applicationInfo.nativeLibraryDir;
7389                    for (int userId : userIds) {
7390                        if (mInstaller.linkNativeLibraryDirectory(pkg.volumeUuid, pkg.packageName,
7391                                nativeLibPath, userId) < 0) {
7392                            throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
7393                                    "Failed linking native library dir (user=" + userId + ")");
7394                        }
7395                    }
7396                } finally {
7397                    Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
7398                }
7399            }
7400        }
7401
7402        // This is a special case for the "system" package, where the ABI is
7403        // dictated by the zygote configuration (and init.rc). We should keep track
7404        // of this ABI so that we can deal with "normal" applications that run under
7405        // the same UID correctly.
7406        if (mPlatformPackage == pkg) {
7407            pkg.applicationInfo.primaryCpuAbi = VMRuntime.getRuntime().is64Bit() ?
7408                    Build.SUPPORTED_64_BIT_ABIS[0] : Build.SUPPORTED_32_BIT_ABIS[0];
7409        }
7410
7411        // If there's a mismatch between the abi-override in the package setting
7412        // and the abiOverride specified for the install. Warn about this because we
7413        // would've already compiled the app without taking the package setting into
7414        // account.
7415        if ((scanFlags & SCAN_NO_DEX) == 0 && (scanFlags & SCAN_NEW_INSTALL) != 0) {
7416            if (cpuAbiOverride == null && pkgSetting.cpuAbiOverrideString != null) {
7417                Slog.w(TAG, "Ignoring persisted ABI override " + cpuAbiOverride +
7418                        " for package " + pkg.packageName);
7419            }
7420        }
7421
7422        pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
7423        pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
7424        pkgSetting.cpuAbiOverrideString = cpuAbiOverride;
7425
7426        // Copy the derived override back to the parsed package, so that we can
7427        // update the package settings accordingly.
7428        pkg.cpuAbiOverride = cpuAbiOverride;
7429
7430        if (DEBUG_ABI_SELECTION) {
7431            Slog.d(TAG, "Resolved nativeLibraryRoot for " + pkg.applicationInfo.packageName
7432                    + " to root=" + pkg.applicationInfo.nativeLibraryRootDir + ", isa="
7433                    + pkg.applicationInfo.nativeLibraryRootRequiresIsa);
7434        }
7435
7436        // Push the derived path down into PackageSettings so we know what to
7437        // clean up at uninstall time.
7438        pkgSetting.legacyNativeLibraryPathString = pkg.applicationInfo.nativeLibraryRootDir;
7439
7440        if (DEBUG_ABI_SELECTION) {
7441            Log.d(TAG, "Abis for package[" + pkg.packageName + "] are" +
7442                    " primary=" + pkg.applicationInfo.primaryCpuAbi +
7443                    " secondary=" + pkg.applicationInfo.secondaryCpuAbi);
7444        }
7445
7446        if ((scanFlags & SCAN_BOOTING) == 0 && pkgSetting.sharedUser != null) {
7447            // We don't do this here during boot because we can do it all
7448            // at once after scanning all existing packages.
7449            //
7450            // We also do this *before* we perform dexopt on this package, so that
7451            // we can avoid redundant dexopts, and also to make sure we've got the
7452            // code and package path correct.
7453            adjustCpuAbisForSharedUserLPw(pkgSetting.sharedUser.packages,
7454                    pkg, true /* boot complete */);
7455        }
7456
7457        if (mFactoryTest && pkg.requestedPermissions.contains(
7458                android.Manifest.permission.FACTORY_TEST)) {
7459            pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST;
7460        }
7461
7462        ArrayList<PackageParser.Package> clientLibPkgs = null;
7463
7464        // writer
7465        synchronized (mPackages) {
7466            if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
7467                // Only system apps can add new shared libraries.
7468                if (pkg.libraryNames != null) {
7469                    for (int i=0; i<pkg.libraryNames.size(); i++) {
7470                        String name = pkg.libraryNames.get(i);
7471                        boolean allowed = false;
7472                        if (pkg.isUpdatedSystemApp()) {
7473                            // New library entries can only be added through the
7474                            // system image.  This is important to get rid of a lot
7475                            // of nasty edge cases: for example if we allowed a non-
7476                            // system update of the app to add a library, then uninstalling
7477                            // the update would make the library go away, and assumptions
7478                            // we made such as through app install filtering would now
7479                            // have allowed apps on the device which aren't compatible
7480                            // with it.  Better to just have the restriction here, be
7481                            // conservative, and create many fewer cases that can negatively
7482                            // impact the user experience.
7483                            final PackageSetting sysPs = mSettings
7484                                    .getDisabledSystemPkgLPr(pkg.packageName);
7485                            if (sysPs.pkg != null && sysPs.pkg.libraryNames != null) {
7486                                for (int j=0; j<sysPs.pkg.libraryNames.size(); j++) {
7487                                    if (name.equals(sysPs.pkg.libraryNames.get(j))) {
7488                                        allowed = true;
7489                                        break;
7490                                    }
7491                                }
7492                            }
7493                        } else {
7494                            allowed = true;
7495                        }
7496                        if (allowed) {
7497                            if (!mSharedLibraries.containsKey(name)) {
7498                                mSharedLibraries.put(name, new SharedLibraryEntry(null, pkg.packageName));
7499                            } else if (!name.equals(pkg.packageName)) {
7500                                Slog.w(TAG, "Package " + pkg.packageName + " library "
7501                                        + name + " already exists; skipping");
7502                            }
7503                        } else {
7504                            Slog.w(TAG, "Package " + pkg.packageName + " declares lib "
7505                                    + name + " that is not declared on system image; skipping");
7506                        }
7507                    }
7508                    if ((scanFlags & SCAN_BOOTING) == 0) {
7509                        // If we are not booting, we need to update any applications
7510                        // that are clients of our shared library.  If we are booting,
7511                        // this will all be done once the scan is complete.
7512                        clientLibPkgs = updateAllSharedLibrariesLPw(pkg);
7513                    }
7514                }
7515            }
7516        }
7517
7518        // Request the ActivityManager to kill the process(only for existing packages)
7519        // so that we do not end up in a confused state while the user is still using the older
7520        // version of the application while the new one gets installed.
7521        if ((scanFlags & SCAN_REPLACING) != 0) {
7522            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "killApplication");
7523
7524            killApplication(pkg.applicationInfo.packageName,
7525                        pkg.applicationInfo.uid, "replace pkg");
7526
7527            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
7528        }
7529
7530        // Also need to kill any apps that are dependent on the library.
7531        if (clientLibPkgs != null) {
7532            for (int i=0; i<clientLibPkgs.size(); i++) {
7533                PackageParser.Package clientPkg = clientLibPkgs.get(i);
7534                killApplication(clientPkg.applicationInfo.packageName,
7535                        clientPkg.applicationInfo.uid, "update lib");
7536            }
7537        }
7538
7539        // Make sure we're not adding any bogus keyset info
7540        KeySetManagerService ksms = mSettings.mKeySetManagerService;
7541        ksms.assertScannedPackageValid(pkg);
7542
7543        // writer
7544        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");
7545
7546        boolean createIdmapFailed = false;
7547        synchronized (mPackages) {
7548            // We don't expect installation to fail beyond this point
7549
7550            // Add the new setting to mSettings
7551            mSettings.insertPackageSettingLPw(pkgSetting, pkg);
7552            // Add the new setting to mPackages
7553            mPackages.put(pkg.applicationInfo.packageName, pkg);
7554            // Make sure we don't accidentally delete its data.
7555            final Iterator<PackageCleanItem> iter = mSettings.mPackagesToBeCleaned.iterator();
7556            while (iter.hasNext()) {
7557                PackageCleanItem item = iter.next();
7558                if (pkgName.equals(item.packageName)) {
7559                    iter.remove();
7560                }
7561            }
7562
7563            // Take care of first install / last update times.
7564            if (currentTime != 0) {
7565                if (pkgSetting.firstInstallTime == 0) {
7566                    pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = currentTime;
7567                } else if ((scanFlags&SCAN_UPDATE_TIME) != 0) {
7568                    pkgSetting.lastUpdateTime = currentTime;
7569                }
7570            } else if (pkgSetting.firstInstallTime == 0) {
7571                // We need *something*.  Take time time stamp of the file.
7572                pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = scanFileTime;
7573            } else if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) != 0) {
7574                if (scanFileTime != pkgSetting.timeStamp) {
7575                    // A package on the system image has changed; consider this
7576                    // to be an update.
7577                    pkgSetting.lastUpdateTime = scanFileTime;
7578                }
7579            }
7580
7581            // Add the package's KeySets to the global KeySetManagerService
7582            ksms.addScannedPackageLPw(pkg);
7583
7584            int N = pkg.providers.size();
7585            StringBuilder r = null;
7586            int i;
7587            for (i=0; i<N; i++) {
7588                PackageParser.Provider p = pkg.providers.get(i);
7589                p.info.processName = fixProcessName(pkg.applicationInfo.processName,
7590                        p.info.processName, pkg.applicationInfo.uid);
7591                mProviders.addProvider(p);
7592                p.syncable = p.info.isSyncable;
7593                if (p.info.authority != null) {
7594                    String names[] = p.info.authority.split(";");
7595                    p.info.authority = null;
7596                    for (int j = 0; j < names.length; j++) {
7597                        if (j == 1 && p.syncable) {
7598                            // We only want the first authority for a provider to possibly be
7599                            // syncable, so if we already added this provider using a different
7600                            // authority clear the syncable flag. We copy the provider before
7601                            // changing it because the mProviders object contains a reference
7602                            // to a provider that we don't want to change.
7603                            // Only do this for the second authority since the resulting provider
7604                            // object can be the same for all future authorities for this provider.
7605                            p = new PackageParser.Provider(p);
7606                            p.syncable = false;
7607                        }
7608                        if (!mProvidersByAuthority.containsKey(names[j])) {
7609                            mProvidersByAuthority.put(names[j], p);
7610                            if (p.info.authority == null) {
7611                                p.info.authority = names[j];
7612                            } else {
7613                                p.info.authority = p.info.authority + ";" + names[j];
7614                            }
7615                            if (DEBUG_PACKAGE_SCANNING) {
7616                                if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
7617                                    Log.d(TAG, "Registered content provider: " + names[j]
7618                                            + ", className = " + p.info.name + ", isSyncable = "
7619                                            + p.info.isSyncable);
7620                            }
7621                        } else {
7622                            PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
7623                            Slog.w(TAG, "Skipping provider name " + names[j] +
7624                                    " (in package " + pkg.applicationInfo.packageName +
7625                                    "): name already used by "
7626                                    + ((other != null && other.getComponentName() != null)
7627                                            ? other.getComponentName().getPackageName() : "?"));
7628                        }
7629                    }
7630                }
7631                if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
7632                    if (r == null) {
7633                        r = new StringBuilder(256);
7634                    } else {
7635                        r.append(' ');
7636                    }
7637                    r.append(p.info.name);
7638                }
7639            }
7640            if (r != null) {
7641                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Providers: " + r);
7642            }
7643
7644            N = pkg.services.size();
7645            r = null;
7646            for (i=0; i<N; i++) {
7647                PackageParser.Service s = pkg.services.get(i);
7648                s.info.processName = fixProcessName(pkg.applicationInfo.processName,
7649                        s.info.processName, pkg.applicationInfo.uid);
7650                mServices.addService(s);
7651                if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
7652                    if (r == null) {
7653                        r = new StringBuilder(256);
7654                    } else {
7655                        r.append(' ');
7656                    }
7657                    r.append(s.info.name);
7658                }
7659            }
7660            if (r != null) {
7661                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Services: " + r);
7662            }
7663
7664            N = pkg.receivers.size();
7665            r = null;
7666            for (i=0; i<N; i++) {
7667                PackageParser.Activity a = pkg.receivers.get(i);
7668                a.info.processName = fixProcessName(pkg.applicationInfo.processName,
7669                        a.info.processName, pkg.applicationInfo.uid);
7670                mReceivers.addActivity(a, "receiver");
7671                if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
7672                    if (r == null) {
7673                        r = new StringBuilder(256);
7674                    } else {
7675                        r.append(' ');
7676                    }
7677                    r.append(a.info.name);
7678                }
7679            }
7680            if (r != null) {
7681                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Receivers: " + r);
7682            }
7683
7684            N = pkg.activities.size();
7685            r = null;
7686            for (i=0; i<N; i++) {
7687                PackageParser.Activity a = pkg.activities.get(i);
7688                a.info.processName = fixProcessName(pkg.applicationInfo.processName,
7689                        a.info.processName, pkg.applicationInfo.uid);
7690                mActivities.addActivity(a, "activity");
7691                if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
7692                    if (r == null) {
7693                        r = new StringBuilder(256);
7694                    } else {
7695                        r.append(' ');
7696                    }
7697                    r.append(a.info.name);
7698                }
7699            }
7700            if (r != null) {
7701                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Activities: " + r);
7702            }
7703
7704            N = pkg.permissionGroups.size();
7705            r = null;
7706            for (i=0; i<N; i++) {
7707                PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i);
7708                PackageParser.PermissionGroup cur = mPermissionGroups.get(pg.info.name);
7709                if (cur == null) {
7710                    mPermissionGroups.put(pg.info.name, pg);
7711                    if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
7712                        if (r == null) {
7713                            r = new StringBuilder(256);
7714                        } else {
7715                            r.append(' ');
7716                        }
7717                        r.append(pg.info.name);
7718                    }
7719                } else {
7720                    Slog.w(TAG, "Permission group " + pg.info.name + " from package "
7721                            + pg.info.packageName + " ignored: original from "
7722                            + cur.info.packageName);
7723                    if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
7724                        if (r == null) {
7725                            r = new StringBuilder(256);
7726                        } else {
7727                            r.append(' ');
7728                        }
7729                        r.append("DUP:");
7730                        r.append(pg.info.name);
7731                    }
7732                }
7733            }
7734            if (r != null) {
7735                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Permission Groups: " + r);
7736            }
7737
7738            N = pkg.permissions.size();
7739            r = null;
7740            for (i=0; i<N; i++) {
7741                PackageParser.Permission p = pkg.permissions.get(i);
7742
7743                // Assume by default that we did not install this permission into the system.
7744                p.info.flags &= ~PermissionInfo.FLAG_INSTALLED;
7745
7746                // Now that permission groups have a special meaning, we ignore permission
7747                // groups for legacy apps to prevent unexpected behavior. In particular,
7748                // permissions for one app being granted to someone just becuase they happen
7749                // to be in a group defined by another app (before this had no implications).
7750                if (pkg.applicationInfo.targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1) {
7751                    p.group = mPermissionGroups.get(p.info.group);
7752                    // Warn for a permission in an unknown group.
7753                    if (p.info.group != null && p.group == null) {
7754                        Slog.w(TAG, "Permission " + p.info.name + " from package "
7755                                + p.info.packageName + " in an unknown group " + p.info.group);
7756                    }
7757                }
7758
7759                ArrayMap<String, BasePermission> permissionMap =
7760                        p.tree ? mSettings.mPermissionTrees
7761                                : mSettings.mPermissions;
7762                BasePermission bp = permissionMap.get(p.info.name);
7763
7764                // Allow system apps to redefine non-system permissions
7765                if (bp != null && !Objects.equals(bp.sourcePackage, p.info.packageName)) {
7766                    final boolean currentOwnerIsSystem = (bp.perm != null
7767                            && isSystemApp(bp.perm.owner));
7768                    if (isSystemApp(p.owner)) {
7769                        if (bp.type == BasePermission.TYPE_BUILTIN && bp.perm == null) {
7770                            // It's a built-in permission and no owner, take ownership now
7771                            bp.packageSetting = pkgSetting;
7772                            bp.perm = p;
7773                            bp.uid = pkg.applicationInfo.uid;
7774                            bp.sourcePackage = p.info.packageName;
7775                            p.info.flags |= PermissionInfo.FLAG_INSTALLED;
7776                        } else if (!currentOwnerIsSystem) {
7777                            String msg = "New decl " + p.owner + " of permission  "
7778                                    + p.info.name + " is system; overriding " + bp.sourcePackage;
7779                            reportSettingsProblem(Log.WARN, msg);
7780                            bp = null;
7781                        }
7782                    }
7783                }
7784
7785                if (bp == null) {
7786                    bp = new BasePermission(p.info.name, p.info.packageName,
7787                            BasePermission.TYPE_NORMAL);
7788                    permissionMap.put(p.info.name, bp);
7789                }
7790
7791                if (bp.perm == null) {
7792                    if (bp.sourcePackage == null
7793                            || bp.sourcePackage.equals(p.info.packageName)) {
7794                        BasePermission tree = findPermissionTreeLP(p.info.name);
7795                        if (tree == null
7796                                || tree.sourcePackage.equals(p.info.packageName)) {
7797                            bp.packageSetting = pkgSetting;
7798                            bp.perm = p;
7799                            bp.uid = pkg.applicationInfo.uid;
7800                            bp.sourcePackage = p.info.packageName;
7801                            p.info.flags |= PermissionInfo.FLAG_INSTALLED;
7802                            if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
7803                                if (r == null) {
7804                                    r = new StringBuilder(256);
7805                                } else {
7806                                    r.append(' ');
7807                                }
7808                                r.append(p.info.name);
7809                            }
7810                        } else {
7811                            Slog.w(TAG, "Permission " + p.info.name + " from package "
7812                                    + p.info.packageName + " ignored: base tree "
7813                                    + tree.name + " is from package "
7814                                    + tree.sourcePackage);
7815                        }
7816                    } else {
7817                        Slog.w(TAG, "Permission " + p.info.name + " from package "
7818                                + p.info.packageName + " ignored: original from "
7819                                + bp.sourcePackage);
7820                    }
7821                } else if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
7822                    if (r == null) {
7823                        r = new StringBuilder(256);
7824                    } else {
7825                        r.append(' ');
7826                    }
7827                    r.append("DUP:");
7828                    r.append(p.info.name);
7829                }
7830                if (bp.perm == p) {
7831                    bp.protectionLevel = p.info.protectionLevel;
7832                }
7833            }
7834
7835            if (r != null) {
7836                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Permissions: " + r);
7837            }
7838
7839            N = pkg.instrumentation.size();
7840            r = null;
7841            for (i=0; i<N; i++) {
7842                PackageParser.Instrumentation a = pkg.instrumentation.get(i);
7843                a.info.packageName = pkg.applicationInfo.packageName;
7844                a.info.sourceDir = pkg.applicationInfo.sourceDir;
7845                a.info.publicSourceDir = pkg.applicationInfo.publicSourceDir;
7846                a.info.splitSourceDirs = pkg.applicationInfo.splitSourceDirs;
7847                a.info.splitPublicSourceDirs = pkg.applicationInfo.splitPublicSourceDirs;
7848                a.info.dataDir = pkg.applicationInfo.dataDir;
7849                a.info.deviceEncryptedDataDir = pkg.applicationInfo.deviceEncryptedDataDir;
7850                a.info.credentialEncryptedDataDir = pkg.applicationInfo.credentialEncryptedDataDir;
7851
7852                // TODO: Update instrumentation.nativeLibraryDir as well ? Does it
7853                // need other information about the application, like the ABI and what not ?
7854                a.info.nativeLibraryDir = pkg.applicationInfo.nativeLibraryDir;
7855                mInstrumentation.put(a.getComponentName(), a);
7856                if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
7857                    if (r == null) {
7858                        r = new StringBuilder(256);
7859                    } else {
7860                        r.append(' ');
7861                    }
7862                    r.append(a.info.name);
7863                }
7864            }
7865            if (r != null) {
7866                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Instrumentation: " + r);
7867            }
7868
7869            if (pkg.protectedBroadcasts != null) {
7870                N = pkg.protectedBroadcasts.size();
7871                for (i=0; i<N; i++) {
7872                    mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i));
7873                }
7874            }
7875
7876            pkgSetting.setTimeStamp(scanFileTime);
7877
7878            // Create idmap files for pairs of (packages, overlay packages).
7879            // Note: "android", ie framework-res.apk, is handled by native layers.
7880            if (pkg.mOverlayTarget != null) {
7881                // This is an overlay package.
7882                if (pkg.mOverlayTarget != null && !pkg.mOverlayTarget.equals("android")) {
7883                    if (!mOverlays.containsKey(pkg.mOverlayTarget)) {
7884                        mOverlays.put(pkg.mOverlayTarget,
7885                                new ArrayMap<String, PackageParser.Package>());
7886                    }
7887                    ArrayMap<String, PackageParser.Package> map = mOverlays.get(pkg.mOverlayTarget);
7888                    map.put(pkg.packageName, pkg);
7889                    PackageParser.Package orig = mPackages.get(pkg.mOverlayTarget);
7890                    if (orig != null && !createIdmapForPackagePairLI(orig, pkg)) {
7891                        createIdmapFailed = true;
7892                    }
7893                }
7894            } else if (mOverlays.containsKey(pkg.packageName) &&
7895                    !pkg.packageName.equals("android")) {
7896                // This is a regular package, with one or more known overlay packages.
7897                createIdmapsForPackageLI(pkg);
7898            }
7899        }
7900
7901        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
7902
7903        if (createIdmapFailed) {
7904            throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
7905                    "scanPackageLI failed to createIdmap");
7906        }
7907        return pkg;
7908    }
7909
7910    /**
7911     * Derive the ABI of a non-system package located at {@code scanFile}. This information
7912     * is derived purely on the basis of the contents of {@code scanFile} and
7913     * {@code cpuAbiOverride}.
7914     *
7915     * If {@code extractLibs} is true, native libraries are extracted from the app if required.
7916     */
7917    public void derivePackageAbi(PackageParser.Package pkg, File scanFile,
7918                                 String cpuAbiOverride, boolean extractLibs)
7919            throws PackageManagerException {
7920        // TODO: We can probably be smarter about this stuff. For installed apps,
7921        // we can calculate this information at install time once and for all. For
7922        // system apps, we can probably assume that this information doesn't change
7923        // after the first boot scan. As things stand, we do lots of unnecessary work.
7924
7925        // Give ourselves some initial paths; we'll come back for another
7926        // pass once we've determined ABI below.
7927        setNativeLibraryPaths(pkg);
7928
7929        // We would never need to extract libs for forward-locked and external packages,
7930        // since the container service will do it for us. We shouldn't attempt to
7931        // extract libs from system app when it was not updated.
7932        if (pkg.isForwardLocked() || pkg.applicationInfo.isExternalAsec() ||
7933                (isSystemApp(pkg) && !pkg.isUpdatedSystemApp())) {
7934            extractLibs = false;
7935        }
7936
7937        final String nativeLibraryRootStr = pkg.applicationInfo.nativeLibraryRootDir;
7938        final boolean useIsaSpecificSubdirs = pkg.applicationInfo.nativeLibraryRootRequiresIsa;
7939
7940        NativeLibraryHelper.Handle handle = null;
7941        try {
7942            handle = NativeLibraryHelper.Handle.create(pkg);
7943            // TODO(multiArch): This can be null for apps that didn't go through the
7944            // usual installation process. We can calculate it again, like we
7945            // do during install time.
7946            //
7947            // TODO(multiArch): Why do we need to rescan ASEC apps again ? It seems totally
7948            // unnecessary.
7949            final File nativeLibraryRoot = new File(nativeLibraryRootStr);
7950
7951            // Null out the abis so that they can be recalculated.
7952            pkg.applicationInfo.primaryCpuAbi = null;
7953            pkg.applicationInfo.secondaryCpuAbi = null;
7954            if (isMultiArch(pkg.applicationInfo)) {
7955                // Warn if we've set an abiOverride for multi-lib packages..
7956                // By definition, we need to copy both 32 and 64 bit libraries for
7957                // such packages.
7958                if (pkg.cpuAbiOverride != null
7959                        && !NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(pkg.cpuAbiOverride)) {
7960                    Slog.w(TAG, "Ignoring abiOverride for multi arch application.");
7961                }
7962
7963                int abi32 = PackageManager.NO_NATIVE_LIBRARIES;
7964                int abi64 = PackageManager.NO_NATIVE_LIBRARIES;
7965                if (Build.SUPPORTED_32_BIT_ABIS.length > 0) {
7966                    if (extractLibs) {
7967                        abi32 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
7968                                nativeLibraryRoot, Build.SUPPORTED_32_BIT_ABIS,
7969                                useIsaSpecificSubdirs);
7970                    } else {
7971                        abi32 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_32_BIT_ABIS);
7972                    }
7973                }
7974
7975                maybeThrowExceptionForMultiArchCopy(
7976                        "Error unpackaging 32 bit native libs for multiarch app.", abi32);
7977
7978                if (Build.SUPPORTED_64_BIT_ABIS.length > 0) {
7979                    if (extractLibs) {
7980                        abi64 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
7981                                nativeLibraryRoot, Build.SUPPORTED_64_BIT_ABIS,
7982                                useIsaSpecificSubdirs);
7983                    } else {
7984                        abi64 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_64_BIT_ABIS);
7985                    }
7986                }
7987
7988                maybeThrowExceptionForMultiArchCopy(
7989                        "Error unpackaging 64 bit native libs for multiarch app.", abi64);
7990
7991                if (abi64 >= 0) {
7992                    pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[abi64];
7993                }
7994
7995                if (abi32 >= 0) {
7996                    final String abi = Build.SUPPORTED_32_BIT_ABIS[abi32];
7997                    if (abi64 >= 0) {
7998                        pkg.applicationInfo.secondaryCpuAbi = abi;
7999                    } else {
8000                        pkg.applicationInfo.primaryCpuAbi = abi;
8001                    }
8002                }
8003            } else {
8004                String[] abiList = (cpuAbiOverride != null) ?
8005                        new String[] { cpuAbiOverride } : Build.SUPPORTED_ABIS;
8006
8007                // Enable gross and lame hacks for apps that are built with old
8008                // SDK tools. We must scan their APKs for renderscript bitcode and
8009                // not launch them if it's present. Don't bother checking on devices
8010                // that don't have 64 bit support.
8011                boolean needsRenderScriptOverride = false;
8012                if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && cpuAbiOverride == null &&
8013                        NativeLibraryHelper.hasRenderscriptBitcode(handle)) {
8014                    abiList = Build.SUPPORTED_32_BIT_ABIS;
8015                    needsRenderScriptOverride = true;
8016                }
8017
8018                final int copyRet;
8019                if (extractLibs) {
8020                    copyRet = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
8021                            nativeLibraryRoot, abiList, useIsaSpecificSubdirs);
8022                } else {
8023                    copyRet = NativeLibraryHelper.findSupportedAbi(handle, abiList);
8024                }
8025
8026                if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) {
8027                    throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
8028                            "Error unpackaging native libs for app, errorCode=" + copyRet);
8029                }
8030
8031                if (copyRet >= 0) {
8032                    pkg.applicationInfo.primaryCpuAbi = abiList[copyRet];
8033                } else if (copyRet == PackageManager.NO_NATIVE_LIBRARIES && cpuAbiOverride != null) {
8034                    pkg.applicationInfo.primaryCpuAbi = cpuAbiOverride;
8035                } else if (needsRenderScriptOverride) {
8036                    pkg.applicationInfo.primaryCpuAbi = abiList[0];
8037                }
8038            }
8039        } catch (IOException ioe) {
8040            Slog.e(TAG, "Unable to get canonical file " + ioe.toString());
8041        } finally {
8042            IoUtils.closeQuietly(handle);
8043        }
8044
8045        // Now that we've calculated the ABIs and determined if it's an internal app,
8046        // we will go ahead and populate the nativeLibraryPath.
8047        setNativeLibraryPaths(pkg);
8048    }
8049
8050    /**
8051     * Adjusts ABIs for a set of packages belonging to a shared user so that they all match.
8052     * i.e, so that all packages can be run inside a single process if required.
8053     *
8054     * Optionally, callers can pass in a parsed package via {@code newPackage} in which case
8055     * this function will either try and make the ABI for all packages in {@code packagesForUser}
8056     * match {@code scannedPackage} or will update the ABI of {@code scannedPackage} to match
8057     * the ABI selected for {@code packagesForUser}. This variant is used when installing or
8058     * updating a package that belongs to a shared user.
8059     *
8060     * NOTE: We currently only match for the primary CPU abi string. Matching the secondary
8061     * adds unnecessary complexity.
8062     */
8063    private void adjustCpuAbisForSharedUserLPw(Set<PackageSetting> packagesForUser,
8064            PackageParser.Package scannedPackage, boolean bootComplete) {
8065        String requiredInstructionSet = null;
8066        if (scannedPackage != null && scannedPackage.applicationInfo.primaryCpuAbi != null) {
8067            requiredInstructionSet = VMRuntime.getInstructionSet(
8068                     scannedPackage.applicationInfo.primaryCpuAbi);
8069        }
8070
8071        PackageSetting requirer = null;
8072        for (PackageSetting ps : packagesForUser) {
8073            // If packagesForUser contains scannedPackage, we skip it. This will happen
8074            // when scannedPackage is an update of an existing package. Without this check,
8075            // we will never be able to change the ABI of any package belonging to a shared
8076            // user, even if it's compatible with other packages.
8077            if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
8078                if (ps.primaryCpuAbiString == null) {
8079                    continue;
8080                }
8081
8082                final String instructionSet = VMRuntime.getInstructionSet(ps.primaryCpuAbiString);
8083                if (requiredInstructionSet != null && !instructionSet.equals(requiredInstructionSet)) {
8084                    // We have a mismatch between instruction sets (say arm vs arm64) warn about
8085                    // this but there's not much we can do.
8086                    String errorMessage = "Instruction set mismatch, "
8087                            + ((requirer == null) ? "[caller]" : requirer)
8088                            + " requires " + requiredInstructionSet + " whereas " + ps
8089                            + " requires " + instructionSet;
8090                    Slog.w(TAG, errorMessage);
8091                }
8092
8093                if (requiredInstructionSet == null) {
8094                    requiredInstructionSet = instructionSet;
8095                    requirer = ps;
8096                }
8097            }
8098        }
8099
8100        if (requiredInstructionSet != null) {
8101            String adjustedAbi;
8102            if (requirer != null) {
8103                // requirer != null implies that either scannedPackage was null or that scannedPackage
8104                // did not require an ABI, in which case we have to adjust scannedPackage to match
8105                // the ABI of the set (which is the same as requirer's ABI)
8106                adjustedAbi = requirer.primaryCpuAbiString;
8107                if (scannedPackage != null) {
8108                    scannedPackage.applicationInfo.primaryCpuAbi = adjustedAbi;
8109                }
8110            } else {
8111                // requirer == null implies that we're updating all ABIs in the set to
8112                // match scannedPackage.
8113                adjustedAbi =  scannedPackage.applicationInfo.primaryCpuAbi;
8114            }
8115
8116            for (PackageSetting ps : packagesForUser) {
8117                if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
8118                    if (ps.primaryCpuAbiString != null) {
8119                        continue;
8120                    }
8121
8122                    ps.primaryCpuAbiString = adjustedAbi;
8123                    if (ps.pkg != null && ps.pkg.applicationInfo != null) {
8124                        ps.pkg.applicationInfo.primaryCpuAbi = adjustedAbi;
8125                        Slog.i(TAG, "Adjusting ABI for " + ps.name + " to " + adjustedAbi);
8126                        mInstaller.rmdex(ps.codePathString,
8127                                getDexCodeInstructionSet(getPreferredInstructionSet()));
8128                    }
8129                }
8130            }
8131        }
8132    }
8133
8134    private void setUpCustomResolverActivity(PackageParser.Package pkg) {
8135        synchronized (mPackages) {
8136            mResolverReplaced = true;
8137            // Set up information for custom user intent resolution activity.
8138            mResolveActivity.applicationInfo = pkg.applicationInfo;
8139            mResolveActivity.name = mCustomResolverComponentName.getClassName();
8140            mResolveActivity.packageName = pkg.applicationInfo.packageName;
8141            mResolveActivity.processName = pkg.applicationInfo.packageName;
8142            mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
8143            mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS |
8144                    ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
8145            mResolveActivity.theme = 0;
8146            mResolveActivity.exported = true;
8147            mResolveActivity.enabled = true;
8148            mResolveInfo.activityInfo = mResolveActivity;
8149            mResolveInfo.priority = 0;
8150            mResolveInfo.preferredOrder = 0;
8151            mResolveInfo.match = 0;
8152            mResolveComponentName = mCustomResolverComponentName;
8153            Slog.i(TAG, "Replacing default ResolverActivity with custom activity: " +
8154                    mResolveComponentName);
8155        }
8156    }
8157
8158    private void setUpEphemeralInstallerActivityLP(ComponentName installerComponent) {
8159        final PackageParser.Package pkg = mPackages.get(installerComponent.getPackageName());
8160
8161        // Set up information for ephemeral installer activity
8162        mEphemeralInstallerActivity.applicationInfo = pkg.applicationInfo;
8163        mEphemeralInstallerActivity.name = mEphemeralInstallerComponent.getClassName();
8164        mEphemeralInstallerActivity.packageName = pkg.applicationInfo.packageName;
8165        mEphemeralInstallerActivity.processName = pkg.applicationInfo.packageName;
8166        mEphemeralInstallerActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
8167        mEphemeralInstallerActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS |
8168                ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
8169        mEphemeralInstallerActivity.theme = 0;
8170        mEphemeralInstallerActivity.exported = true;
8171        mEphemeralInstallerActivity.enabled = true;
8172        mEphemeralInstallerInfo.activityInfo = mEphemeralInstallerActivity;
8173        mEphemeralInstallerInfo.priority = 0;
8174        mEphemeralInstallerInfo.preferredOrder = 0;
8175        mEphemeralInstallerInfo.match = 0;
8176
8177        if (DEBUG_EPHEMERAL) {
8178            Slog.d(TAG, "Set ephemeral installer activity: " + mEphemeralInstallerComponent);
8179        }
8180    }
8181
8182    private static String calculateBundledApkRoot(final String codePathString) {
8183        final File codePath = new File(codePathString);
8184        final File codeRoot;
8185        if (FileUtils.contains(Environment.getRootDirectory(), codePath)) {
8186            codeRoot = Environment.getRootDirectory();
8187        } else if (FileUtils.contains(Environment.getOemDirectory(), codePath)) {
8188            codeRoot = Environment.getOemDirectory();
8189        } else if (FileUtils.contains(Environment.getVendorDirectory(), codePath)) {
8190            codeRoot = Environment.getVendorDirectory();
8191        } else {
8192            // Unrecognized code path; take its top real segment as the apk root:
8193            // e.g. /something/app/blah.apk => /something
8194            try {
8195                File f = codePath.getCanonicalFile();
8196                File parent = f.getParentFile();    // non-null because codePath is a file
8197                File tmp;
8198                while ((tmp = parent.getParentFile()) != null) {
8199                    f = parent;
8200                    parent = tmp;
8201                }
8202                codeRoot = f;
8203                Slog.w(TAG, "Unrecognized code path "
8204                        + codePath + " - using " + codeRoot);
8205            } catch (IOException e) {
8206                // Can't canonicalize the code path -- shenanigans?
8207                Slog.w(TAG, "Can't canonicalize code path " + codePath);
8208                return Environment.getRootDirectory().getPath();
8209            }
8210        }
8211        return codeRoot.getPath();
8212    }
8213
8214    /**
8215     * Derive and set the location of native libraries for the given package,
8216     * which varies depending on where and how the package was installed.
8217     */
8218    private void setNativeLibraryPaths(PackageParser.Package pkg) {
8219        final ApplicationInfo info = pkg.applicationInfo;
8220        final String codePath = pkg.codePath;
8221        final File codeFile = new File(codePath);
8222        final boolean bundledApp = info.isSystemApp() && !info.isUpdatedSystemApp();
8223        final boolean asecApp = info.isForwardLocked() || info.isExternalAsec();
8224
8225        info.nativeLibraryRootDir = null;
8226        info.nativeLibraryRootRequiresIsa = false;
8227        info.nativeLibraryDir = null;
8228        info.secondaryNativeLibraryDir = null;
8229
8230        if (isApkFile(codeFile)) {
8231            // Monolithic install
8232            if (bundledApp) {
8233                // If "/system/lib64/apkname" exists, assume that is the per-package
8234                // native library directory to use; otherwise use "/system/lib/apkname".
8235                final String apkRoot = calculateBundledApkRoot(info.sourceDir);
8236                final boolean is64Bit = VMRuntime.is64BitInstructionSet(
8237                        getPrimaryInstructionSet(info));
8238
8239                // This is a bundled system app so choose the path based on the ABI.
8240                // if it's a 64 bit abi, use lib64 otherwise use lib32. Note that this
8241                // is just the default path.
8242                final String apkName = deriveCodePathName(codePath);
8243                final String libDir = is64Bit ? LIB64_DIR_NAME : LIB_DIR_NAME;
8244                info.nativeLibraryRootDir = Environment.buildPath(new File(apkRoot), libDir,
8245                        apkName).getAbsolutePath();
8246
8247                if (info.secondaryCpuAbi != null) {
8248                    final String secondaryLibDir = is64Bit ? LIB_DIR_NAME : LIB64_DIR_NAME;
8249                    info.secondaryNativeLibraryDir = Environment.buildPath(new File(apkRoot),
8250                            secondaryLibDir, apkName).getAbsolutePath();
8251                }
8252            } else if (asecApp) {
8253                info.nativeLibraryRootDir = new File(codeFile.getParentFile(), LIB_DIR_NAME)
8254                        .getAbsolutePath();
8255            } else {
8256                final String apkName = deriveCodePathName(codePath);
8257                info.nativeLibraryRootDir = new File(mAppLib32InstallDir, apkName)
8258                        .getAbsolutePath();
8259            }
8260
8261            info.nativeLibraryRootRequiresIsa = false;
8262            info.nativeLibraryDir = info.nativeLibraryRootDir;
8263        } else {
8264            // Cluster install
8265            info.nativeLibraryRootDir = new File(codeFile, LIB_DIR_NAME).getAbsolutePath();
8266            info.nativeLibraryRootRequiresIsa = true;
8267
8268            info.nativeLibraryDir = new File(info.nativeLibraryRootDir,
8269                    getPrimaryInstructionSet(info)).getAbsolutePath();
8270
8271            if (info.secondaryCpuAbi != null) {
8272                info.secondaryNativeLibraryDir = new File(info.nativeLibraryRootDir,
8273                        VMRuntime.getInstructionSet(info.secondaryCpuAbi)).getAbsolutePath();
8274            }
8275        }
8276    }
8277
8278    /**
8279     * Calculate the abis and roots for a bundled app. These can uniquely
8280     * be determined from the contents of the system partition, i.e whether
8281     * it contains 64 or 32 bit shared libraries etc. We do not validate any
8282     * of this information, and instead assume that the system was built
8283     * sensibly.
8284     */
8285    private void setBundledAppAbisAndRoots(PackageParser.Package pkg,
8286                                           PackageSetting pkgSetting) {
8287        final String apkName = deriveCodePathName(pkg.applicationInfo.getCodePath());
8288
8289        // If "/system/lib64/apkname" exists, assume that is the per-package
8290        // native library directory to use; otherwise use "/system/lib/apkname".
8291        final String apkRoot = calculateBundledApkRoot(pkg.applicationInfo.sourceDir);
8292        setBundledAppAbi(pkg, apkRoot, apkName);
8293        // pkgSetting might be null during rescan following uninstall of updates
8294        // to a bundled app, so accommodate that possibility.  The settings in
8295        // that case will be established later from the parsed package.
8296        //
8297        // If the settings aren't null, sync them up with what we've just derived.
8298        // note that apkRoot isn't stored in the package settings.
8299        if (pkgSetting != null) {
8300            pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
8301            pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
8302        }
8303    }
8304
8305    /**
8306     * Deduces the ABI of a bundled app and sets the relevant fields on the
8307     * parsed pkg object.
8308     *
8309     * @param apkRoot the root of the installed apk, something like {@code /system} or {@code /oem}
8310     *        under which system libraries are installed.
8311     * @param apkName the name of the installed package.
8312     */
8313    private static void setBundledAppAbi(PackageParser.Package pkg, String apkRoot, String apkName) {
8314        final File codeFile = new File(pkg.codePath);
8315
8316        final boolean has64BitLibs;
8317        final boolean has32BitLibs;
8318        if (isApkFile(codeFile)) {
8319            // Monolithic install
8320            has64BitLibs = (new File(apkRoot, new File(LIB64_DIR_NAME, apkName).getPath())).exists();
8321            has32BitLibs = (new File(apkRoot, new File(LIB_DIR_NAME, apkName).getPath())).exists();
8322        } else {
8323            // Cluster install
8324            final File rootDir = new File(codeFile, LIB_DIR_NAME);
8325            if (!ArrayUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS)
8326                    && !TextUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS[0])) {
8327                final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_64_BIT_ABIS[0]);
8328                has64BitLibs = (new File(rootDir, isa)).exists();
8329            } else {
8330                has64BitLibs = false;
8331            }
8332            if (!ArrayUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS)
8333                    && !TextUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS[0])) {
8334                final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_32_BIT_ABIS[0]);
8335                has32BitLibs = (new File(rootDir, isa)).exists();
8336            } else {
8337                has32BitLibs = false;
8338            }
8339        }
8340
8341        if (has64BitLibs && !has32BitLibs) {
8342            // The package has 64 bit libs, but not 32 bit libs. Its primary
8343            // ABI should be 64 bit. We can safely assume here that the bundled
8344            // native libraries correspond to the most preferred ABI in the list.
8345
8346            pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
8347            pkg.applicationInfo.secondaryCpuAbi = null;
8348        } else if (has32BitLibs && !has64BitLibs) {
8349            // The package has 32 bit libs but not 64 bit libs. Its primary
8350            // ABI should be 32 bit.
8351
8352            pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
8353            pkg.applicationInfo.secondaryCpuAbi = null;
8354        } else if (has32BitLibs && has64BitLibs) {
8355            // The application has both 64 and 32 bit bundled libraries. We check
8356            // here that the app declares multiArch support, and warn if it doesn't.
8357            //
8358            // We will be lenient here and record both ABIs. The primary will be the
8359            // ABI that's higher on the list, i.e, a device that's configured to prefer
8360            // 64 bit apps will see a 64 bit primary ABI,
8361
8362            if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) == 0) {
8363                Slog.e(TAG, "Package " + pkg + " has multiple bundled libs, but is not multiarch.");
8364            }
8365
8366            if (VMRuntime.is64BitInstructionSet(getPreferredInstructionSet())) {
8367                pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
8368                pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
8369            } else {
8370                pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
8371                pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
8372            }
8373        } else {
8374            pkg.applicationInfo.primaryCpuAbi = null;
8375            pkg.applicationInfo.secondaryCpuAbi = null;
8376        }
8377    }
8378
8379    private void killApplication(String pkgName, int appId, String reason) {
8380        // Request the ActivityManager to kill the process(only for existing packages)
8381        // so that we do not end up in a confused state while the user is still using the older
8382        // version of the application while the new one gets installed.
8383        IActivityManager am = ActivityManagerNative.getDefault();
8384        if (am != null) {
8385            try {
8386                am.killApplicationWithAppId(pkgName, appId, reason);
8387            } catch (RemoteException e) {
8388            }
8389        }
8390    }
8391
8392    void removePackageLI(PackageSetting ps, boolean chatty) {
8393        if (DEBUG_INSTALL) {
8394            if (chatty)
8395                Log.d(TAG, "Removing package " + ps.name);
8396        }
8397
8398        // writer
8399        synchronized (mPackages) {
8400            mPackages.remove(ps.name);
8401            final PackageParser.Package pkg = ps.pkg;
8402            if (pkg != null) {
8403                cleanPackageDataStructuresLILPw(pkg, chatty);
8404            }
8405        }
8406    }
8407
8408    void removeInstalledPackageLI(PackageParser.Package pkg, boolean chatty) {
8409        if (DEBUG_INSTALL) {
8410            if (chatty)
8411                Log.d(TAG, "Removing package " + pkg.applicationInfo.packageName);
8412        }
8413
8414        // writer
8415        synchronized (mPackages) {
8416            mPackages.remove(pkg.applicationInfo.packageName);
8417            cleanPackageDataStructuresLILPw(pkg, chatty);
8418        }
8419    }
8420
8421    void cleanPackageDataStructuresLILPw(PackageParser.Package pkg, boolean chatty) {
8422        int N = pkg.providers.size();
8423        StringBuilder r = null;
8424        int i;
8425        for (i=0; i<N; i++) {
8426            PackageParser.Provider p = pkg.providers.get(i);
8427            mProviders.removeProvider(p);
8428            if (p.info.authority == null) {
8429
8430                /* There was another ContentProvider with this authority when
8431                 * this app was installed so this authority is null,
8432                 * Ignore it as we don't have to unregister the provider.
8433                 */
8434                continue;
8435            }
8436            String names[] = p.info.authority.split(";");
8437            for (int j = 0; j < names.length; j++) {
8438                if (mProvidersByAuthority.get(names[j]) == p) {
8439                    mProvidersByAuthority.remove(names[j]);
8440                    if (DEBUG_REMOVE) {
8441                        if (chatty)
8442                            Log.d(TAG, "Unregistered content provider: " + names[j]
8443                                    + ", className = " + p.info.name + ", isSyncable = "
8444                                    + p.info.isSyncable);
8445                    }
8446                }
8447            }
8448            if (DEBUG_REMOVE && chatty) {
8449                if (r == null) {
8450                    r = new StringBuilder(256);
8451                } else {
8452                    r.append(' ');
8453                }
8454                r.append(p.info.name);
8455            }
8456        }
8457        if (r != null) {
8458            if (DEBUG_REMOVE) Log.d(TAG, "  Providers: " + r);
8459        }
8460
8461        N = pkg.services.size();
8462        r = null;
8463        for (i=0; i<N; i++) {
8464            PackageParser.Service s = pkg.services.get(i);
8465            mServices.removeService(s);
8466            if (chatty) {
8467                if (r == null) {
8468                    r = new StringBuilder(256);
8469                } else {
8470                    r.append(' ');
8471                }
8472                r.append(s.info.name);
8473            }
8474        }
8475        if (r != null) {
8476            if (DEBUG_REMOVE) Log.d(TAG, "  Services: " + r);
8477        }
8478
8479        N = pkg.receivers.size();
8480        r = null;
8481        for (i=0; i<N; i++) {
8482            PackageParser.Activity a = pkg.receivers.get(i);
8483            mReceivers.removeActivity(a, "receiver");
8484            if (DEBUG_REMOVE && chatty) {
8485                if (r == null) {
8486                    r = new StringBuilder(256);
8487                } else {
8488                    r.append(' ');
8489                }
8490                r.append(a.info.name);
8491            }
8492        }
8493        if (r != null) {
8494            if (DEBUG_REMOVE) Log.d(TAG, "  Receivers: " + r);
8495        }
8496
8497        N = pkg.activities.size();
8498        r = null;
8499        for (i=0; i<N; i++) {
8500            PackageParser.Activity a = pkg.activities.get(i);
8501            mActivities.removeActivity(a, "activity");
8502            if (DEBUG_REMOVE && chatty) {
8503                if (r == null) {
8504                    r = new StringBuilder(256);
8505                } else {
8506                    r.append(' ');
8507                }
8508                r.append(a.info.name);
8509            }
8510        }
8511        if (r != null) {
8512            if (DEBUG_REMOVE) Log.d(TAG, "  Activities: " + r);
8513        }
8514
8515        N = pkg.permissions.size();
8516        r = null;
8517        for (i=0; i<N; i++) {
8518            PackageParser.Permission p = pkg.permissions.get(i);
8519            BasePermission bp = mSettings.mPermissions.get(p.info.name);
8520            if (bp == null) {
8521                bp = mSettings.mPermissionTrees.get(p.info.name);
8522            }
8523            if (bp != null && bp.perm == p) {
8524                bp.perm = null;
8525                if (DEBUG_REMOVE && chatty) {
8526                    if (r == null) {
8527                        r = new StringBuilder(256);
8528                    } else {
8529                        r.append(' ');
8530                    }
8531                    r.append(p.info.name);
8532                }
8533            }
8534            if ((p.info.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
8535                ArraySet<String> appOpPkgs = mAppOpPermissionPackages.get(p.info.name);
8536                if (appOpPkgs != null) {
8537                    appOpPkgs.remove(pkg.packageName);
8538                }
8539            }
8540        }
8541        if (r != null) {
8542            if (DEBUG_REMOVE) Log.d(TAG, "  Permissions: " + r);
8543        }
8544
8545        N = pkg.requestedPermissions.size();
8546        r = null;
8547        for (i=0; i<N; i++) {
8548            String perm = pkg.requestedPermissions.get(i);
8549            BasePermission bp = mSettings.mPermissions.get(perm);
8550            if (bp != null && (bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
8551                ArraySet<String> appOpPkgs = mAppOpPermissionPackages.get(perm);
8552                if (appOpPkgs != null) {
8553                    appOpPkgs.remove(pkg.packageName);
8554                    if (appOpPkgs.isEmpty()) {
8555                        mAppOpPermissionPackages.remove(perm);
8556                    }
8557                }
8558            }
8559        }
8560        if (r != null) {
8561            if (DEBUG_REMOVE) Log.d(TAG, "  Permissions: " + r);
8562        }
8563
8564        N = pkg.instrumentation.size();
8565        r = null;
8566        for (i=0; i<N; i++) {
8567            PackageParser.Instrumentation a = pkg.instrumentation.get(i);
8568            mInstrumentation.remove(a.getComponentName());
8569            if (DEBUG_REMOVE && chatty) {
8570                if (r == null) {
8571                    r = new StringBuilder(256);
8572                } else {
8573                    r.append(' ');
8574                }
8575                r.append(a.info.name);
8576            }
8577        }
8578        if (r != null) {
8579            if (DEBUG_REMOVE) Log.d(TAG, "  Instrumentation: " + r);
8580        }
8581
8582        r = null;
8583        if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
8584            // Only system apps can hold shared libraries.
8585            if (pkg.libraryNames != null) {
8586                for (i=0; i<pkg.libraryNames.size(); i++) {
8587                    String name = pkg.libraryNames.get(i);
8588                    SharedLibraryEntry cur = mSharedLibraries.get(name);
8589                    if (cur != null && cur.apk != null && cur.apk.equals(pkg.packageName)) {
8590                        mSharedLibraries.remove(name);
8591                        if (DEBUG_REMOVE && chatty) {
8592                            if (r == null) {
8593                                r = new StringBuilder(256);
8594                            } else {
8595                                r.append(' ');
8596                            }
8597                            r.append(name);
8598                        }
8599                    }
8600                }
8601            }
8602        }
8603        if (r != null) {
8604            if (DEBUG_REMOVE) Log.d(TAG, "  Libraries: " + r);
8605        }
8606    }
8607
8608    private static boolean hasPermission(PackageParser.Package pkgInfo, String perm) {
8609        for (int i=pkgInfo.permissions.size()-1; i>=0; i--) {
8610            if (pkgInfo.permissions.get(i).info.name.equals(perm)) {
8611                return true;
8612            }
8613        }
8614        return false;
8615    }
8616
8617    static final int UPDATE_PERMISSIONS_ALL = 1<<0;
8618    static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1<<1;
8619    static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1<<2;
8620
8621    private void updatePermissionsLPw(String changingPkg, PackageParser.Package pkgInfo,
8622            int flags) {
8623        final String volumeUuid = (pkgInfo != null) ? getVolumeUuidForPackage(pkgInfo) : null;
8624        updatePermissionsLPw(changingPkg, pkgInfo, volumeUuid, flags);
8625    }
8626
8627    private void updatePermissionsLPw(String changingPkg,
8628            PackageParser.Package pkgInfo, String replaceVolumeUuid, int flags) {
8629        // Make sure there are no dangling permission trees.
8630        Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator();
8631        while (it.hasNext()) {
8632            final BasePermission bp = it.next();
8633            if (bp.packageSetting == null) {
8634                // We may not yet have parsed the package, so just see if
8635                // we still know about its settings.
8636                bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage);
8637            }
8638            if (bp.packageSetting == null) {
8639                Slog.w(TAG, "Removing dangling permission tree: " + bp.name
8640                        + " from package " + bp.sourcePackage);
8641                it.remove();
8642            } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) {
8643                if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
8644                    Slog.i(TAG, "Removing old permission tree: " + bp.name
8645                            + " from package " + bp.sourcePackage);
8646                    flags |= UPDATE_PERMISSIONS_ALL;
8647                    it.remove();
8648                }
8649            }
8650        }
8651
8652        // Make sure all dynamic permissions have been assigned to a package,
8653        // and make sure there are no dangling permissions.
8654        it = mSettings.mPermissions.values().iterator();
8655        while (it.hasNext()) {
8656            final BasePermission bp = it.next();
8657            if (bp.type == BasePermission.TYPE_DYNAMIC) {
8658                if (DEBUG_SETTINGS) Log.v(TAG, "Dynamic permission: name="
8659                        + bp.name + " pkg=" + bp.sourcePackage
8660                        + " info=" + bp.pendingInfo);
8661                if (bp.packageSetting == null && bp.pendingInfo != null) {
8662                    final BasePermission tree = findPermissionTreeLP(bp.name);
8663                    if (tree != null && tree.perm != null) {
8664                        bp.packageSetting = tree.packageSetting;
8665                        bp.perm = new PackageParser.Permission(tree.perm.owner,
8666                                new PermissionInfo(bp.pendingInfo));
8667                        bp.perm.info.packageName = tree.perm.info.packageName;
8668                        bp.perm.info.name = bp.name;
8669                        bp.uid = tree.uid;
8670                    }
8671                }
8672            }
8673            if (bp.packageSetting == null) {
8674                // We may not yet have parsed the package, so just see if
8675                // we still know about its settings.
8676                bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage);
8677            }
8678            if (bp.packageSetting == null) {
8679                Slog.w(TAG, "Removing dangling permission: " + bp.name
8680                        + " from package " + bp.sourcePackage);
8681                it.remove();
8682            } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) {
8683                if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
8684                    Slog.i(TAG, "Removing old permission: " + bp.name
8685                            + " from package " + bp.sourcePackage);
8686                    flags |= UPDATE_PERMISSIONS_ALL;
8687                    it.remove();
8688                }
8689            }
8690        }
8691
8692        // Now update the permissions for all packages, in particular
8693        // replace the granted permissions of the system packages.
8694        if ((flags&UPDATE_PERMISSIONS_ALL) != 0) {
8695            for (PackageParser.Package pkg : mPackages.values()) {
8696                if (pkg != pkgInfo) {
8697                    // Only replace for packages on requested volume
8698                    final String volumeUuid = getVolumeUuidForPackage(pkg);
8699                    final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_ALL) != 0)
8700                            && Objects.equals(replaceVolumeUuid, volumeUuid);
8701                    grantPermissionsLPw(pkg, replace, changingPkg);
8702                }
8703            }
8704        }
8705
8706        if (pkgInfo != null) {
8707            // Only replace for packages on requested volume
8708            final String volumeUuid = getVolumeUuidForPackage(pkgInfo);
8709            final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_PKG) != 0)
8710                    && Objects.equals(replaceVolumeUuid, volumeUuid);
8711            grantPermissionsLPw(pkgInfo, replace, changingPkg);
8712        }
8713    }
8714
8715    private void grantPermissionsLPw(PackageParser.Package pkg, boolean replace,
8716            String packageOfInterest) {
8717        // IMPORTANT: There are two types of permissions: install and runtime.
8718        // Install time permissions are granted when the app is installed to
8719        // all device users and users added in the future. Runtime permissions
8720        // are granted at runtime explicitly to specific users. Normal and signature
8721        // protected permissions are install time permissions. Dangerous permissions
8722        // are install permissions if the app's target SDK is Lollipop MR1 or older,
8723        // otherwise they are runtime permissions. This function does not manage
8724        // runtime permissions except for the case an app targeting Lollipop MR1
8725        // being upgraded to target a newer SDK, in which case dangerous permissions
8726        // are transformed from install time to runtime ones.
8727
8728        final PackageSetting ps = (PackageSetting) pkg.mExtras;
8729        if (ps == null) {
8730            return;
8731        }
8732
8733        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "grantPermissions");
8734
8735        PermissionsState permissionsState = ps.getPermissionsState();
8736        PermissionsState origPermissions = permissionsState;
8737
8738        final int[] currentUserIds = UserManagerService.getInstance().getUserIds();
8739
8740        boolean runtimePermissionsRevoked = false;
8741        int[] changedRuntimePermissionUserIds = EMPTY_INT_ARRAY;
8742
8743        boolean changedInstallPermission = false;
8744
8745        if (replace) {
8746            ps.installPermissionsFixed = false;
8747            if (!ps.isSharedUser()) {
8748                origPermissions = new PermissionsState(permissionsState);
8749                permissionsState.reset();
8750            } else {
8751                // We need to know only about runtime permission changes since the
8752                // calling code always writes the install permissions state but
8753                // the runtime ones are written only if changed. The only cases of
8754                // changed runtime permissions here are promotion of an install to
8755                // runtime and revocation of a runtime from a shared user.
8756                changedRuntimePermissionUserIds = revokeUnusedSharedUserPermissionsLPw(
8757                        ps.sharedUser, UserManagerService.getInstance().getUserIds());
8758                if (!ArrayUtils.isEmpty(changedRuntimePermissionUserIds)) {
8759                    runtimePermissionsRevoked = true;
8760                }
8761            }
8762        }
8763
8764        permissionsState.setGlobalGids(mGlobalGids);
8765
8766        final int N = pkg.requestedPermissions.size();
8767        for (int i=0; i<N; i++) {
8768            final String name = pkg.requestedPermissions.get(i);
8769            final BasePermission bp = mSettings.mPermissions.get(name);
8770
8771            if (DEBUG_INSTALL) {
8772                Log.i(TAG, "Package " + pkg.packageName + " checking " + name + ": " + bp);
8773            }
8774
8775            if (bp == null || bp.packageSetting == null) {
8776                if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) {
8777                    Slog.w(TAG, "Unknown permission " + name
8778                            + " in package " + pkg.packageName);
8779                }
8780                continue;
8781            }
8782
8783            final String perm = bp.name;
8784            boolean allowedSig = false;
8785            int grant = GRANT_DENIED;
8786
8787            // Keep track of app op permissions.
8788            if ((bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
8789                ArraySet<String> pkgs = mAppOpPermissionPackages.get(bp.name);
8790                if (pkgs == null) {
8791                    pkgs = new ArraySet<>();
8792                    mAppOpPermissionPackages.put(bp.name, pkgs);
8793                }
8794                pkgs.add(pkg.packageName);
8795            }
8796
8797            final int level = bp.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE;
8798            final boolean appSupportsRuntimePermissions = pkg.applicationInfo.targetSdkVersion
8799                    >= Build.VERSION_CODES.M;
8800            switch (level) {
8801                case PermissionInfo.PROTECTION_NORMAL: {
8802                    // For all apps normal permissions are install time ones.
8803                    grant = GRANT_INSTALL;
8804                } break;
8805
8806                case PermissionInfo.PROTECTION_DANGEROUS: {
8807                    // If a permission review is required for legacy apps we represent
8808                    // their permissions as always granted runtime ones since we need
8809                    // to keep the review required permission flag per user while an
8810                    // install permission's state is shared across all users.
8811                    if (!appSupportsRuntimePermissions && !Build.PERMISSIONS_REVIEW_REQUIRED) {
8812                        // For legacy apps dangerous permissions are install time ones.
8813                        grant = GRANT_INSTALL;
8814                    } else if (origPermissions.hasInstallPermission(bp.name)) {
8815                        // For legacy apps that became modern, install becomes runtime.
8816                        grant = GRANT_UPGRADE;
8817                    } else if (mPromoteSystemApps
8818                            && isSystemApp(ps)
8819                            && mExistingSystemPackages.contains(ps.name)) {
8820                        // For legacy system apps, install becomes runtime.
8821                        // We cannot check hasInstallPermission() for system apps since those
8822                        // permissions were granted implicitly and not persisted pre-M.
8823                        grant = GRANT_UPGRADE;
8824                    } else {
8825                        // For modern apps keep runtime permissions unchanged.
8826                        grant = GRANT_RUNTIME;
8827                    }
8828                } break;
8829
8830                case PermissionInfo.PROTECTION_SIGNATURE: {
8831                    // For all apps signature permissions are install time ones.
8832                    allowedSig = grantSignaturePermission(perm, pkg, bp, origPermissions);
8833                    if (allowedSig) {
8834                        grant = GRANT_INSTALL;
8835                    }
8836                } break;
8837            }
8838
8839            if (DEBUG_INSTALL) {
8840                Log.i(TAG, "Package " + pkg.packageName + " granting " + perm);
8841            }
8842
8843            if (grant != GRANT_DENIED) {
8844                if (!isSystemApp(ps) && ps.installPermissionsFixed) {
8845                    // If this is an existing, non-system package, then
8846                    // we can't add any new permissions to it.
8847                    if (!allowedSig && !origPermissions.hasInstallPermission(perm)) {
8848                        // Except...  if this is a permission that was added
8849                        // to the platform (note: need to only do this when
8850                        // updating the platform).
8851                        if (!isNewPlatformPermissionForPackage(perm, pkg)) {
8852                            grant = GRANT_DENIED;
8853                        }
8854                    }
8855                }
8856
8857                switch (grant) {
8858                    case GRANT_INSTALL: {
8859                        // Revoke this as runtime permission to handle the case of
8860                        // a runtime permission being downgraded to an install one. Also in permission review mode we keep dangerous permissions for legacy apps
8861                        for (int userId : UserManagerService.getInstance().getUserIds()) {
8862                            if (origPermissions.getRuntimePermissionState(
8863                                    bp.name, userId) != null) {
8864                                // Revoke the runtime permission and clear the flags.
8865                                origPermissions.revokeRuntimePermission(bp, userId);
8866                                origPermissions.updatePermissionFlags(bp, userId,
8867                                      PackageManager.MASK_PERMISSION_FLAGS, 0);
8868                                // If we revoked a permission permission, we have to write.
8869                                changedRuntimePermissionUserIds = ArrayUtils.appendInt(
8870                                        changedRuntimePermissionUserIds, userId);
8871                            }
8872                        }
8873                        // Grant an install permission.
8874                        if (permissionsState.grantInstallPermission(bp) !=
8875                                PermissionsState.PERMISSION_OPERATION_FAILURE) {
8876                            changedInstallPermission = true;
8877                        }
8878                    } break;
8879
8880                    case GRANT_RUNTIME: {
8881                        // Grant previously granted runtime permissions.
8882                        for (int userId : UserManagerService.getInstance().getUserIds()) {
8883                            PermissionState permissionState = origPermissions
8884                                    .getRuntimePermissionState(bp.name, userId);
8885                            int flags = permissionState != null
8886                                    ? permissionState.getFlags() : 0;
8887                            if (origPermissions.hasRuntimePermission(bp.name, userId)) {
8888                                if (permissionsState.grantRuntimePermission(bp, userId) ==
8889                                        PermissionsState.PERMISSION_OPERATION_FAILURE) {
8890                                    // If we cannot put the permission as it was, we have to write.
8891                                    changedRuntimePermissionUserIds = ArrayUtils.appendInt(
8892                                            changedRuntimePermissionUserIds, userId);
8893                                }
8894                                // If the app supports runtime permissions no need for a review.
8895                                if (Build.PERMISSIONS_REVIEW_REQUIRED
8896                                        && appSupportsRuntimePermissions
8897                                        && (flags & PackageManager
8898                                                .FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
8899                                    flags &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
8900                                    // Since we changed the flags, we have to write.
8901                                    changedRuntimePermissionUserIds = ArrayUtils.appendInt(
8902                                            changedRuntimePermissionUserIds, userId);
8903                                }
8904                            } else if (Build.PERMISSIONS_REVIEW_REQUIRED
8905                                    && !appSupportsRuntimePermissions) {
8906                                // For legacy apps that need a permission review, every new
8907                                // runtime permission is granted but it is pending a review.
8908                                if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) {
8909                                    permissionsState.grantRuntimePermission(bp, userId);
8910                                    flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
8911                                    // We changed the permission and flags, hence have to write.
8912                                    changedRuntimePermissionUserIds = ArrayUtils.appendInt(
8913                                            changedRuntimePermissionUserIds, userId);
8914                                }
8915                            }
8916                            // Propagate the permission flags.
8917                            permissionsState.updatePermissionFlags(bp, userId, flags, flags);
8918                        }
8919                    } break;
8920
8921                    case GRANT_UPGRADE: {
8922                        // Grant runtime permissions for a previously held install permission.
8923                        PermissionState permissionState = origPermissions
8924                                .getInstallPermissionState(bp.name);
8925                        final int flags = permissionState != null ? permissionState.getFlags() : 0;
8926
8927                        if (origPermissions.revokeInstallPermission(bp)
8928                                != PermissionsState.PERMISSION_OPERATION_FAILURE) {
8929                            // We will be transferring the permission flags, so clear them.
8930                            origPermissions.updatePermissionFlags(bp, UserHandle.USER_ALL,
8931                                    PackageManager.MASK_PERMISSION_FLAGS, 0);
8932                            changedInstallPermission = true;
8933                        }
8934
8935                        // If the permission is not to be promoted to runtime we ignore it and
8936                        // also its other flags as they are not applicable to install permissions.
8937                        if ((flags & PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE) == 0) {
8938                            for (int userId : currentUserIds) {
8939                                if (permissionsState.grantRuntimePermission(bp, userId) !=
8940                                        PermissionsState.PERMISSION_OPERATION_FAILURE) {
8941                                    // Transfer the permission flags.
8942                                    permissionsState.updatePermissionFlags(bp, userId,
8943                                            flags, flags);
8944                                    // If we granted the permission, we have to write.
8945                                    changedRuntimePermissionUserIds = ArrayUtils.appendInt(
8946                                            changedRuntimePermissionUserIds, userId);
8947                                }
8948                            }
8949                        }
8950                    } break;
8951
8952                    default: {
8953                        if (packageOfInterest == null
8954                                || packageOfInterest.equals(pkg.packageName)) {
8955                            Slog.w(TAG, "Not granting permission " + perm
8956                                    + " to package " + pkg.packageName
8957                                    + " because it was previously installed without");
8958                        }
8959                    } break;
8960                }
8961            } else {
8962                if (permissionsState.revokeInstallPermission(bp) !=
8963                        PermissionsState.PERMISSION_OPERATION_FAILURE) {
8964                    // Also drop the permission flags.
8965                    permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
8966                            PackageManager.MASK_PERMISSION_FLAGS, 0);
8967                    changedInstallPermission = true;
8968                    Slog.i(TAG, "Un-granting permission " + perm
8969                            + " from package " + pkg.packageName
8970                            + " (protectionLevel=" + bp.protectionLevel
8971                            + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
8972                            + ")");
8973                } else if ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) == 0) {
8974                    // Don't print warning for app op permissions, since it is fine for them
8975                    // not to be granted, there is a UI for the user to decide.
8976                    if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) {
8977                        Slog.w(TAG, "Not granting permission " + perm
8978                                + " to package " + pkg.packageName
8979                                + " (protectionLevel=" + bp.protectionLevel
8980                                + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
8981                                + ")");
8982                    }
8983                }
8984            }
8985        }
8986
8987        if ((changedInstallPermission || replace) && !ps.installPermissionsFixed &&
8988                !isSystemApp(ps) || isUpdatedSystemApp(ps)){
8989            // This is the first that we have heard about this package, so the
8990            // permissions we have now selected are fixed until explicitly
8991            // changed.
8992            ps.installPermissionsFixed = true;
8993        }
8994
8995        // Persist the runtime permissions state for users with changes. If permissions
8996        // were revoked because no app in the shared user declares them we have to
8997        // write synchronously to avoid losing runtime permissions state.
8998        for (int userId : changedRuntimePermissionUserIds) {
8999            mSettings.writeRuntimePermissionsForUserLPr(userId, runtimePermissionsRevoked);
9000        }
9001
9002        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9003    }
9004
9005    private boolean isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg) {
9006        boolean allowed = false;
9007        final int NP = PackageParser.NEW_PERMISSIONS.length;
9008        for (int ip=0; ip<NP; ip++) {
9009            final PackageParser.NewPermissionInfo npi
9010                    = PackageParser.NEW_PERMISSIONS[ip];
9011            if (npi.name.equals(perm)
9012                    && pkg.applicationInfo.targetSdkVersion < npi.sdkVersion) {
9013                allowed = true;
9014                Log.i(TAG, "Auto-granting " + perm + " to old pkg "
9015                        + pkg.packageName);
9016                break;
9017            }
9018        }
9019        return allowed;
9020    }
9021
9022    private boolean grantSignaturePermission(String perm, PackageParser.Package pkg,
9023            BasePermission bp, PermissionsState origPermissions) {
9024        boolean allowed;
9025        allowed = (compareSignatures(
9026                bp.packageSetting.signatures.mSignatures, pkg.mSignatures)
9027                        == PackageManager.SIGNATURE_MATCH)
9028                || (compareSignatures(mPlatformPackage.mSignatures, pkg.mSignatures)
9029                        == PackageManager.SIGNATURE_MATCH);
9030        if (!allowed && (bp.protectionLevel
9031                & PermissionInfo.PROTECTION_FLAG_PRIVILEGED) != 0) {
9032            if (isSystemApp(pkg)) {
9033                // For updated system applications, a system permission
9034                // is granted only if it had been defined by the original application.
9035                if (pkg.isUpdatedSystemApp()) {
9036                    final PackageSetting sysPs = mSettings
9037                            .getDisabledSystemPkgLPr(pkg.packageName);
9038                    if (sysPs.getPermissionsState().hasInstallPermission(perm)) {
9039                        // If the original was granted this permission, we take
9040                        // that grant decision as read and propagate it to the
9041                        // update.
9042                        if (sysPs.isPrivileged()) {
9043                            allowed = true;
9044                        }
9045                    } else {
9046                        // The system apk may have been updated with an older
9047                        // version of the one on the data partition, but which
9048                        // granted a new system permission that it didn't have
9049                        // before.  In this case we do want to allow the app to
9050                        // now get the new permission if the ancestral apk is
9051                        // privileged to get it.
9052                        if (sysPs.pkg != null && sysPs.isPrivileged()) {
9053                            for (int j=0;
9054                                    j<sysPs.pkg.requestedPermissions.size(); j++) {
9055                                if (perm.equals(
9056                                        sysPs.pkg.requestedPermissions.get(j))) {
9057                                    allowed = true;
9058                                    break;
9059                                }
9060                            }
9061                        }
9062                    }
9063                } else {
9064                    allowed = isPrivilegedApp(pkg);
9065                }
9066            }
9067        }
9068        if (!allowed) {
9069            if (!allowed && (bp.protectionLevel
9070                    & PermissionInfo.PROTECTION_FLAG_PRE23) != 0
9071                    && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
9072                // If this was a previously normal/dangerous permission that got moved
9073                // to a system permission as part of the runtime permission redesign, then
9074                // we still want to blindly grant it to old apps.
9075                allowed = true;
9076            }
9077            if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_INSTALLER) != 0
9078                    && pkg.packageName.equals(mRequiredInstallerPackage)) {
9079                // If this permission is to be granted to the system installer and
9080                // this app is an installer, then it gets the permission.
9081                allowed = true;
9082            }
9083            if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_VERIFIER) != 0
9084                    && pkg.packageName.equals(mRequiredVerifierPackage)) {
9085                // If this permission is to be granted to the system verifier and
9086                // this app is a verifier, then it gets the permission.
9087                allowed = true;
9088            }
9089            if (!allowed && (bp.protectionLevel
9090                    & PermissionInfo.PROTECTION_FLAG_PREINSTALLED) != 0
9091                    && isSystemApp(pkg)) {
9092                // Any pre-installed system app is allowed to get this permission.
9093                allowed = true;
9094            }
9095            if (!allowed && (bp.protectionLevel
9096                    & PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0) {
9097                // For development permissions, a development permission
9098                // is granted only if it was already granted.
9099                allowed = origPermissions.hasInstallPermission(perm);
9100            }
9101        }
9102        return allowed;
9103    }
9104
9105    final class ActivityIntentResolver
9106            extends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo> {
9107        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
9108                boolean defaultOnly, int userId) {
9109            if (!sUserManager.exists(userId)) return null;
9110            mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
9111            return super.queryIntent(intent, resolvedType, defaultOnly, userId);
9112        }
9113
9114        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
9115                int userId) {
9116            if (!sUserManager.exists(userId)) return null;
9117            mFlags = flags;
9118            return super.queryIntent(intent, resolvedType,
9119                    (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId);
9120        }
9121
9122        public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
9123                int flags, ArrayList<PackageParser.Activity> packageActivities, int userId) {
9124            if (!sUserManager.exists(userId)) return null;
9125            if (packageActivities == null) {
9126                return null;
9127            }
9128            mFlags = flags;
9129            final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0;
9130            final int N = packageActivities.size();
9131            ArrayList<PackageParser.ActivityIntentInfo[]> listCut =
9132                new ArrayList<PackageParser.ActivityIntentInfo[]>(N);
9133
9134            ArrayList<PackageParser.ActivityIntentInfo> intentFilters;
9135            for (int i = 0; i < N; ++i) {
9136                intentFilters = packageActivities.get(i).intents;
9137                if (intentFilters != null && intentFilters.size() > 0) {
9138                    PackageParser.ActivityIntentInfo[] array =
9139                            new PackageParser.ActivityIntentInfo[intentFilters.size()];
9140                    intentFilters.toArray(array);
9141                    listCut.add(array);
9142                }
9143            }
9144            return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
9145        }
9146
9147        public final void addActivity(PackageParser.Activity a, String type) {
9148            final boolean systemApp = a.info.applicationInfo.isSystemApp();
9149            mActivities.put(a.getComponentName(), a);
9150            if (DEBUG_SHOW_INFO)
9151                Log.v(
9152                TAG, "  " + type + " " +
9153                (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel : a.info.name) + ":");
9154            if (DEBUG_SHOW_INFO)
9155                Log.v(TAG, "    Class=" + a.info.name);
9156            final int NI = a.intents.size();
9157            for (int j=0; j<NI; j++) {
9158                PackageParser.ActivityIntentInfo intent = a.intents.get(j);
9159                if (!systemApp && intent.getPriority() > 0 && "activity".equals(type)) {
9160                    intent.setPriority(0);
9161                    Log.w(TAG, "Package " + a.info.applicationInfo.packageName + " has activity "
9162                            + a.className + " with priority > 0, forcing to 0");
9163                }
9164                if (DEBUG_SHOW_INFO) {
9165                    Log.v(TAG, "    IntentFilter:");
9166                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
9167                }
9168                if (!intent.debugCheck()) {
9169                    Log.w(TAG, "==> For Activity " + a.info.name);
9170                }
9171                addFilter(intent);
9172            }
9173        }
9174
9175        public final void removeActivity(PackageParser.Activity a, String type) {
9176            mActivities.remove(a.getComponentName());
9177            if (DEBUG_SHOW_INFO) {
9178                Log.v(TAG, "  " + type + " "
9179                        + (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel
9180                                : a.info.name) + ":");
9181                Log.v(TAG, "    Class=" + a.info.name);
9182            }
9183            final int NI = a.intents.size();
9184            for (int j=0; j<NI; j++) {
9185                PackageParser.ActivityIntentInfo intent = a.intents.get(j);
9186                if (DEBUG_SHOW_INFO) {
9187                    Log.v(TAG, "    IntentFilter:");
9188                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
9189                }
9190                removeFilter(intent);
9191            }
9192        }
9193
9194        @Override
9195        protected boolean allowFilterResult(
9196                PackageParser.ActivityIntentInfo filter, List<ResolveInfo> dest) {
9197            ActivityInfo filterAi = filter.activity.info;
9198            for (int i=dest.size()-1; i>=0; i--) {
9199                ActivityInfo destAi = dest.get(i).activityInfo;
9200                if (destAi.name == filterAi.name
9201                        && destAi.packageName == filterAi.packageName) {
9202                    return false;
9203                }
9204            }
9205            return true;
9206        }
9207
9208        @Override
9209        protected ActivityIntentInfo[] newArray(int size) {
9210            return new ActivityIntentInfo[size];
9211        }
9212
9213        @Override
9214        protected boolean isFilterStopped(PackageParser.ActivityIntentInfo filter, int userId) {
9215            if (!sUserManager.exists(userId)) return true;
9216            PackageParser.Package p = filter.activity.owner;
9217            if (p != null) {
9218                PackageSetting ps = (PackageSetting)p.mExtras;
9219                if (ps != null) {
9220                    // System apps are never considered stopped for purposes of
9221                    // filtering, because there may be no way for the user to
9222                    // actually re-launch them.
9223                    return (ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0
9224                            && ps.getStopped(userId);
9225                }
9226            }
9227            return false;
9228        }
9229
9230        @Override
9231        protected boolean isPackageForFilter(String packageName,
9232                PackageParser.ActivityIntentInfo info) {
9233            return packageName.equals(info.activity.owner.packageName);
9234        }
9235
9236        @Override
9237        protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info,
9238                int match, int userId) {
9239            if (!sUserManager.exists(userId)) return null;
9240            if (!mSettings.isEnabledAndMatchLPr(info.activity.info, mFlags, userId)) {
9241                return null;
9242            }
9243            final PackageParser.Activity activity = info.activity;
9244            if (mSafeMode && (activity.info.applicationInfo.flags
9245                    &ApplicationInfo.FLAG_SYSTEM) == 0) {
9246                return null;
9247            }
9248            PackageSetting ps = (PackageSetting) activity.owner.mExtras;
9249            if (ps == null) {
9250                return null;
9251            }
9252            ActivityInfo ai = PackageParser.generateActivityInfo(activity, mFlags,
9253                    ps.readUserState(userId), userId);
9254            if (ai == null) {
9255                return null;
9256            }
9257            final ResolveInfo res = new ResolveInfo();
9258            res.activityInfo = ai;
9259            if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
9260                res.filter = info;
9261            }
9262            if (info != null) {
9263                res.handleAllWebDataURI = info.handleAllWebDataURI();
9264            }
9265            res.priority = info.getPriority();
9266            res.preferredOrder = activity.owner.mPreferredOrder;
9267            //System.out.println("Result: " + res.activityInfo.className +
9268            //                   " = " + res.priority);
9269            res.match = match;
9270            res.isDefault = info.hasDefault;
9271            res.labelRes = info.labelRes;
9272            res.nonLocalizedLabel = info.nonLocalizedLabel;
9273            if (userNeedsBadging(userId)) {
9274                res.noResourceId = true;
9275            } else {
9276                res.icon = info.icon;
9277            }
9278            res.iconResourceId = info.icon;
9279            res.system = res.activityInfo.applicationInfo.isSystemApp();
9280            return res;
9281        }
9282
9283        @Override
9284        protected void sortResults(List<ResolveInfo> results) {
9285            Collections.sort(results, mResolvePrioritySorter);
9286        }
9287
9288        @Override
9289        protected void dumpFilter(PrintWriter out, String prefix,
9290                PackageParser.ActivityIntentInfo filter) {
9291            out.print(prefix); out.print(
9292                    Integer.toHexString(System.identityHashCode(filter.activity)));
9293                    out.print(' ');
9294                    filter.activity.printComponentShortName(out);
9295                    out.print(" filter ");
9296                    out.println(Integer.toHexString(System.identityHashCode(filter)));
9297        }
9298
9299        @Override
9300        protected Object filterToLabel(PackageParser.ActivityIntentInfo filter) {
9301            return filter.activity;
9302        }
9303
9304        protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
9305            PackageParser.Activity activity = (PackageParser.Activity)label;
9306            out.print(prefix); out.print(
9307                    Integer.toHexString(System.identityHashCode(activity)));
9308                    out.print(' ');
9309                    activity.printComponentShortName(out);
9310            if (count > 1) {
9311                out.print(" ("); out.print(count); out.print(" filters)");
9312            }
9313            out.println();
9314        }
9315
9316//        List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) {
9317//            final Iterator<ResolveInfo> i = resolveInfoList.iterator();
9318//            final List<ResolveInfo> retList = Lists.newArrayList();
9319//            while (i.hasNext()) {
9320//                final ResolveInfo resolveInfo = i.next();
9321//                if (isEnabledLP(resolveInfo.activityInfo)) {
9322//                    retList.add(resolveInfo);
9323//                }
9324//            }
9325//            return retList;
9326//        }
9327
9328        // Keys are String (activity class name), values are Activity.
9329        private final ArrayMap<ComponentName, PackageParser.Activity> mActivities
9330                = new ArrayMap<ComponentName, PackageParser.Activity>();
9331        private int mFlags;
9332    }
9333
9334    private final class ServiceIntentResolver
9335            extends IntentResolver<PackageParser.ServiceIntentInfo, ResolveInfo> {
9336        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
9337                boolean defaultOnly, int userId) {
9338            mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
9339            return super.queryIntent(intent, resolvedType, defaultOnly, userId);
9340        }
9341
9342        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
9343                int userId) {
9344            if (!sUserManager.exists(userId)) return null;
9345            mFlags = flags;
9346            return super.queryIntent(intent, resolvedType,
9347                    (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId);
9348        }
9349
9350        public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
9351                int flags, ArrayList<PackageParser.Service> packageServices, int userId) {
9352            if (!sUserManager.exists(userId)) return null;
9353            if (packageServices == null) {
9354                return null;
9355            }
9356            mFlags = flags;
9357            final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0;
9358            final int N = packageServices.size();
9359            ArrayList<PackageParser.ServiceIntentInfo[]> listCut =
9360                new ArrayList<PackageParser.ServiceIntentInfo[]>(N);
9361
9362            ArrayList<PackageParser.ServiceIntentInfo> intentFilters;
9363            for (int i = 0; i < N; ++i) {
9364                intentFilters = packageServices.get(i).intents;
9365                if (intentFilters != null && intentFilters.size() > 0) {
9366                    PackageParser.ServiceIntentInfo[] array =
9367                            new PackageParser.ServiceIntentInfo[intentFilters.size()];
9368                    intentFilters.toArray(array);
9369                    listCut.add(array);
9370                }
9371            }
9372            return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
9373        }
9374
9375        public final void addService(PackageParser.Service s) {
9376            mServices.put(s.getComponentName(), s);
9377            if (DEBUG_SHOW_INFO) {
9378                Log.v(TAG, "  "
9379                        + (s.info.nonLocalizedLabel != null
9380                        ? s.info.nonLocalizedLabel : s.info.name) + ":");
9381                Log.v(TAG, "    Class=" + s.info.name);
9382            }
9383            final int NI = s.intents.size();
9384            int j;
9385            for (j=0; j<NI; j++) {
9386                PackageParser.ServiceIntentInfo intent = s.intents.get(j);
9387                if (DEBUG_SHOW_INFO) {
9388                    Log.v(TAG, "    IntentFilter:");
9389                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
9390                }
9391                if (!intent.debugCheck()) {
9392                    Log.w(TAG, "==> For Service " + s.info.name);
9393                }
9394                addFilter(intent);
9395            }
9396        }
9397
9398        public final void removeService(PackageParser.Service s) {
9399            mServices.remove(s.getComponentName());
9400            if (DEBUG_SHOW_INFO) {
9401                Log.v(TAG, "  " + (s.info.nonLocalizedLabel != null
9402                        ? s.info.nonLocalizedLabel : s.info.name) + ":");
9403                Log.v(TAG, "    Class=" + s.info.name);
9404            }
9405            final int NI = s.intents.size();
9406            int j;
9407            for (j=0; j<NI; j++) {
9408                PackageParser.ServiceIntentInfo intent = s.intents.get(j);
9409                if (DEBUG_SHOW_INFO) {
9410                    Log.v(TAG, "    IntentFilter:");
9411                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
9412                }
9413                removeFilter(intent);
9414            }
9415        }
9416
9417        @Override
9418        protected boolean allowFilterResult(
9419                PackageParser.ServiceIntentInfo filter, List<ResolveInfo> dest) {
9420            ServiceInfo filterSi = filter.service.info;
9421            for (int i=dest.size()-1; i>=0; i--) {
9422                ServiceInfo destAi = dest.get(i).serviceInfo;
9423                if (destAi.name == filterSi.name
9424                        && destAi.packageName == filterSi.packageName) {
9425                    return false;
9426                }
9427            }
9428            return true;
9429        }
9430
9431        @Override
9432        protected PackageParser.ServiceIntentInfo[] newArray(int size) {
9433            return new PackageParser.ServiceIntentInfo[size];
9434        }
9435
9436        @Override
9437        protected boolean isFilterStopped(PackageParser.ServiceIntentInfo filter, int userId) {
9438            if (!sUserManager.exists(userId)) return true;
9439            PackageParser.Package p = filter.service.owner;
9440            if (p != null) {
9441                PackageSetting ps = (PackageSetting)p.mExtras;
9442                if (ps != null) {
9443                    // System apps are never considered stopped for purposes of
9444                    // filtering, because there may be no way for the user to
9445                    // actually re-launch them.
9446                    return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
9447                            && ps.getStopped(userId);
9448                }
9449            }
9450            return false;
9451        }
9452
9453        @Override
9454        protected boolean isPackageForFilter(String packageName,
9455                PackageParser.ServiceIntentInfo info) {
9456            return packageName.equals(info.service.owner.packageName);
9457        }
9458
9459        @Override
9460        protected ResolveInfo newResult(PackageParser.ServiceIntentInfo filter,
9461                int match, int userId) {
9462            if (!sUserManager.exists(userId)) return null;
9463            final PackageParser.ServiceIntentInfo info = (PackageParser.ServiceIntentInfo)filter;
9464            if (!mSettings.isEnabledAndMatchLPr(info.service.info, mFlags, userId)) {
9465                return null;
9466            }
9467            final PackageParser.Service service = info.service;
9468            if (mSafeMode && (service.info.applicationInfo.flags
9469                    &ApplicationInfo.FLAG_SYSTEM) == 0) {
9470                return null;
9471            }
9472            PackageSetting ps = (PackageSetting) service.owner.mExtras;
9473            if (ps == null) {
9474                return null;
9475            }
9476            ServiceInfo si = PackageParser.generateServiceInfo(service, mFlags,
9477                    ps.readUserState(userId), userId);
9478            if (si == null) {
9479                return null;
9480            }
9481            final ResolveInfo res = new ResolveInfo();
9482            res.serviceInfo = si;
9483            if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
9484                res.filter = filter;
9485            }
9486            res.priority = info.getPriority();
9487            res.preferredOrder = service.owner.mPreferredOrder;
9488            res.match = match;
9489            res.isDefault = info.hasDefault;
9490            res.labelRes = info.labelRes;
9491            res.nonLocalizedLabel = info.nonLocalizedLabel;
9492            res.icon = info.icon;
9493            res.system = res.serviceInfo.applicationInfo.isSystemApp();
9494            return res;
9495        }
9496
9497        @Override
9498        protected void sortResults(List<ResolveInfo> results) {
9499            Collections.sort(results, mResolvePrioritySorter);
9500        }
9501
9502        @Override
9503        protected void dumpFilter(PrintWriter out, String prefix,
9504                PackageParser.ServiceIntentInfo filter) {
9505            out.print(prefix); out.print(
9506                    Integer.toHexString(System.identityHashCode(filter.service)));
9507                    out.print(' ');
9508                    filter.service.printComponentShortName(out);
9509                    out.print(" filter ");
9510                    out.println(Integer.toHexString(System.identityHashCode(filter)));
9511        }
9512
9513        @Override
9514        protected Object filterToLabel(PackageParser.ServiceIntentInfo filter) {
9515            return filter.service;
9516        }
9517
9518        protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
9519            PackageParser.Service service = (PackageParser.Service)label;
9520            out.print(prefix); out.print(
9521                    Integer.toHexString(System.identityHashCode(service)));
9522                    out.print(' ');
9523                    service.printComponentShortName(out);
9524            if (count > 1) {
9525                out.print(" ("); out.print(count); out.print(" filters)");
9526            }
9527            out.println();
9528        }
9529
9530//        List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) {
9531//            final Iterator<ResolveInfo> i = resolveInfoList.iterator();
9532//            final List<ResolveInfo> retList = Lists.newArrayList();
9533//            while (i.hasNext()) {
9534//                final ResolveInfo resolveInfo = (ResolveInfo) i;
9535//                if (isEnabledLP(resolveInfo.serviceInfo)) {
9536//                    retList.add(resolveInfo);
9537//                }
9538//            }
9539//            return retList;
9540//        }
9541
9542        // Keys are String (activity class name), values are Activity.
9543        private final ArrayMap<ComponentName, PackageParser.Service> mServices
9544                = new ArrayMap<ComponentName, PackageParser.Service>();
9545        private int mFlags;
9546    };
9547
9548    private final class ProviderIntentResolver
9549            extends IntentResolver<PackageParser.ProviderIntentInfo, ResolveInfo> {
9550        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
9551                boolean defaultOnly, int userId) {
9552            mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
9553            return super.queryIntent(intent, resolvedType, defaultOnly, userId);
9554        }
9555
9556        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
9557                int userId) {
9558            if (!sUserManager.exists(userId))
9559                return null;
9560            mFlags = flags;
9561            return super.queryIntent(intent, resolvedType,
9562                    (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId);
9563        }
9564
9565        public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
9566                int flags, ArrayList<PackageParser.Provider> packageProviders, int userId) {
9567            if (!sUserManager.exists(userId))
9568                return null;
9569            if (packageProviders == null) {
9570                return null;
9571            }
9572            mFlags = flags;
9573            final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0;
9574            final int N = packageProviders.size();
9575            ArrayList<PackageParser.ProviderIntentInfo[]> listCut =
9576                    new ArrayList<PackageParser.ProviderIntentInfo[]>(N);
9577
9578            ArrayList<PackageParser.ProviderIntentInfo> intentFilters;
9579            for (int i = 0; i < N; ++i) {
9580                intentFilters = packageProviders.get(i).intents;
9581                if (intentFilters != null && intentFilters.size() > 0) {
9582                    PackageParser.ProviderIntentInfo[] array =
9583                            new PackageParser.ProviderIntentInfo[intentFilters.size()];
9584                    intentFilters.toArray(array);
9585                    listCut.add(array);
9586                }
9587            }
9588            return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
9589        }
9590
9591        public final void addProvider(PackageParser.Provider p) {
9592            if (mProviders.containsKey(p.getComponentName())) {
9593                Slog.w(TAG, "Provider " + p.getComponentName() + " already defined; ignoring");
9594                return;
9595            }
9596
9597            mProviders.put(p.getComponentName(), p);
9598            if (DEBUG_SHOW_INFO) {
9599                Log.v(TAG, "  "
9600                        + (p.info.nonLocalizedLabel != null
9601                                ? p.info.nonLocalizedLabel : p.info.name) + ":");
9602                Log.v(TAG, "    Class=" + p.info.name);
9603            }
9604            final int NI = p.intents.size();
9605            int j;
9606            for (j = 0; j < NI; j++) {
9607                PackageParser.ProviderIntentInfo intent = p.intents.get(j);
9608                if (DEBUG_SHOW_INFO) {
9609                    Log.v(TAG, "    IntentFilter:");
9610                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
9611                }
9612                if (!intent.debugCheck()) {
9613                    Log.w(TAG, "==> For Provider " + p.info.name);
9614                }
9615                addFilter(intent);
9616            }
9617        }
9618
9619        public final void removeProvider(PackageParser.Provider p) {
9620            mProviders.remove(p.getComponentName());
9621            if (DEBUG_SHOW_INFO) {
9622                Log.v(TAG, "  " + (p.info.nonLocalizedLabel != null
9623                        ? p.info.nonLocalizedLabel : p.info.name) + ":");
9624                Log.v(TAG, "    Class=" + p.info.name);
9625            }
9626            final int NI = p.intents.size();
9627            int j;
9628            for (j = 0; j < NI; j++) {
9629                PackageParser.ProviderIntentInfo intent = p.intents.get(j);
9630                if (DEBUG_SHOW_INFO) {
9631                    Log.v(TAG, "    IntentFilter:");
9632                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
9633                }
9634                removeFilter(intent);
9635            }
9636        }
9637
9638        @Override
9639        protected boolean allowFilterResult(
9640                PackageParser.ProviderIntentInfo filter, List<ResolveInfo> dest) {
9641            ProviderInfo filterPi = filter.provider.info;
9642            for (int i = dest.size() - 1; i >= 0; i--) {
9643                ProviderInfo destPi = dest.get(i).providerInfo;
9644                if (destPi.name == filterPi.name
9645                        && destPi.packageName == filterPi.packageName) {
9646                    return false;
9647                }
9648            }
9649            return true;
9650        }
9651
9652        @Override
9653        protected PackageParser.ProviderIntentInfo[] newArray(int size) {
9654            return new PackageParser.ProviderIntentInfo[size];
9655        }
9656
9657        @Override
9658        protected boolean isFilterStopped(PackageParser.ProviderIntentInfo filter, int userId) {
9659            if (!sUserManager.exists(userId))
9660                return true;
9661            PackageParser.Package p = filter.provider.owner;
9662            if (p != null) {
9663                PackageSetting ps = (PackageSetting) p.mExtras;
9664                if (ps != null) {
9665                    // System apps are never considered stopped for purposes of
9666                    // filtering, because there may be no way for the user to
9667                    // actually re-launch them.
9668                    return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
9669                            && ps.getStopped(userId);
9670                }
9671            }
9672            return false;
9673        }
9674
9675        @Override
9676        protected boolean isPackageForFilter(String packageName,
9677                PackageParser.ProviderIntentInfo info) {
9678            return packageName.equals(info.provider.owner.packageName);
9679        }
9680
9681        @Override
9682        protected ResolveInfo newResult(PackageParser.ProviderIntentInfo filter,
9683                int match, int userId) {
9684            if (!sUserManager.exists(userId))
9685                return null;
9686            final PackageParser.ProviderIntentInfo info = filter;
9687            if (!mSettings.isEnabledAndMatchLPr(info.provider.info, mFlags, userId)) {
9688                return null;
9689            }
9690            final PackageParser.Provider provider = info.provider;
9691            if (mSafeMode && (provider.info.applicationInfo.flags
9692                    & ApplicationInfo.FLAG_SYSTEM) == 0) {
9693                return null;
9694            }
9695            PackageSetting ps = (PackageSetting) provider.owner.mExtras;
9696            if (ps == null) {
9697                return null;
9698            }
9699            ProviderInfo pi = PackageParser.generateProviderInfo(provider, mFlags,
9700                    ps.readUserState(userId), userId);
9701            if (pi == null) {
9702                return null;
9703            }
9704            final ResolveInfo res = new ResolveInfo();
9705            res.providerInfo = pi;
9706            if ((mFlags & PackageManager.GET_RESOLVED_FILTER) != 0) {
9707                res.filter = filter;
9708            }
9709            res.priority = info.getPriority();
9710            res.preferredOrder = provider.owner.mPreferredOrder;
9711            res.match = match;
9712            res.isDefault = info.hasDefault;
9713            res.labelRes = info.labelRes;
9714            res.nonLocalizedLabel = info.nonLocalizedLabel;
9715            res.icon = info.icon;
9716            res.system = res.providerInfo.applicationInfo.isSystemApp();
9717            return res;
9718        }
9719
9720        @Override
9721        protected void sortResults(List<ResolveInfo> results) {
9722            Collections.sort(results, mResolvePrioritySorter);
9723        }
9724
9725        @Override
9726        protected void dumpFilter(PrintWriter out, String prefix,
9727                PackageParser.ProviderIntentInfo filter) {
9728            out.print(prefix);
9729            out.print(
9730                    Integer.toHexString(System.identityHashCode(filter.provider)));
9731            out.print(' ');
9732            filter.provider.printComponentShortName(out);
9733            out.print(" filter ");
9734            out.println(Integer.toHexString(System.identityHashCode(filter)));
9735        }
9736
9737        @Override
9738        protected Object filterToLabel(PackageParser.ProviderIntentInfo filter) {
9739            return filter.provider;
9740        }
9741
9742        protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
9743            PackageParser.Provider provider = (PackageParser.Provider)label;
9744            out.print(prefix); out.print(
9745                    Integer.toHexString(System.identityHashCode(provider)));
9746                    out.print(' ');
9747                    provider.printComponentShortName(out);
9748            if (count > 1) {
9749                out.print(" ("); out.print(count); out.print(" filters)");
9750            }
9751            out.println();
9752        }
9753
9754        private final ArrayMap<ComponentName, PackageParser.Provider> mProviders
9755                = new ArrayMap<ComponentName, PackageParser.Provider>();
9756        private int mFlags;
9757    }
9758
9759    private static final class EphemeralIntentResolver
9760            extends IntentResolver<EphemeralResolveIntentInfo, EphemeralResolveInfo> {
9761        @Override
9762        protected EphemeralResolveIntentInfo[] newArray(int size) {
9763            return new EphemeralResolveIntentInfo[size];
9764        }
9765
9766        @Override
9767        protected boolean isPackageForFilter(String packageName, EphemeralResolveIntentInfo info) {
9768            return true;
9769        }
9770
9771        @Override
9772        protected EphemeralResolveInfo newResult(EphemeralResolveIntentInfo info, int match,
9773                int userId) {
9774            if (!sUserManager.exists(userId)) {
9775                return null;
9776            }
9777            return info.getEphemeralResolveInfo();
9778        }
9779    }
9780
9781    private static final Comparator<ResolveInfo> mResolvePrioritySorter =
9782            new Comparator<ResolveInfo>() {
9783        public int compare(ResolveInfo r1, ResolveInfo r2) {
9784            int v1 = r1.priority;
9785            int v2 = r2.priority;
9786            //System.out.println("Comparing: q1=" + q1 + " q2=" + q2);
9787            if (v1 != v2) {
9788                return (v1 > v2) ? -1 : 1;
9789            }
9790            v1 = r1.preferredOrder;
9791            v2 = r2.preferredOrder;
9792            if (v1 != v2) {
9793                return (v1 > v2) ? -1 : 1;
9794            }
9795            if (r1.isDefault != r2.isDefault) {
9796                return r1.isDefault ? -1 : 1;
9797            }
9798            v1 = r1.match;
9799            v2 = r2.match;
9800            //System.out.println("Comparing: m1=" + m1 + " m2=" + m2);
9801            if (v1 != v2) {
9802                return (v1 > v2) ? -1 : 1;
9803            }
9804            if (r1.system != r2.system) {
9805                return r1.system ? -1 : 1;
9806            }
9807            if (r1.activityInfo != null) {
9808                return r1.activityInfo.packageName.compareTo(r2.activityInfo.packageName);
9809            }
9810            if (r1.serviceInfo != null) {
9811                return r1.serviceInfo.packageName.compareTo(r2.serviceInfo.packageName);
9812            }
9813            if (r1.providerInfo != null) {
9814                return r1.providerInfo.packageName.compareTo(r2.providerInfo.packageName);
9815            }
9816            return 0;
9817        }
9818    };
9819
9820    private static final Comparator<ProviderInfo> mProviderInitOrderSorter =
9821            new Comparator<ProviderInfo>() {
9822        public int compare(ProviderInfo p1, ProviderInfo p2) {
9823            final int v1 = p1.initOrder;
9824            final int v2 = p2.initOrder;
9825            return (v1 > v2) ? -1 : ((v1 < v2) ? 1 : 0);
9826        }
9827    };
9828
9829    final void sendPackageBroadcast(final String action, final String pkg, final Bundle extras,
9830            final int flags, final String targetPkg, final IIntentReceiver finishedReceiver,
9831            final int[] userIds) {
9832        mHandler.post(new Runnable() {
9833            @Override
9834            public void run() {
9835                try {
9836                    final IActivityManager am = ActivityManagerNative.getDefault();
9837                    if (am == null) return;
9838                    final int[] resolvedUserIds;
9839                    if (userIds == null) {
9840                        resolvedUserIds = am.getRunningUserIds();
9841                    } else {
9842                        resolvedUserIds = userIds;
9843                    }
9844                    for (int id : resolvedUserIds) {
9845                        final Intent intent = new Intent(action,
9846                                pkg != null ? Uri.fromParts("package", pkg, null) : null);
9847                        if (extras != null) {
9848                            intent.putExtras(extras);
9849                        }
9850                        if (targetPkg != null) {
9851                            intent.setPackage(targetPkg);
9852                        }
9853                        // Modify the UID when posting to other users
9854                        int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
9855                        if (uid > 0 && UserHandle.getUserId(uid) != id) {
9856                            uid = UserHandle.getUid(id, UserHandle.getAppId(uid));
9857                            intent.putExtra(Intent.EXTRA_UID, uid);
9858                        }
9859                        intent.putExtra(Intent.EXTRA_USER_HANDLE, id);
9860                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT | flags);
9861                        if (DEBUG_BROADCASTS) {
9862                            RuntimeException here = new RuntimeException("here");
9863                            here.fillInStackTrace();
9864                            Slog.d(TAG, "Sending to user " + id + ": "
9865                                    + intent.toShortString(false, true, false, false)
9866                                    + " " + intent.getExtras(), here);
9867                        }
9868                        am.broadcastIntent(null, intent, null, finishedReceiver,
9869                                0, null, null, null, android.app.AppOpsManager.OP_NONE,
9870                                null, finishedReceiver != null, false, id);
9871                    }
9872                } catch (RemoteException ex) {
9873                }
9874            }
9875        });
9876    }
9877
9878    /**
9879     * Check if the external storage media is available. This is true if there
9880     * is a mounted external storage medium or if the external storage is
9881     * emulated.
9882     */
9883    private boolean isExternalMediaAvailable() {
9884        return mMediaMounted || Environment.isExternalStorageEmulated();
9885    }
9886
9887    @Override
9888    public PackageCleanItem nextPackageToClean(PackageCleanItem lastPackage) {
9889        // writer
9890        synchronized (mPackages) {
9891            if (!isExternalMediaAvailable()) {
9892                // If the external storage is no longer mounted at this point,
9893                // the caller may not have been able to delete all of this
9894                // packages files and can not delete any more.  Bail.
9895                return null;
9896            }
9897            final ArrayList<PackageCleanItem> pkgs = mSettings.mPackagesToBeCleaned;
9898            if (lastPackage != null) {
9899                pkgs.remove(lastPackage);
9900            }
9901            if (pkgs.size() > 0) {
9902                return pkgs.get(0);
9903            }
9904        }
9905        return null;
9906    }
9907
9908    void schedulePackageCleaning(String packageName, int userId, boolean andCode) {
9909        final Message msg = mHandler.obtainMessage(START_CLEANING_PACKAGE,
9910                userId, andCode ? 1 : 0, packageName);
9911        if (mSystemReady) {
9912            msg.sendToTarget();
9913        } else {
9914            if (mPostSystemReadyMessages == null) {
9915                mPostSystemReadyMessages = new ArrayList<>();
9916            }
9917            mPostSystemReadyMessages.add(msg);
9918        }
9919    }
9920
9921    void startCleaningPackages() {
9922        // reader
9923        synchronized (mPackages) {
9924            if (!isExternalMediaAvailable()) {
9925                return;
9926            }
9927            if (mSettings.mPackagesToBeCleaned.isEmpty()) {
9928                return;
9929            }
9930        }
9931        Intent intent = new Intent(PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE);
9932        intent.setComponent(DEFAULT_CONTAINER_COMPONENT);
9933        IActivityManager am = ActivityManagerNative.getDefault();
9934        if (am != null) {
9935            try {
9936                am.startService(null, intent, null, mContext.getOpPackageName(),
9937                        UserHandle.USER_SYSTEM);
9938            } catch (RemoteException e) {
9939            }
9940        }
9941    }
9942
9943    @Override
9944    public void installPackage(String originPath, IPackageInstallObserver2 observer,
9945            int installFlags, String installerPackageName, VerificationParams verificationParams,
9946            String packageAbiOverride) {
9947        installPackageAsUser(originPath, observer, installFlags, installerPackageName,
9948                verificationParams, packageAbiOverride, UserHandle.getCallingUserId());
9949    }
9950
9951    @Override
9952    public void installPackageAsUser(String originPath, IPackageInstallObserver2 observer,
9953            int installFlags, String installerPackageName, VerificationParams verificationParams,
9954            String packageAbiOverride, int userId) {
9955        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null);
9956
9957        final int callingUid = Binder.getCallingUid();
9958        enforceCrossUserPermission(callingUid, userId, true, true, "installPackageAsUser");
9959
9960        if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
9961            try {
9962                if (observer != null) {
9963                    observer.onPackageInstalled("", INSTALL_FAILED_USER_RESTRICTED, null, null);
9964                }
9965            } catch (RemoteException re) {
9966            }
9967            return;
9968        }
9969
9970        if ((callingUid == Process.SHELL_UID) || (callingUid == Process.ROOT_UID)) {
9971            installFlags |= PackageManager.INSTALL_FROM_ADB;
9972
9973        } else {
9974            // Caller holds INSTALL_PACKAGES permission, so we're less strict
9975            // about installerPackageName.
9976
9977            installFlags &= ~PackageManager.INSTALL_FROM_ADB;
9978            installFlags &= ~PackageManager.INSTALL_ALL_USERS;
9979        }
9980
9981        UserHandle user;
9982        if ((installFlags & PackageManager.INSTALL_ALL_USERS) != 0) {
9983            user = UserHandle.ALL;
9984        } else {
9985            user = new UserHandle(userId);
9986        }
9987
9988        // Only system components can circumvent runtime permissions when installing.
9989        if ((installFlags & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0
9990                && mContext.checkCallingOrSelfPermission(Manifest.permission
9991                .INSTALL_GRANT_RUNTIME_PERMISSIONS) == PackageManager.PERMISSION_DENIED) {
9992            throw new SecurityException("You need the "
9993                    + "android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS permission "
9994                    + "to use the PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS flag");
9995        }
9996
9997        verificationParams.setInstallerUid(callingUid);
9998
9999        final File originFile = new File(originPath);
10000        final OriginInfo origin = OriginInfo.fromUntrustedFile(originFile);
10001
10002        final Message msg = mHandler.obtainMessage(INIT_COPY);
10003        final InstallParams params = new InstallParams(origin, null, observer, installFlags,
10004                installerPackageName, null, verificationParams, user, packageAbiOverride, null);
10005        params.setTraceMethod("installAsUser").setTraceCookie(System.identityHashCode(params));
10006        msg.obj = params;
10007
10008        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installAsUser",
10009                System.identityHashCode(msg.obj));
10010        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
10011                System.identityHashCode(msg.obj));
10012
10013        mHandler.sendMessage(msg);
10014    }
10015
10016    void installStage(String packageName, File stagedDir, String stagedCid,
10017            IPackageInstallObserver2 observer, PackageInstaller.SessionParams sessionParams,
10018            String installerPackageName, int installerUid, UserHandle user) {
10019        if (DEBUG_EPHEMERAL) {
10020            if ((sessionParams.installFlags & PackageManager.INSTALL_EPHEMERAL) != 0) {
10021                Slog.d(TAG, "Ephemeral install of " + packageName);
10022            }
10023        }
10024        final VerificationParams verifParams = new VerificationParams(
10025                null, sessionParams.originatingUri, sessionParams.referrerUri,
10026                sessionParams.originatingUid);
10027        verifParams.setInstallerUid(installerUid);
10028
10029        final OriginInfo origin;
10030        if (stagedDir != null) {
10031            origin = OriginInfo.fromStagedFile(stagedDir);
10032        } else {
10033            origin = OriginInfo.fromStagedContainer(stagedCid);
10034        }
10035
10036        final Message msg = mHandler.obtainMessage(INIT_COPY);
10037        final InstallParams params = new InstallParams(origin, null, observer,
10038                sessionParams.installFlags, installerPackageName, sessionParams.volumeUuid,
10039                verifParams, user, sessionParams.abiOverride,
10040                sessionParams.grantedRuntimePermissions);
10041        params.setTraceMethod("installStage").setTraceCookie(System.identityHashCode(params));
10042        msg.obj = params;
10043
10044        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installStage",
10045                System.identityHashCode(msg.obj));
10046        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
10047                System.identityHashCode(msg.obj));
10048
10049        mHandler.sendMessage(msg);
10050    }
10051
10052    private void sendPackageAddedForUser(String packageName, PackageSetting pkgSetting, int userId) {
10053        Bundle extras = new Bundle(1);
10054        extras.putInt(Intent.EXTRA_UID, UserHandle.getUid(userId, pkgSetting.appId));
10055
10056        sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
10057                packageName, extras, 0, null, null, new int[] {userId});
10058        try {
10059            IActivityManager am = ActivityManagerNative.getDefault();
10060            final boolean isSystem =
10061                    isSystemApp(pkgSetting) || isUpdatedSystemApp(pkgSetting);
10062            if (isSystem && am.isUserRunning(userId, 0)) {
10063                // The just-installed/enabled app is bundled on the system, so presumed
10064                // to be able to run automatically without needing an explicit launch.
10065                // Send it a BOOT_COMPLETED if it would ordinarily have gotten one.
10066                Intent bcIntent = new Intent(Intent.ACTION_BOOT_COMPLETED)
10067                        .addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES)
10068                        .setPackage(packageName);
10069                am.broadcastIntent(null, bcIntent, null, null, 0, null, null, null,
10070                        android.app.AppOpsManager.OP_NONE, null, false, false, userId);
10071            }
10072        } catch (RemoteException e) {
10073            // shouldn't happen
10074            Slog.w(TAG, "Unable to bootstrap installed package", e);
10075        }
10076    }
10077
10078    @Override
10079    public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden,
10080            int userId) {
10081        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
10082        PackageSetting pkgSetting;
10083        final int uid = Binder.getCallingUid();
10084        enforceCrossUserPermission(uid, userId, true, true,
10085                "setApplicationHiddenSetting for user " + userId);
10086
10087        if (hidden && isPackageDeviceAdmin(packageName, userId)) {
10088            Slog.w(TAG, "Not hiding package " + packageName + ": has active device admin");
10089            return false;
10090        }
10091
10092        long callingId = Binder.clearCallingIdentity();
10093        try {
10094            boolean sendAdded = false;
10095            boolean sendRemoved = false;
10096            // writer
10097            synchronized (mPackages) {
10098                pkgSetting = mSettings.mPackages.get(packageName);
10099                if (pkgSetting == null) {
10100                    return false;
10101                }
10102                if (pkgSetting.getHidden(userId) != hidden) {
10103                    pkgSetting.setHidden(hidden, userId);
10104                    mSettings.writePackageRestrictionsLPr(userId);
10105                    if (hidden) {
10106                        sendRemoved = true;
10107                    } else {
10108                        sendAdded = true;
10109                    }
10110                }
10111            }
10112            if (sendAdded) {
10113                sendPackageAddedForUser(packageName, pkgSetting, userId);
10114                return true;
10115            }
10116            if (sendRemoved) {
10117                killApplication(packageName, UserHandle.getUid(userId, pkgSetting.appId),
10118                        "hiding pkg");
10119                sendApplicationHiddenForUser(packageName, pkgSetting, userId);
10120                return true;
10121            }
10122        } finally {
10123            Binder.restoreCallingIdentity(callingId);
10124        }
10125        return false;
10126    }
10127
10128    private void sendApplicationHiddenForUser(String packageName, PackageSetting pkgSetting,
10129            int userId) {
10130        final PackageRemovedInfo info = new PackageRemovedInfo();
10131        info.removedPackage = packageName;
10132        info.removedUsers = new int[] {userId};
10133        info.uid = UserHandle.getUid(userId, pkgSetting.appId);
10134        info.sendBroadcast(false, false, false);
10135    }
10136
10137    /**
10138     * Returns true if application is not found or there was an error. Otherwise it returns
10139     * the hidden state of the package for the given user.
10140     */
10141    @Override
10142    public boolean getApplicationHiddenSettingAsUser(String packageName, int userId) {
10143        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
10144        enforceCrossUserPermission(Binder.getCallingUid(), userId, true,
10145                false, "getApplicationHidden for user " + userId);
10146        PackageSetting pkgSetting;
10147        long callingId = Binder.clearCallingIdentity();
10148        try {
10149            // writer
10150            synchronized (mPackages) {
10151                pkgSetting = mSettings.mPackages.get(packageName);
10152                if (pkgSetting == null) {
10153                    return true;
10154                }
10155                return pkgSetting.getHidden(userId);
10156            }
10157        } finally {
10158            Binder.restoreCallingIdentity(callingId);
10159        }
10160    }
10161
10162    /**
10163     * @hide
10164     */
10165    @Override
10166    public int installExistingPackageAsUser(String packageName, int userId) {
10167        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES,
10168                null);
10169        PackageSetting pkgSetting;
10170        final int uid = Binder.getCallingUid();
10171        enforceCrossUserPermission(uid, userId, true, true, "installExistingPackage for user "
10172                + userId);
10173        if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
10174            return PackageManager.INSTALL_FAILED_USER_RESTRICTED;
10175        }
10176
10177        long callingId = Binder.clearCallingIdentity();
10178        try {
10179            boolean sendAdded = false;
10180
10181            // writer
10182            synchronized (mPackages) {
10183                pkgSetting = mSettings.mPackages.get(packageName);
10184                if (pkgSetting == null) {
10185                    return PackageManager.INSTALL_FAILED_INVALID_URI;
10186                }
10187                if (!pkgSetting.getInstalled(userId)) {
10188                    pkgSetting.setInstalled(true, userId);
10189                    pkgSetting.setHidden(false, userId);
10190                    mSettings.writePackageRestrictionsLPr(userId);
10191                    sendAdded = true;
10192                }
10193            }
10194
10195            if (sendAdded) {
10196                sendPackageAddedForUser(packageName, pkgSetting, userId);
10197            }
10198        } finally {
10199            Binder.restoreCallingIdentity(callingId);
10200        }
10201
10202        return PackageManager.INSTALL_SUCCEEDED;
10203    }
10204
10205    boolean isUserRestricted(int userId, String restrictionKey) {
10206        Bundle restrictions = sUserManager.getUserRestrictions(userId);
10207        if (restrictions.getBoolean(restrictionKey, false)) {
10208            Log.w(TAG, "User is restricted: " + restrictionKey);
10209            return true;
10210        }
10211        return false;
10212    }
10213
10214    @Override
10215    public boolean setPackageSuspendedAsUser(String packageName, boolean suspended, int userId) {
10216        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
10217        enforceCrossUserPermission(Binder.getCallingUid(), userId, true, true,
10218                "setPackageSuspended for user " + userId);
10219
10220        long callingId = Binder.clearCallingIdentity();
10221        try {
10222            synchronized (mPackages) {
10223                final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
10224                if (pkgSetting != null) {
10225                    if (pkgSetting.getSuspended(userId) != suspended) {
10226                        pkgSetting.setSuspended(suspended, userId);
10227                        mSettings.writePackageRestrictionsLPr(userId);
10228                    }
10229
10230                    // TODO:
10231                    // * broadcast a PACKAGE_(UN)SUSPENDED intent for launchers to pick up
10232                    // * remove app from recents (kill app it if it is running)
10233                    // * erase existing notifications for this app
10234                    return true;
10235                }
10236
10237                return false;
10238            }
10239        } finally {
10240            Binder.restoreCallingIdentity(callingId);
10241        }
10242    }
10243
10244    @Override
10245    public void verifyPendingInstall(int id, int verificationCode) throws RemoteException {
10246        mContext.enforceCallingOrSelfPermission(
10247                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
10248                "Only package verification agents can verify applications");
10249
10250        final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
10251        final PackageVerificationResponse response = new PackageVerificationResponse(
10252                verificationCode, Binder.getCallingUid());
10253        msg.arg1 = id;
10254        msg.obj = response;
10255        mHandler.sendMessage(msg);
10256    }
10257
10258    @Override
10259    public void extendVerificationTimeout(int id, int verificationCodeAtTimeout,
10260            long millisecondsToDelay) {
10261        mContext.enforceCallingOrSelfPermission(
10262                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
10263                "Only package verification agents can extend verification timeouts");
10264
10265        final PackageVerificationState state = mPendingVerification.get(id);
10266        final PackageVerificationResponse response = new PackageVerificationResponse(
10267                verificationCodeAtTimeout, Binder.getCallingUid());
10268
10269        if (millisecondsToDelay > PackageManager.MAXIMUM_VERIFICATION_TIMEOUT) {
10270            millisecondsToDelay = PackageManager.MAXIMUM_VERIFICATION_TIMEOUT;
10271        }
10272        if (millisecondsToDelay < 0) {
10273            millisecondsToDelay = 0;
10274        }
10275        if ((verificationCodeAtTimeout != PackageManager.VERIFICATION_ALLOW)
10276                && (verificationCodeAtTimeout != PackageManager.VERIFICATION_REJECT)) {
10277            verificationCodeAtTimeout = PackageManager.VERIFICATION_REJECT;
10278        }
10279
10280        if ((state != null) && !state.timeoutExtended()) {
10281            state.extendTimeout();
10282
10283            final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
10284            msg.arg1 = id;
10285            msg.obj = response;
10286            mHandler.sendMessageDelayed(msg, millisecondsToDelay);
10287        }
10288    }
10289
10290    private void broadcastPackageVerified(int verificationId, Uri packageUri,
10291            int verificationCode, UserHandle user) {
10292        final Intent intent = new Intent(Intent.ACTION_PACKAGE_VERIFIED);
10293        intent.setDataAndType(packageUri, PACKAGE_MIME_TYPE);
10294        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
10295        intent.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
10296        intent.putExtra(PackageManager.EXTRA_VERIFICATION_RESULT, verificationCode);
10297
10298        mContext.sendBroadcastAsUser(intent, user,
10299                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT);
10300    }
10301
10302    private ComponentName matchComponentForVerifier(String packageName,
10303            List<ResolveInfo> receivers) {
10304        ActivityInfo targetReceiver = null;
10305
10306        final int NR = receivers.size();
10307        for (int i = 0; i < NR; i++) {
10308            final ResolveInfo info = receivers.get(i);
10309            if (info.activityInfo == null) {
10310                continue;
10311            }
10312
10313            if (packageName.equals(info.activityInfo.packageName)) {
10314                targetReceiver = info.activityInfo;
10315                break;
10316            }
10317        }
10318
10319        if (targetReceiver == null) {
10320            return null;
10321        }
10322
10323        return new ComponentName(targetReceiver.packageName, targetReceiver.name);
10324    }
10325
10326    private List<ComponentName> matchVerifiers(PackageInfoLite pkgInfo,
10327            List<ResolveInfo> receivers, final PackageVerificationState verificationState) {
10328        if (pkgInfo.verifiers.length == 0) {
10329            return null;
10330        }
10331
10332        final int N = pkgInfo.verifiers.length;
10333        final List<ComponentName> sufficientVerifiers = new ArrayList<ComponentName>(N + 1);
10334        for (int i = 0; i < N; i++) {
10335            final VerifierInfo verifierInfo = pkgInfo.verifiers[i];
10336
10337            final ComponentName comp = matchComponentForVerifier(verifierInfo.packageName,
10338                    receivers);
10339            if (comp == null) {
10340                continue;
10341            }
10342
10343            final int verifierUid = getUidForVerifier(verifierInfo);
10344            if (verifierUid == -1) {
10345                continue;
10346            }
10347
10348            if (DEBUG_VERIFY) {
10349                Slog.d(TAG, "Added sufficient verifier " + verifierInfo.packageName
10350                        + " with the correct signature");
10351            }
10352            sufficientVerifiers.add(comp);
10353            verificationState.addSufficientVerifier(verifierUid);
10354        }
10355
10356        return sufficientVerifiers;
10357    }
10358
10359    private int getUidForVerifier(VerifierInfo verifierInfo) {
10360        synchronized (mPackages) {
10361            final PackageParser.Package pkg = mPackages.get(verifierInfo.packageName);
10362            if (pkg == null) {
10363                return -1;
10364            } else if (pkg.mSignatures.length != 1) {
10365                Slog.i(TAG, "Verifier package " + verifierInfo.packageName
10366                        + " has more than one signature; ignoring");
10367                return -1;
10368            }
10369
10370            /*
10371             * If the public key of the package's signature does not match
10372             * our expected public key, then this is a different package and
10373             * we should skip.
10374             */
10375
10376            final byte[] expectedPublicKey;
10377            try {
10378                final Signature verifierSig = pkg.mSignatures[0];
10379                final PublicKey publicKey = verifierSig.getPublicKey();
10380                expectedPublicKey = publicKey.getEncoded();
10381            } catch (CertificateException e) {
10382                return -1;
10383            }
10384
10385            final byte[] actualPublicKey = verifierInfo.publicKey.getEncoded();
10386
10387            if (!Arrays.equals(actualPublicKey, expectedPublicKey)) {
10388                Slog.i(TAG, "Verifier package " + verifierInfo.packageName
10389                        + " does not have the expected public key; ignoring");
10390                return -1;
10391            }
10392
10393            return pkg.applicationInfo.uid;
10394        }
10395    }
10396
10397    @Override
10398    public void finishPackageInstall(int token) {
10399        enforceSystemOrRoot("Only the system is allowed to finish installs");
10400
10401        if (DEBUG_INSTALL) {
10402            Slog.v(TAG, "BM finishing package install for " + token);
10403        }
10404        Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "restore", token);
10405
10406        final Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0);
10407        mHandler.sendMessage(msg);
10408    }
10409
10410    /**
10411     * Get the verification agent timeout.
10412     *
10413     * @return verification timeout in milliseconds
10414     */
10415    private long getVerificationTimeout() {
10416        return android.provider.Settings.Global.getLong(mContext.getContentResolver(),
10417                android.provider.Settings.Global.PACKAGE_VERIFIER_TIMEOUT,
10418                DEFAULT_VERIFICATION_TIMEOUT);
10419    }
10420
10421    /**
10422     * Get the default verification agent response code.
10423     *
10424     * @return default verification response code
10425     */
10426    private int getDefaultVerificationResponse() {
10427        return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
10428                android.provider.Settings.Global.PACKAGE_VERIFIER_DEFAULT_RESPONSE,
10429                DEFAULT_VERIFICATION_RESPONSE);
10430    }
10431
10432    /**
10433     * Check whether or not package verification has been enabled.
10434     *
10435     * @return true if verification should be performed
10436     */
10437    private boolean isVerificationEnabled(int userId, int installFlags) {
10438        if (!DEFAULT_VERIFY_ENABLE) {
10439            return false;
10440        }
10441        // Ephemeral apps don't get the full verification treatment
10442        if ((installFlags & PackageManager.INSTALL_EPHEMERAL) != 0) {
10443            if (DEBUG_EPHEMERAL) {
10444                Slog.d(TAG, "INSTALL_EPHEMERAL so skipping verification");
10445            }
10446            return false;
10447        }
10448
10449        boolean ensureVerifyAppsEnabled = isUserRestricted(userId, UserManager.ENSURE_VERIFY_APPS);
10450
10451        // Check if installing from ADB
10452        if ((installFlags & PackageManager.INSTALL_FROM_ADB) != 0) {
10453            // Do not run verification in a test harness environment
10454            if (ActivityManager.isRunningInTestHarness()) {
10455                return false;
10456            }
10457            if (ensureVerifyAppsEnabled) {
10458                return true;
10459            }
10460            // Check if the developer does not want package verification for ADB installs
10461            if (android.provider.Settings.Global.getInt(mContext.getContentResolver(),
10462                    android.provider.Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, 1) == 0) {
10463                return false;
10464            }
10465        }
10466
10467        if (ensureVerifyAppsEnabled) {
10468            return true;
10469        }
10470
10471        return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
10472                android.provider.Settings.Global.PACKAGE_VERIFIER_ENABLE, 1) == 1;
10473    }
10474
10475    @Override
10476    public void verifyIntentFilter(int id, int verificationCode, List<String> failedDomains)
10477            throws RemoteException {
10478        mContext.enforceCallingOrSelfPermission(
10479                Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT,
10480                "Only intentfilter verification agents can verify applications");
10481
10482        final Message msg = mHandler.obtainMessage(INTENT_FILTER_VERIFIED);
10483        final IntentFilterVerificationResponse response = new IntentFilterVerificationResponse(
10484                Binder.getCallingUid(), verificationCode, failedDomains);
10485        msg.arg1 = id;
10486        msg.obj = response;
10487        mHandler.sendMessage(msg);
10488    }
10489
10490    @Override
10491    public int getIntentVerificationStatus(String packageName, int userId) {
10492        synchronized (mPackages) {
10493            return mSettings.getIntentFilterVerificationStatusLPr(packageName, userId);
10494        }
10495    }
10496
10497    @Override
10498    public boolean updateIntentVerificationStatus(String packageName, int status, int userId) {
10499        mContext.enforceCallingOrSelfPermission(
10500                android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
10501
10502        boolean result = false;
10503        synchronized (mPackages) {
10504            result = mSettings.updateIntentFilterVerificationStatusLPw(packageName, status, userId);
10505        }
10506        if (result) {
10507            scheduleWritePackageRestrictionsLocked(userId);
10508        }
10509        return result;
10510    }
10511
10512    @Override
10513    public List<IntentFilterVerificationInfo> getIntentFilterVerifications(String packageName) {
10514        synchronized (mPackages) {
10515            return mSettings.getIntentFilterVerificationsLPr(packageName);
10516        }
10517    }
10518
10519    @Override
10520    public List<IntentFilter> getAllIntentFilters(String packageName) {
10521        if (TextUtils.isEmpty(packageName)) {
10522            return Collections.<IntentFilter>emptyList();
10523        }
10524        synchronized (mPackages) {
10525            PackageParser.Package pkg = mPackages.get(packageName);
10526            if (pkg == null || pkg.activities == null) {
10527                return Collections.<IntentFilter>emptyList();
10528            }
10529            final int count = pkg.activities.size();
10530            ArrayList<IntentFilter> result = new ArrayList<>();
10531            for (int n=0; n<count; n++) {
10532                PackageParser.Activity activity = pkg.activities.get(n);
10533                if (activity.intents != null && activity.intents.size() > 0) {
10534                    result.addAll(activity.intents);
10535                }
10536            }
10537            return result;
10538        }
10539    }
10540
10541    @Override
10542    public boolean setDefaultBrowserPackageName(String packageName, int userId) {
10543        mContext.enforceCallingOrSelfPermission(
10544                android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
10545
10546        synchronized (mPackages) {
10547            boolean result = mSettings.setDefaultBrowserPackageNameLPw(packageName, userId);
10548            if (packageName != null) {
10549                result |= updateIntentVerificationStatus(packageName,
10550                        PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS,
10551                        userId);
10552                mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultBrowserLPr(
10553                        packageName, userId);
10554            }
10555            return result;
10556        }
10557    }
10558
10559    @Override
10560    public String getDefaultBrowserPackageName(int userId) {
10561        synchronized (mPackages) {
10562            return mSettings.getDefaultBrowserPackageNameLPw(userId);
10563        }
10564    }
10565
10566    /**
10567     * Get the "allow unknown sources" setting.
10568     *
10569     * @return the current "allow unknown sources" setting
10570     */
10571    private int getUnknownSourcesSettings() {
10572        return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
10573                android.provider.Settings.Global.INSTALL_NON_MARKET_APPS,
10574                -1);
10575    }
10576
10577    @Override
10578    public void setInstallerPackageName(String targetPackage, String installerPackageName) {
10579        final int uid = Binder.getCallingUid();
10580        // writer
10581        synchronized (mPackages) {
10582            PackageSetting targetPackageSetting = mSettings.mPackages.get(targetPackage);
10583            if (targetPackageSetting == null) {
10584                throw new IllegalArgumentException("Unknown target package: " + targetPackage);
10585            }
10586
10587            PackageSetting installerPackageSetting;
10588            if (installerPackageName != null) {
10589                installerPackageSetting = mSettings.mPackages.get(installerPackageName);
10590                if (installerPackageSetting == null) {
10591                    throw new IllegalArgumentException("Unknown installer package: "
10592                            + installerPackageName);
10593                }
10594            } else {
10595                installerPackageSetting = null;
10596            }
10597
10598            Signature[] callerSignature;
10599            Object obj = mSettings.getUserIdLPr(uid);
10600            if (obj != null) {
10601                if (obj instanceof SharedUserSetting) {
10602                    callerSignature = ((SharedUserSetting)obj).signatures.mSignatures;
10603                } else if (obj instanceof PackageSetting) {
10604                    callerSignature = ((PackageSetting)obj).signatures.mSignatures;
10605                } else {
10606                    throw new SecurityException("Bad object " + obj + " for uid " + uid);
10607                }
10608            } else {
10609                throw new SecurityException("Unknown calling UID: " + uid);
10610            }
10611
10612            // Verify: can't set installerPackageName to a package that is
10613            // not signed with the same cert as the caller.
10614            if (installerPackageSetting != null) {
10615                if (compareSignatures(callerSignature,
10616                        installerPackageSetting.signatures.mSignatures)
10617                        != PackageManager.SIGNATURE_MATCH) {
10618                    throw new SecurityException(
10619                            "Caller does not have same cert as new installer package "
10620                            + installerPackageName);
10621                }
10622            }
10623
10624            // Verify: if target already has an installer package, it must
10625            // be signed with the same cert as the caller.
10626            if (targetPackageSetting.installerPackageName != null) {
10627                PackageSetting setting = mSettings.mPackages.get(
10628                        targetPackageSetting.installerPackageName);
10629                // If the currently set package isn't valid, then it's always
10630                // okay to change it.
10631                if (setting != null) {
10632                    if (compareSignatures(callerSignature,
10633                            setting.signatures.mSignatures)
10634                            != PackageManager.SIGNATURE_MATCH) {
10635                        throw new SecurityException(
10636                                "Caller does not have same cert as old installer package "
10637                                + targetPackageSetting.installerPackageName);
10638                    }
10639                }
10640            }
10641
10642            // Okay!
10643            targetPackageSetting.installerPackageName = installerPackageName;
10644            scheduleWriteSettingsLocked();
10645        }
10646    }
10647
10648    private void processPendingInstall(final InstallArgs args, final int currentStatus) {
10649        // Queue up an async operation since the package installation may take a little while.
10650        mHandler.post(new Runnable() {
10651            public void run() {
10652                mHandler.removeCallbacks(this);
10653                 // Result object to be returned
10654                PackageInstalledInfo res = new PackageInstalledInfo();
10655                res.returnCode = currentStatus;
10656                res.uid = -1;
10657                res.pkg = null;
10658                res.removedInfo = new PackageRemovedInfo();
10659                if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
10660                    args.doPreInstall(res.returnCode);
10661                    synchronized (mInstallLock) {
10662                        installPackageTracedLI(args, res);
10663                    }
10664                    args.doPostInstall(res.returnCode, res.uid);
10665                }
10666
10667                // A restore should be performed at this point if (a) the install
10668                // succeeded, (b) the operation is not an update, and (c) the new
10669                // package has not opted out of backup participation.
10670                final boolean update = res.removedInfo.removedPackage != null;
10671                final int flags = (res.pkg == null) ? 0 : res.pkg.applicationInfo.flags;
10672                boolean doRestore = !update
10673                        && ((flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0);
10674
10675                // Set up the post-install work request bookkeeping.  This will be used
10676                // and cleaned up by the post-install event handling regardless of whether
10677                // there's a restore pass performed.  Token values are >= 1.
10678                int token;
10679                if (mNextInstallToken < 0) mNextInstallToken = 1;
10680                token = mNextInstallToken++;
10681
10682                PostInstallData data = new PostInstallData(args, res);
10683                mRunningInstalls.put(token, data);
10684                if (DEBUG_INSTALL) Log.v(TAG, "+ starting restore round-trip " + token);
10685
10686                if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && doRestore) {
10687                    // Pass responsibility to the Backup Manager.  It will perform a
10688                    // restore if appropriate, then pass responsibility back to the
10689                    // Package Manager to run the post-install observer callbacks
10690                    // and broadcasts.
10691                    IBackupManager bm = IBackupManager.Stub.asInterface(
10692                            ServiceManager.getService(Context.BACKUP_SERVICE));
10693                    if (bm != null) {
10694                        if (DEBUG_INSTALL) Log.v(TAG, "token " + token
10695                                + " to BM for possible restore");
10696                        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "restore", token);
10697                        try {
10698                            // TODO: http://b/22388012
10699                            if (bm.isBackupServiceActive(UserHandle.USER_SYSTEM)) {
10700                                bm.restoreAtInstall(res.pkg.applicationInfo.packageName, token);
10701                            } else {
10702                                doRestore = false;
10703                            }
10704                        } catch (RemoteException e) {
10705                            // can't happen; the backup manager is local
10706                        } catch (Exception e) {
10707                            Slog.e(TAG, "Exception trying to enqueue restore", e);
10708                            doRestore = false;
10709                        }
10710                    } else {
10711                        Slog.e(TAG, "Backup Manager not found!");
10712                        doRestore = false;
10713                    }
10714                }
10715
10716                if (!doRestore) {
10717                    // No restore possible, or the Backup Manager was mysteriously not
10718                    // available -- just fire the post-install work request directly.
10719                    if (DEBUG_INSTALL) Log.v(TAG, "No restore - queue post-install for " + token);
10720
10721                    Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "postInstall", token);
10722
10723                    Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0);
10724                    mHandler.sendMessage(msg);
10725                }
10726            }
10727        });
10728    }
10729
10730    private abstract class HandlerParams {
10731        private static final int MAX_RETRIES = 4;
10732
10733        /**
10734         * Number of times startCopy() has been attempted and had a non-fatal
10735         * error.
10736         */
10737        private int mRetries = 0;
10738
10739        /** User handle for the user requesting the information or installation. */
10740        private final UserHandle mUser;
10741        String traceMethod;
10742        int traceCookie;
10743
10744        HandlerParams(UserHandle user) {
10745            mUser = user;
10746        }
10747
10748        UserHandle getUser() {
10749            return mUser;
10750        }
10751
10752        HandlerParams setTraceMethod(String traceMethod) {
10753            this.traceMethod = traceMethod;
10754            return this;
10755        }
10756
10757        HandlerParams setTraceCookie(int traceCookie) {
10758            this.traceCookie = traceCookie;
10759            return this;
10760        }
10761
10762        final boolean startCopy() {
10763            boolean res;
10764            try {
10765                if (DEBUG_INSTALL) Slog.i(TAG, "startCopy " + mUser + ": " + this);
10766
10767                if (++mRetries > MAX_RETRIES) {
10768                    Slog.w(TAG, "Failed to invoke remote methods on default container service. Giving up");
10769                    mHandler.sendEmptyMessage(MCS_GIVE_UP);
10770                    handleServiceError();
10771                    return false;
10772                } else {
10773                    handleStartCopy();
10774                    res = true;
10775                }
10776            } catch (RemoteException e) {
10777                if (DEBUG_INSTALL) Slog.i(TAG, "Posting install MCS_RECONNECT");
10778                mHandler.sendEmptyMessage(MCS_RECONNECT);
10779                res = false;
10780            }
10781            handleReturnCode();
10782            return res;
10783        }
10784
10785        final void serviceError() {
10786            if (DEBUG_INSTALL) Slog.i(TAG, "serviceError");
10787            handleServiceError();
10788            handleReturnCode();
10789        }
10790
10791        abstract void handleStartCopy() throws RemoteException;
10792        abstract void handleServiceError();
10793        abstract void handleReturnCode();
10794    }
10795
10796    class MeasureParams extends HandlerParams {
10797        private final PackageStats mStats;
10798        private boolean mSuccess;
10799
10800        private final IPackageStatsObserver mObserver;
10801
10802        public MeasureParams(PackageStats stats, IPackageStatsObserver observer) {
10803            super(new UserHandle(stats.userHandle));
10804            mObserver = observer;
10805            mStats = stats;
10806        }
10807
10808        @Override
10809        public String toString() {
10810            return "MeasureParams{"
10811                + Integer.toHexString(System.identityHashCode(this))
10812                + " " + mStats.packageName + "}";
10813        }
10814
10815        @Override
10816        void handleStartCopy() throws RemoteException {
10817            synchronized (mInstallLock) {
10818                mSuccess = getPackageSizeInfoLI(mStats.packageName, mStats.userHandle, mStats);
10819            }
10820
10821            if (mSuccess) {
10822                final boolean mounted;
10823                if (Environment.isExternalStorageEmulated()) {
10824                    mounted = true;
10825                } else {
10826                    final String status = Environment.getExternalStorageState();
10827                    mounted = (Environment.MEDIA_MOUNTED.equals(status)
10828                            || Environment.MEDIA_MOUNTED_READ_ONLY.equals(status));
10829                }
10830
10831                if (mounted) {
10832                    final UserEnvironment userEnv = new UserEnvironment(mStats.userHandle);
10833
10834                    mStats.externalCacheSize = calculateDirectorySize(mContainerService,
10835                            userEnv.buildExternalStorageAppCacheDirs(mStats.packageName));
10836
10837                    mStats.externalDataSize = calculateDirectorySize(mContainerService,
10838                            userEnv.buildExternalStorageAppDataDirs(mStats.packageName));
10839
10840                    // Always subtract cache size, since it's a subdirectory
10841                    mStats.externalDataSize -= mStats.externalCacheSize;
10842
10843                    mStats.externalMediaSize = calculateDirectorySize(mContainerService,
10844                            userEnv.buildExternalStorageAppMediaDirs(mStats.packageName));
10845
10846                    mStats.externalObbSize = calculateDirectorySize(mContainerService,
10847                            userEnv.buildExternalStorageAppObbDirs(mStats.packageName));
10848                }
10849            }
10850        }
10851
10852        @Override
10853        void handleReturnCode() {
10854            if (mObserver != null) {
10855                try {
10856                    mObserver.onGetStatsCompleted(mStats, mSuccess);
10857                } catch (RemoteException e) {
10858                    Slog.i(TAG, "Observer no longer exists.");
10859                }
10860            }
10861        }
10862
10863        @Override
10864        void handleServiceError() {
10865            Slog.e(TAG, "Could not measure application " + mStats.packageName
10866                            + " external storage");
10867        }
10868    }
10869
10870    private static long calculateDirectorySize(IMediaContainerService mcs, File[] paths)
10871            throws RemoteException {
10872        long result = 0;
10873        for (File path : paths) {
10874            result += mcs.calculateDirectorySize(path.getAbsolutePath());
10875        }
10876        return result;
10877    }
10878
10879    private static void clearDirectory(IMediaContainerService mcs, File[] paths) {
10880        for (File path : paths) {
10881            try {
10882                mcs.clearDirectory(path.getAbsolutePath());
10883            } catch (RemoteException e) {
10884            }
10885        }
10886    }
10887
10888    static class OriginInfo {
10889        /**
10890         * Location where install is coming from, before it has been
10891         * copied/renamed into place. This could be a single monolithic APK
10892         * file, or a cluster directory. This location may be untrusted.
10893         */
10894        final File file;
10895        final String cid;
10896
10897        /**
10898         * Flag indicating that {@link #file} or {@link #cid} has already been
10899         * staged, meaning downstream users don't need to defensively copy the
10900         * contents.
10901         */
10902        final boolean staged;
10903
10904        /**
10905         * Flag indicating that {@link #file} or {@link #cid} is an already
10906         * installed app that is being moved.
10907         */
10908        final boolean existing;
10909
10910        final String resolvedPath;
10911        final File resolvedFile;
10912
10913        static OriginInfo fromNothing() {
10914            return new OriginInfo(null, null, false, false);
10915        }
10916
10917        static OriginInfo fromUntrustedFile(File file) {
10918            return new OriginInfo(file, null, false, false);
10919        }
10920
10921        static OriginInfo fromExistingFile(File file) {
10922            return new OriginInfo(file, null, false, true);
10923        }
10924
10925        static OriginInfo fromStagedFile(File file) {
10926            return new OriginInfo(file, null, true, false);
10927        }
10928
10929        static OriginInfo fromStagedContainer(String cid) {
10930            return new OriginInfo(null, cid, true, false);
10931        }
10932
10933        private OriginInfo(File file, String cid, boolean staged, boolean existing) {
10934            this.file = file;
10935            this.cid = cid;
10936            this.staged = staged;
10937            this.existing = existing;
10938
10939            if (cid != null) {
10940                resolvedPath = PackageHelper.getSdDir(cid);
10941                resolvedFile = new File(resolvedPath);
10942            } else if (file != null) {
10943                resolvedPath = file.getAbsolutePath();
10944                resolvedFile = file;
10945            } else {
10946                resolvedPath = null;
10947                resolvedFile = null;
10948            }
10949        }
10950    }
10951
10952    static class MoveInfo {
10953        final int moveId;
10954        final String fromUuid;
10955        final String toUuid;
10956        final String packageName;
10957        final String dataAppName;
10958        final int appId;
10959        final String seinfo;
10960
10961        public MoveInfo(int moveId, String fromUuid, String toUuid, String packageName,
10962                String dataAppName, int appId, String seinfo) {
10963            this.moveId = moveId;
10964            this.fromUuid = fromUuid;
10965            this.toUuid = toUuid;
10966            this.packageName = packageName;
10967            this.dataAppName = dataAppName;
10968            this.appId = appId;
10969            this.seinfo = seinfo;
10970        }
10971    }
10972
10973    class InstallParams extends HandlerParams {
10974        final OriginInfo origin;
10975        final MoveInfo move;
10976        final IPackageInstallObserver2 observer;
10977        int installFlags;
10978        final String installerPackageName;
10979        final String volumeUuid;
10980        final VerificationParams verificationParams;
10981        private InstallArgs mArgs;
10982        private int mRet;
10983        final String packageAbiOverride;
10984        final String[] grantedRuntimePermissions;
10985
10986        InstallParams(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
10987                int installFlags, String installerPackageName, String volumeUuid,
10988                VerificationParams verificationParams, UserHandle user, String packageAbiOverride,
10989                String[] grantedPermissions) {
10990            super(user);
10991            this.origin = origin;
10992            this.move = move;
10993            this.observer = observer;
10994            this.installFlags = installFlags;
10995            this.installerPackageName = installerPackageName;
10996            this.volumeUuid = volumeUuid;
10997            this.verificationParams = verificationParams;
10998            this.packageAbiOverride = packageAbiOverride;
10999            this.grantedRuntimePermissions = grantedPermissions;
11000        }
11001
11002        @Override
11003        public String toString() {
11004            return "InstallParams{" + Integer.toHexString(System.identityHashCode(this))
11005                    + " file=" + origin.file + " cid=" + origin.cid + "}";
11006        }
11007
11008        private int installLocationPolicy(PackageInfoLite pkgLite) {
11009            String packageName = pkgLite.packageName;
11010            int installLocation = pkgLite.installLocation;
11011            boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
11012            // reader
11013            synchronized (mPackages) {
11014                PackageParser.Package pkg = mPackages.get(packageName);
11015                if (pkg != null) {
11016                    if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
11017                        // Check for downgrading.
11018                        if ((installFlags & PackageManager.INSTALL_ALLOW_DOWNGRADE) == 0) {
11019                            try {
11020                                checkDowngrade(pkg, pkgLite);
11021                            } catch (PackageManagerException e) {
11022                                Slog.w(TAG, "Downgrade detected: " + e.getMessage());
11023                                return PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE;
11024                            }
11025                        }
11026                        // Check for updated system application.
11027                        if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11028                            if (onSd) {
11029                                Slog.w(TAG, "Cannot install update to system app on sdcard");
11030                                return PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION;
11031                            }
11032                            return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
11033                        } else {
11034                            if (onSd) {
11035                                // Install flag overrides everything.
11036                                return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
11037                            }
11038                            // If current upgrade specifies particular preference
11039                            if (installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) {
11040                                // Application explicitly specified internal.
11041                                return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
11042                            } else if (installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) {
11043                                // App explictly prefers external. Let policy decide
11044                            } else {
11045                                // Prefer previous location
11046                                if (isExternal(pkg)) {
11047                                    return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
11048                                }
11049                                return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
11050                            }
11051                        }
11052                    } else {
11053                        // Invalid install. Return error code
11054                        return PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS;
11055                    }
11056                }
11057            }
11058            // All the special cases have been taken care of.
11059            // Return result based on recommended install location.
11060            if (onSd) {
11061                return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
11062            }
11063            return pkgLite.recommendedInstallLocation;
11064        }
11065
11066        /*
11067         * Invoke remote method to get package information and install
11068         * location values. Override install location based on default
11069         * policy if needed and then create install arguments based
11070         * on the install location.
11071         */
11072        public void handleStartCopy() throws RemoteException {
11073            int ret = PackageManager.INSTALL_SUCCEEDED;
11074
11075            // If we're already staged, we've firmly committed to an install location
11076            if (origin.staged) {
11077                if (origin.file != null) {
11078                    installFlags |= PackageManager.INSTALL_INTERNAL;
11079                    installFlags &= ~PackageManager.INSTALL_EXTERNAL;
11080                } else if (origin.cid != null) {
11081                    installFlags |= PackageManager.INSTALL_EXTERNAL;
11082                    installFlags &= ~PackageManager.INSTALL_INTERNAL;
11083                } else {
11084                    throw new IllegalStateException("Invalid stage location");
11085                }
11086            }
11087
11088            final boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
11089            final boolean onInt = (installFlags & PackageManager.INSTALL_INTERNAL) != 0;
11090            final boolean ephemeral = (installFlags & PackageManager.INSTALL_EPHEMERAL) != 0;
11091            PackageInfoLite pkgLite = null;
11092
11093            if (onInt && onSd) {
11094                // Check if both bits are set.
11095                Slog.w(TAG, "Conflicting flags specified for installing on both internal and external");
11096                ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
11097            } else if (onSd && ephemeral) {
11098                Slog.w(TAG,  "Conflicting flags specified for installing ephemeral on external");
11099                ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
11100            } else {
11101                pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, installFlags,
11102                        packageAbiOverride);
11103
11104                if (DEBUG_EPHEMERAL && ephemeral) {
11105                    Slog.v(TAG, "pkgLite for install: " + pkgLite);
11106                }
11107
11108                /*
11109                 * If we have too little free space, try to free cache
11110                 * before giving up.
11111                 */
11112                if (!origin.staged && pkgLite.recommendedInstallLocation
11113                        == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
11114                    // TODO: focus freeing disk space on the target device
11115                    final StorageManager storage = StorageManager.from(mContext);
11116                    final long lowThreshold = storage.getStorageLowBytes(
11117                            Environment.getDataDirectory());
11118
11119                    final long sizeBytes = mContainerService.calculateInstalledSize(
11120                            origin.resolvedPath, isForwardLocked(), packageAbiOverride);
11121
11122                    if (mInstaller.freeCache(null, sizeBytes + lowThreshold) >= 0) {
11123                        pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath,
11124                                installFlags, packageAbiOverride);
11125                    }
11126
11127                    /*
11128                     * The cache free must have deleted the file we
11129                     * downloaded to install.
11130                     *
11131                     * TODO: fix the "freeCache" call to not delete
11132                     *       the file we care about.
11133                     */
11134                    if (pkgLite.recommendedInstallLocation
11135                            == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
11136                        pkgLite.recommendedInstallLocation
11137                            = PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE;
11138                    }
11139                }
11140            }
11141
11142            if (ret == PackageManager.INSTALL_SUCCEEDED) {
11143                int loc = pkgLite.recommendedInstallLocation;
11144                if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION) {
11145                    ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
11146                } else if (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS) {
11147                    ret = PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
11148                } else if (loc == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
11149                    ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
11150                } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_APK) {
11151                    ret = PackageManager.INSTALL_FAILED_INVALID_APK;
11152                } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
11153                    ret = PackageManager.INSTALL_FAILED_INVALID_URI;
11154                } else if (loc == PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE) {
11155                    ret = PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE;
11156                } else {
11157                    // Override with defaults if needed.
11158                    loc = installLocationPolicy(pkgLite);
11159                    if (loc == PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE) {
11160                        ret = PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
11161                    } else if (!onSd && !onInt) {
11162                        // Override install location with flags
11163                        if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) {
11164                            // Set the flag to install on external media.
11165                            installFlags |= PackageManager.INSTALL_EXTERNAL;
11166                            installFlags &= ~PackageManager.INSTALL_INTERNAL;
11167                        } else if (loc == PackageHelper.RECOMMEND_INSTALL_EPHEMERAL) {
11168                            if (DEBUG_EPHEMERAL) {
11169                                Slog.v(TAG, "...setting INSTALL_EPHEMERAL install flag");
11170                            }
11171                            installFlags |= PackageManager.INSTALL_EPHEMERAL;
11172                            installFlags &= ~(PackageManager.INSTALL_EXTERNAL
11173                                    |PackageManager.INSTALL_INTERNAL);
11174                        } else {
11175                            // Make sure the flag for installing on external
11176                            // media is unset
11177                            installFlags |= PackageManager.INSTALL_INTERNAL;
11178                            installFlags &= ~PackageManager.INSTALL_EXTERNAL;
11179                        }
11180                    }
11181                }
11182            }
11183
11184            final InstallArgs args = createInstallArgs(this);
11185            mArgs = args;
11186
11187            if (ret == PackageManager.INSTALL_SUCCEEDED) {
11188                // TODO: http://b/22976637
11189                // Apps installed for "all" users use the device owner to verify the app
11190                UserHandle verifierUser = getUser();
11191                if (verifierUser == UserHandle.ALL) {
11192                    verifierUser = UserHandle.SYSTEM;
11193                }
11194
11195                /*
11196                 * Determine if we have any installed package verifiers. If we
11197                 * do, then we'll defer to them to verify the packages.
11198                 */
11199                final int requiredUid = mRequiredVerifierPackage == null ? -1
11200                        : getPackageUid(mRequiredVerifierPackage, verifierUser.getIdentifier());
11201                if (!origin.existing && requiredUid != -1
11202                        && isVerificationEnabled(verifierUser.getIdentifier(), installFlags)) {
11203                    final Intent verification = new Intent(
11204                            Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
11205                    verification.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
11206                    verification.setDataAndType(Uri.fromFile(new File(origin.resolvedPath)),
11207                            PACKAGE_MIME_TYPE);
11208                    verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
11209
11210                    // Query all live verifiers based on current user state
11211                    final List<ResolveInfo> receivers = queryIntentReceivers(verification,
11212                            PACKAGE_MIME_TYPE, 0, verifierUser.getIdentifier());
11213
11214                    if (DEBUG_VERIFY) {
11215                        Slog.d(TAG, "Found " + receivers.size() + " verifiers for intent "
11216                                + verification.toString() + " with " + pkgLite.verifiers.length
11217                                + " optional verifiers");
11218                    }
11219
11220                    final int verificationId = mPendingVerificationToken++;
11221
11222                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
11223
11224                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_PACKAGE,
11225                            installerPackageName);
11226
11227                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALL_FLAGS,
11228                            installFlags);
11229
11230                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_PACKAGE_NAME,
11231                            pkgLite.packageName);
11232
11233                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_VERSION_CODE,
11234                            pkgLite.versionCode);
11235
11236                    if (verificationParams != null) {
11237                        if (verificationParams.getVerificationURI() != null) {
11238                           verification.putExtra(PackageManager.EXTRA_VERIFICATION_URI,
11239                                 verificationParams.getVerificationURI());
11240                        }
11241                        if (verificationParams.getOriginatingURI() != null) {
11242                            verification.putExtra(Intent.EXTRA_ORIGINATING_URI,
11243                                  verificationParams.getOriginatingURI());
11244                        }
11245                        if (verificationParams.getReferrer() != null) {
11246                            verification.putExtra(Intent.EXTRA_REFERRER,
11247                                  verificationParams.getReferrer());
11248                        }
11249                        if (verificationParams.getOriginatingUid() >= 0) {
11250                            verification.putExtra(Intent.EXTRA_ORIGINATING_UID,
11251                                  verificationParams.getOriginatingUid());
11252                        }
11253                        if (verificationParams.getInstallerUid() >= 0) {
11254                            verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_UID,
11255                                  verificationParams.getInstallerUid());
11256                        }
11257                    }
11258
11259                    final PackageVerificationState verificationState = new PackageVerificationState(
11260                            requiredUid, args);
11261
11262                    mPendingVerification.append(verificationId, verificationState);
11263
11264                    final List<ComponentName> sufficientVerifiers = matchVerifiers(pkgLite,
11265                            receivers, verificationState);
11266
11267                    /*
11268                     * If any sufficient verifiers were listed in the package
11269                     * manifest, attempt to ask them.
11270                     */
11271                    if (sufficientVerifiers != null) {
11272                        final int N = sufficientVerifiers.size();
11273                        if (N == 0) {
11274                            Slog.i(TAG, "Additional verifiers required, but none installed.");
11275                            ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
11276                        } else {
11277                            for (int i = 0; i < N; i++) {
11278                                final ComponentName verifierComponent = sufficientVerifiers.get(i);
11279
11280                                final Intent sufficientIntent = new Intent(verification);
11281                                sufficientIntent.setComponent(verifierComponent);
11282                                mContext.sendBroadcastAsUser(sufficientIntent, verifierUser);
11283                            }
11284                        }
11285                    }
11286
11287                    final ComponentName requiredVerifierComponent = matchComponentForVerifier(
11288                            mRequiredVerifierPackage, receivers);
11289                    if (ret == PackageManager.INSTALL_SUCCEEDED
11290                            && mRequiredVerifierPackage != null) {
11291                        Trace.asyncTraceBegin(
11292                                TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
11293                        /*
11294                         * Send the intent to the required verification agent,
11295                         * but only start the verification timeout after the
11296                         * target BroadcastReceivers have run.
11297                         */
11298                        verification.setComponent(requiredVerifierComponent);
11299                        mContext.sendOrderedBroadcastAsUser(verification, verifierUser,
11300                                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
11301                                new BroadcastReceiver() {
11302                                    @Override
11303                                    public void onReceive(Context context, Intent intent) {
11304                                        final Message msg = mHandler
11305                                                .obtainMessage(CHECK_PENDING_VERIFICATION);
11306                                        msg.arg1 = verificationId;
11307                                        mHandler.sendMessageDelayed(msg, getVerificationTimeout());
11308                                    }
11309                                }, null, 0, null, null);
11310
11311                        /*
11312                         * We don't want the copy to proceed until verification
11313                         * succeeds, so null out this field.
11314                         */
11315                        mArgs = null;
11316                    }
11317                } else {
11318                    /*
11319                     * No package verification is enabled, so immediately start
11320                     * the remote call to initiate copy using temporary file.
11321                     */
11322                    ret = args.copyApk(mContainerService, true);
11323                }
11324            }
11325
11326            mRet = ret;
11327        }
11328
11329        @Override
11330        void handleReturnCode() {
11331            // If mArgs is null, then MCS couldn't be reached. When it
11332            // reconnects, it will try again to install. At that point, this
11333            // will succeed.
11334            if (mArgs != null) {
11335                processPendingInstall(mArgs, mRet);
11336            }
11337        }
11338
11339        @Override
11340        void handleServiceError() {
11341            mArgs = createInstallArgs(this);
11342            mRet = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
11343        }
11344
11345        public boolean isForwardLocked() {
11346            return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
11347        }
11348    }
11349
11350    /**
11351     * Used during creation of InstallArgs
11352     *
11353     * @param installFlags package installation flags
11354     * @return true if should be installed on external storage
11355     */
11356    private static boolean installOnExternalAsec(int installFlags) {
11357        if ((installFlags & PackageManager.INSTALL_INTERNAL) != 0) {
11358            return false;
11359        }
11360        if ((installFlags & PackageManager.INSTALL_EXTERNAL) != 0) {
11361            return true;
11362        }
11363        return false;
11364    }
11365
11366    /**
11367     * Used during creation of InstallArgs
11368     *
11369     * @param installFlags package installation flags
11370     * @return true if should be installed as forward locked
11371     */
11372    private static boolean installForwardLocked(int installFlags) {
11373        return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
11374    }
11375
11376    private InstallArgs createInstallArgs(InstallParams params) {
11377        if (params.move != null) {
11378            return new MoveInstallArgs(params);
11379        } else if (installOnExternalAsec(params.installFlags) || params.isForwardLocked()) {
11380            return new AsecInstallArgs(params);
11381        } else {
11382            return new FileInstallArgs(params);
11383        }
11384    }
11385
11386    /**
11387     * Create args that describe an existing installed package. Typically used
11388     * when cleaning up old installs, or used as a move source.
11389     */
11390    private InstallArgs createInstallArgsForExisting(int installFlags, String codePath,
11391            String resourcePath, String[] instructionSets) {
11392        final boolean isInAsec;
11393        if (installOnExternalAsec(installFlags)) {
11394            /* Apps on SD card are always in ASEC containers. */
11395            isInAsec = true;
11396        } else if (installForwardLocked(installFlags)
11397                && !codePath.startsWith(mDrmAppPrivateInstallDir.getAbsolutePath())) {
11398            /*
11399             * Forward-locked apps are only in ASEC containers if they're the
11400             * new style
11401             */
11402            isInAsec = true;
11403        } else {
11404            isInAsec = false;
11405        }
11406
11407        if (isInAsec) {
11408            return new AsecInstallArgs(codePath, instructionSets,
11409                    installOnExternalAsec(installFlags), installForwardLocked(installFlags));
11410        } else {
11411            return new FileInstallArgs(codePath, resourcePath, instructionSets);
11412        }
11413    }
11414
11415    static abstract class InstallArgs {
11416        /** @see InstallParams#origin */
11417        final OriginInfo origin;
11418        /** @see InstallParams#move */
11419        final MoveInfo move;
11420
11421        final IPackageInstallObserver2 observer;
11422        // Always refers to PackageManager flags only
11423        final int installFlags;
11424        final String installerPackageName;
11425        final String volumeUuid;
11426        final UserHandle user;
11427        final String abiOverride;
11428        final String[] installGrantPermissions;
11429        /** If non-null, drop an async trace when the install completes */
11430        final String traceMethod;
11431        final int traceCookie;
11432
11433        // The list of instruction sets supported by this app. This is currently
11434        // only used during the rmdex() phase to clean up resources. We can get rid of this
11435        // if we move dex files under the common app path.
11436        /* nullable */ String[] instructionSets;
11437
11438        InstallArgs(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
11439                int installFlags, String installerPackageName, String volumeUuid,
11440                UserHandle user, String[] instructionSets,
11441                String abiOverride, String[] installGrantPermissions,
11442                String traceMethod, int traceCookie) {
11443            this.origin = origin;
11444            this.move = move;
11445            this.installFlags = installFlags;
11446            this.observer = observer;
11447            this.installerPackageName = installerPackageName;
11448            this.volumeUuid = volumeUuid;
11449            this.user = user;
11450            this.instructionSets = instructionSets;
11451            this.abiOverride = abiOverride;
11452            this.installGrantPermissions = installGrantPermissions;
11453            this.traceMethod = traceMethod;
11454            this.traceCookie = traceCookie;
11455        }
11456
11457        abstract int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException;
11458        abstract int doPreInstall(int status);
11459
11460        /**
11461         * Rename package into final resting place. All paths on the given
11462         * scanned package should be updated to reflect the rename.
11463         */
11464        abstract boolean doRename(int status, PackageParser.Package pkg, String oldCodePath);
11465        abstract int doPostInstall(int status, int uid);
11466
11467        /** @see PackageSettingBase#codePathString */
11468        abstract String getCodePath();
11469        /** @see PackageSettingBase#resourcePathString */
11470        abstract String getResourcePath();
11471
11472        // Need installer lock especially for dex file removal.
11473        abstract void cleanUpResourcesLI();
11474        abstract boolean doPostDeleteLI(boolean delete);
11475
11476        /**
11477         * Called before the source arguments are copied. This is used mostly
11478         * for MoveParams when it needs to read the source file to put it in the
11479         * destination.
11480         */
11481        int doPreCopy() {
11482            return PackageManager.INSTALL_SUCCEEDED;
11483        }
11484
11485        /**
11486         * Called after the source arguments are copied. This is used mostly for
11487         * MoveParams when it needs to read the source file to put it in the
11488         * destination.
11489         *
11490         * @return
11491         */
11492        int doPostCopy(int uid) {
11493            return PackageManager.INSTALL_SUCCEEDED;
11494        }
11495
11496        protected boolean isFwdLocked() {
11497            return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
11498        }
11499
11500        protected boolean isExternalAsec() {
11501            return (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
11502        }
11503
11504        protected boolean isEphemeral() {
11505            return (installFlags & PackageManager.INSTALL_EPHEMERAL) != 0;
11506        }
11507
11508        UserHandle getUser() {
11509            return user;
11510        }
11511    }
11512
11513    private void removeDexFiles(List<String> allCodePaths, String[] instructionSets) {
11514        if (!allCodePaths.isEmpty()) {
11515            if (instructionSets == null) {
11516                throw new IllegalStateException("instructionSet == null");
11517            }
11518            String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
11519            for (String codePath : allCodePaths) {
11520                for (String dexCodeInstructionSet : dexCodeInstructionSets) {
11521                    int retCode = mInstaller.rmdex(codePath, dexCodeInstructionSet);
11522                    if (retCode < 0) {
11523                        Slog.w(TAG, "Couldn't remove dex file for package at location " + codePath
11524                                + ", retcode=" + retCode);
11525                        // we don't consider this to be a failure of the core package deletion
11526                    }
11527                }
11528            }
11529        }
11530    }
11531
11532    /**
11533     * Logic to handle installation of non-ASEC applications, including copying
11534     * and renaming logic.
11535     */
11536    class FileInstallArgs extends InstallArgs {
11537        private File codeFile;
11538        private File resourceFile;
11539
11540        // Example topology:
11541        // /data/app/com.example/base.apk
11542        // /data/app/com.example/split_foo.apk
11543        // /data/app/com.example/lib/arm/libfoo.so
11544        // /data/app/com.example/lib/arm64/libfoo.so
11545        // /data/app/com.example/dalvik/arm/base.apk@classes.dex
11546
11547        /** New install */
11548        FileInstallArgs(InstallParams params) {
11549            super(params.origin, params.move, params.observer, params.installFlags,
11550                    params.installerPackageName, params.volumeUuid,
11551                    params.getUser(), null /* instruction sets */, params.packageAbiOverride,
11552                    params.grantedRuntimePermissions,
11553                    params.traceMethod, params.traceCookie);
11554            if (isFwdLocked()) {
11555                throw new IllegalArgumentException("Forward locking only supported in ASEC");
11556            }
11557        }
11558
11559        /** Existing install */
11560        FileInstallArgs(String codePath, String resourcePath, String[] instructionSets) {
11561            super(OriginInfo.fromNothing(), null, null, 0, null, null, null, instructionSets,
11562                    null, null, null, 0);
11563            this.codeFile = (codePath != null) ? new File(codePath) : null;
11564            this.resourceFile = (resourcePath != null) ? new File(resourcePath) : null;
11565        }
11566
11567        int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
11568            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyApk");
11569            try {
11570                return doCopyApk(imcs, temp);
11571            } finally {
11572                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
11573            }
11574        }
11575
11576        private int doCopyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
11577            if (origin.staged) {
11578                if (DEBUG_INSTALL) Slog.d(TAG, origin.file + " already staged; skipping copy");
11579                codeFile = origin.file;
11580                resourceFile = origin.file;
11581                return PackageManager.INSTALL_SUCCEEDED;
11582            }
11583
11584            try {
11585                final boolean isEphemeral = (installFlags & PackageManager.INSTALL_EPHEMERAL) != 0;
11586                final File tempDir =
11587                        mInstallerService.allocateStageDirLegacy(volumeUuid, isEphemeral);
11588                codeFile = tempDir;
11589                resourceFile = tempDir;
11590            } catch (IOException e) {
11591                Slog.w(TAG, "Failed to create copy file: " + e);
11592                return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
11593            }
11594
11595            final IParcelFileDescriptorFactory target = new IParcelFileDescriptorFactory.Stub() {
11596                @Override
11597                public ParcelFileDescriptor open(String name, int mode) throws RemoteException {
11598                    if (!FileUtils.isValidExtFilename(name)) {
11599                        throw new IllegalArgumentException("Invalid filename: " + name);
11600                    }
11601                    try {
11602                        final File file = new File(codeFile, name);
11603                        final FileDescriptor fd = Os.open(file.getAbsolutePath(),
11604                                O_RDWR | O_CREAT, 0644);
11605                        Os.chmod(file.getAbsolutePath(), 0644);
11606                        return new ParcelFileDescriptor(fd);
11607                    } catch (ErrnoException e) {
11608                        throw new RemoteException("Failed to open: " + e.getMessage());
11609                    }
11610                }
11611            };
11612
11613            int ret = PackageManager.INSTALL_SUCCEEDED;
11614            ret = imcs.copyPackage(origin.file.getAbsolutePath(), target);
11615            if (ret != PackageManager.INSTALL_SUCCEEDED) {
11616                Slog.e(TAG, "Failed to copy package");
11617                return ret;
11618            }
11619
11620            final File libraryRoot = new File(codeFile, LIB_DIR_NAME);
11621            NativeLibraryHelper.Handle handle = null;
11622            try {
11623                handle = NativeLibraryHelper.Handle.create(codeFile);
11624                ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot,
11625                        abiOverride);
11626            } catch (IOException e) {
11627                Slog.e(TAG, "Copying native libraries failed", e);
11628                ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
11629            } finally {
11630                IoUtils.closeQuietly(handle);
11631            }
11632
11633            return ret;
11634        }
11635
11636        int doPreInstall(int status) {
11637            if (status != PackageManager.INSTALL_SUCCEEDED) {
11638                cleanUp();
11639            }
11640            return status;
11641        }
11642
11643        boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
11644            if (status != PackageManager.INSTALL_SUCCEEDED) {
11645                cleanUp();
11646                return false;
11647            }
11648
11649            final File targetDir = codeFile.getParentFile();
11650            final File beforeCodeFile = codeFile;
11651            final File afterCodeFile = getNextCodePath(targetDir, pkg.packageName);
11652
11653            if (DEBUG_INSTALL) Slog.d(TAG, "Renaming " + beforeCodeFile + " to " + afterCodeFile);
11654            try {
11655                Os.rename(beforeCodeFile.getAbsolutePath(), afterCodeFile.getAbsolutePath());
11656            } catch (ErrnoException e) {
11657                Slog.w(TAG, "Failed to rename", e);
11658                return false;
11659            }
11660
11661            if (!SELinux.restoreconRecursive(afterCodeFile)) {
11662                Slog.w(TAG, "Failed to restorecon");
11663                return false;
11664            }
11665
11666            // Reflect the rename internally
11667            codeFile = afterCodeFile;
11668            resourceFile = afterCodeFile;
11669
11670            // Reflect the rename in scanned details
11671            pkg.codePath = afterCodeFile.getAbsolutePath();
11672            pkg.baseCodePath = FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile,
11673                    pkg.baseCodePath);
11674            pkg.splitCodePaths = FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile,
11675                    pkg.splitCodePaths);
11676
11677            // Reflect the rename in app info
11678            pkg.applicationInfo.volumeUuid = pkg.volumeUuid;
11679            pkg.applicationInfo.setCodePath(pkg.codePath);
11680            pkg.applicationInfo.setBaseCodePath(pkg.baseCodePath);
11681            pkg.applicationInfo.setSplitCodePaths(pkg.splitCodePaths);
11682            pkg.applicationInfo.setResourcePath(pkg.codePath);
11683            pkg.applicationInfo.setBaseResourcePath(pkg.baseCodePath);
11684            pkg.applicationInfo.setSplitResourcePaths(pkg.splitCodePaths);
11685
11686            return true;
11687        }
11688
11689        int doPostInstall(int status, int uid) {
11690            if (status != PackageManager.INSTALL_SUCCEEDED) {
11691                cleanUp();
11692            }
11693            return status;
11694        }
11695
11696        @Override
11697        String getCodePath() {
11698            return (codeFile != null) ? codeFile.getAbsolutePath() : null;
11699        }
11700
11701        @Override
11702        String getResourcePath() {
11703            return (resourceFile != null) ? resourceFile.getAbsolutePath() : null;
11704        }
11705
11706        private boolean cleanUp() {
11707            if (codeFile == null || !codeFile.exists()) {
11708                return false;
11709            }
11710
11711            if (codeFile.isDirectory()) {
11712                mInstaller.rmPackageDir(codeFile.getAbsolutePath());
11713            } else {
11714                codeFile.delete();
11715            }
11716
11717            if (resourceFile != null && !FileUtils.contains(codeFile, resourceFile)) {
11718                resourceFile.delete();
11719            }
11720
11721            return true;
11722        }
11723
11724        void cleanUpResourcesLI() {
11725            // Try enumerating all code paths before deleting
11726            List<String> allCodePaths = Collections.EMPTY_LIST;
11727            if (codeFile != null && codeFile.exists()) {
11728                try {
11729                    final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0);
11730                    allCodePaths = pkg.getAllCodePaths();
11731                } catch (PackageParserException e) {
11732                    // Ignored; we tried our best
11733                }
11734            }
11735
11736            cleanUp();
11737            removeDexFiles(allCodePaths, instructionSets);
11738        }
11739
11740        boolean doPostDeleteLI(boolean delete) {
11741            // XXX err, shouldn't we respect the delete flag?
11742            cleanUpResourcesLI();
11743            return true;
11744        }
11745    }
11746
11747    private boolean isAsecExternal(String cid) {
11748        final String asecPath = PackageHelper.getSdFilesystem(cid);
11749        return !asecPath.startsWith(mAsecInternalPath);
11750    }
11751
11752    private static void maybeThrowExceptionForMultiArchCopy(String message, int copyRet) throws
11753            PackageManagerException {
11754        if (copyRet < 0) {
11755            if (copyRet != PackageManager.NO_NATIVE_LIBRARIES &&
11756                    copyRet != PackageManager.INSTALL_FAILED_NO_MATCHING_ABIS) {
11757                throw new PackageManagerException(copyRet, message);
11758            }
11759        }
11760    }
11761
11762    /**
11763     * Extract the MountService "container ID" from the full code path of an
11764     * .apk.
11765     */
11766    static String cidFromCodePath(String fullCodePath) {
11767        int eidx = fullCodePath.lastIndexOf("/");
11768        String subStr1 = fullCodePath.substring(0, eidx);
11769        int sidx = subStr1.lastIndexOf("/");
11770        return subStr1.substring(sidx+1, eidx);
11771    }
11772
11773    /**
11774     * Logic to handle installation of ASEC applications, including copying and
11775     * renaming logic.
11776     */
11777    class AsecInstallArgs extends InstallArgs {
11778        static final String RES_FILE_NAME = "pkg.apk";
11779        static final String PUBLIC_RES_FILE_NAME = "res.zip";
11780
11781        String cid;
11782        String packagePath;
11783        String resourcePath;
11784
11785        /** New install */
11786        AsecInstallArgs(InstallParams params) {
11787            super(params.origin, params.move, params.observer, params.installFlags,
11788                    params.installerPackageName, params.volumeUuid,
11789                    params.getUser(), null /* instruction sets */, params.packageAbiOverride,
11790                    params.grantedRuntimePermissions,
11791                    params.traceMethod, params.traceCookie);
11792        }
11793
11794        /** Existing install */
11795        AsecInstallArgs(String fullCodePath, String[] instructionSets,
11796                        boolean isExternal, boolean isForwardLocked) {
11797            super(OriginInfo.fromNothing(), null, null, (isExternal ? INSTALL_EXTERNAL : 0)
11798                    | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null,
11799                    instructionSets, null, null, null, 0);
11800            // Hackily pretend we're still looking at a full code path
11801            if (!fullCodePath.endsWith(RES_FILE_NAME)) {
11802                fullCodePath = new File(fullCodePath, RES_FILE_NAME).getAbsolutePath();
11803            }
11804
11805            // Extract cid from fullCodePath
11806            int eidx = fullCodePath.lastIndexOf("/");
11807            String subStr1 = fullCodePath.substring(0, eidx);
11808            int sidx = subStr1.lastIndexOf("/");
11809            cid = subStr1.substring(sidx+1, eidx);
11810            setMountPath(subStr1);
11811        }
11812
11813        AsecInstallArgs(String cid, String[] instructionSets, boolean isForwardLocked) {
11814            super(OriginInfo.fromNothing(), null, null, (isAsecExternal(cid) ? INSTALL_EXTERNAL : 0)
11815                    | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null,
11816                    instructionSets, null, null, null, 0);
11817            this.cid = cid;
11818            setMountPath(PackageHelper.getSdDir(cid));
11819        }
11820
11821        void createCopyFile() {
11822            cid = mInstallerService.allocateExternalStageCidLegacy();
11823        }
11824
11825        int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
11826            if (origin.staged && origin.cid != null) {
11827                if (DEBUG_INSTALL) Slog.d(TAG, origin.cid + " already staged; skipping copy");
11828                cid = origin.cid;
11829                setMountPath(PackageHelper.getSdDir(cid));
11830                return PackageManager.INSTALL_SUCCEEDED;
11831            }
11832
11833            if (temp) {
11834                createCopyFile();
11835            } else {
11836                /*
11837                 * Pre-emptively destroy the container since it's destroyed if
11838                 * copying fails due to it existing anyway.
11839                 */
11840                PackageHelper.destroySdDir(cid);
11841            }
11842
11843            final String newMountPath = imcs.copyPackageToContainer(
11844                    origin.file.getAbsolutePath(), cid, getEncryptKey(), isExternalAsec(),
11845                    isFwdLocked(), deriveAbiOverride(abiOverride, null /* settings */));
11846
11847            if (newMountPath != null) {
11848                setMountPath(newMountPath);
11849                return PackageManager.INSTALL_SUCCEEDED;
11850            } else {
11851                return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
11852            }
11853        }
11854
11855        @Override
11856        String getCodePath() {
11857            return packagePath;
11858        }
11859
11860        @Override
11861        String getResourcePath() {
11862            return resourcePath;
11863        }
11864
11865        int doPreInstall(int status) {
11866            if (status != PackageManager.INSTALL_SUCCEEDED) {
11867                // Destroy container
11868                PackageHelper.destroySdDir(cid);
11869            } else {
11870                boolean mounted = PackageHelper.isContainerMounted(cid);
11871                if (!mounted) {
11872                    String newMountPath = PackageHelper.mountSdDir(cid, getEncryptKey(),
11873                            Process.SYSTEM_UID);
11874                    if (newMountPath != null) {
11875                        setMountPath(newMountPath);
11876                    } else {
11877                        return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
11878                    }
11879                }
11880            }
11881            return status;
11882        }
11883
11884        boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
11885            String newCacheId = getNextCodePath(oldCodePath, pkg.packageName, "/" + RES_FILE_NAME);
11886            String newMountPath = null;
11887            if (PackageHelper.isContainerMounted(cid)) {
11888                // Unmount the container
11889                if (!PackageHelper.unMountSdDir(cid)) {
11890                    Slog.i(TAG, "Failed to unmount " + cid + " before renaming");
11891                    return false;
11892                }
11893            }
11894            if (!PackageHelper.renameSdDir(cid, newCacheId)) {
11895                Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId +
11896                        " which might be stale. Will try to clean up.");
11897                // Clean up the stale container and proceed to recreate.
11898                if (!PackageHelper.destroySdDir(newCacheId)) {
11899                    Slog.e(TAG, "Very strange. Cannot clean up stale container " + newCacheId);
11900                    return false;
11901                }
11902                // Successfully cleaned up stale container. Try to rename again.
11903                if (!PackageHelper.renameSdDir(cid, newCacheId)) {
11904                    Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId
11905                            + " inspite of cleaning it up.");
11906                    return false;
11907                }
11908            }
11909            if (!PackageHelper.isContainerMounted(newCacheId)) {
11910                Slog.w(TAG, "Mounting container " + newCacheId);
11911                newMountPath = PackageHelper.mountSdDir(newCacheId,
11912                        getEncryptKey(), Process.SYSTEM_UID);
11913            } else {
11914                newMountPath = PackageHelper.getSdDir(newCacheId);
11915            }
11916            if (newMountPath == null) {
11917                Slog.w(TAG, "Failed to get cache path for  " + newCacheId);
11918                return false;
11919            }
11920            Log.i(TAG, "Succesfully renamed " + cid +
11921                    " to " + newCacheId +
11922                    " at new path: " + newMountPath);
11923            cid = newCacheId;
11924
11925            final File beforeCodeFile = new File(packagePath);
11926            setMountPath(newMountPath);
11927            final File afterCodeFile = new File(packagePath);
11928
11929            // Reflect the rename in scanned details
11930            pkg.codePath = afterCodeFile.getAbsolutePath();
11931            pkg.baseCodePath = FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile,
11932                    pkg.baseCodePath);
11933            pkg.splitCodePaths = FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile,
11934                    pkg.splitCodePaths);
11935
11936            // Reflect the rename in app info
11937            pkg.applicationInfo.volumeUuid = pkg.volumeUuid;
11938            pkg.applicationInfo.setCodePath(pkg.codePath);
11939            pkg.applicationInfo.setBaseCodePath(pkg.baseCodePath);
11940            pkg.applicationInfo.setSplitCodePaths(pkg.splitCodePaths);
11941            pkg.applicationInfo.setResourcePath(pkg.codePath);
11942            pkg.applicationInfo.setBaseResourcePath(pkg.baseCodePath);
11943            pkg.applicationInfo.setSplitResourcePaths(pkg.splitCodePaths);
11944
11945            return true;
11946        }
11947
11948        private void setMountPath(String mountPath) {
11949            final File mountFile = new File(mountPath);
11950
11951            final File monolithicFile = new File(mountFile, RES_FILE_NAME);
11952            if (monolithicFile.exists()) {
11953                packagePath = monolithicFile.getAbsolutePath();
11954                if (isFwdLocked()) {
11955                    resourcePath = new File(mountFile, PUBLIC_RES_FILE_NAME).getAbsolutePath();
11956                } else {
11957                    resourcePath = packagePath;
11958                }
11959            } else {
11960                packagePath = mountFile.getAbsolutePath();
11961                resourcePath = packagePath;
11962            }
11963        }
11964
11965        int doPostInstall(int status, int uid) {
11966            if (status != PackageManager.INSTALL_SUCCEEDED) {
11967                cleanUp();
11968            } else {
11969                final int groupOwner;
11970                final String protectedFile;
11971                if (isFwdLocked()) {
11972                    groupOwner = UserHandle.getSharedAppGid(uid);
11973                    protectedFile = RES_FILE_NAME;
11974                } else {
11975                    groupOwner = -1;
11976                    protectedFile = null;
11977                }
11978
11979                if (uid < Process.FIRST_APPLICATION_UID
11980                        || !PackageHelper.fixSdPermissions(cid, groupOwner, protectedFile)) {
11981                    Slog.e(TAG, "Failed to finalize " + cid);
11982                    PackageHelper.destroySdDir(cid);
11983                    return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
11984                }
11985
11986                boolean mounted = PackageHelper.isContainerMounted(cid);
11987                if (!mounted) {
11988                    PackageHelper.mountSdDir(cid, getEncryptKey(), Process.myUid());
11989                }
11990            }
11991            return status;
11992        }
11993
11994        private void cleanUp() {
11995            if (DEBUG_SD_INSTALL) Slog.i(TAG, "cleanUp");
11996
11997            // Destroy secure container
11998            PackageHelper.destroySdDir(cid);
11999        }
12000
12001        private List<String> getAllCodePaths() {
12002            final File codeFile = new File(getCodePath());
12003            if (codeFile != null && codeFile.exists()) {
12004                try {
12005                    final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0);
12006                    return pkg.getAllCodePaths();
12007                } catch (PackageParserException e) {
12008                    // Ignored; we tried our best
12009                }
12010            }
12011            return Collections.EMPTY_LIST;
12012        }
12013
12014        void cleanUpResourcesLI() {
12015            // Enumerate all code paths before deleting
12016            cleanUpResourcesLI(getAllCodePaths());
12017        }
12018
12019        private void cleanUpResourcesLI(List<String> allCodePaths) {
12020            cleanUp();
12021            removeDexFiles(allCodePaths, instructionSets);
12022        }
12023
12024        String getPackageName() {
12025            return getAsecPackageName(cid);
12026        }
12027
12028        boolean doPostDeleteLI(boolean delete) {
12029            if (DEBUG_SD_INSTALL) Slog.i(TAG, "doPostDeleteLI() del=" + delete);
12030            final List<String> allCodePaths = getAllCodePaths();
12031            boolean mounted = PackageHelper.isContainerMounted(cid);
12032            if (mounted) {
12033                // Unmount first
12034                if (PackageHelper.unMountSdDir(cid)) {
12035                    mounted = false;
12036                }
12037            }
12038            if (!mounted && delete) {
12039                cleanUpResourcesLI(allCodePaths);
12040            }
12041            return !mounted;
12042        }
12043
12044        @Override
12045        int doPreCopy() {
12046            if (isFwdLocked()) {
12047                if (!PackageHelper.fixSdPermissions(cid,
12048                        getPackageUid(DEFAULT_CONTAINER_PACKAGE, 0), RES_FILE_NAME)) {
12049                    return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
12050                }
12051            }
12052
12053            return PackageManager.INSTALL_SUCCEEDED;
12054        }
12055
12056        @Override
12057        int doPostCopy(int uid) {
12058            if (isFwdLocked()) {
12059                if (uid < Process.FIRST_APPLICATION_UID
12060                        || !PackageHelper.fixSdPermissions(cid, UserHandle.getSharedAppGid(uid),
12061                                RES_FILE_NAME)) {
12062                    Slog.e(TAG, "Failed to finalize " + cid);
12063                    PackageHelper.destroySdDir(cid);
12064                    return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
12065                }
12066            }
12067
12068            return PackageManager.INSTALL_SUCCEEDED;
12069        }
12070    }
12071
12072    /**
12073     * Logic to handle movement of existing installed applications.
12074     */
12075    class MoveInstallArgs extends InstallArgs {
12076        private File codeFile;
12077        private File resourceFile;
12078
12079        /** New install */
12080        MoveInstallArgs(InstallParams params) {
12081            super(params.origin, params.move, params.observer, params.installFlags,
12082                    params.installerPackageName, params.volumeUuid,
12083                    params.getUser(), null /* instruction sets */, params.packageAbiOverride,
12084                    params.grantedRuntimePermissions,
12085                    params.traceMethod, params.traceCookie);
12086        }
12087
12088        int copyApk(IMediaContainerService imcs, boolean temp) {
12089            if (DEBUG_INSTALL) Slog.d(TAG, "Moving " + move.packageName + " from "
12090                    + move.fromUuid + " to " + move.toUuid);
12091            synchronized (mInstaller) {
12092                if (mInstaller.copyCompleteApp(move.fromUuid, move.toUuid, move.packageName,
12093                        move.dataAppName, move.appId, move.seinfo) != 0) {
12094                    return PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
12095                }
12096            }
12097
12098            codeFile = new File(Environment.getDataAppDirectory(move.toUuid), move.dataAppName);
12099            resourceFile = codeFile;
12100            if (DEBUG_INSTALL) Slog.d(TAG, "codeFile after move is " + codeFile);
12101
12102            return PackageManager.INSTALL_SUCCEEDED;
12103        }
12104
12105        int doPreInstall(int status) {
12106            if (status != PackageManager.INSTALL_SUCCEEDED) {
12107                cleanUp(move.toUuid);
12108            }
12109            return status;
12110        }
12111
12112        boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
12113            if (status != PackageManager.INSTALL_SUCCEEDED) {
12114                cleanUp(move.toUuid);
12115                return false;
12116            }
12117
12118            // Reflect the move in app info
12119            pkg.applicationInfo.volumeUuid = pkg.volumeUuid;
12120            pkg.applicationInfo.setCodePath(pkg.codePath);
12121            pkg.applicationInfo.setBaseCodePath(pkg.baseCodePath);
12122            pkg.applicationInfo.setSplitCodePaths(pkg.splitCodePaths);
12123            pkg.applicationInfo.setResourcePath(pkg.codePath);
12124            pkg.applicationInfo.setBaseResourcePath(pkg.baseCodePath);
12125            pkg.applicationInfo.setSplitResourcePaths(pkg.splitCodePaths);
12126
12127            return true;
12128        }
12129
12130        int doPostInstall(int status, int uid) {
12131            if (status == PackageManager.INSTALL_SUCCEEDED) {
12132                cleanUp(move.fromUuid);
12133            } else {
12134                cleanUp(move.toUuid);
12135            }
12136            return status;
12137        }
12138
12139        @Override
12140        String getCodePath() {
12141            return (codeFile != null) ? codeFile.getAbsolutePath() : null;
12142        }
12143
12144        @Override
12145        String getResourcePath() {
12146            return (resourceFile != null) ? resourceFile.getAbsolutePath() : null;
12147        }
12148
12149        private boolean cleanUp(String volumeUuid) {
12150            final File codeFile = new File(Environment.getDataAppDirectory(volumeUuid),
12151                    move.dataAppName);
12152            Slog.d(TAG, "Cleaning up " + move.packageName + " on " + volumeUuid);
12153            synchronized (mInstallLock) {
12154                // Clean up both app data and code
12155                removeDataDirsLI(volumeUuid, move.packageName);
12156                if (codeFile.isDirectory()) {
12157                    mInstaller.rmPackageDir(codeFile.getAbsolutePath());
12158                } else {
12159                    codeFile.delete();
12160                }
12161            }
12162            return true;
12163        }
12164
12165        void cleanUpResourcesLI() {
12166            throw new UnsupportedOperationException();
12167        }
12168
12169        boolean doPostDeleteLI(boolean delete) {
12170            throw new UnsupportedOperationException();
12171        }
12172    }
12173
12174    static String getAsecPackageName(String packageCid) {
12175        int idx = packageCid.lastIndexOf("-");
12176        if (idx == -1) {
12177            return packageCid;
12178        }
12179        return packageCid.substring(0, idx);
12180    }
12181
12182    // Utility method used to create code paths based on package name and available index.
12183    private static String getNextCodePath(String oldCodePath, String prefix, String suffix) {
12184        String idxStr = "";
12185        int idx = 1;
12186        // Fall back to default value of idx=1 if prefix is not
12187        // part of oldCodePath
12188        if (oldCodePath != null) {
12189            String subStr = oldCodePath;
12190            // Drop the suffix right away
12191            if (suffix != null && subStr.endsWith(suffix)) {
12192                subStr = subStr.substring(0, subStr.length() - suffix.length());
12193            }
12194            // If oldCodePath already contains prefix find out the
12195            // ending index to either increment or decrement.
12196            int sidx = subStr.lastIndexOf(prefix);
12197            if (sidx != -1) {
12198                subStr = subStr.substring(sidx + prefix.length());
12199                if (subStr != null) {
12200                    if (subStr.startsWith(INSTALL_PACKAGE_SUFFIX)) {
12201                        subStr = subStr.substring(INSTALL_PACKAGE_SUFFIX.length());
12202                    }
12203                    try {
12204                        idx = Integer.parseInt(subStr);
12205                        if (idx <= 1) {
12206                            idx++;
12207                        } else {
12208                            idx--;
12209                        }
12210                    } catch(NumberFormatException e) {
12211                    }
12212                }
12213            }
12214        }
12215        idxStr = INSTALL_PACKAGE_SUFFIX + Integer.toString(idx);
12216        return prefix + idxStr;
12217    }
12218
12219    private File getNextCodePath(File targetDir, String packageName) {
12220        int suffix = 1;
12221        File result;
12222        do {
12223            result = new File(targetDir, packageName + "-" + suffix);
12224            suffix++;
12225        } while (result.exists());
12226        return result;
12227    }
12228
12229    // Utility method that returns the relative package path with respect
12230    // to the installation directory. Like say for /data/data/com.test-1.apk
12231    // string com.test-1 is returned.
12232    static String deriveCodePathName(String codePath) {
12233        if (codePath == null) {
12234            return null;
12235        }
12236        final File codeFile = new File(codePath);
12237        final String name = codeFile.getName();
12238        if (codeFile.isDirectory()) {
12239            return name;
12240        } else if (name.endsWith(".apk") || name.endsWith(".tmp")) {
12241            final int lastDot = name.lastIndexOf('.');
12242            return name.substring(0, lastDot);
12243        } else {
12244            Slog.w(TAG, "Odd, " + codePath + " doesn't look like an APK");
12245            return null;
12246        }
12247    }
12248
12249    static class PackageInstalledInfo {
12250        String name;
12251        int uid;
12252        // The set of users that originally had this package installed.
12253        int[] origUsers;
12254        // The set of users that now have this package installed.
12255        int[] newUsers;
12256        PackageParser.Package pkg;
12257        int returnCode;
12258        String returnMsg;
12259        PackageRemovedInfo removedInfo;
12260
12261        public void setError(int code, String msg) {
12262            returnCode = code;
12263            returnMsg = msg;
12264            Slog.w(TAG, msg);
12265        }
12266
12267        public void setError(String msg, PackageParserException e) {
12268            returnCode = e.error;
12269            returnMsg = ExceptionUtils.getCompleteMessage(msg, e);
12270            Slog.w(TAG, msg, e);
12271        }
12272
12273        public void setError(String msg, PackageManagerException e) {
12274            returnCode = e.error;
12275            returnMsg = ExceptionUtils.getCompleteMessage(msg, e);
12276            Slog.w(TAG, msg, e);
12277        }
12278
12279        // In some error cases we want to convey more info back to the observer
12280        String origPackage;
12281        String origPermission;
12282    }
12283
12284    /*
12285     * Install a non-existing package.
12286     */
12287    private void installNewPackageLI(PackageParser.Package pkg, int parseFlags, int scanFlags,
12288            UserHandle user, String installerPackageName, String volumeUuid,
12289            PackageInstalledInfo res) {
12290        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installNewPackage");
12291
12292        // Remember this for later, in case we need to rollback this install
12293        String pkgName = pkg.packageName;
12294
12295        if (DEBUG_INSTALL) Slog.d(TAG, "installNewPackageLI: " + pkg);
12296        // TODO: b/23350563
12297        final boolean dataDirExists = Environment
12298                .getDataUserPackageDirectory(volumeUuid, UserHandle.USER_SYSTEM, pkgName).exists();
12299
12300        synchronized(mPackages) {
12301            if (mSettings.mRenamedPackages.containsKey(pkgName)) {
12302                // A package with the same name is already installed, though
12303                // it has been renamed to an older name.  The package we
12304                // are trying to install should be installed as an update to
12305                // the existing one, but that has not been requested, so bail.
12306                res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName
12307                        + " without first uninstalling package running as "
12308                        + mSettings.mRenamedPackages.get(pkgName));
12309                return;
12310            }
12311            if (mPackages.containsKey(pkgName)) {
12312                // Don't allow installation over an existing package with the same name.
12313                res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName
12314                        + " without first uninstalling.");
12315                return;
12316            }
12317        }
12318
12319        try {
12320            PackageParser.Package newPackage = scanPackageTracedLI(pkg, parseFlags, scanFlags,
12321                    System.currentTimeMillis(), user);
12322
12323            updateSettingsLI(newPackage, installerPackageName, volumeUuid, null, null, res, user);
12324            // delete the partially installed application. the data directory will have to be
12325            // restored if it was already existing
12326            if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
12327                // remove package from internal structures.  Note that we want deletePackageX to
12328                // delete the package data and cache directories that it created in
12329                // scanPackageLocked, unless those directories existed before we even tried to
12330                // install.
12331                deletePackageLI(pkgName, UserHandle.ALL, false, null, null,
12332                        dataDirExists ? PackageManager.DELETE_KEEP_DATA : 0,
12333                                res.removedInfo, true);
12334            }
12335
12336        } catch (PackageManagerException e) {
12337            res.setError("Package couldn't be installed in " + pkg.codePath, e);
12338        }
12339
12340        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
12341    }
12342
12343    private boolean shouldCheckUpgradeKeySetLP(PackageSetting oldPs, int scanFlags) {
12344        // Can't rotate keys during boot or if sharedUser.
12345        if (oldPs == null || (scanFlags&SCAN_INITIAL) != 0 || oldPs.sharedUser != null
12346                || !oldPs.keySetData.isUsingUpgradeKeySets()) {
12347            return false;
12348        }
12349        // app is using upgradeKeySets; make sure all are valid
12350        KeySetManagerService ksms = mSettings.mKeySetManagerService;
12351        long[] upgradeKeySets = oldPs.keySetData.getUpgradeKeySets();
12352        for (int i = 0; i < upgradeKeySets.length; i++) {
12353            if (!ksms.isIdValidKeySetId(upgradeKeySets[i])) {
12354                Slog.wtf(TAG, "Package "
12355                         + (oldPs.name != null ? oldPs.name : "<null>")
12356                         + " contains upgrade-key-set reference to unknown key-set: "
12357                         + upgradeKeySets[i]
12358                         + " reverting to signatures check.");
12359                return false;
12360            }
12361        }
12362        return true;
12363    }
12364
12365    private boolean checkUpgradeKeySetLP(PackageSetting oldPS, PackageParser.Package newPkg) {
12366        // Upgrade keysets are being used.  Determine if new package has a superset of the
12367        // required keys.
12368        long[] upgradeKeySets = oldPS.keySetData.getUpgradeKeySets();
12369        KeySetManagerService ksms = mSettings.mKeySetManagerService;
12370        for (int i = 0; i < upgradeKeySets.length; i++) {
12371            Set<PublicKey> upgradeSet = ksms.getPublicKeysFromKeySetLPr(upgradeKeySets[i]);
12372            if (upgradeSet != null && newPkg.mSigningKeys.containsAll(upgradeSet)) {
12373                return true;
12374            }
12375        }
12376        return false;
12377    }
12378
12379    private void replacePackageLI(PackageParser.Package pkg, int parseFlags, int scanFlags,
12380            UserHandle user, String installerPackageName, String volumeUuid,
12381            PackageInstalledInfo res) {
12382        final boolean isEphemeral = (parseFlags & PackageParser.PARSE_IS_EPHEMERAL) != 0;
12383
12384        final PackageParser.Package oldPackage;
12385        final String pkgName = pkg.packageName;
12386        final int[] allUsers;
12387        final boolean[] perUserInstalled;
12388
12389        // First find the old package info and check signatures
12390        synchronized(mPackages) {
12391            oldPackage = mPackages.get(pkgName);
12392            final boolean oldIsEphemeral = oldPackage.applicationInfo.isEphemeralApp();
12393            if (isEphemeral && !oldIsEphemeral) {
12394                // can't downgrade from full to ephemeral
12395                Slog.w(TAG, "Can't replace app with ephemeral: " + pkgName);
12396                res.returnCode = PackageManager.INSTALL_FAILED_EPHEMERAL_INVALID;
12397                return;
12398            }
12399            if (DEBUG_INSTALL) Slog.d(TAG, "replacePackageLI: new=" + pkg + ", old=" + oldPackage);
12400            final PackageSetting ps = mSettings.mPackages.get(pkgName);
12401            if (shouldCheckUpgradeKeySetLP(ps, scanFlags)) {
12402                if(!checkUpgradeKeySetLP(ps, pkg)) {
12403                    res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
12404                            "New package not signed by keys specified by upgrade-keysets: "
12405                            + pkgName);
12406                    return;
12407                }
12408            } else {
12409                // default to original signature matching
12410                if (compareSignatures(oldPackage.mSignatures, pkg.mSignatures)
12411                    != PackageManager.SIGNATURE_MATCH) {
12412                    res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
12413                            "New package has a different signature: " + pkgName);
12414                    return;
12415                }
12416            }
12417
12418            // In case of rollback, remember per-user/profile install state
12419            allUsers = sUserManager.getUserIds();
12420            perUserInstalled = new boolean[allUsers.length];
12421            for (int i = 0; i < allUsers.length; i++) {
12422                perUserInstalled[i] = ps != null ? ps.getInstalled(allUsers[i]) : false;
12423            }
12424        }
12425
12426        boolean sysPkg = (isSystemApp(oldPackage));
12427        if (sysPkg) {
12428            replaceSystemPackageLI(oldPackage, pkg, parseFlags, scanFlags,
12429                    user, allUsers, perUserInstalled, installerPackageName, volumeUuid, res);
12430        } else {
12431            replaceNonSystemPackageLI(oldPackage, pkg, parseFlags, scanFlags,
12432                    user, allUsers, perUserInstalled, installerPackageName, volumeUuid, res);
12433        }
12434    }
12435
12436    private void replaceNonSystemPackageLI(PackageParser.Package deletedPackage,
12437            PackageParser.Package pkg, int parseFlags, int scanFlags, UserHandle user,
12438            int[] allUsers, boolean[] perUserInstalled, String installerPackageName,
12439            String volumeUuid, PackageInstalledInfo res) {
12440        String pkgName = deletedPackage.packageName;
12441        boolean deletedPkg = true;
12442        boolean updatedSettings = false;
12443
12444        if (DEBUG_INSTALL) Slog.d(TAG, "replaceNonSystemPackageLI: new=" + pkg + ", old="
12445                + deletedPackage);
12446        long origUpdateTime;
12447        if (pkg.mExtras != null) {
12448            origUpdateTime = ((PackageSetting)pkg.mExtras).lastUpdateTime;
12449        } else {
12450            origUpdateTime = 0;
12451        }
12452
12453        // First delete the existing package while retaining the data directory
12454        if (!deletePackageLI(pkgName, null, true, null, null, PackageManager.DELETE_KEEP_DATA,
12455                res.removedInfo, true)) {
12456            // If the existing package wasn't successfully deleted
12457            res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE, "replaceNonSystemPackageLI");
12458            deletedPkg = false;
12459        } else {
12460            // Successfully deleted the old package; proceed with replace.
12461
12462            // If deleted package lived in a container, give users a chance to
12463            // relinquish resources before killing.
12464            if (deletedPackage.isForwardLocked() || isExternal(deletedPackage)) {
12465                if (DEBUG_INSTALL) {
12466                    Slog.i(TAG, "upgrading pkg " + deletedPackage + " is ASEC-hosted -> UNAVAILABLE");
12467                }
12468                final int[] uidArray = new int[] { deletedPackage.applicationInfo.uid };
12469                final ArrayList<String> pkgList = new ArrayList<String>(1);
12470                pkgList.add(deletedPackage.applicationInfo.packageName);
12471                sendResourcesChangedBroadcast(false, true, pkgList, uidArray, null);
12472            }
12473
12474            deleteCodeCacheDirsLI(pkg.volumeUuid, pkgName);
12475            try {
12476                final PackageParser.Package newPackage = scanPackageTracedLI(pkg, parseFlags,
12477                        scanFlags | SCAN_UPDATE_TIME, System.currentTimeMillis(), user);
12478                updateSettingsLI(newPackage, installerPackageName, volumeUuid, allUsers,
12479                        perUserInstalled, res, user);
12480                updatedSettings = true;
12481            } catch (PackageManagerException e) {
12482                res.setError("Package couldn't be installed in " + pkg.codePath, e);
12483            }
12484        }
12485
12486        if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
12487            // remove package from internal structures.  Note that we want deletePackageX to
12488            // delete the package data and cache directories that it created in
12489            // scanPackageLocked, unless those directories existed before we even tried to
12490            // install.
12491            if(updatedSettings) {
12492                if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, rolling pack: " + pkgName);
12493                deletePackageLI(
12494                        pkgName, null, true, allUsers, perUserInstalled,
12495                        PackageManager.DELETE_KEEP_DATA,
12496                                res.removedInfo, true);
12497            }
12498            // Since we failed to install the new package we need to restore the old
12499            // package that we deleted.
12500            if (deletedPkg) {
12501                if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, reinstalling: " + deletedPackage);
12502                File restoreFile = new File(deletedPackage.codePath);
12503                // Parse old package
12504                boolean oldExternal = isExternal(deletedPackage);
12505                int oldParseFlags  = mDefParseFlags | PackageParser.PARSE_CHATTY |
12506                        (deletedPackage.isForwardLocked() ? PackageParser.PARSE_FORWARD_LOCK : 0) |
12507                        (oldExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0);
12508                int oldScanFlags = SCAN_UPDATE_SIGNATURE | SCAN_UPDATE_TIME;
12509                try {
12510                    scanPackageTracedLI(restoreFile, oldParseFlags, oldScanFlags, origUpdateTime,
12511                            null);
12512                } catch (PackageManagerException e) {
12513                    Slog.e(TAG, "Failed to restore package : " + pkgName + " after failed upgrade: "
12514                            + e.getMessage());
12515                    return;
12516                }
12517                // Restore of old package succeeded. Update permissions.
12518                // writer
12519                synchronized (mPackages) {
12520                    updatePermissionsLPw(deletedPackage.packageName, deletedPackage,
12521                            UPDATE_PERMISSIONS_ALL);
12522                    // can downgrade to reader
12523                    mSettings.writeLPr();
12524                }
12525                Slog.i(TAG, "Successfully restored package : " + pkgName + " after failed upgrade");
12526            }
12527        }
12528    }
12529
12530    private void replaceSystemPackageLI(PackageParser.Package deletedPackage,
12531            PackageParser.Package pkg, int parseFlags, int scanFlags, UserHandle user,
12532            int[] allUsers, boolean[] perUserInstalled, String installerPackageName,
12533            String volumeUuid, PackageInstalledInfo res) {
12534        if (DEBUG_INSTALL) Slog.d(TAG, "replaceSystemPackageLI: new=" + pkg
12535                + ", old=" + deletedPackage);
12536        boolean disabledSystem = false;
12537        boolean updatedSettings = false;
12538        parseFlags |= PackageParser.PARSE_IS_SYSTEM;
12539        if ((deletedPackage.applicationInfo.privateFlags&ApplicationInfo.PRIVATE_FLAG_PRIVILEGED)
12540                != 0) {
12541            parseFlags |= PackageParser.PARSE_IS_PRIVILEGED;
12542        }
12543        String packageName = deletedPackage.packageName;
12544        if (packageName == null) {
12545            res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE,
12546                    "Attempt to delete null packageName.");
12547            return;
12548        }
12549        PackageParser.Package oldPkg;
12550        PackageSetting oldPkgSetting;
12551        // reader
12552        synchronized (mPackages) {
12553            oldPkg = mPackages.get(packageName);
12554            oldPkgSetting = mSettings.mPackages.get(packageName);
12555            if((oldPkg == null) || (oldPkg.applicationInfo == null) ||
12556                    (oldPkgSetting == null)) {
12557                res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE,
12558                        "Couldn't find package " + packageName + " information");
12559                return;
12560            }
12561        }
12562
12563        killApplication(packageName, oldPkg.applicationInfo.uid, "replace sys pkg");
12564
12565        res.removedInfo.uid = oldPkg.applicationInfo.uid;
12566        res.removedInfo.removedPackage = packageName;
12567        // Remove existing system package
12568        removePackageLI(oldPkgSetting, true);
12569        // writer
12570        synchronized (mPackages) {
12571            disabledSystem = mSettings.disableSystemPackageLPw(packageName);
12572            if (!disabledSystem && deletedPackage != null) {
12573                // We didn't need to disable the .apk as a current system package,
12574                // which means we are replacing another update that is already
12575                // installed.  We need to make sure to delete the older one's .apk.
12576                res.removedInfo.args = createInstallArgsForExisting(0,
12577                        deletedPackage.applicationInfo.getCodePath(),
12578                        deletedPackage.applicationInfo.getResourcePath(),
12579                        getAppDexInstructionSets(deletedPackage.applicationInfo));
12580            } else {
12581                res.removedInfo.args = null;
12582            }
12583        }
12584
12585        // Successfully disabled the old package. Now proceed with re-installation
12586        deleteCodeCacheDirsLI(pkg.volumeUuid, packageName);
12587
12588        res.returnCode = PackageManager.INSTALL_SUCCEEDED;
12589        pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
12590
12591        PackageParser.Package newPackage = null;
12592        try {
12593            newPackage = scanPackageTracedLI(pkg, parseFlags, scanFlags, 0, user);
12594            if (newPackage.mExtras != null) {
12595                final PackageSetting newPkgSetting = (PackageSetting) newPackage.mExtras;
12596                newPkgSetting.firstInstallTime = oldPkgSetting.firstInstallTime;
12597                newPkgSetting.lastUpdateTime = System.currentTimeMillis();
12598
12599                // is the update attempting to change shared user? that isn't going to work...
12600                if (oldPkgSetting.sharedUser != newPkgSetting.sharedUser) {
12601                    res.setError(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
12602                            "Forbidding shared user change from " + oldPkgSetting.sharedUser
12603                            + " to " + newPkgSetting.sharedUser);
12604                    updatedSettings = true;
12605                }
12606            }
12607
12608            if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
12609                updateSettingsLI(newPackage, installerPackageName, volumeUuid, allUsers,
12610                        perUserInstalled, res, user);
12611                updatedSettings = true;
12612            }
12613
12614        } catch (PackageManagerException e) {
12615            res.setError("Package couldn't be installed in " + pkg.codePath, e);
12616        }
12617
12618        if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
12619            // Re installation failed. Restore old information
12620            // Remove new pkg information
12621            if (newPackage != null) {
12622                removeInstalledPackageLI(newPackage, true);
12623            }
12624            // Add back the old system package
12625            try {
12626                scanPackageTracedLI(oldPkg, parseFlags, SCAN_UPDATE_SIGNATURE, 0, user);
12627            } catch (PackageManagerException e) {
12628                Slog.e(TAG, "Failed to restore original package: " + e.getMessage());
12629            }
12630            // Restore the old system information in Settings
12631            synchronized (mPackages) {
12632                if (disabledSystem) {
12633                    mSettings.enableSystemPackageLPw(packageName);
12634                }
12635                if (updatedSettings) {
12636                    mSettings.setInstallerPackageName(packageName,
12637                            oldPkgSetting.installerPackageName);
12638                }
12639                mSettings.writeLPr();
12640            }
12641        }
12642    }
12643
12644    private int[] revokeUnusedSharedUserPermissionsLPw(SharedUserSetting su, int[] allUserIds) {
12645        // Collect all used permissions in the UID
12646        ArraySet<String> usedPermissions = new ArraySet<>();
12647        final int packageCount = su.packages.size();
12648        for (int i = 0; i < packageCount; i++) {
12649            PackageSetting ps = su.packages.valueAt(i);
12650            if (ps.pkg == null) {
12651                continue;
12652            }
12653            final int requestedPermCount = ps.pkg.requestedPermissions.size();
12654            for (int j = 0; j < requestedPermCount; j++) {
12655                String permission = ps.pkg.requestedPermissions.get(j);
12656                BasePermission bp = mSettings.mPermissions.get(permission);
12657                if (bp != null) {
12658                    usedPermissions.add(permission);
12659                }
12660            }
12661        }
12662
12663        PermissionsState permissionsState = su.getPermissionsState();
12664        // Prune install permissions
12665        List<PermissionState> installPermStates = permissionsState.getInstallPermissionStates();
12666        final int installPermCount = installPermStates.size();
12667        for (int i = installPermCount - 1; i >= 0;  i--) {
12668            PermissionState permissionState = installPermStates.get(i);
12669            if (!usedPermissions.contains(permissionState.getName())) {
12670                BasePermission bp = mSettings.mPermissions.get(permissionState.getName());
12671                if (bp != null) {
12672                    permissionsState.revokeInstallPermission(bp);
12673                    permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
12674                            PackageManager.MASK_PERMISSION_FLAGS, 0);
12675                }
12676            }
12677        }
12678
12679        int[] runtimePermissionChangedUserIds = EmptyArray.INT;
12680
12681        // Prune runtime permissions
12682        for (int userId : allUserIds) {
12683            List<PermissionState> runtimePermStates = permissionsState
12684                    .getRuntimePermissionStates(userId);
12685            final int runtimePermCount = runtimePermStates.size();
12686            for (int i = runtimePermCount - 1; i >= 0; i--) {
12687                PermissionState permissionState = runtimePermStates.get(i);
12688                if (!usedPermissions.contains(permissionState.getName())) {
12689                    BasePermission bp = mSettings.mPermissions.get(permissionState.getName());
12690                    if (bp != null) {
12691                        permissionsState.revokeRuntimePermission(bp, userId);
12692                        permissionsState.updatePermissionFlags(bp, userId,
12693                                PackageManager.MASK_PERMISSION_FLAGS, 0);
12694                        runtimePermissionChangedUserIds = ArrayUtils.appendInt(
12695                                runtimePermissionChangedUserIds, userId);
12696                    }
12697                }
12698            }
12699        }
12700
12701        return runtimePermissionChangedUserIds;
12702    }
12703
12704    private void updateSettingsLI(PackageParser.Package newPackage, String installerPackageName,
12705            String volumeUuid, int[] allUsers, boolean[] perUserInstalled, PackageInstalledInfo res,
12706            UserHandle user) {
12707        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");
12708
12709        String pkgName = newPackage.packageName;
12710        synchronized (mPackages) {
12711            //write settings. the installStatus will be incomplete at this stage.
12712            //note that the new package setting would have already been
12713            //added to mPackages. It hasn't been persisted yet.
12714            mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_INCOMPLETE);
12715            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings");
12716            mSettings.writeLPr();
12717            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
12718        }
12719
12720        if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + newPackage.codePath);
12721        synchronized (mPackages) {
12722            updatePermissionsLPw(newPackage.packageName, newPackage,
12723                    UPDATE_PERMISSIONS_REPLACE_PKG | (newPackage.permissions.size() > 0
12724                            ? UPDATE_PERMISSIONS_ALL : 0));
12725            // For system-bundled packages, we assume that installing an upgraded version
12726            // of the package implies that the user actually wants to run that new code,
12727            // so we enable the package.
12728            PackageSetting ps = mSettings.mPackages.get(pkgName);
12729            if (ps != null) {
12730                if (isSystemApp(newPackage)) {
12731                    // NB: implicit assumption that system package upgrades apply to all users
12732                    if (DEBUG_INSTALL) {
12733                        Slog.d(TAG, "Implicitly enabling system package on upgrade: " + pkgName);
12734                    }
12735                    if (res.origUsers != null) {
12736                        for (int userHandle : res.origUsers) {
12737                            ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT,
12738                                    userHandle, installerPackageName);
12739                        }
12740                    }
12741                    // Also convey the prior install/uninstall state
12742                    if (allUsers != null && perUserInstalled != null) {
12743                        for (int i = 0; i < allUsers.length; i++) {
12744                            if (DEBUG_INSTALL) {
12745                                Slog.d(TAG, "    user " + allUsers[i]
12746                                        + " => " + perUserInstalled[i]);
12747                            }
12748                            ps.setInstalled(perUserInstalled[i], allUsers[i]);
12749                        }
12750                        // these install state changes will be persisted in the
12751                        // upcoming call to mSettings.writeLPr().
12752                    }
12753                }
12754                // It's implied that when a user requests installation, they want the app to be
12755                // installed and enabled.
12756                int userId = user.getIdentifier();
12757                if (userId != UserHandle.USER_ALL) {
12758                    ps.setInstalled(true, userId);
12759                    ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, userId, installerPackageName);
12760                }
12761            }
12762            res.name = pkgName;
12763            res.uid = newPackage.applicationInfo.uid;
12764            res.pkg = newPackage;
12765            mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_COMPLETE);
12766            mSettings.setInstallerPackageName(pkgName, installerPackageName);
12767            res.returnCode = PackageManager.INSTALL_SUCCEEDED;
12768            //to update install status
12769            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings");
12770            mSettings.writeLPr();
12771            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
12772        }
12773
12774        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
12775    }
12776
12777    private void installPackageTracedLI(InstallArgs args, PackageInstalledInfo res) {
12778        try {
12779            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installPackage");
12780            installPackageLI(args, res);
12781        } finally {
12782            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
12783        }
12784    }
12785
12786    private void installPackageLI(InstallArgs args, PackageInstalledInfo res) {
12787        final int installFlags = args.installFlags;
12788        final String installerPackageName = args.installerPackageName;
12789        final String volumeUuid = args.volumeUuid;
12790        final File tmpPackageFile = new File(args.getCodePath());
12791        final boolean forwardLocked = ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0);
12792        final boolean onExternal = (((installFlags & PackageManager.INSTALL_EXTERNAL) != 0)
12793                || (args.volumeUuid != null));
12794        final boolean ephemeral = ((installFlags & PackageManager.INSTALL_EPHEMERAL) != 0);
12795        boolean replace = false;
12796        int scanFlags = SCAN_NEW_INSTALL | SCAN_UPDATE_SIGNATURE;
12797        if (args.move != null) {
12798            // moving a complete application; perfom an initial scan on the new install location
12799            scanFlags |= SCAN_INITIAL;
12800        }
12801        // Result object to be returned
12802        res.returnCode = PackageManager.INSTALL_SUCCEEDED;
12803
12804        if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile);
12805
12806        // Sanity check
12807        if (ephemeral && (forwardLocked || onExternal)) {
12808            Slog.i(TAG, "Incompatible ephemeral install; fwdLocked=" + forwardLocked
12809                    + " external=" + onExternal);
12810            res.returnCode = PackageManager.INSTALL_FAILED_EPHEMERAL_INVALID;
12811            return;
12812        }
12813
12814        // Retrieve PackageSettings and parse package
12815        final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY
12816                | PackageParser.PARSE_ENFORCE_CODE
12817                | (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0)
12818                | (onExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0)
12819                | (ephemeral ? PackageParser.PARSE_IS_EPHEMERAL : 0);
12820        PackageParser pp = new PackageParser();
12821        pp.setSeparateProcesses(mSeparateProcesses);
12822        pp.setDisplayMetrics(mMetrics);
12823
12824        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
12825        final PackageParser.Package pkg;
12826        try {
12827            pkg = pp.parsePackage(tmpPackageFile, parseFlags);
12828        } catch (PackageParserException e) {
12829            res.setError("Failed parse during installPackageLI", e);
12830            return;
12831        } finally {
12832            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
12833        }
12834
12835        // Mark that we have an install time CPU ABI override.
12836        pkg.cpuAbiOverride = args.abiOverride;
12837
12838        String pkgName = res.name = pkg.packageName;
12839        if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_TEST_ONLY) != 0) {
12840            if ((installFlags & PackageManager.INSTALL_ALLOW_TEST) == 0) {
12841                res.setError(INSTALL_FAILED_TEST_ONLY, "installPackageLI");
12842                return;
12843            }
12844        }
12845
12846        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "collectCertificates");
12847        try {
12848            pp.collectCertificates(pkg, parseFlags);
12849        } catch (PackageParserException e) {
12850            res.setError("Failed collect during installPackageLI", e);
12851            return;
12852        } finally {
12853            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
12854        }
12855
12856        // Get rid of all references to package scan path via parser.
12857        pp = null;
12858        String oldCodePath = null;
12859        boolean systemApp = false;
12860        synchronized (mPackages) {
12861            // Check if installing already existing package
12862            if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
12863                String oldName = mSettings.mRenamedPackages.get(pkgName);
12864                if (pkg.mOriginalPackages != null
12865                        && pkg.mOriginalPackages.contains(oldName)
12866                        && mPackages.containsKey(oldName)) {
12867                    // This package is derived from an original package,
12868                    // and this device has been updating from that original
12869                    // name.  We must continue using the original name, so
12870                    // rename the new package here.
12871                    pkg.setPackageName(oldName);
12872                    pkgName = pkg.packageName;
12873                    replace = true;
12874                    if (DEBUG_INSTALL) Slog.d(TAG, "Replacing existing renamed package: oldName="
12875                            + oldName + " pkgName=" + pkgName);
12876                } else if (mPackages.containsKey(pkgName)) {
12877                    // This package, under its official name, already exists
12878                    // on the device; we should replace it.
12879                    replace = true;
12880                    if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing pacakge: " + pkgName);
12881                }
12882
12883                // Prevent apps opting out from runtime permissions
12884                if (replace) {
12885                    PackageParser.Package oldPackage = mPackages.get(pkgName);
12886                    final int oldTargetSdk = oldPackage.applicationInfo.targetSdkVersion;
12887                    final int newTargetSdk = pkg.applicationInfo.targetSdkVersion;
12888                    if (oldTargetSdk > Build.VERSION_CODES.LOLLIPOP_MR1
12889                            && newTargetSdk <= Build.VERSION_CODES.LOLLIPOP_MR1) {
12890                        res.setError(PackageManager.INSTALL_FAILED_PERMISSION_MODEL_DOWNGRADE,
12891                                "Package " + pkg.packageName + " new target SDK " + newTargetSdk
12892                                        + " doesn't support runtime permissions but the old"
12893                                        + " target SDK " + oldTargetSdk + " does.");
12894                        return;
12895                    }
12896                }
12897            }
12898
12899            PackageSetting ps = mSettings.mPackages.get(pkgName);
12900            if (ps != null) {
12901                if (DEBUG_INSTALL) Slog.d(TAG, "Existing package: " + ps);
12902
12903                // Quick sanity check that we're signed correctly if updating;
12904                // we'll check this again later when scanning, but we want to
12905                // bail early here before tripping over redefined permissions.
12906                if (shouldCheckUpgradeKeySetLP(ps, scanFlags)) {
12907                    if (!checkUpgradeKeySetLP(ps, pkg)) {
12908                        res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
12909                                + pkg.packageName + " upgrade keys do not match the "
12910                                + "previously installed version");
12911                        return;
12912                    }
12913                } else {
12914                    try {
12915                        verifySignaturesLP(ps, pkg);
12916                    } catch (PackageManagerException e) {
12917                        res.setError(e.error, e.getMessage());
12918                        return;
12919                    }
12920                }
12921
12922                oldCodePath = mSettings.mPackages.get(pkgName).codePathString;
12923                if (ps.pkg != null && ps.pkg.applicationInfo != null) {
12924                    systemApp = (ps.pkg.applicationInfo.flags &
12925                            ApplicationInfo.FLAG_SYSTEM) != 0;
12926                }
12927                res.origUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
12928            }
12929
12930            // Check whether the newly-scanned package wants to define an already-defined perm
12931            int N = pkg.permissions.size();
12932            for (int i = N-1; i >= 0; i--) {
12933                PackageParser.Permission perm = pkg.permissions.get(i);
12934                BasePermission bp = mSettings.mPermissions.get(perm.info.name);
12935                if (bp != null) {
12936                    // If the defining package is signed with our cert, it's okay.  This
12937                    // also includes the "updating the same package" case, of course.
12938                    // "updating same package" could also involve key-rotation.
12939                    final boolean sigsOk;
12940                    if (bp.sourcePackage.equals(pkg.packageName)
12941                            && (bp.packageSetting instanceof PackageSetting)
12942                            && (shouldCheckUpgradeKeySetLP((PackageSetting) bp.packageSetting,
12943                                    scanFlags))) {
12944                        sigsOk = checkUpgradeKeySetLP((PackageSetting) bp.packageSetting, pkg);
12945                    } else {
12946                        sigsOk = compareSignatures(bp.packageSetting.signatures.mSignatures,
12947                                pkg.mSignatures) == PackageManager.SIGNATURE_MATCH;
12948                    }
12949                    if (!sigsOk) {
12950                        // If the owning package is the system itself, we log but allow
12951                        // install to proceed; we fail the install on all other permission
12952                        // redefinitions.
12953                        if (!bp.sourcePackage.equals("android")) {
12954                            res.setError(INSTALL_FAILED_DUPLICATE_PERMISSION, "Package "
12955                                    + pkg.packageName + " attempting to redeclare permission "
12956                                    + perm.info.name + " already owned by " + bp.sourcePackage);
12957                            res.origPermission = perm.info.name;
12958                            res.origPackage = bp.sourcePackage;
12959                            return;
12960                        } else {
12961                            Slog.w(TAG, "Package " + pkg.packageName
12962                                    + " attempting to redeclare system permission "
12963                                    + perm.info.name + "; ignoring new declaration");
12964                            pkg.permissions.remove(i);
12965                        }
12966                    }
12967                }
12968            }
12969
12970        }
12971
12972        if (systemApp) {
12973            if (onExternal) {
12974                // Abort update; system app can't be replaced with app on sdcard
12975                res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
12976                        "Cannot install updates to system apps on sdcard");
12977                return;
12978            } else if (ephemeral) {
12979                // Abort update; system app can't be replaced with an ephemeral app
12980                res.setError(INSTALL_FAILED_EPHEMERAL_INVALID,
12981                        "Cannot update a system app with an ephemeral app");
12982                return;
12983            }
12984        }
12985
12986        if (args.move != null) {
12987            // We did an in-place move, so dex is ready to roll
12988            scanFlags |= SCAN_NO_DEX;
12989            scanFlags |= SCAN_MOVE;
12990
12991            synchronized (mPackages) {
12992                final PackageSetting ps = mSettings.mPackages.get(pkgName);
12993                if (ps == null) {
12994                    res.setError(INSTALL_FAILED_INTERNAL_ERROR,
12995                            "Missing settings for moved package " + pkgName);
12996                }
12997
12998                // We moved the entire application as-is, so bring over the
12999                // previously derived ABI information.
13000                pkg.applicationInfo.primaryCpuAbi = ps.primaryCpuAbiString;
13001                pkg.applicationInfo.secondaryCpuAbi = ps.secondaryCpuAbiString;
13002            }
13003
13004        } else if (!forwardLocked && !pkg.applicationInfo.isExternalAsec()) {
13005            // Enable SCAN_NO_DEX flag to skip dexopt at a later stage
13006            scanFlags |= SCAN_NO_DEX;
13007
13008            try {
13009                derivePackageAbi(pkg, new File(pkg.codePath), args.abiOverride,
13010                        true /* extract libs */);
13011            } catch (PackageManagerException pme) {
13012                Slog.e(TAG, "Error deriving application ABI", pme);
13013                res.setError(INSTALL_FAILED_INTERNAL_ERROR, "Error deriving application ABI");
13014                return;
13015            }
13016        }
13017
13018        if (!args.doRename(res.returnCode, pkg, oldCodePath)) {
13019            res.setError(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename");
13020            return;
13021        }
13022
13023        startIntentFilterVerifications(args.user.getIdentifier(), replace, pkg);
13024
13025        if (replace) {
13026            replacePackageLI(pkg, parseFlags, scanFlags | SCAN_REPLACING, args.user,
13027                    installerPackageName, volumeUuid, res);
13028        } else {
13029            installNewPackageLI(pkg, parseFlags, scanFlags | SCAN_DELETE_DATA_ON_FAILURES,
13030                    args.user, installerPackageName, volumeUuid, res);
13031        }
13032        synchronized (mPackages) {
13033            final PackageSetting ps = mSettings.mPackages.get(pkgName);
13034            if (ps != null) {
13035                res.newUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
13036            }
13037        }
13038    }
13039
13040    private void startIntentFilterVerifications(int userId, boolean replacing,
13041            PackageParser.Package pkg) {
13042        if (mIntentFilterVerifierComponent == null) {
13043            Slog.w(TAG, "No IntentFilter verification will not be done as "
13044                    + "there is no IntentFilterVerifier available!");
13045            return;
13046        }
13047
13048        final int verifierUid = getPackageUid(
13049                mIntentFilterVerifierComponent.getPackageName(),
13050                (userId == UserHandle.USER_ALL) ? UserHandle.USER_SYSTEM : userId);
13051
13052        mHandler.removeMessages(START_INTENT_FILTER_VERIFICATIONS);
13053        final Message msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS);
13054        msg.obj = new IFVerificationParams(pkg, replacing, userId, verifierUid);
13055        mHandler.sendMessage(msg);
13056    }
13057
13058    private void verifyIntentFiltersIfNeeded(int userId, int verifierUid, boolean replacing,
13059            PackageParser.Package pkg) {
13060        int size = pkg.activities.size();
13061        if (size == 0) {
13062            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
13063                    "No activity, so no need to verify any IntentFilter!");
13064            return;
13065        }
13066
13067        final boolean hasDomainURLs = hasDomainURLs(pkg);
13068        if (!hasDomainURLs) {
13069            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
13070                    "No domain URLs, so no need to verify any IntentFilter!");
13071            return;
13072        }
13073
13074        if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Checking for userId:" + userId
13075                + " if any IntentFilter from the " + size
13076                + " Activities needs verification ...");
13077
13078        int count = 0;
13079        final String packageName = pkg.packageName;
13080
13081        synchronized (mPackages) {
13082            // If this is a new install and we see that we've already run verification for this
13083            // package, we have nothing to do: it means the state was restored from backup.
13084            if (!replacing) {
13085                IntentFilterVerificationInfo ivi =
13086                        mSettings.getIntentFilterVerificationLPr(packageName);
13087                if (ivi != null) {
13088                    if (DEBUG_DOMAIN_VERIFICATION) {
13089                        Slog.i(TAG, "Package " + packageName+ " already verified: status="
13090                                + ivi.getStatusString());
13091                    }
13092                    return;
13093                }
13094            }
13095
13096            // If any filters need to be verified, then all need to be.
13097            boolean needToVerify = false;
13098            for (PackageParser.Activity a : pkg.activities) {
13099                for (ActivityIntentInfo filter : a.intents) {
13100                    if (filter.needsVerification() && needsNetworkVerificationLPr(filter)) {
13101                        if (DEBUG_DOMAIN_VERIFICATION) {
13102                            Slog.d(TAG, "Intent filter needs verification, so processing all filters");
13103                        }
13104                        needToVerify = true;
13105                        break;
13106                    }
13107                }
13108            }
13109
13110            if (needToVerify) {
13111                final int verificationId = mIntentFilterVerificationToken++;
13112                for (PackageParser.Activity a : pkg.activities) {
13113                    for (ActivityIntentInfo filter : a.intents) {
13114                        if (filter.handlesWebUris(true) && needsNetworkVerificationLPr(filter)) {
13115                            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
13116                                    "Verification needed for IntentFilter:" + filter.toString());
13117                            mIntentFilterVerifier.addOneIntentFilterVerification(
13118                                    verifierUid, userId, verificationId, filter, packageName);
13119                            count++;
13120                        }
13121                    }
13122                }
13123            }
13124        }
13125
13126        if (count > 0) {
13127            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Starting " + count
13128                    + " IntentFilter verification" + (count > 1 ? "s" : "")
13129                    +  " for userId:" + userId);
13130            mIntentFilterVerifier.startVerifications(userId);
13131        } else {
13132            if (DEBUG_DOMAIN_VERIFICATION) {
13133                Slog.d(TAG, "No filters or not all autoVerify for " + packageName);
13134            }
13135        }
13136    }
13137
13138    private boolean needsNetworkVerificationLPr(ActivityIntentInfo filter) {
13139        final ComponentName cn  = filter.activity.getComponentName();
13140        final String packageName = cn.getPackageName();
13141
13142        IntentFilterVerificationInfo ivi = mSettings.getIntentFilterVerificationLPr(
13143                packageName);
13144        if (ivi == null) {
13145            return true;
13146        }
13147        int status = ivi.getStatus();
13148        switch (status) {
13149            case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED:
13150            case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK:
13151                return true;
13152
13153            default:
13154                // Nothing to do
13155                return false;
13156        }
13157    }
13158
13159    private static boolean isMultiArch(ApplicationInfo info) {
13160        return (info.flags & ApplicationInfo.FLAG_MULTIARCH) != 0;
13161    }
13162
13163    private static boolean isExternal(PackageParser.Package pkg) {
13164        return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
13165    }
13166
13167    private static boolean isExternal(PackageSetting ps) {
13168        return (ps.pkgFlags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
13169    }
13170
13171    private static boolean isEphemeral(PackageParser.Package pkg) {
13172        return pkg.applicationInfo.isEphemeralApp();
13173    }
13174
13175    private static boolean isEphemeral(PackageSetting ps) {
13176        return ps.pkg != null && isEphemeral(ps.pkg);
13177    }
13178
13179    private static boolean isSystemApp(PackageParser.Package pkg) {
13180        return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
13181    }
13182
13183    private static boolean isPrivilegedApp(PackageParser.Package pkg) {
13184        return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0;
13185    }
13186
13187    private static boolean hasDomainURLs(PackageParser.Package pkg) {
13188        return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) != 0;
13189    }
13190
13191    private static boolean isSystemApp(PackageSetting ps) {
13192        return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0;
13193    }
13194
13195    private static boolean isUpdatedSystemApp(PackageSetting ps) {
13196        return (ps.pkgFlags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
13197    }
13198
13199    private int packageFlagsToInstallFlags(PackageSetting ps) {
13200        int installFlags = 0;
13201        if (isEphemeral(ps)) {
13202            installFlags |= PackageManager.INSTALL_EPHEMERAL;
13203        }
13204        if (isExternal(ps) && TextUtils.isEmpty(ps.volumeUuid)) {
13205            // This existing package was an external ASEC install when we have
13206            // the external flag without a UUID
13207            installFlags |= PackageManager.INSTALL_EXTERNAL;
13208        }
13209        if (ps.isForwardLocked()) {
13210            installFlags |= PackageManager.INSTALL_FORWARD_LOCK;
13211        }
13212        return installFlags;
13213    }
13214
13215    private String getVolumeUuidForPackage(PackageParser.Package pkg) {
13216        if (isExternal(pkg)) {
13217            if (TextUtils.isEmpty(pkg.volumeUuid)) {
13218                return StorageManager.UUID_PRIMARY_PHYSICAL;
13219            } else {
13220                return pkg.volumeUuid;
13221            }
13222        } else {
13223            return StorageManager.UUID_PRIVATE_INTERNAL;
13224        }
13225    }
13226
13227    private VersionInfo getSettingsVersionForPackage(PackageParser.Package pkg) {
13228        if (isExternal(pkg)) {
13229            if (TextUtils.isEmpty(pkg.volumeUuid)) {
13230                return mSettings.getExternalVersion();
13231            } else {
13232                return mSettings.findOrCreateVersion(pkg.volumeUuid);
13233            }
13234        } else {
13235            return mSettings.getInternalVersion();
13236        }
13237    }
13238
13239    private void deleteTempPackageFiles() {
13240        final FilenameFilter filter = new FilenameFilter() {
13241            public boolean accept(File dir, String name) {
13242                return name.startsWith("vmdl") && name.endsWith(".tmp");
13243            }
13244        };
13245        for (File file : mDrmAppPrivateInstallDir.listFiles(filter)) {
13246            file.delete();
13247        }
13248    }
13249
13250    @Override
13251    public void deletePackageAsUser(String packageName, IPackageDeleteObserver observer, int userId,
13252            int flags) {
13253        deletePackage(packageName, new LegacyPackageDeleteObserver(observer).getBinder(), userId,
13254                flags);
13255    }
13256
13257    @Override
13258    public void deletePackage(final String packageName,
13259            final IPackageDeleteObserver2 observer, final int userId, final int flags) {
13260        mContext.enforceCallingOrSelfPermission(
13261                android.Manifest.permission.DELETE_PACKAGES, null);
13262        Preconditions.checkNotNull(packageName);
13263        Preconditions.checkNotNull(observer);
13264        final int uid = Binder.getCallingUid();
13265        final boolean deleteAllUsers = (flags & PackageManager.DELETE_ALL_USERS) != 0;
13266        final int[] users = deleteAllUsers ? sUserManager.getUserIds() : new int[]{ userId };
13267        if (UserHandle.getUserId(uid) != userId || (deleteAllUsers && users.length > 1)) {
13268            mContext.enforceCallingOrSelfPermission(
13269                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
13270                    "deletePackage for user " + userId);
13271        }
13272
13273        if (isUserRestricted(userId, UserManager.DISALLOW_UNINSTALL_APPS)) {
13274            try {
13275                observer.onPackageDeleted(packageName,
13276                        PackageManager.DELETE_FAILED_USER_RESTRICTED, null);
13277            } catch (RemoteException re) {
13278            }
13279            return;
13280        }
13281
13282        for (int currentUserId : users) {
13283            if (getBlockUninstallForUser(packageName, currentUserId)) {
13284                try {
13285                    observer.onPackageDeleted(packageName,
13286                            PackageManager.DELETE_FAILED_OWNER_BLOCKED, null);
13287                } catch (RemoteException re) {
13288                }
13289                return;
13290            }
13291        }
13292
13293        if (DEBUG_REMOVE) {
13294            Slog.d(TAG, "deletePackageAsUser: pkg=" + packageName + " user=" + userId);
13295        }
13296        // Queue up an async operation since the package deletion may take a little while.
13297        mHandler.post(new Runnable() {
13298            public void run() {
13299                mHandler.removeCallbacks(this);
13300                final int returnCode = deletePackageX(packageName, userId, flags);
13301                try {
13302                    observer.onPackageDeleted(packageName, returnCode, null);
13303                } catch (RemoteException e) {
13304                    Log.i(TAG, "Observer no longer exists.");
13305                } //end catch
13306            } //end run
13307        });
13308    }
13309
13310    private boolean isPackageDeviceAdmin(String packageName, int userId) {
13311        IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
13312                ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
13313        try {
13314            if (dpm != null) {
13315                final ComponentName deviceOwnerComponentName = dpm.getDeviceOwnerComponent(
13316                        /* callingUserOnly =*/ false);
13317                final String deviceOwnerPackageName = deviceOwnerComponentName == null ? null
13318                        : deviceOwnerComponentName.getPackageName();
13319                // Does the package contains the device owner?
13320                // TODO Do we have to do it even if userId != UserHandle.USER_ALL?  Otherwise,
13321                // this check is probably not needed, since DO should be registered as a device
13322                // admin on some user too. (Original bug for this: b/17657954)
13323                if (packageName.equals(deviceOwnerPackageName)) {
13324                    return true;
13325                }
13326                // Does it contain a device admin for any user?
13327                int[] users;
13328                if (userId == UserHandle.USER_ALL) {
13329                    users = sUserManager.getUserIds();
13330                } else {
13331                    users = new int[]{userId};
13332                }
13333                for (int i = 0; i < users.length; ++i) {
13334                    if (dpm.packageHasActiveAdmins(packageName, users[i])) {
13335                        return true;
13336                    }
13337                }
13338            }
13339        } catch (RemoteException e) {
13340        }
13341        return false;
13342    }
13343
13344    private boolean shouldKeepUninstalledPackageLPr(String packageName) {
13345        return mKeepUninstalledPackages != null && mKeepUninstalledPackages.contains(packageName);
13346    }
13347
13348    /**
13349     *  This method is an internal method that could be get invoked either
13350     *  to delete an installed package or to clean up a failed installation.
13351     *  After deleting an installed package, a broadcast is sent to notify any
13352     *  listeners that the package has been installed. For cleaning up a failed
13353     *  installation, the broadcast is not necessary since the package's
13354     *  installation wouldn't have sent the initial broadcast either
13355     *  The key steps in deleting a package are
13356     *  deleting the package information in internal structures like mPackages,
13357     *  deleting the packages base directories through installd
13358     *  updating mSettings to reflect current status
13359     *  persisting settings for later use
13360     *  sending a broadcast if necessary
13361     */
13362    private int deletePackageX(String packageName, int userId, int flags) {
13363        final PackageRemovedInfo info = new PackageRemovedInfo();
13364        final boolean res;
13365
13366        final UserHandle removeForUser = (flags & PackageManager.DELETE_ALL_USERS) != 0
13367                ? UserHandle.ALL : new UserHandle(userId);
13368
13369        if (isPackageDeviceAdmin(packageName, removeForUser.getIdentifier())) {
13370            Slog.w(TAG, "Not removing package " + packageName + ": has active device admin");
13371            return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER;
13372        }
13373
13374        boolean removedForAllUsers = false;
13375        boolean systemUpdate = false;
13376
13377        PackageParser.Package uninstalledPkg;
13378
13379        // for the uninstall-updates case and restricted profiles, remember the per-
13380        // userhandle installed state
13381        int[] allUsers;
13382        boolean[] perUserInstalled;
13383        synchronized (mPackages) {
13384            uninstalledPkg = mPackages.get(packageName);
13385            PackageSetting ps = mSettings.mPackages.get(packageName);
13386            allUsers = sUserManager.getUserIds();
13387            perUserInstalled = new boolean[allUsers.length];
13388            for (int i = 0; i < allUsers.length; i++) {
13389                perUserInstalled[i] = ps != null ? ps.getInstalled(allUsers[i]) : false;
13390            }
13391        }
13392
13393        synchronized (mInstallLock) {
13394            if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageX: pkg=" + packageName + " user=" + userId);
13395            res = deletePackageLI(packageName, removeForUser,
13396                    true, allUsers, perUserInstalled,
13397                    flags | REMOVE_CHATTY, info, true);
13398            systemUpdate = info.isRemovedPackageSystemUpdate;
13399            synchronized (mPackages) {
13400                if (res) {
13401                    if (!systemUpdate && mPackages.get(packageName) == null) {
13402                        removedForAllUsers = true;
13403                    }
13404                    mEphemeralApplicationRegistry.onPackageUninstalledLPw(uninstalledPkg);
13405                }
13406            }
13407            if (DEBUG_REMOVE) Slog.d(TAG, "delete res: systemUpdate=" + systemUpdate
13408                    + " removedForAllUsers=" + removedForAllUsers);
13409        }
13410
13411        if (res) {
13412            info.sendBroadcast(true, systemUpdate, removedForAllUsers);
13413
13414            // If the removed package was a system update, the old system package
13415            // was re-enabled; we need to broadcast this information
13416            if (systemUpdate) {
13417                Bundle extras = new Bundle(1);
13418                extras.putInt(Intent.EXTRA_UID, info.removedAppId >= 0
13419                        ? info.removedAppId : info.uid);
13420                extras.putBoolean(Intent.EXTRA_REPLACING, true);
13421
13422                sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
13423                        extras, 0, null, null, null);
13424                sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, packageName,
13425                        extras, 0, null, null, null);
13426                sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, null,
13427                        null, 0, packageName, null, null);
13428            }
13429        }
13430        // Force a gc here.
13431        Runtime.getRuntime().gc();
13432        // Delete the resources here after sending the broadcast to let
13433        // other processes clean up before deleting resources.
13434        if (info.args != null) {
13435            synchronized (mInstallLock) {
13436                info.args.doPostDeleteLI(true);
13437            }
13438        }
13439
13440        return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR;
13441    }
13442
13443    class PackageRemovedInfo {
13444        String removedPackage;
13445        int uid = -1;
13446        int removedAppId = -1;
13447        int[] removedUsers = null;
13448        boolean isRemovedPackageSystemUpdate = false;
13449        // Clean up resources deleted packages.
13450        InstallArgs args = null;
13451
13452        void sendBroadcast(boolean fullRemove, boolean replacing, boolean removedForAllUsers) {
13453            Bundle extras = new Bundle(1);
13454            extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid);
13455            extras.putBoolean(Intent.EXTRA_DATA_REMOVED, fullRemove);
13456            if (replacing) {
13457                extras.putBoolean(Intent.EXTRA_REPLACING, true);
13458            }
13459            extras.putBoolean(Intent.EXTRA_REMOVED_FOR_ALL_USERS, removedForAllUsers);
13460            if (removedPackage != null) {
13461                sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED, removedPackage,
13462                        extras, 0, null, null, removedUsers);
13463                if (fullRemove && !replacing) {
13464                    sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED, removedPackage,
13465                            extras, 0, null, null, removedUsers);
13466                }
13467            }
13468            if (removedAppId >= 0) {
13469                sendPackageBroadcast(Intent.ACTION_UID_REMOVED, null, extras, 0, null, null,
13470                        removedUsers);
13471            }
13472        }
13473    }
13474
13475    /*
13476     * This method deletes the package from internal data structures. If the DONT_DELETE_DATA
13477     * flag is not set, the data directory is removed as well.
13478     * make sure this flag is set for partially installed apps. If not its meaningless to
13479     * delete a partially installed application.
13480     */
13481    private void removePackageDataLI(PackageSetting ps,
13482            int[] allUserHandles, boolean[] perUserInstalled,
13483            PackageRemovedInfo outInfo, int flags, boolean writeSettings) {
13484        String packageName = ps.name;
13485        if (DEBUG_REMOVE) Slog.d(TAG, "removePackageDataLI: " + ps);
13486        removePackageLI(ps, (flags&REMOVE_CHATTY) != 0);
13487        // Retrieve object to delete permissions for shared user later on
13488        final PackageSetting deletedPs;
13489        // reader
13490        synchronized (mPackages) {
13491            deletedPs = mSettings.mPackages.get(packageName);
13492            if (outInfo != null) {
13493                outInfo.removedPackage = packageName;
13494                outInfo.removedUsers = deletedPs != null
13495                        ? deletedPs.queryInstalledUsers(sUserManager.getUserIds(), true)
13496                        : null;
13497            }
13498        }
13499        if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) {
13500            removeDataDirsLI(ps.volumeUuid, packageName);
13501            schedulePackageCleaning(packageName, UserHandle.USER_ALL, true);
13502        }
13503        // writer
13504        synchronized (mPackages) {
13505            if (deletedPs != null) {
13506                if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) {
13507                    clearIntentFilterVerificationsLPw(deletedPs.name, UserHandle.USER_ALL);
13508                    clearDefaultBrowserIfNeeded(packageName);
13509                    if (outInfo != null) {
13510                        mSettings.mKeySetManagerService.removeAppKeySetDataLPw(packageName);
13511                        outInfo.removedAppId = mSettings.removePackageLPw(packageName);
13512                    }
13513                    updatePermissionsLPw(deletedPs.name, null, 0);
13514                    if (deletedPs.sharedUser != null) {
13515                        // Remove permissions associated with package. Since runtime
13516                        // permissions are per user we have to kill the removed package
13517                        // or packages running under the shared user of the removed
13518                        // package if revoking the permissions requested only by the removed
13519                        // package is successful and this causes a change in gids.
13520                        for (int userId : UserManagerService.getInstance().getUserIds()) {
13521                            final int userIdToKill = mSettings.updateSharedUserPermsLPw(deletedPs,
13522                                    userId);
13523                            if (userIdToKill == UserHandle.USER_ALL
13524                                    || userIdToKill >= UserHandle.USER_SYSTEM) {
13525                                // If gids changed for this user, kill all affected packages.
13526                                mHandler.post(new Runnable() {
13527                                    @Override
13528                                    public void run() {
13529                                        // This has to happen with no lock held.
13530                                        killApplication(deletedPs.name, deletedPs.appId,
13531                                                KILL_APP_REASON_GIDS_CHANGED);
13532                                    }
13533                                });
13534                                break;
13535                            }
13536                        }
13537                    }
13538                    clearPackagePreferredActivitiesLPw(deletedPs.name, UserHandle.USER_ALL);
13539                }
13540                // make sure to preserve per-user disabled state if this removal was just
13541                // a downgrade of a system app to the factory package
13542                if (allUserHandles != null && perUserInstalled != null) {
13543                    if (DEBUG_REMOVE) {
13544                        Slog.d(TAG, "Propagating install state across downgrade");
13545                    }
13546                    for (int i = 0; i < allUserHandles.length; i++) {
13547                        if (DEBUG_REMOVE) {
13548                            Slog.d(TAG, "    user " + allUserHandles[i]
13549                                    + " => " + perUserInstalled[i]);
13550                        }
13551                        ps.setInstalled(perUserInstalled[i], allUserHandles[i]);
13552                    }
13553                }
13554            }
13555            // can downgrade to reader
13556            if (writeSettings) {
13557                // Save settings now
13558                mSettings.writeLPr();
13559            }
13560        }
13561        if (outInfo != null) {
13562            // A user ID was deleted here. Go through all users and remove it
13563            // from KeyStore.
13564            removeKeystoreDataIfNeeded(UserHandle.USER_ALL, outInfo.removedAppId);
13565        }
13566    }
13567
13568    static boolean locationIsPrivileged(File path) {
13569        try {
13570            final String privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app")
13571                    .getCanonicalPath();
13572            return path.getCanonicalPath().startsWith(privilegedAppDir);
13573        } catch (IOException e) {
13574            Slog.e(TAG, "Unable to access code path " + path);
13575        }
13576        return false;
13577    }
13578
13579    /*
13580     * Tries to delete system package.
13581     */
13582    private boolean deleteSystemPackageLI(PackageSetting newPs,
13583            int[] allUserHandles, boolean[] perUserInstalled,
13584            int flags, PackageRemovedInfo outInfo, boolean writeSettings) {
13585        final boolean applyUserRestrictions
13586                = (allUserHandles != null) && (perUserInstalled != null);
13587        PackageSetting disabledPs = null;
13588        // Confirm if the system package has been updated
13589        // An updated system app can be deleted. This will also have to restore
13590        // the system pkg from system partition
13591        // reader
13592        synchronized (mPackages) {
13593            disabledPs = mSettings.getDisabledSystemPkgLPr(newPs.name);
13594        }
13595        if (DEBUG_REMOVE) Slog.d(TAG, "deleteSystemPackageLI: newPs=" + newPs
13596                + " disabledPs=" + disabledPs);
13597        if (disabledPs == null) {
13598            Slog.w(TAG, "Attempt to delete unknown system package "+ newPs.name);
13599            return false;
13600        } else if (DEBUG_REMOVE) {
13601            Slog.d(TAG, "Deleting system pkg from data partition");
13602        }
13603        if (DEBUG_REMOVE) {
13604            if (applyUserRestrictions) {
13605                Slog.d(TAG, "Remembering install states:");
13606                for (int i = 0; i < allUserHandles.length; i++) {
13607                    Slog.d(TAG, "   u=" + allUserHandles[i] + " inst=" + perUserInstalled[i]);
13608                }
13609            }
13610        }
13611        // Delete the updated package
13612        outInfo.isRemovedPackageSystemUpdate = true;
13613        if (disabledPs.versionCode < newPs.versionCode) {
13614            // Delete data for downgrades
13615            flags &= ~PackageManager.DELETE_KEEP_DATA;
13616        } else {
13617            // Preserve data by setting flag
13618            flags |= PackageManager.DELETE_KEEP_DATA;
13619        }
13620        boolean ret = deleteInstalledPackageLI(newPs, true, flags,
13621                allUserHandles, perUserInstalled, outInfo, writeSettings);
13622        if (!ret) {
13623            return false;
13624        }
13625        // writer
13626        synchronized (mPackages) {
13627            // Reinstate the old system package
13628            mSettings.enableSystemPackageLPw(newPs.name);
13629            // Remove any native libraries from the upgraded package.
13630            NativeLibraryHelper.removeNativeBinariesLI(newPs.legacyNativeLibraryPathString);
13631        }
13632        // Install the system package
13633        if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs);
13634        int parseFlags = PackageParser.PARSE_MUST_BE_APK | PackageParser.PARSE_IS_SYSTEM;
13635        if (locationIsPrivileged(disabledPs.codePath)) {
13636            parseFlags |= PackageParser.PARSE_IS_PRIVILEGED;
13637        }
13638
13639        final PackageParser.Package newPkg;
13640        try {
13641            newPkg = scanPackageTracedLI(disabledPs.codePath, parseFlags, SCAN_NO_PATHS, 0, null);
13642        } catch (PackageManagerException e) {
13643            Slog.w(TAG, "Failed to restore system package " + newPs.name + ": " + e.getMessage());
13644            return false;
13645        }
13646
13647        // writer
13648        synchronized (mPackages) {
13649            PackageSetting ps = mSettings.mPackages.get(newPkg.packageName);
13650
13651            // Propagate the permissions state as we do not want to drop on the floor
13652            // runtime permissions. The update permissions method below will take
13653            // care of removing obsolete permissions and grant install permissions.
13654            ps.getPermissionsState().copyFrom(newPs.getPermissionsState());
13655            updatePermissionsLPw(newPkg.packageName, newPkg,
13656                    UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG);
13657
13658            if (applyUserRestrictions) {
13659                if (DEBUG_REMOVE) {
13660                    Slog.d(TAG, "Propagating install state across reinstall");
13661                }
13662                for (int i = 0; i < allUserHandles.length; i++) {
13663                    if (DEBUG_REMOVE) {
13664                        Slog.d(TAG, "    user " + allUserHandles[i]
13665                                + " => " + perUserInstalled[i]);
13666                    }
13667                    ps.setInstalled(perUserInstalled[i], allUserHandles[i]);
13668
13669                    mSettings.writeRuntimePermissionsForUserLPr(allUserHandles[i], false);
13670                }
13671                // Regardless of writeSettings we need to ensure that this restriction
13672                // state propagation is persisted
13673                mSettings.writeAllUsersPackageRestrictionsLPr();
13674            }
13675            // can downgrade to reader here
13676            if (writeSettings) {
13677                mSettings.writeLPr();
13678            }
13679        }
13680        return true;
13681    }
13682
13683    private boolean deleteInstalledPackageLI(PackageSetting ps,
13684            boolean deleteCodeAndResources, int flags,
13685            int[] allUserHandles, boolean[] perUserInstalled,
13686            PackageRemovedInfo outInfo, boolean writeSettings) {
13687        if (outInfo != null) {
13688            outInfo.uid = ps.appId;
13689        }
13690
13691        // Delete package data from internal structures and also remove data if flag is set
13692        removePackageDataLI(ps, allUserHandles, perUserInstalled, outInfo, flags, writeSettings);
13693
13694        // Delete application code and resources
13695        if (deleteCodeAndResources && (outInfo != null)) {
13696            outInfo.args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
13697                    ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
13698            if (DEBUG_SD_INSTALL) Slog.i(TAG, "args=" + outInfo.args);
13699        }
13700        return true;
13701    }
13702
13703    @Override
13704    public boolean setBlockUninstallForUser(String packageName, boolean blockUninstall,
13705            int userId) {
13706        mContext.enforceCallingOrSelfPermission(
13707                android.Manifest.permission.DELETE_PACKAGES, null);
13708        synchronized (mPackages) {
13709            PackageSetting ps = mSettings.mPackages.get(packageName);
13710            if (ps == null) {
13711                Log.i(TAG, "Package doesn't exist in set block uninstall " + packageName);
13712                return false;
13713            }
13714            if (!ps.getInstalled(userId)) {
13715                // Can't block uninstall for an app that is not installed or enabled.
13716                Log.i(TAG, "Package not installed in set block uninstall " + packageName);
13717                return false;
13718            }
13719            ps.setBlockUninstall(blockUninstall, userId);
13720            mSettings.writePackageRestrictionsLPr(userId);
13721        }
13722        return true;
13723    }
13724
13725    @Override
13726    public boolean getBlockUninstallForUser(String packageName, int userId) {
13727        synchronized (mPackages) {
13728            PackageSetting ps = mSettings.mPackages.get(packageName);
13729            if (ps == null) {
13730                Log.i(TAG, "Package doesn't exist in get block uninstall " + packageName);
13731                return false;
13732            }
13733            return ps.getBlockUninstall(userId);
13734        }
13735    }
13736
13737    @Override
13738    public boolean setRequiredForSystemUser(String packageName, boolean systemUserApp) {
13739        int callingUid = Binder.getCallingUid();
13740        if (callingUid != Process.SYSTEM_UID && callingUid != Process.ROOT_UID) {
13741            throw new SecurityException(
13742                    "setRequiredForSystemUser can only be run by the system or root");
13743        }
13744        synchronized (mPackages) {
13745            PackageSetting ps = mSettings.mPackages.get(packageName);
13746            if (ps == null) {
13747                Log.w(TAG, "Package doesn't exist: " + packageName);
13748                return false;
13749            }
13750            if (systemUserApp) {
13751                ps.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER;
13752            } else {
13753                ps.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER;
13754            }
13755            mSettings.writeLPr();
13756        }
13757        return true;
13758    }
13759
13760    /*
13761     * This method handles package deletion in general
13762     */
13763    private boolean deletePackageLI(String packageName, UserHandle user,
13764            boolean deleteCodeAndResources, int[] allUserHandles, boolean[] perUserInstalled,
13765            int flags, PackageRemovedInfo outInfo,
13766            boolean writeSettings) {
13767        if (packageName == null) {
13768            Slog.w(TAG, "Attempt to delete null packageName.");
13769            return false;
13770        }
13771        if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: " + packageName + " user " + user);
13772        PackageSetting ps;
13773        boolean dataOnly = false;
13774        int removeUser = -1;
13775        int appId = -1;
13776        synchronized (mPackages) {
13777            ps = mSettings.mPackages.get(packageName);
13778            if (ps == null) {
13779                Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
13780                return false;
13781            }
13782            if ((!isSystemApp(ps) || (flags&PackageManager.DELETE_SYSTEM_APP) != 0) && user != null
13783                    && user.getIdentifier() != UserHandle.USER_ALL) {
13784                // The caller is asking that the package only be deleted for a single
13785                // user.  To do this, we just mark its uninstalled state and delete
13786                // its data.  If this is a system app, we only allow this to happen if
13787                // they have set the special DELETE_SYSTEM_APP which requests different
13788                // semantics than normal for uninstalling system apps.
13789                if (DEBUG_REMOVE) Slog.d(TAG, "Only deleting for single user");
13790                final int userId = user.getIdentifier();
13791                ps.setUserState(userId,
13792                        COMPONENT_ENABLED_STATE_DEFAULT,
13793                        false, //installed
13794                        true,  //stopped
13795                        true,  //notLaunched
13796                        false, //hidden
13797                        false, //suspended
13798                        null, null, null,
13799                        false, // blockUninstall
13800                        ps.readUserState(userId).domainVerificationStatus, 0);
13801                if (!isSystemApp(ps)) {
13802                    // Do not uninstall the APK if an app should be cached
13803                    boolean keepUninstalledPackage = shouldKeepUninstalledPackageLPr(packageName);
13804                    if (ps.isAnyInstalled(sUserManager.getUserIds()) || keepUninstalledPackage) {
13805                        // Other user still have this package installed, so all
13806                        // we need to do is clear this user's data and save that
13807                        // it is uninstalled.
13808                        if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users");
13809                        removeUser = user.getIdentifier();
13810                        appId = ps.appId;
13811                        scheduleWritePackageRestrictionsLocked(removeUser);
13812                    } else {
13813                        // We need to set it back to 'installed' so the uninstall
13814                        // broadcasts will be sent correctly.
13815                        if (DEBUG_REMOVE) Slog.d(TAG, "Not installed by other users, full delete");
13816                        ps.setInstalled(true, user.getIdentifier());
13817                    }
13818                } else {
13819                    // This is a system app, so we assume that the
13820                    // other users still have this package installed, so all
13821                    // we need to do is clear this user's data and save that
13822                    // it is uninstalled.
13823                    if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app");
13824                    removeUser = user.getIdentifier();
13825                    appId = ps.appId;
13826                    scheduleWritePackageRestrictionsLocked(removeUser);
13827                }
13828            }
13829        }
13830
13831        if (removeUser >= 0) {
13832            // From above, we determined that we are deleting this only
13833            // for a single user.  Continue the work here.
13834            if (DEBUG_REMOVE) Slog.d(TAG, "Updating install state for user: " + removeUser);
13835            if (outInfo != null) {
13836                outInfo.removedPackage = packageName;
13837                outInfo.removedAppId = appId;
13838                outInfo.removedUsers = new int[] {removeUser};
13839            }
13840            mInstaller.clearUserData(ps.volumeUuid, packageName, removeUser);
13841            removeKeystoreDataIfNeeded(removeUser, appId);
13842            schedulePackageCleaning(packageName, removeUser, false);
13843            synchronized (mPackages) {
13844                if (clearPackagePreferredActivitiesLPw(packageName, removeUser)) {
13845                    scheduleWritePackageRestrictionsLocked(removeUser);
13846                }
13847                resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, removeUser);
13848            }
13849            return true;
13850        }
13851
13852        if (dataOnly) {
13853            // Delete application data first
13854            if (DEBUG_REMOVE) Slog.d(TAG, "Removing package data only");
13855            removePackageDataLI(ps, null, null, outInfo, flags, writeSettings);
13856            return true;
13857        }
13858
13859        boolean ret = false;
13860        if (isSystemApp(ps)) {
13861            if (DEBUG_REMOVE) Slog.d(TAG, "Removing system package: " + ps.name);
13862            // When an updated system application is deleted we delete the existing resources as well and
13863            // fall back to existing code in system partition
13864            ret = deleteSystemPackageLI(ps, allUserHandles, perUserInstalled,
13865                    flags, outInfo, writeSettings);
13866        } else {
13867            if (DEBUG_REMOVE) Slog.d(TAG, "Removing non-system package: " + ps.name);
13868            // Kill application pre-emptively especially for apps on sd.
13869            killApplication(packageName, ps.appId, "uninstall pkg");
13870            ret = deleteInstalledPackageLI(ps, deleteCodeAndResources, flags,
13871                    allUserHandles, perUserInstalled,
13872                    outInfo, writeSettings);
13873        }
13874
13875        return ret;
13876    }
13877
13878    private final static class ClearStorageConnection implements ServiceConnection {
13879        IMediaContainerService mContainerService;
13880
13881        @Override
13882        public void onServiceConnected(ComponentName name, IBinder service) {
13883            synchronized (this) {
13884                mContainerService = IMediaContainerService.Stub.asInterface(service);
13885                notifyAll();
13886            }
13887        }
13888
13889        @Override
13890        public void onServiceDisconnected(ComponentName name) {
13891        }
13892    }
13893
13894    private void clearExternalStorageDataSync(String packageName, int userId, boolean allData) {
13895        final boolean mounted;
13896        if (Environment.isExternalStorageEmulated()) {
13897            mounted = true;
13898        } else {
13899            final String status = Environment.getExternalStorageState();
13900
13901            mounted = status.equals(Environment.MEDIA_MOUNTED)
13902                    || status.equals(Environment.MEDIA_MOUNTED_READ_ONLY);
13903        }
13904
13905        if (!mounted) {
13906            return;
13907        }
13908
13909        final Intent containerIntent = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
13910        int[] users;
13911        if (userId == UserHandle.USER_ALL) {
13912            users = sUserManager.getUserIds();
13913        } else {
13914            users = new int[] { userId };
13915        }
13916        final ClearStorageConnection conn = new ClearStorageConnection();
13917        if (mContext.bindServiceAsUser(
13918                containerIntent, conn, Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) {
13919            try {
13920                for (int curUser : users) {
13921                    long timeout = SystemClock.uptimeMillis() + 5000;
13922                    synchronized (conn) {
13923                        long now = SystemClock.uptimeMillis();
13924                        while (conn.mContainerService == null && now < timeout) {
13925                            try {
13926                                conn.wait(timeout - now);
13927                            } catch (InterruptedException e) {
13928                            }
13929                        }
13930                    }
13931                    if (conn.mContainerService == null) {
13932                        return;
13933                    }
13934
13935                    final UserEnvironment userEnv = new UserEnvironment(curUser);
13936                    clearDirectory(conn.mContainerService,
13937                            userEnv.buildExternalStorageAppCacheDirs(packageName));
13938                    if (allData) {
13939                        clearDirectory(conn.mContainerService,
13940                                userEnv.buildExternalStorageAppDataDirs(packageName));
13941                        clearDirectory(conn.mContainerService,
13942                                userEnv.buildExternalStorageAppMediaDirs(packageName));
13943                    }
13944                }
13945            } finally {
13946                mContext.unbindService(conn);
13947            }
13948        }
13949    }
13950
13951    @Override
13952    public void clearApplicationUserData(final String packageName,
13953            final IPackageDataObserver observer, final int userId) {
13954        mContext.enforceCallingOrSelfPermission(
13955                android.Manifest.permission.CLEAR_APP_USER_DATA, null);
13956        enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, "clear application data");
13957        // Queue up an async operation since the package deletion may take a little while.
13958        mHandler.post(new Runnable() {
13959            public void run() {
13960                mHandler.removeCallbacks(this);
13961                final boolean succeeded;
13962                synchronized (mInstallLock) {
13963                    succeeded = clearApplicationUserDataLI(packageName, userId);
13964                }
13965                clearExternalStorageDataSync(packageName, userId, true);
13966                if (succeeded) {
13967                    // invoke DeviceStorageMonitor's update method to clear any notifications
13968                    DeviceStorageMonitorInternal
13969                            dsm = LocalServices.getService(DeviceStorageMonitorInternal.class);
13970                    if (dsm != null) {
13971                        dsm.checkMemory();
13972                    }
13973                }
13974                if(observer != null) {
13975                    try {
13976                        observer.onRemoveCompleted(packageName, succeeded);
13977                    } catch (RemoteException e) {
13978                        Log.i(TAG, "Observer no longer exists.");
13979                    }
13980                } //end if observer
13981            } //end run
13982        });
13983    }
13984
13985    private boolean clearApplicationUserDataLI(String packageName, int userId) {
13986        if (packageName == null) {
13987            Slog.w(TAG, "Attempt to delete null packageName.");
13988            return false;
13989        }
13990
13991        // Try finding details about the requested package
13992        PackageParser.Package pkg;
13993        synchronized (mPackages) {
13994            pkg = mPackages.get(packageName);
13995            if (pkg == null) {
13996                final PackageSetting ps = mSettings.mPackages.get(packageName);
13997                if (ps != null) {
13998                    pkg = ps.pkg;
13999                }
14000            }
14001
14002            if (pkg == null) {
14003                Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
14004                return false;
14005            }
14006
14007            PackageSetting ps = (PackageSetting) pkg.mExtras;
14008            resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
14009        }
14010
14011        // Always delete data directories for package, even if we found no other
14012        // record of app. This helps users recover from UID mismatches without
14013        // resorting to a full data wipe.
14014        int retCode = mInstaller.clearUserData(pkg.volumeUuid, packageName, userId);
14015        if (retCode < 0) {
14016            Slog.w(TAG, "Couldn't remove cache files for package " + packageName);
14017            return false;
14018        }
14019
14020        final int appId = pkg.applicationInfo.uid;
14021        removeKeystoreDataIfNeeded(userId, appId);
14022
14023        // Create a native library symlink only if we have native libraries
14024        // and if the native libraries are 32 bit libraries. We do not provide
14025        // this symlink for 64 bit libraries.
14026        if (pkg.applicationInfo.primaryCpuAbi != null &&
14027                !VMRuntime.is64BitAbi(pkg.applicationInfo.primaryCpuAbi)) {
14028            final String nativeLibPath = pkg.applicationInfo.nativeLibraryDir;
14029            if (mInstaller.linkNativeLibraryDirectory(pkg.volumeUuid, pkg.packageName,
14030                    nativeLibPath, userId) < 0) {
14031                Slog.w(TAG, "Failed linking native library dir");
14032                return false;
14033            }
14034        }
14035
14036        return true;
14037    }
14038
14039    /**
14040     * Reverts user permission state changes (permissions and flags) in
14041     * all packages for a given user.
14042     *
14043     * @param userId The device user for which to do a reset.
14044     */
14045    private void resetUserChangesToRuntimePermissionsAndFlagsLPw(int userId) {
14046        final int packageCount = mPackages.size();
14047        for (int i = 0; i < packageCount; i++) {
14048            PackageParser.Package pkg = mPackages.valueAt(i);
14049            PackageSetting ps = (PackageSetting) pkg.mExtras;
14050            resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
14051        }
14052    }
14053
14054    /**
14055     * Reverts user permission state changes (permissions and flags).
14056     *
14057     * @param ps The package for which to reset.
14058     * @param userId The device user for which to do a reset.
14059     */
14060    private void resetUserChangesToRuntimePermissionsAndFlagsLPw(
14061            final PackageSetting ps, final int userId) {
14062        if (ps.pkg == null) {
14063            return;
14064        }
14065
14066        // These are flags that can change base on user actions.
14067        final int userSettableMask = FLAG_PERMISSION_USER_SET
14068                | FLAG_PERMISSION_USER_FIXED
14069                | FLAG_PERMISSION_REVOKE_ON_UPGRADE
14070                | FLAG_PERMISSION_REVIEW_REQUIRED;
14071
14072        final int policyOrSystemFlags = FLAG_PERMISSION_SYSTEM_FIXED
14073                | FLAG_PERMISSION_POLICY_FIXED;
14074
14075        boolean writeInstallPermissions = false;
14076        boolean writeRuntimePermissions = false;
14077
14078        final int permissionCount = ps.pkg.requestedPermissions.size();
14079        for (int i = 0; i < permissionCount; i++) {
14080            String permission = ps.pkg.requestedPermissions.get(i);
14081
14082            BasePermission bp = mSettings.mPermissions.get(permission);
14083            if (bp == null) {
14084                continue;
14085            }
14086
14087            // If shared user we just reset the state to which only this app contributed.
14088            if (ps.sharedUser != null) {
14089                boolean used = false;
14090                final int packageCount = ps.sharedUser.packages.size();
14091                for (int j = 0; j < packageCount; j++) {
14092                    PackageSetting pkg = ps.sharedUser.packages.valueAt(j);
14093                    if (pkg.pkg != null && !pkg.pkg.packageName.equals(ps.pkg.packageName)
14094                            && pkg.pkg.requestedPermissions.contains(permission)) {
14095                        used = true;
14096                        break;
14097                    }
14098                }
14099                if (used) {
14100                    continue;
14101                }
14102            }
14103
14104            PermissionsState permissionsState = ps.getPermissionsState();
14105
14106            final int oldFlags = permissionsState.getPermissionFlags(bp.name, userId);
14107
14108            // Always clear the user settable flags.
14109            final boolean hasInstallState = permissionsState.getInstallPermissionState(
14110                    bp.name) != null;
14111            // If permission review is enabled and this is a legacy app, mark the
14112            // permission as requiring a review as this is the initial state.
14113            int flags = 0;
14114            if (Build.PERMISSIONS_REVIEW_REQUIRED
14115                    && ps.pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
14116                flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
14117            }
14118            if (permissionsState.updatePermissionFlags(bp, userId, userSettableMask, flags)) {
14119                if (hasInstallState) {
14120                    writeInstallPermissions = true;
14121                } else {
14122                    writeRuntimePermissions = true;
14123                }
14124            }
14125
14126            // Below is only runtime permission handling.
14127            if (!bp.isRuntime()) {
14128                continue;
14129            }
14130
14131            // Never clobber system or policy.
14132            if ((oldFlags & policyOrSystemFlags) != 0) {
14133                continue;
14134            }
14135
14136            // If this permission was granted by default, make sure it is.
14137            if ((oldFlags & FLAG_PERMISSION_GRANTED_BY_DEFAULT) != 0) {
14138                if (permissionsState.grantRuntimePermission(bp, userId)
14139                        != PERMISSION_OPERATION_FAILURE) {
14140                    writeRuntimePermissions = true;
14141                }
14142            // If permission review is enabled the permissions for a legacy apps
14143            // are represented as constantly granted runtime ones, so don't revoke.
14144            } else if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) {
14145                // Otherwise, reset the permission.
14146                final int revokeResult = permissionsState.revokeRuntimePermission(bp, userId);
14147                switch (revokeResult) {
14148                    case PERMISSION_OPERATION_SUCCESS: {
14149                        writeRuntimePermissions = true;
14150                    } break;
14151
14152                    case PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
14153                        writeRuntimePermissions = true;
14154                        final int appId = ps.appId;
14155                        mHandler.post(new Runnable() {
14156                            @Override
14157                            public void run() {
14158                                killUid(appId, userId, KILL_APP_REASON_GIDS_CHANGED);
14159                            }
14160                        });
14161                    } break;
14162                }
14163            }
14164        }
14165
14166        // Synchronously write as we are taking permissions away.
14167        if (writeRuntimePermissions) {
14168            mSettings.writeRuntimePermissionsForUserLPr(userId, true);
14169        }
14170
14171        // Synchronously write as we are taking permissions away.
14172        if (writeInstallPermissions) {
14173            mSettings.writeLPr();
14174        }
14175    }
14176
14177    /**
14178     * Remove entries from the keystore daemon. Will only remove it if the
14179     * {@code appId} is valid.
14180     */
14181    private static void removeKeystoreDataIfNeeded(int userId, int appId) {
14182        if (appId < 0) {
14183            return;
14184        }
14185
14186        final KeyStore keyStore = KeyStore.getInstance();
14187        if (keyStore != null) {
14188            if (userId == UserHandle.USER_ALL) {
14189                for (final int individual : sUserManager.getUserIds()) {
14190                    keyStore.clearUid(UserHandle.getUid(individual, appId));
14191                }
14192            } else {
14193                keyStore.clearUid(UserHandle.getUid(userId, appId));
14194            }
14195        } else {
14196            Slog.w(TAG, "Could not contact keystore to clear entries for app id " + appId);
14197        }
14198    }
14199
14200    @Override
14201    public void deleteApplicationCacheFiles(final String packageName,
14202            final IPackageDataObserver observer) {
14203        mContext.enforceCallingOrSelfPermission(
14204                android.Manifest.permission.DELETE_CACHE_FILES, null);
14205        // Queue up an async operation since the package deletion may take a little while.
14206        final int userId = UserHandle.getCallingUserId();
14207        mHandler.post(new Runnable() {
14208            public void run() {
14209                mHandler.removeCallbacks(this);
14210                final boolean succeded;
14211                synchronized (mInstallLock) {
14212                    succeded = deleteApplicationCacheFilesLI(packageName, userId);
14213                }
14214                clearExternalStorageDataSync(packageName, userId, false);
14215                if (observer != null) {
14216                    try {
14217                        observer.onRemoveCompleted(packageName, succeded);
14218                    } catch (RemoteException e) {
14219                        Log.i(TAG, "Observer no longer exists.");
14220                    }
14221                } //end if observer
14222            } //end run
14223        });
14224    }
14225
14226    private boolean deleteApplicationCacheFilesLI(String packageName, int userId) {
14227        if (packageName == null) {
14228            Slog.w(TAG, "Attempt to delete null packageName.");
14229            return false;
14230        }
14231        PackageParser.Package p;
14232        synchronized (mPackages) {
14233            p = mPackages.get(packageName);
14234        }
14235        if (p == null) {
14236            Slog.w(TAG, "Package named '" + packageName +"' doesn't exist.");
14237            return false;
14238        }
14239        final ApplicationInfo applicationInfo = p.applicationInfo;
14240        if (applicationInfo == null) {
14241            Slog.w(TAG, "Package " + packageName + " has no applicationInfo.");
14242            return false;
14243        }
14244        int retCode = mInstaller.deleteCacheFiles(p.volumeUuid, packageName, userId);
14245        if (retCode < 0) {
14246            Slog.w(TAG, "Couldn't remove cache files for package "
14247                       + packageName + " u" + userId);
14248            return false;
14249        }
14250        return true;
14251    }
14252
14253    @Override
14254    public void getPackageSizeInfo(final String packageName, int userHandle,
14255            final IPackageStatsObserver observer) {
14256        mContext.enforceCallingOrSelfPermission(
14257                android.Manifest.permission.GET_PACKAGE_SIZE, null);
14258        if (packageName == null) {
14259            throw new IllegalArgumentException("Attempt to get size of null packageName");
14260        }
14261
14262        PackageStats stats = new PackageStats(packageName, userHandle);
14263
14264        /*
14265         * Queue up an async operation since the package measurement may take a
14266         * little while.
14267         */
14268        Message msg = mHandler.obtainMessage(INIT_COPY);
14269        msg.obj = new MeasureParams(stats, observer);
14270        mHandler.sendMessage(msg);
14271    }
14272
14273    private boolean getPackageSizeInfoLI(String packageName, int userHandle,
14274            PackageStats pStats) {
14275        if (packageName == null) {
14276            Slog.w(TAG, "Attempt to get size of null packageName.");
14277            return false;
14278        }
14279        PackageParser.Package p;
14280        boolean dataOnly = false;
14281        String libDirRoot = null;
14282        String asecPath = null;
14283        PackageSetting ps = null;
14284        synchronized (mPackages) {
14285            p = mPackages.get(packageName);
14286            ps = mSettings.mPackages.get(packageName);
14287            if(p == null) {
14288                dataOnly = true;
14289                if((ps == null) || (ps.pkg == null)) {
14290                    Slog.w(TAG, "Package named '" + packageName +"' doesn't exist.");
14291                    return false;
14292                }
14293                p = ps.pkg;
14294            }
14295            if (ps != null) {
14296                libDirRoot = ps.legacyNativeLibraryPathString;
14297            }
14298            if (p != null && (p.isForwardLocked() || p.applicationInfo.isExternalAsec())) {
14299                final long token = Binder.clearCallingIdentity();
14300                try {
14301                    String secureContainerId = cidFromCodePath(p.applicationInfo.getBaseCodePath());
14302                    if (secureContainerId != null) {
14303                        asecPath = PackageHelper.getSdFilesystem(secureContainerId);
14304                    }
14305                } finally {
14306                    Binder.restoreCallingIdentity(token);
14307                }
14308            }
14309        }
14310        String publicSrcDir = null;
14311        if(!dataOnly) {
14312            final ApplicationInfo applicationInfo = p.applicationInfo;
14313            if (applicationInfo == null) {
14314                Slog.w(TAG, "Package " + packageName + " has no applicationInfo.");
14315                return false;
14316            }
14317            if (p.isForwardLocked()) {
14318                publicSrcDir = applicationInfo.getBaseResourcePath();
14319            }
14320        }
14321        // TODO: extend to measure size of split APKs
14322        // TODO(multiArch): Extend getSizeInfo to look at the full subdirectory tree,
14323        // not just the first level.
14324        // TODO(multiArch): Extend getSizeInfo to look at *all* instruction sets, not
14325        // just the primary.
14326        String[] dexCodeInstructionSets = getDexCodeInstructionSets(getAppDexInstructionSets(ps));
14327
14328        String apkPath;
14329        File packageDir = new File(p.codePath);
14330
14331        if (packageDir.isDirectory() && p.canHaveOatDir()) {
14332            apkPath = packageDir.getAbsolutePath();
14333            // If libDirRoot is inside a package dir, set it to null to avoid it being counted twice
14334            if (libDirRoot != null && libDirRoot.startsWith(apkPath)) {
14335                libDirRoot = null;
14336            }
14337        } else {
14338            apkPath = p.baseCodePath;
14339        }
14340
14341        int res = mInstaller.getSizeInfo(p.volumeUuid, packageName, userHandle, apkPath,
14342                libDirRoot, publicSrcDir, asecPath, dexCodeInstructionSets, pStats);
14343        if (res < 0) {
14344            return false;
14345        }
14346
14347        // Fix-up for forward-locked applications in ASEC containers.
14348        if (!isExternal(p)) {
14349            pStats.codeSize += pStats.externalCodeSize;
14350            pStats.externalCodeSize = 0L;
14351        }
14352
14353        return true;
14354    }
14355
14356
14357    @Override
14358    public void addPackageToPreferred(String packageName) {
14359        Slog.w(TAG, "addPackageToPreferred: this is now a no-op");
14360    }
14361
14362    @Override
14363    public void removePackageFromPreferred(String packageName) {
14364        Slog.w(TAG, "removePackageFromPreferred: this is now a no-op");
14365    }
14366
14367    @Override
14368    public List<PackageInfo> getPreferredPackages(int flags) {
14369        return new ArrayList<PackageInfo>();
14370    }
14371
14372    private int getUidTargetSdkVersionLockedLPr(int uid) {
14373        Object obj = mSettings.getUserIdLPr(uid);
14374        if (obj instanceof SharedUserSetting) {
14375            final SharedUserSetting sus = (SharedUserSetting) obj;
14376            int vers = Build.VERSION_CODES.CUR_DEVELOPMENT;
14377            final Iterator<PackageSetting> it = sus.packages.iterator();
14378            while (it.hasNext()) {
14379                final PackageSetting ps = it.next();
14380                if (ps.pkg != null) {
14381                    int v = ps.pkg.applicationInfo.targetSdkVersion;
14382                    if (v < vers) vers = v;
14383                }
14384            }
14385            return vers;
14386        } else if (obj instanceof PackageSetting) {
14387            final PackageSetting ps = (PackageSetting) obj;
14388            if (ps.pkg != null) {
14389                return ps.pkg.applicationInfo.targetSdkVersion;
14390            }
14391        }
14392        return Build.VERSION_CODES.CUR_DEVELOPMENT;
14393    }
14394
14395    @Override
14396    public void addPreferredActivity(IntentFilter filter, int match,
14397            ComponentName[] set, ComponentName activity, int userId) {
14398        addPreferredActivityInternal(filter, match, set, activity, true, userId,
14399                "Adding preferred");
14400    }
14401
14402    private void addPreferredActivityInternal(IntentFilter filter, int match,
14403            ComponentName[] set, ComponentName activity, boolean always, int userId,
14404            String opname) {
14405        // writer
14406        int callingUid = Binder.getCallingUid();
14407        enforceCrossUserPermission(callingUid, userId, true, false, "add preferred activity");
14408        if (filter.countActions() == 0) {
14409            Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
14410            return;
14411        }
14412        synchronized (mPackages) {
14413            if (mContext.checkCallingOrSelfPermission(
14414                    android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
14415                    != PackageManager.PERMISSION_GRANTED) {
14416                if (getUidTargetSdkVersionLockedLPr(callingUid)
14417                        < Build.VERSION_CODES.FROYO) {
14418                    Slog.w(TAG, "Ignoring addPreferredActivity() from uid "
14419                            + callingUid);
14420                    return;
14421                }
14422                mContext.enforceCallingOrSelfPermission(
14423                        android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
14424            }
14425
14426            PreferredIntentResolver pir = mSettings.editPreferredActivitiesLPw(userId);
14427            Slog.i(TAG, opname + " activity " + activity.flattenToShortString() + " for user "
14428                    + userId + ":");
14429            filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
14430            pir.addFilter(new PreferredActivity(filter, match, set, activity, always));
14431            scheduleWritePackageRestrictionsLocked(userId);
14432        }
14433    }
14434
14435    @Override
14436    public void replacePreferredActivity(IntentFilter filter, int match,
14437            ComponentName[] set, ComponentName activity, int userId) {
14438        if (filter.countActions() != 1) {
14439            throw new IllegalArgumentException(
14440                    "replacePreferredActivity expects filter to have only 1 action.");
14441        }
14442        if (filter.countDataAuthorities() != 0
14443                || filter.countDataPaths() != 0
14444                || filter.countDataSchemes() > 1
14445                || filter.countDataTypes() != 0) {
14446            throw new IllegalArgumentException(
14447                    "replacePreferredActivity expects filter to have no data authorities, " +
14448                    "paths, or types; and at most one scheme.");
14449        }
14450
14451        final int callingUid = Binder.getCallingUid();
14452        enforceCrossUserPermission(callingUid, userId, true, false, "replace preferred activity");
14453        synchronized (mPackages) {
14454            if (mContext.checkCallingOrSelfPermission(
14455                    android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
14456                    != PackageManager.PERMISSION_GRANTED) {
14457                if (getUidTargetSdkVersionLockedLPr(callingUid)
14458                        < Build.VERSION_CODES.FROYO) {
14459                    Slog.w(TAG, "Ignoring replacePreferredActivity() from uid "
14460                            + Binder.getCallingUid());
14461                    return;
14462                }
14463                mContext.enforceCallingOrSelfPermission(
14464                        android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
14465            }
14466
14467            PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
14468            if (pir != null) {
14469                // Get all of the existing entries that exactly match this filter.
14470                ArrayList<PreferredActivity> existing = pir.findFilters(filter);
14471                if (existing != null && existing.size() == 1) {
14472                    PreferredActivity cur = existing.get(0);
14473                    if (DEBUG_PREFERRED) {
14474                        Slog.i(TAG, "Checking replace of preferred:");
14475                        filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
14476                        if (!cur.mPref.mAlways) {
14477                            Slog.i(TAG, "  -- CUR; not mAlways!");
14478                        } else {
14479                            Slog.i(TAG, "  -- CUR: mMatch=" + cur.mPref.mMatch);
14480                            Slog.i(TAG, "  -- CUR: mSet="
14481                                    + Arrays.toString(cur.mPref.mSetComponents));
14482                            Slog.i(TAG, "  -- CUR: mComponent=" + cur.mPref.mShortComponent);
14483                            Slog.i(TAG, "  -- NEW: mMatch="
14484                                    + (match&IntentFilter.MATCH_CATEGORY_MASK));
14485                            Slog.i(TAG, "  -- CUR: mSet=" + Arrays.toString(set));
14486                            Slog.i(TAG, "  -- CUR: mComponent=" + activity.flattenToShortString());
14487                        }
14488                    }
14489                    if (cur.mPref.mAlways && cur.mPref.mComponent.equals(activity)
14490                            && cur.mPref.mMatch == (match&IntentFilter.MATCH_CATEGORY_MASK)
14491                            && cur.mPref.sameSet(set)) {
14492                        // Setting the preferred activity to what it happens to be already
14493                        if (DEBUG_PREFERRED) {
14494                            Slog.i(TAG, "Replacing with same preferred activity "
14495                                    + cur.mPref.mShortComponent + " for user "
14496                                    + userId + ":");
14497                            filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
14498                        }
14499                        return;
14500                    }
14501                }
14502
14503                if (existing != null) {
14504                    if (DEBUG_PREFERRED) {
14505                        Slog.i(TAG, existing.size() + " existing preferred matches for:");
14506                        filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
14507                    }
14508                    for (int i = 0; i < existing.size(); i++) {
14509                        PreferredActivity pa = existing.get(i);
14510                        if (DEBUG_PREFERRED) {
14511                            Slog.i(TAG, "Removing existing preferred activity "
14512                                    + pa.mPref.mComponent + ":");
14513                            pa.dump(new LogPrinter(Log.INFO, TAG), "  ");
14514                        }
14515                        pir.removeFilter(pa);
14516                    }
14517                }
14518            }
14519            addPreferredActivityInternal(filter, match, set, activity, true, userId,
14520                    "Replacing preferred");
14521        }
14522    }
14523
14524    @Override
14525    public void clearPackagePreferredActivities(String packageName) {
14526        final int uid = Binder.getCallingUid();
14527        // writer
14528        synchronized (mPackages) {
14529            PackageParser.Package pkg = mPackages.get(packageName);
14530            if (pkg == null || pkg.applicationInfo.uid != uid) {
14531                if (mContext.checkCallingOrSelfPermission(
14532                        android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
14533                        != PackageManager.PERMISSION_GRANTED) {
14534                    if (getUidTargetSdkVersionLockedLPr(Binder.getCallingUid())
14535                            < Build.VERSION_CODES.FROYO) {
14536                        Slog.w(TAG, "Ignoring clearPackagePreferredActivities() from uid "
14537                                + Binder.getCallingUid());
14538                        return;
14539                    }
14540                    mContext.enforceCallingOrSelfPermission(
14541                            android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
14542                }
14543            }
14544
14545            int user = UserHandle.getCallingUserId();
14546            if (clearPackagePreferredActivitiesLPw(packageName, user)) {
14547                scheduleWritePackageRestrictionsLocked(user);
14548            }
14549        }
14550    }
14551
14552    /** This method takes a specific user id as well as UserHandle.USER_ALL. */
14553    boolean clearPackagePreferredActivitiesLPw(String packageName, int userId) {
14554        ArrayList<PreferredActivity> removed = null;
14555        boolean changed = false;
14556        for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
14557            final int thisUserId = mSettings.mPreferredActivities.keyAt(i);
14558            PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
14559            if (userId != UserHandle.USER_ALL && userId != thisUserId) {
14560                continue;
14561            }
14562            Iterator<PreferredActivity> it = pir.filterIterator();
14563            while (it.hasNext()) {
14564                PreferredActivity pa = it.next();
14565                // Mark entry for removal only if it matches the package name
14566                // and the entry is of type "always".
14567                if (packageName == null ||
14568                        (pa.mPref.mComponent.getPackageName().equals(packageName)
14569                                && pa.mPref.mAlways)) {
14570                    if (removed == null) {
14571                        removed = new ArrayList<PreferredActivity>();
14572                    }
14573                    removed.add(pa);
14574                }
14575            }
14576            if (removed != null) {
14577                for (int j=0; j<removed.size(); j++) {
14578                    PreferredActivity pa = removed.get(j);
14579                    pir.removeFilter(pa);
14580                }
14581                changed = true;
14582            }
14583        }
14584        return changed;
14585    }
14586
14587    /** This method takes a specific user id as well as UserHandle.USER_ALL. */
14588    private void clearIntentFilterVerificationsLPw(int userId) {
14589        final int packageCount = mPackages.size();
14590        for (int i = 0; i < packageCount; i++) {
14591            PackageParser.Package pkg = mPackages.valueAt(i);
14592            clearIntentFilterVerificationsLPw(pkg.packageName, userId);
14593        }
14594    }
14595
14596    /** This method takes a specific user id as well as UserHandle.USER_ALL. */
14597    void clearIntentFilterVerificationsLPw(String packageName, int userId) {
14598        if (userId == UserHandle.USER_ALL) {
14599            if (mSettings.removeIntentFilterVerificationLPw(packageName,
14600                    sUserManager.getUserIds())) {
14601                for (int oneUserId : sUserManager.getUserIds()) {
14602                    scheduleWritePackageRestrictionsLocked(oneUserId);
14603                }
14604            }
14605        } else {
14606            if (mSettings.removeIntentFilterVerificationLPw(packageName, userId)) {
14607                scheduleWritePackageRestrictionsLocked(userId);
14608            }
14609        }
14610    }
14611
14612    void clearDefaultBrowserIfNeeded(String packageName) {
14613        for (int oneUserId : sUserManager.getUserIds()) {
14614            String defaultBrowserPackageName = getDefaultBrowserPackageName(oneUserId);
14615            if (TextUtils.isEmpty(defaultBrowserPackageName)) continue;
14616            if (packageName.equals(defaultBrowserPackageName)) {
14617                setDefaultBrowserPackageName(null, oneUserId);
14618            }
14619        }
14620    }
14621
14622    @Override
14623    public void resetApplicationPreferences(int userId) {
14624        mContext.enforceCallingOrSelfPermission(
14625                android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
14626        // writer
14627        synchronized (mPackages) {
14628            final long identity = Binder.clearCallingIdentity();
14629            try {
14630                clearPackagePreferredActivitiesLPw(null, userId);
14631                mSettings.applyDefaultPreferredAppsLPw(this, userId);
14632                // TODO: We have to reset the default SMS and Phone. This requires
14633                // significant refactoring to keep all default apps in the package
14634                // manager (cleaner but more work) or have the services provide
14635                // callbacks to the package manager to request a default app reset.
14636                applyFactoryDefaultBrowserLPw(userId);
14637                clearIntentFilterVerificationsLPw(userId);
14638                primeDomainVerificationsLPw(userId);
14639                resetUserChangesToRuntimePermissionsAndFlagsLPw(userId);
14640                scheduleWritePackageRestrictionsLocked(userId);
14641            } finally {
14642                Binder.restoreCallingIdentity(identity);
14643            }
14644        }
14645    }
14646
14647    @Override
14648    public int getPreferredActivities(List<IntentFilter> outFilters,
14649            List<ComponentName> outActivities, String packageName) {
14650
14651        int num = 0;
14652        final int userId = UserHandle.getCallingUserId();
14653        // reader
14654        synchronized (mPackages) {
14655            PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
14656            if (pir != null) {
14657                final Iterator<PreferredActivity> it = pir.filterIterator();
14658                while (it.hasNext()) {
14659                    final PreferredActivity pa = it.next();
14660                    if (packageName == null
14661                            || (pa.mPref.mComponent.getPackageName().equals(packageName)
14662                                    && pa.mPref.mAlways)) {
14663                        if (outFilters != null) {
14664                            outFilters.add(new IntentFilter(pa));
14665                        }
14666                        if (outActivities != null) {
14667                            outActivities.add(pa.mPref.mComponent);
14668                        }
14669                    }
14670                }
14671            }
14672        }
14673
14674        return num;
14675    }
14676
14677    @Override
14678    public void addPersistentPreferredActivity(IntentFilter filter, ComponentName activity,
14679            int userId) {
14680        int callingUid = Binder.getCallingUid();
14681        if (callingUid != Process.SYSTEM_UID) {
14682            throw new SecurityException(
14683                    "addPersistentPreferredActivity can only be run by the system");
14684        }
14685        if (filter.countActions() == 0) {
14686            Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
14687            return;
14688        }
14689        synchronized (mPackages) {
14690            Slog.i(TAG, "Adding persistent preferred activity " + activity + " for user " + userId +
14691                    ":");
14692            filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
14693            mSettings.editPersistentPreferredActivitiesLPw(userId).addFilter(
14694                    new PersistentPreferredActivity(filter, activity));
14695            scheduleWritePackageRestrictionsLocked(userId);
14696        }
14697    }
14698
14699    @Override
14700    public void clearPackagePersistentPreferredActivities(String packageName, int userId) {
14701        int callingUid = Binder.getCallingUid();
14702        if (callingUid != Process.SYSTEM_UID) {
14703            throw new SecurityException(
14704                    "clearPackagePersistentPreferredActivities can only be run by the system");
14705        }
14706        ArrayList<PersistentPreferredActivity> removed = null;
14707        boolean changed = false;
14708        synchronized (mPackages) {
14709            for (int i=0; i<mSettings.mPersistentPreferredActivities.size(); i++) {
14710                final int thisUserId = mSettings.mPersistentPreferredActivities.keyAt(i);
14711                PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
14712                        .valueAt(i);
14713                if (userId != thisUserId) {
14714                    continue;
14715                }
14716                Iterator<PersistentPreferredActivity> it = ppir.filterIterator();
14717                while (it.hasNext()) {
14718                    PersistentPreferredActivity ppa = it.next();
14719                    // Mark entry for removal only if it matches the package name.
14720                    if (ppa.mComponent.getPackageName().equals(packageName)) {
14721                        if (removed == null) {
14722                            removed = new ArrayList<PersistentPreferredActivity>();
14723                        }
14724                        removed.add(ppa);
14725                    }
14726                }
14727                if (removed != null) {
14728                    for (int j=0; j<removed.size(); j++) {
14729                        PersistentPreferredActivity ppa = removed.get(j);
14730                        ppir.removeFilter(ppa);
14731                    }
14732                    changed = true;
14733                }
14734            }
14735
14736            if (changed) {
14737                scheduleWritePackageRestrictionsLocked(userId);
14738            }
14739        }
14740    }
14741
14742    /**
14743     * Common machinery for picking apart a restored XML blob and passing
14744     * it to a caller-supplied functor to be applied to the running system.
14745     */
14746    private void restoreFromXml(XmlPullParser parser, int userId,
14747            String expectedStartTag, BlobXmlRestorer functor)
14748            throws IOException, XmlPullParserException {
14749        int type;
14750        while ((type = parser.next()) != XmlPullParser.START_TAG
14751                && type != XmlPullParser.END_DOCUMENT) {
14752        }
14753        if (type != XmlPullParser.START_TAG) {
14754            // oops didn't find a start tag?!
14755            if (DEBUG_BACKUP) {
14756                Slog.e(TAG, "Didn't find start tag during restore");
14757            }
14758            return;
14759        }
14760
14761        // this is supposed to be TAG_PREFERRED_BACKUP
14762        if (!expectedStartTag.equals(parser.getName())) {
14763            if (DEBUG_BACKUP) {
14764                Slog.e(TAG, "Found unexpected tag " + parser.getName());
14765            }
14766            return;
14767        }
14768
14769        // skip interfering stuff, then we're aligned with the backing implementation
14770        while ((type = parser.next()) == XmlPullParser.TEXT) { }
14771        functor.apply(parser, userId);
14772    }
14773
14774    private interface BlobXmlRestorer {
14775        public void apply(XmlPullParser parser, int userId) throws IOException, XmlPullParserException;
14776    }
14777
14778    /**
14779     * Non-Binder method, support for the backup/restore mechanism: write the
14780     * full set of preferred activities in its canonical XML format.  Returns the
14781     * XML output as a byte array, or null if there is none.
14782     */
14783    @Override
14784    public byte[] getPreferredActivityBackup(int userId) {
14785        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
14786            throw new SecurityException("Only the system may call getPreferredActivityBackup()");
14787        }
14788
14789        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
14790        try {
14791            final XmlSerializer serializer = new FastXmlSerializer();
14792            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
14793            serializer.startDocument(null, true);
14794            serializer.startTag(null, TAG_PREFERRED_BACKUP);
14795
14796            synchronized (mPackages) {
14797                mSettings.writePreferredActivitiesLPr(serializer, userId, true);
14798            }
14799
14800            serializer.endTag(null, TAG_PREFERRED_BACKUP);
14801            serializer.endDocument();
14802            serializer.flush();
14803        } catch (Exception e) {
14804            if (DEBUG_BACKUP) {
14805                Slog.e(TAG, "Unable to write preferred activities for backup", e);
14806            }
14807            return null;
14808        }
14809
14810        return dataStream.toByteArray();
14811    }
14812
14813    @Override
14814    public void restorePreferredActivities(byte[] backup, int userId) {
14815        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
14816            throw new SecurityException("Only the system may call restorePreferredActivities()");
14817        }
14818
14819        try {
14820            final XmlPullParser parser = Xml.newPullParser();
14821            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
14822            restoreFromXml(parser, userId, TAG_PREFERRED_BACKUP,
14823                    new BlobXmlRestorer() {
14824                        @Override
14825                        public void apply(XmlPullParser parser, int userId)
14826                                throws XmlPullParserException, IOException {
14827                            synchronized (mPackages) {
14828                                mSettings.readPreferredActivitiesLPw(parser, userId);
14829                            }
14830                        }
14831                    } );
14832        } catch (Exception e) {
14833            if (DEBUG_BACKUP) {
14834                Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
14835            }
14836        }
14837    }
14838
14839    /**
14840     * Non-Binder method, support for the backup/restore mechanism: write the
14841     * default browser (etc) settings in its canonical XML format.  Returns the default
14842     * browser XML representation as a byte array, or null if there is none.
14843     */
14844    @Override
14845    public byte[] getDefaultAppsBackup(int userId) {
14846        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
14847            throw new SecurityException("Only the system may call getDefaultAppsBackup()");
14848        }
14849
14850        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
14851        try {
14852            final XmlSerializer serializer = new FastXmlSerializer();
14853            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
14854            serializer.startDocument(null, true);
14855            serializer.startTag(null, TAG_DEFAULT_APPS);
14856
14857            synchronized (mPackages) {
14858                mSettings.writeDefaultAppsLPr(serializer, userId);
14859            }
14860
14861            serializer.endTag(null, TAG_DEFAULT_APPS);
14862            serializer.endDocument();
14863            serializer.flush();
14864        } catch (Exception e) {
14865            if (DEBUG_BACKUP) {
14866                Slog.e(TAG, "Unable to write default apps for backup", e);
14867            }
14868            return null;
14869        }
14870
14871        return dataStream.toByteArray();
14872    }
14873
14874    @Override
14875    public void restoreDefaultApps(byte[] backup, int userId) {
14876        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
14877            throw new SecurityException("Only the system may call restoreDefaultApps()");
14878        }
14879
14880        try {
14881            final XmlPullParser parser = Xml.newPullParser();
14882            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
14883            restoreFromXml(parser, userId, TAG_DEFAULT_APPS,
14884                    new BlobXmlRestorer() {
14885                        @Override
14886                        public void apply(XmlPullParser parser, int userId)
14887                                throws XmlPullParserException, IOException {
14888                            synchronized (mPackages) {
14889                                mSettings.readDefaultAppsLPw(parser, userId);
14890                            }
14891                        }
14892                    } );
14893        } catch (Exception e) {
14894            if (DEBUG_BACKUP) {
14895                Slog.e(TAG, "Exception restoring default apps: " + e.getMessage());
14896            }
14897        }
14898    }
14899
14900    @Override
14901    public byte[] getIntentFilterVerificationBackup(int userId) {
14902        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
14903            throw new SecurityException("Only the system may call getIntentFilterVerificationBackup()");
14904        }
14905
14906        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
14907        try {
14908            final XmlSerializer serializer = new FastXmlSerializer();
14909            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
14910            serializer.startDocument(null, true);
14911            serializer.startTag(null, TAG_INTENT_FILTER_VERIFICATION);
14912
14913            synchronized (mPackages) {
14914                mSettings.writeAllDomainVerificationsLPr(serializer, userId);
14915            }
14916
14917            serializer.endTag(null, TAG_INTENT_FILTER_VERIFICATION);
14918            serializer.endDocument();
14919            serializer.flush();
14920        } catch (Exception e) {
14921            if (DEBUG_BACKUP) {
14922                Slog.e(TAG, "Unable to write default apps for backup", e);
14923            }
14924            return null;
14925        }
14926
14927        return dataStream.toByteArray();
14928    }
14929
14930    @Override
14931    public void restoreIntentFilterVerification(byte[] backup, int userId) {
14932        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
14933            throw new SecurityException("Only the system may call restorePreferredActivities()");
14934        }
14935
14936        try {
14937            final XmlPullParser parser = Xml.newPullParser();
14938            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
14939            restoreFromXml(parser, userId, TAG_INTENT_FILTER_VERIFICATION,
14940                    new BlobXmlRestorer() {
14941                        @Override
14942                        public void apply(XmlPullParser parser, int userId)
14943                                throws XmlPullParserException, IOException {
14944                            synchronized (mPackages) {
14945                                mSettings.readAllDomainVerificationsLPr(parser, userId);
14946                                mSettings.writeLPr();
14947                            }
14948                        }
14949                    } );
14950        } catch (Exception e) {
14951            if (DEBUG_BACKUP) {
14952                Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
14953            }
14954        }
14955    }
14956
14957    @Override
14958    public void addCrossProfileIntentFilter(IntentFilter intentFilter, String ownerPackage,
14959            int sourceUserId, int targetUserId, int flags) {
14960        mContext.enforceCallingOrSelfPermission(
14961                        android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
14962        int callingUid = Binder.getCallingUid();
14963        enforceOwnerRights(ownerPackage, callingUid);
14964        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
14965        if (intentFilter.countActions() == 0) {
14966            Slog.w(TAG, "Cannot set a crossProfile intent filter with no filter actions");
14967            return;
14968        }
14969        synchronized (mPackages) {
14970            CrossProfileIntentFilter newFilter = new CrossProfileIntentFilter(intentFilter,
14971                    ownerPackage, targetUserId, flags);
14972            CrossProfileIntentResolver resolver =
14973                    mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
14974            ArrayList<CrossProfileIntentFilter> existing = resolver.findFilters(intentFilter);
14975            // We have all those whose filter is equal. Now checking if the rest is equal as well.
14976            if (existing != null) {
14977                int size = existing.size();
14978                for (int i = 0; i < size; i++) {
14979                    if (newFilter.equalsIgnoreFilter(existing.get(i))) {
14980                        return;
14981                    }
14982                }
14983            }
14984            resolver.addFilter(newFilter);
14985            scheduleWritePackageRestrictionsLocked(sourceUserId);
14986        }
14987    }
14988
14989    @Override
14990    public void clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage) {
14991        mContext.enforceCallingOrSelfPermission(
14992                        android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
14993        int callingUid = Binder.getCallingUid();
14994        enforceOwnerRights(ownerPackage, callingUid);
14995        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
14996        synchronized (mPackages) {
14997            CrossProfileIntentResolver resolver =
14998                    mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
14999            ArraySet<CrossProfileIntentFilter> set =
15000                    new ArraySet<CrossProfileIntentFilter>(resolver.filterSet());
15001            for (CrossProfileIntentFilter filter : set) {
15002                if (filter.getOwnerPackage().equals(ownerPackage)) {
15003                    resolver.removeFilter(filter);
15004                }
15005            }
15006            scheduleWritePackageRestrictionsLocked(sourceUserId);
15007        }
15008    }
15009
15010    // Enforcing that callingUid is owning pkg on userId
15011    private void enforceOwnerRights(String pkg, int callingUid) {
15012        // The system owns everything.
15013        if (UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) {
15014            return;
15015        }
15016        int callingUserId = UserHandle.getUserId(callingUid);
15017        PackageInfo pi = getPackageInfo(pkg, 0, callingUserId);
15018        if (pi == null) {
15019            throw new IllegalArgumentException("Unknown package " + pkg + " on user "
15020                    + callingUserId);
15021        }
15022        if (!UserHandle.isSameApp(pi.applicationInfo.uid, callingUid)) {
15023            throw new SecurityException("Calling uid " + callingUid
15024                    + " does not own package " + pkg);
15025        }
15026    }
15027
15028    @Override
15029    public ComponentName getHomeActivities(List<ResolveInfo> allHomeCandidates) {
15030        Intent intent = new Intent(Intent.ACTION_MAIN);
15031        intent.addCategory(Intent.CATEGORY_HOME);
15032
15033        final int callingUserId = UserHandle.getCallingUserId();
15034        List<ResolveInfo> list = queryIntentActivities(intent, null,
15035                PackageManager.GET_META_DATA, callingUserId);
15036        ResolveInfo preferred = findPreferredActivity(intent, null, 0, list, 0,
15037                true, false, false, callingUserId);
15038
15039        allHomeCandidates.clear();
15040        if (list != null) {
15041            for (ResolveInfo ri : list) {
15042                allHomeCandidates.add(ri);
15043            }
15044        }
15045        return (preferred == null || preferred.activityInfo == null)
15046                ? null
15047                : new ComponentName(preferred.activityInfo.packageName,
15048                        preferred.activityInfo.name);
15049    }
15050
15051    @Override
15052    public void setApplicationEnabledSetting(String appPackageName,
15053            int newState, int flags, int userId, String callingPackage) {
15054        if (!sUserManager.exists(userId)) return;
15055        if (callingPackage == null) {
15056            callingPackage = Integer.toString(Binder.getCallingUid());
15057        }
15058        setEnabledSetting(appPackageName, null, newState, flags, userId, callingPackage);
15059    }
15060
15061    @Override
15062    public void setComponentEnabledSetting(ComponentName componentName,
15063            int newState, int flags, int userId) {
15064        if (!sUserManager.exists(userId)) return;
15065        setEnabledSetting(componentName.getPackageName(),
15066                componentName.getClassName(), newState, flags, userId, null);
15067    }
15068
15069    private void setEnabledSetting(final String packageName, String className, int newState,
15070            final int flags, int userId, String callingPackage) {
15071        if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT
15072              || newState == COMPONENT_ENABLED_STATE_ENABLED
15073              || newState == COMPONENT_ENABLED_STATE_DISABLED
15074              || newState == COMPONENT_ENABLED_STATE_DISABLED_USER
15075              || newState == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED)) {
15076            throw new IllegalArgumentException("Invalid new component state: "
15077                    + newState);
15078        }
15079        PackageSetting pkgSetting;
15080        final int uid = Binder.getCallingUid();
15081        final int permission = mContext.checkCallingOrSelfPermission(
15082                android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
15083        enforceCrossUserPermission(uid, userId, false, true, "set enabled");
15084        final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
15085        boolean sendNow = false;
15086        boolean isApp = (className == null);
15087        String componentName = isApp ? packageName : className;
15088        int packageUid = -1;
15089        ArrayList<String> components;
15090
15091        // writer
15092        synchronized (mPackages) {
15093            pkgSetting = mSettings.mPackages.get(packageName);
15094            if (pkgSetting == null) {
15095                if (className == null) {
15096                    throw new IllegalArgumentException("Unknown package: " + packageName);
15097                }
15098                throw new IllegalArgumentException(
15099                        "Unknown component: " + packageName + "/" + className);
15100            }
15101            // Allow root and verify that userId is not being specified by a different user
15102            if (!allowedByPermission && !UserHandle.isSameApp(uid, pkgSetting.appId)) {
15103                throw new SecurityException(
15104                        "Permission Denial: attempt to change component state from pid="
15105                        + Binder.getCallingPid()
15106                        + ", uid=" + uid + ", package uid=" + pkgSetting.appId);
15107            }
15108            if (className == null) {
15109                // We're dealing with an application/package level state change
15110                if (pkgSetting.getEnabled(userId) == newState) {
15111                    // Nothing to do
15112                    return;
15113                }
15114                if (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
15115                    || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {
15116                    // Don't care about who enables an app.
15117                    callingPackage = null;
15118                }
15119                pkgSetting.setEnabled(newState, userId, callingPackage);
15120                // pkgSetting.pkg.mSetEnabled = newState;
15121            } else {
15122                // We're dealing with a component level state change
15123                // First, verify that this is a valid class name.
15124                PackageParser.Package pkg = pkgSetting.pkg;
15125                if (pkg == null || !pkg.hasComponentClassName(className)) {
15126                    if (pkg != null &&
15127                            pkg.applicationInfo.targetSdkVersion >=
15128                                    Build.VERSION_CODES.JELLY_BEAN) {
15129                        throw new IllegalArgumentException("Component class " + className
15130                                + " does not exist in " + packageName);
15131                    } else {
15132                        Slog.w(TAG, "Failed setComponentEnabledSetting: component class "
15133                                + className + " does not exist in " + packageName);
15134                    }
15135                }
15136                switch (newState) {
15137                case COMPONENT_ENABLED_STATE_ENABLED:
15138                    if (!pkgSetting.enableComponentLPw(className, userId)) {
15139                        return;
15140                    }
15141                    break;
15142                case COMPONENT_ENABLED_STATE_DISABLED:
15143                    if (!pkgSetting.disableComponentLPw(className, userId)) {
15144                        return;
15145                    }
15146                    break;
15147                case COMPONENT_ENABLED_STATE_DEFAULT:
15148                    if (!pkgSetting.restoreComponentLPw(className, userId)) {
15149                        return;
15150                    }
15151                    break;
15152                default:
15153                    Slog.e(TAG, "Invalid new component state: " + newState);
15154                    return;
15155                }
15156            }
15157            scheduleWritePackageRestrictionsLocked(userId);
15158            components = mPendingBroadcasts.get(userId, packageName);
15159            final boolean newPackage = components == null;
15160            if (newPackage) {
15161                components = new ArrayList<String>();
15162            }
15163            if (!components.contains(componentName)) {
15164                components.add(componentName);
15165            }
15166            if ((flags&PackageManager.DONT_KILL_APP) == 0) {
15167                sendNow = true;
15168                // Purge entry from pending broadcast list if another one exists already
15169                // since we are sending one right away.
15170                mPendingBroadcasts.remove(userId, packageName);
15171            } else {
15172                if (newPackage) {
15173                    mPendingBroadcasts.put(userId, packageName, components);
15174                }
15175                if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) {
15176                    // Schedule a message
15177                    mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, BROADCAST_DELAY);
15178                }
15179            }
15180        }
15181
15182        long callingId = Binder.clearCallingIdentity();
15183        try {
15184            if (sendNow) {
15185                packageUid = UserHandle.getUid(userId, pkgSetting.appId);
15186                sendPackageChangedBroadcast(packageName,
15187                        (flags&PackageManager.DONT_KILL_APP) != 0, components, packageUid);
15188            }
15189        } finally {
15190            Binder.restoreCallingIdentity(callingId);
15191        }
15192    }
15193
15194    private void sendPackageChangedBroadcast(String packageName,
15195            boolean killFlag, ArrayList<String> componentNames, int packageUid) {
15196        if (DEBUG_INSTALL)
15197            Log.v(TAG, "Sending package changed: package=" + packageName + " components="
15198                    + componentNames);
15199        Bundle extras = new Bundle(4);
15200        extras.putString(Intent.EXTRA_CHANGED_COMPONENT_NAME, componentNames.get(0));
15201        String nameList[] = new String[componentNames.size()];
15202        componentNames.toArray(nameList);
15203        extras.putStringArray(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST, nameList);
15204        extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, killFlag);
15205        extras.putInt(Intent.EXTRA_UID, packageUid);
15206        // If this is not reporting a change of the overall package, then only send it
15207        // to registered receivers.  We don't want to launch a swath of apps for every
15208        // little component state change.
15209        final int flags = !componentNames.contains(packageName)
15210                ? Intent.FLAG_RECEIVER_REGISTERED_ONLY : 0;
15211        sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED,  packageName, extras, flags, null, null,
15212                new int[] {UserHandle.getUserId(packageUid)});
15213    }
15214
15215    @Override
15216    public void setPackageStoppedState(String packageName, boolean stopped, int userId) {
15217        if (!sUserManager.exists(userId)) return;
15218        final int uid = Binder.getCallingUid();
15219        final int permission = mContext.checkCallingOrSelfPermission(
15220                android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
15221        final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
15222        enforceCrossUserPermission(uid, userId, true, true, "stop package");
15223        // writer
15224        synchronized (mPackages) {
15225            if (mSettings.setPackageStoppedStateLPw(this, packageName, stopped,
15226                    allowedByPermission, uid, userId)) {
15227                scheduleWritePackageRestrictionsLocked(userId);
15228            }
15229        }
15230    }
15231
15232    @Override
15233    public String getInstallerPackageName(String packageName) {
15234        // reader
15235        synchronized (mPackages) {
15236            return mSettings.getInstallerPackageNameLPr(packageName);
15237        }
15238    }
15239
15240    @Override
15241    public int getApplicationEnabledSetting(String packageName, int userId) {
15242        if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
15243        int uid = Binder.getCallingUid();
15244        enforceCrossUserPermission(uid, userId, false, false, "get enabled");
15245        // reader
15246        synchronized (mPackages) {
15247            return mSettings.getApplicationEnabledSettingLPr(packageName, userId);
15248        }
15249    }
15250
15251    @Override
15252    public int getComponentEnabledSetting(ComponentName componentName, int userId) {
15253        if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
15254        int uid = Binder.getCallingUid();
15255        enforceCrossUserPermission(uid, userId, false, false, "get component enabled");
15256        // reader
15257        synchronized (mPackages) {
15258            return mSettings.getComponentEnabledSettingLPr(componentName, userId);
15259        }
15260    }
15261
15262    @Override
15263    public void enterSafeMode() {
15264        enforceSystemOrRoot("Only the system can request entering safe mode");
15265
15266        if (!mSystemReady) {
15267            mSafeMode = true;
15268        }
15269    }
15270
15271    @Override
15272    public void systemReady() {
15273        mSystemReady = true;
15274
15275        // Read the compatibilty setting when the system is ready.
15276        boolean compatibilityModeEnabled = android.provider.Settings.Global.getInt(
15277                mContext.getContentResolver(),
15278                android.provider.Settings.Global.COMPATIBILITY_MODE, 1) == 1;
15279        PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled);
15280        if (DEBUG_SETTINGS) {
15281            Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled);
15282        }
15283
15284        int[] grantPermissionsUserIds = EMPTY_INT_ARRAY;
15285
15286        synchronized (mPackages) {
15287            // Verify that all of the preferred activity components actually
15288            // exist.  It is possible for applications to be updated and at
15289            // that point remove a previously declared activity component that
15290            // had been set as a preferred activity.  We try to clean this up
15291            // the next time we encounter that preferred activity, but it is
15292            // possible for the user flow to never be able to return to that
15293            // situation so here we do a sanity check to make sure we haven't
15294            // left any junk around.
15295            ArrayList<PreferredActivity> removed = new ArrayList<PreferredActivity>();
15296            for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
15297                PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
15298                removed.clear();
15299                for (PreferredActivity pa : pir.filterSet()) {
15300                    if (mActivities.mActivities.get(pa.mPref.mComponent) == null) {
15301                        removed.add(pa);
15302                    }
15303                }
15304                if (removed.size() > 0) {
15305                    for (int r=0; r<removed.size(); r++) {
15306                        PreferredActivity pa = removed.get(r);
15307                        Slog.w(TAG, "Removing dangling preferred activity: "
15308                                + pa.mPref.mComponent);
15309                        pir.removeFilter(pa);
15310                    }
15311                    mSettings.writePackageRestrictionsLPr(
15312                            mSettings.mPreferredActivities.keyAt(i));
15313                }
15314            }
15315
15316            for (int userId : UserManagerService.getInstance().getUserIds()) {
15317                if (!mSettings.areDefaultRuntimePermissionsGrantedLPr(userId)) {
15318                    grantPermissionsUserIds = ArrayUtils.appendInt(
15319                            grantPermissionsUserIds, userId);
15320                }
15321            }
15322        }
15323        sUserManager.systemReady();
15324
15325        // If we upgraded grant all default permissions before kicking off.
15326        for (int userId : grantPermissionsUserIds) {
15327            mDefaultPermissionPolicy.grantDefaultPermissions(userId);
15328        }
15329
15330        // Kick off any messages waiting for system ready
15331        if (mPostSystemReadyMessages != null) {
15332            for (Message msg : mPostSystemReadyMessages) {
15333                msg.sendToTarget();
15334            }
15335            mPostSystemReadyMessages = null;
15336        }
15337
15338        // Watch for external volumes that come and go over time
15339        final StorageManager storage = mContext.getSystemService(StorageManager.class);
15340        storage.registerListener(mStorageListener);
15341
15342        mInstallerService.systemReady();
15343        mPackageDexOptimizer.systemReady();
15344
15345        MountServiceInternal mountServiceInternal = LocalServices.getService(
15346                MountServiceInternal.class);
15347        mountServiceInternal.addExternalStoragePolicy(
15348                new MountServiceInternal.ExternalStorageMountPolicy() {
15349            @Override
15350            public int getMountMode(int uid, String packageName) {
15351                if (Process.isIsolated(uid)) {
15352                    return Zygote.MOUNT_EXTERNAL_NONE;
15353                }
15354                if (checkUidPermission(WRITE_MEDIA_STORAGE, uid) == PERMISSION_GRANTED) {
15355                    return Zygote.MOUNT_EXTERNAL_DEFAULT;
15356                }
15357                if (checkUidPermission(READ_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) {
15358                    return Zygote.MOUNT_EXTERNAL_DEFAULT;
15359                }
15360                if (checkUidPermission(WRITE_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) {
15361                    return Zygote.MOUNT_EXTERNAL_READ;
15362                }
15363                return Zygote.MOUNT_EXTERNAL_WRITE;
15364            }
15365
15366            @Override
15367            public boolean hasExternalStorage(int uid, String packageName) {
15368                return true;
15369            }
15370        });
15371    }
15372
15373    @Override
15374    public boolean isSafeMode() {
15375        return mSafeMode;
15376    }
15377
15378    @Override
15379    public boolean hasSystemUidErrors() {
15380        return mHasSystemUidErrors;
15381    }
15382
15383    static String arrayToString(int[] array) {
15384        StringBuffer buf = new StringBuffer(128);
15385        buf.append('[');
15386        if (array != null) {
15387            for (int i=0; i<array.length; i++) {
15388                if (i > 0) buf.append(", ");
15389                buf.append(array[i]);
15390            }
15391        }
15392        buf.append(']');
15393        return buf.toString();
15394    }
15395
15396    static class DumpState {
15397        public static final int DUMP_LIBS = 1 << 0;
15398        public static final int DUMP_FEATURES = 1 << 1;
15399        public static final int DUMP_ACTIVITY_RESOLVERS = 1 << 2;
15400        public static final int DUMP_SERVICE_RESOLVERS = 1 << 3;
15401        public static final int DUMP_RECEIVER_RESOLVERS = 1 << 4;
15402        public static final int DUMP_CONTENT_RESOLVERS = 1 << 5;
15403        public static final int DUMP_PERMISSIONS = 1 << 6;
15404        public static final int DUMP_PACKAGES = 1 << 7;
15405        public static final int DUMP_SHARED_USERS = 1 << 8;
15406        public static final int DUMP_MESSAGES = 1 << 9;
15407        public static final int DUMP_PROVIDERS = 1 << 10;
15408        public static final int DUMP_VERIFIERS = 1 << 11;
15409        public static final int DUMP_PREFERRED = 1 << 12;
15410        public static final int DUMP_PREFERRED_XML = 1 << 13;
15411        public static final int DUMP_KEYSETS = 1 << 14;
15412        public static final int DUMP_VERSION = 1 << 15;
15413        public static final int DUMP_INSTALLS = 1 << 16;
15414        public static final int DUMP_INTENT_FILTER_VERIFIERS = 1 << 17;
15415        public static final int DUMP_DOMAIN_PREFERRED = 1 << 18;
15416
15417        public static final int OPTION_SHOW_FILTERS = 1 << 0;
15418
15419        private int mTypes;
15420
15421        private int mOptions;
15422
15423        private boolean mTitlePrinted;
15424
15425        private SharedUserSetting mSharedUser;
15426
15427        public boolean isDumping(int type) {
15428            if (mTypes == 0 && type != DUMP_PREFERRED_XML) {
15429                return true;
15430            }
15431
15432            return (mTypes & type) != 0;
15433        }
15434
15435        public void setDump(int type) {
15436            mTypes |= type;
15437        }
15438
15439        public boolean isOptionEnabled(int option) {
15440            return (mOptions & option) != 0;
15441        }
15442
15443        public void setOptionEnabled(int option) {
15444            mOptions |= option;
15445        }
15446
15447        public boolean onTitlePrinted() {
15448            final boolean printed = mTitlePrinted;
15449            mTitlePrinted = true;
15450            return printed;
15451        }
15452
15453        public boolean getTitlePrinted() {
15454            return mTitlePrinted;
15455        }
15456
15457        public void setTitlePrinted(boolean enabled) {
15458            mTitlePrinted = enabled;
15459        }
15460
15461        public SharedUserSetting getSharedUser() {
15462            return mSharedUser;
15463        }
15464
15465        public void setSharedUser(SharedUserSetting user) {
15466            mSharedUser = user;
15467        }
15468    }
15469
15470    @Override
15471    public void onShellCommand(FileDescriptor in, FileDescriptor out,
15472            FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
15473        (new PackageManagerShellCommand(this)).exec(
15474                this, in, out, err, args, resultReceiver);
15475    }
15476
15477    @Override
15478    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
15479        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
15480                != PackageManager.PERMISSION_GRANTED) {
15481            pw.println("Permission Denial: can't dump ActivityManager from from pid="
15482                    + Binder.getCallingPid()
15483                    + ", uid=" + Binder.getCallingUid()
15484                    + " without permission "
15485                    + android.Manifest.permission.DUMP);
15486            return;
15487        }
15488
15489        DumpState dumpState = new DumpState();
15490        boolean fullPreferred = false;
15491        boolean checkin = false;
15492
15493        String packageName = null;
15494        ArraySet<String> permissionNames = null;
15495
15496        int opti = 0;
15497        while (opti < args.length) {
15498            String opt = args[opti];
15499            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15500                break;
15501            }
15502            opti++;
15503
15504            if ("-a".equals(opt)) {
15505                // Right now we only know how to print all.
15506            } else if ("-h".equals(opt)) {
15507                pw.println("Package manager dump options:");
15508                pw.println("  [-h] [-f] [--checkin] [cmd] ...");
15509                pw.println("    --checkin: dump for a checkin");
15510                pw.println("    -f: print details of intent filters");
15511                pw.println("    -h: print this help");
15512                pw.println("  cmd may be one of:");
15513                pw.println("    l[ibraries]: list known shared libraries");
15514                pw.println("    f[eatures]: list device features");
15515                pw.println("    k[eysets]: print known keysets");
15516                pw.println("    r[esolvers] [activity|service|receiver|content]: dump intent resolvers");
15517                pw.println("    perm[issions]: dump permissions");
15518                pw.println("    permission [name ...]: dump declaration and use of given permission");
15519                pw.println("    pref[erred]: print preferred package settings");
15520                pw.println("    preferred-xml [--full]: print preferred package settings as xml");
15521                pw.println("    prov[iders]: dump content providers");
15522                pw.println("    p[ackages]: dump installed packages");
15523                pw.println("    s[hared-users]: dump shared user IDs");
15524                pw.println("    m[essages]: print collected runtime messages");
15525                pw.println("    v[erifiers]: print package verifier info");
15526                pw.println("    d[omain-preferred-apps]: print domains preferred apps");
15527                pw.println("    i[ntent-filter-verifiers]|ifv: print intent filter verifier info");
15528                pw.println("    version: print database version info");
15529                pw.println("    write: write current settings now");
15530                pw.println("    installs: details about install sessions");
15531                pw.println("    check-permission <permission> <package> [<user>]: does pkg hold perm?");
15532                pw.println("    <package.name>: info about given package");
15533                return;
15534            } else if ("--checkin".equals(opt)) {
15535                checkin = true;
15536            } else if ("-f".equals(opt)) {
15537                dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
15538            } else {
15539                pw.println("Unknown argument: " + opt + "; use -h for help");
15540            }
15541        }
15542
15543        // Is the caller requesting to dump a particular piece of data?
15544        if (opti < args.length) {
15545            String cmd = args[opti];
15546            opti++;
15547            // Is this a package name?
15548            if ("android".equals(cmd) || cmd.contains(".")) {
15549                packageName = cmd;
15550                // When dumping a single package, we always dump all of its
15551                // filter information since the amount of data will be reasonable.
15552                dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
15553            } else if ("check-permission".equals(cmd)) {
15554                if (opti >= args.length) {
15555                    pw.println("Error: check-permission missing permission argument");
15556                    return;
15557                }
15558                String perm = args[opti];
15559                opti++;
15560                if (opti >= args.length) {
15561                    pw.println("Error: check-permission missing package argument");
15562                    return;
15563                }
15564                String pkg = args[opti];
15565                opti++;
15566                int user = UserHandle.getUserId(Binder.getCallingUid());
15567                if (opti < args.length) {
15568                    try {
15569                        user = Integer.parseInt(args[opti]);
15570                    } catch (NumberFormatException e) {
15571                        pw.println("Error: check-permission user argument is not a number: "
15572                                + args[opti]);
15573                        return;
15574                    }
15575                }
15576                pw.println(checkPermission(perm, pkg, user));
15577                return;
15578            } else if ("l".equals(cmd) || "libraries".equals(cmd)) {
15579                dumpState.setDump(DumpState.DUMP_LIBS);
15580            } else if ("f".equals(cmd) || "features".equals(cmd)) {
15581                dumpState.setDump(DumpState.DUMP_FEATURES);
15582            } else if ("r".equals(cmd) || "resolvers".equals(cmd)) {
15583                if (opti >= args.length) {
15584                    dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS
15585                            | DumpState.DUMP_SERVICE_RESOLVERS
15586                            | DumpState.DUMP_RECEIVER_RESOLVERS
15587                            | DumpState.DUMP_CONTENT_RESOLVERS);
15588                } else {
15589                    while (opti < args.length) {
15590                        String name = args[opti];
15591                        if ("a".equals(name) || "activity".equals(name)) {
15592                            dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS);
15593                        } else if ("s".equals(name) || "service".equals(name)) {
15594                            dumpState.setDump(DumpState.DUMP_SERVICE_RESOLVERS);
15595                        } else if ("r".equals(name) || "receiver".equals(name)) {
15596                            dumpState.setDump(DumpState.DUMP_RECEIVER_RESOLVERS);
15597                        } else if ("c".equals(name) || "content".equals(name)) {
15598                            dumpState.setDump(DumpState.DUMP_CONTENT_RESOLVERS);
15599                        } else {
15600                            pw.println("Error: unknown resolver table type: " + name);
15601                            return;
15602                        }
15603                        opti++;
15604                    }
15605                }
15606            } else if ("perm".equals(cmd) || "permissions".equals(cmd)) {
15607                dumpState.setDump(DumpState.DUMP_PERMISSIONS);
15608            } else if ("permission".equals(cmd)) {
15609                if (opti >= args.length) {
15610                    pw.println("Error: permission requires permission name");
15611                    return;
15612                }
15613                permissionNames = new ArraySet<>();
15614                while (opti < args.length) {
15615                    permissionNames.add(args[opti]);
15616                    opti++;
15617                }
15618                dumpState.setDump(DumpState.DUMP_PERMISSIONS
15619                        | DumpState.DUMP_PACKAGES | DumpState.DUMP_SHARED_USERS);
15620            } else if ("pref".equals(cmd) || "preferred".equals(cmd)) {
15621                dumpState.setDump(DumpState.DUMP_PREFERRED);
15622            } else if ("preferred-xml".equals(cmd)) {
15623                dumpState.setDump(DumpState.DUMP_PREFERRED_XML);
15624                if (opti < args.length && "--full".equals(args[opti])) {
15625                    fullPreferred = true;
15626                    opti++;
15627                }
15628            } else if ("d".equals(cmd) || "domain-preferred-apps".equals(cmd)) {
15629                dumpState.setDump(DumpState.DUMP_DOMAIN_PREFERRED);
15630            } else if ("p".equals(cmd) || "packages".equals(cmd)) {
15631                dumpState.setDump(DumpState.DUMP_PACKAGES);
15632            } else if ("s".equals(cmd) || "shared-users".equals(cmd)) {
15633                dumpState.setDump(DumpState.DUMP_SHARED_USERS);
15634            } else if ("prov".equals(cmd) || "providers".equals(cmd)) {
15635                dumpState.setDump(DumpState.DUMP_PROVIDERS);
15636            } else if ("m".equals(cmd) || "messages".equals(cmd)) {
15637                dumpState.setDump(DumpState.DUMP_MESSAGES);
15638            } else if ("v".equals(cmd) || "verifiers".equals(cmd)) {
15639                dumpState.setDump(DumpState.DUMP_VERIFIERS);
15640            } else if ("i".equals(cmd) || "ifv".equals(cmd)
15641                    || "intent-filter-verifiers".equals(cmd)) {
15642                dumpState.setDump(DumpState.DUMP_INTENT_FILTER_VERIFIERS);
15643            } else if ("version".equals(cmd)) {
15644                dumpState.setDump(DumpState.DUMP_VERSION);
15645            } else if ("k".equals(cmd) || "keysets".equals(cmd)) {
15646                dumpState.setDump(DumpState.DUMP_KEYSETS);
15647            } else if ("installs".equals(cmd)) {
15648                dumpState.setDump(DumpState.DUMP_INSTALLS);
15649            } else if ("write".equals(cmd)) {
15650                synchronized (mPackages) {
15651                    mSettings.writeLPr();
15652                    pw.println("Settings written.");
15653                    return;
15654                }
15655            }
15656        }
15657
15658        if (checkin) {
15659            pw.println("vers,1");
15660        }
15661
15662        // reader
15663        synchronized (mPackages) {
15664            if (dumpState.isDumping(DumpState.DUMP_VERSION) && packageName == null) {
15665                if (!checkin) {
15666                    if (dumpState.onTitlePrinted())
15667                        pw.println();
15668                    pw.println("Database versions:");
15669                    mSettings.dumpVersionLPr(new IndentingPrintWriter(pw, "  "));
15670                }
15671            }
15672
15673            if (dumpState.isDumping(DumpState.DUMP_VERIFIERS) && packageName == null) {
15674                if (!checkin) {
15675                    if (dumpState.onTitlePrinted())
15676                        pw.println();
15677                    pw.println("Verifiers:");
15678                    pw.print("  Required: ");
15679                    pw.print(mRequiredVerifierPackage);
15680                    pw.print(" (uid=");
15681                    pw.print(getPackageUid(mRequiredVerifierPackage, 0));
15682                    pw.println(")");
15683                } else if (mRequiredVerifierPackage != null) {
15684                    pw.print("vrfy,"); pw.print(mRequiredVerifierPackage);
15685                    pw.print(","); pw.println(getPackageUid(mRequiredVerifierPackage, 0));
15686                }
15687            }
15688
15689            if (dumpState.isDumping(DumpState.DUMP_INTENT_FILTER_VERIFIERS) &&
15690                    packageName == null) {
15691                if (mIntentFilterVerifierComponent != null) {
15692                    String verifierPackageName = mIntentFilterVerifierComponent.getPackageName();
15693                    if (!checkin) {
15694                        if (dumpState.onTitlePrinted())
15695                            pw.println();
15696                        pw.println("Intent Filter Verifier:");
15697                        pw.print("  Using: ");
15698                        pw.print(verifierPackageName);
15699                        pw.print(" (uid=");
15700                        pw.print(getPackageUid(verifierPackageName, 0));
15701                        pw.println(")");
15702                    } else if (verifierPackageName != null) {
15703                        pw.print("ifv,"); pw.print(verifierPackageName);
15704                        pw.print(","); pw.println(getPackageUid(verifierPackageName, 0));
15705                    }
15706                } else {
15707                    pw.println();
15708                    pw.println("No Intent Filter Verifier available!");
15709                }
15710            }
15711
15712            if (dumpState.isDumping(DumpState.DUMP_LIBS) && packageName == null) {
15713                boolean printedHeader = false;
15714                final Iterator<String> it = mSharedLibraries.keySet().iterator();
15715                while (it.hasNext()) {
15716                    String name = it.next();
15717                    SharedLibraryEntry ent = mSharedLibraries.get(name);
15718                    if (!checkin) {
15719                        if (!printedHeader) {
15720                            if (dumpState.onTitlePrinted())
15721                                pw.println();
15722                            pw.println("Libraries:");
15723                            printedHeader = true;
15724                        }
15725                        pw.print("  ");
15726                    } else {
15727                        pw.print("lib,");
15728                    }
15729                    pw.print(name);
15730                    if (!checkin) {
15731                        pw.print(" -> ");
15732                    }
15733                    if (ent.path != null) {
15734                        if (!checkin) {
15735                            pw.print("(jar) ");
15736                            pw.print(ent.path);
15737                        } else {
15738                            pw.print(",jar,");
15739                            pw.print(ent.path);
15740                        }
15741                    } else {
15742                        if (!checkin) {
15743                            pw.print("(apk) ");
15744                            pw.print(ent.apk);
15745                        } else {
15746                            pw.print(",apk,");
15747                            pw.print(ent.apk);
15748                        }
15749                    }
15750                    pw.println();
15751                }
15752            }
15753
15754            if (dumpState.isDumping(DumpState.DUMP_FEATURES) && packageName == null) {
15755                if (dumpState.onTitlePrinted())
15756                    pw.println();
15757                if (!checkin) {
15758                    pw.println("Features:");
15759                }
15760                Iterator<String> it = mAvailableFeatures.keySet().iterator();
15761                while (it.hasNext()) {
15762                    String name = it.next();
15763                    if (!checkin) {
15764                        pw.print("  ");
15765                    } else {
15766                        pw.print("feat,");
15767                    }
15768                    pw.println(name);
15769                }
15770            }
15771
15772            if (!checkin && dumpState.isDumping(DumpState.DUMP_ACTIVITY_RESOLVERS)) {
15773                if (mActivities.dump(pw, dumpState.getTitlePrinted() ? "\nActivity Resolver Table:"
15774                        : "Activity Resolver Table:", "  ", packageName,
15775                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
15776                    dumpState.setTitlePrinted(true);
15777                }
15778            }
15779            if (!checkin && dumpState.isDumping(DumpState.DUMP_RECEIVER_RESOLVERS)) {
15780                if (mReceivers.dump(pw, dumpState.getTitlePrinted() ? "\nReceiver Resolver Table:"
15781                        : "Receiver Resolver Table:", "  ", packageName,
15782                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
15783                    dumpState.setTitlePrinted(true);
15784                }
15785            }
15786            if (!checkin && dumpState.isDumping(DumpState.DUMP_SERVICE_RESOLVERS)) {
15787                if (mServices.dump(pw, dumpState.getTitlePrinted() ? "\nService Resolver Table:"
15788                        : "Service Resolver Table:", "  ", packageName,
15789                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
15790                    dumpState.setTitlePrinted(true);
15791                }
15792            }
15793            if (!checkin && dumpState.isDumping(DumpState.DUMP_CONTENT_RESOLVERS)) {
15794                if (mProviders.dump(pw, dumpState.getTitlePrinted() ? "\nProvider Resolver Table:"
15795                        : "Provider Resolver Table:", "  ", packageName,
15796                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
15797                    dumpState.setTitlePrinted(true);
15798                }
15799            }
15800
15801            if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED)) {
15802                for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
15803                    PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
15804                    int user = mSettings.mPreferredActivities.keyAt(i);
15805                    if (pir.dump(pw,
15806                            dumpState.getTitlePrinted()
15807                                ? "\nPreferred Activities User " + user + ":"
15808                                : "Preferred Activities User " + user + ":", "  ",
15809                            packageName, true, false)) {
15810                        dumpState.setTitlePrinted(true);
15811                    }
15812                }
15813            }
15814
15815            if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED_XML)) {
15816                pw.flush();
15817                FileOutputStream fout = new FileOutputStream(fd);
15818                BufferedOutputStream str = new BufferedOutputStream(fout);
15819                XmlSerializer serializer = new FastXmlSerializer();
15820                try {
15821                    serializer.setOutput(str, StandardCharsets.UTF_8.name());
15822                    serializer.startDocument(null, true);
15823                    serializer.setFeature(
15824                            "http://xmlpull.org/v1/doc/features.html#indent-output", true);
15825                    mSettings.writePreferredActivitiesLPr(serializer, 0, fullPreferred);
15826                    serializer.endDocument();
15827                    serializer.flush();
15828                } catch (IllegalArgumentException e) {
15829                    pw.println("Failed writing: " + e);
15830                } catch (IllegalStateException e) {
15831                    pw.println("Failed writing: " + e);
15832                } catch (IOException e) {
15833                    pw.println("Failed writing: " + e);
15834                }
15835            }
15836
15837            if (!checkin
15838                    && dumpState.isDumping(DumpState.DUMP_DOMAIN_PREFERRED)
15839                    && packageName == null) {
15840                pw.println();
15841                int count = mSettings.mPackages.size();
15842                if (count == 0) {
15843                    pw.println("No applications!");
15844                    pw.println();
15845                } else {
15846                    final String prefix = "  ";
15847                    Collection<PackageSetting> allPackageSettings = mSettings.mPackages.values();
15848                    if (allPackageSettings.size() == 0) {
15849                        pw.println("No domain preferred apps!");
15850                        pw.println();
15851                    } else {
15852                        pw.println("App verification status:");
15853                        pw.println();
15854                        count = 0;
15855                        for (PackageSetting ps : allPackageSettings) {
15856                            IntentFilterVerificationInfo ivi = ps.getIntentFilterVerificationInfo();
15857                            if (ivi == null || ivi.getPackageName() == null) continue;
15858                            pw.println(prefix + "Package: " + ivi.getPackageName());
15859                            pw.println(prefix + "Domains: " + ivi.getDomainsString());
15860                            pw.println(prefix + "Status:  " + ivi.getStatusString());
15861                            pw.println();
15862                            count++;
15863                        }
15864                        if (count == 0) {
15865                            pw.println(prefix + "No app verification established.");
15866                            pw.println();
15867                        }
15868                        for (int userId : sUserManager.getUserIds()) {
15869                            pw.println("App linkages for user " + userId + ":");
15870                            pw.println();
15871                            count = 0;
15872                            for (PackageSetting ps : allPackageSettings) {
15873                                final long status = ps.getDomainVerificationStatusForUser(userId);
15874                                if (status >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) {
15875                                    continue;
15876                                }
15877                                pw.println(prefix + "Package: " + ps.name);
15878                                pw.println(prefix + "Domains: " + dumpDomainString(ps.name));
15879                                String statusStr = IntentFilterVerificationInfo.
15880                                        getStatusStringFromValue(status);
15881                                pw.println(prefix + "Status:  " + statusStr);
15882                                pw.println();
15883                                count++;
15884                            }
15885                            if (count == 0) {
15886                                pw.println(prefix + "No configured app linkages.");
15887                                pw.println();
15888                            }
15889                        }
15890                    }
15891                }
15892            }
15893
15894            if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) {
15895                mSettings.dumpPermissionsLPr(pw, packageName, permissionNames, dumpState);
15896                if (packageName == null && permissionNames == null) {
15897                    for (int iperm=0; iperm<mAppOpPermissionPackages.size(); iperm++) {
15898                        if (iperm == 0) {
15899                            if (dumpState.onTitlePrinted())
15900                                pw.println();
15901                            pw.println("AppOp Permissions:");
15902                        }
15903                        pw.print("  AppOp Permission ");
15904                        pw.print(mAppOpPermissionPackages.keyAt(iperm));
15905                        pw.println(":");
15906                        ArraySet<String> pkgs = mAppOpPermissionPackages.valueAt(iperm);
15907                        for (int ipkg=0; ipkg<pkgs.size(); ipkg++) {
15908                            pw.print("    "); pw.println(pkgs.valueAt(ipkg));
15909                        }
15910                    }
15911                }
15912            }
15913
15914            if (!checkin && dumpState.isDumping(DumpState.DUMP_PROVIDERS)) {
15915                boolean printedSomething = false;
15916                for (PackageParser.Provider p : mProviders.mProviders.values()) {
15917                    if (packageName != null && !packageName.equals(p.info.packageName)) {
15918                        continue;
15919                    }
15920                    if (!printedSomething) {
15921                        if (dumpState.onTitlePrinted())
15922                            pw.println();
15923                        pw.println("Registered ContentProviders:");
15924                        printedSomething = true;
15925                    }
15926                    pw.print("  "); p.printComponentShortName(pw); pw.println(":");
15927                    pw.print("    "); pw.println(p.toString());
15928                }
15929                printedSomething = false;
15930                for (Map.Entry<String, PackageParser.Provider> entry :
15931                        mProvidersByAuthority.entrySet()) {
15932                    PackageParser.Provider p = entry.getValue();
15933                    if (packageName != null && !packageName.equals(p.info.packageName)) {
15934                        continue;
15935                    }
15936                    if (!printedSomething) {
15937                        if (dumpState.onTitlePrinted())
15938                            pw.println();
15939                        pw.println("ContentProvider Authorities:");
15940                        printedSomething = true;
15941                    }
15942                    pw.print("  ["); pw.print(entry.getKey()); pw.println("]:");
15943                    pw.print("    "); pw.println(p.toString());
15944                    if (p.info != null && p.info.applicationInfo != null) {
15945                        final String appInfo = p.info.applicationInfo.toString();
15946                        pw.print("      applicationInfo="); pw.println(appInfo);
15947                    }
15948                }
15949            }
15950
15951            if (!checkin && dumpState.isDumping(DumpState.DUMP_KEYSETS)) {
15952                mSettings.mKeySetManagerService.dumpLPr(pw, packageName, dumpState);
15953            }
15954
15955            if (dumpState.isDumping(DumpState.DUMP_PACKAGES)) {
15956                mSettings.dumpPackagesLPr(pw, packageName, permissionNames, dumpState, checkin);
15957            }
15958
15959            if (dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) {
15960                mSettings.dumpSharedUsersLPr(pw, packageName, permissionNames, dumpState, checkin);
15961            }
15962
15963            if (!checkin && dumpState.isDumping(DumpState.DUMP_INSTALLS) && packageName == null) {
15964                // XXX should handle packageName != null by dumping only install data that
15965                // the given package is involved with.
15966                if (dumpState.onTitlePrinted()) pw.println();
15967                mInstallerService.dump(new IndentingPrintWriter(pw, "  ", 120));
15968            }
15969
15970            if (!checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES) && packageName == null) {
15971                if (dumpState.onTitlePrinted()) pw.println();
15972                mSettings.dumpReadMessagesLPr(pw, dumpState);
15973
15974                pw.println();
15975                pw.println("Package warning messages:");
15976                BufferedReader in = null;
15977                String line = null;
15978                try {
15979                    in = new BufferedReader(new FileReader(getSettingsProblemFile()));
15980                    while ((line = in.readLine()) != null) {
15981                        if (line.contains("ignored: updated version")) continue;
15982                        pw.println(line);
15983                    }
15984                } catch (IOException ignored) {
15985                } finally {
15986                    IoUtils.closeQuietly(in);
15987                }
15988            }
15989
15990            if (checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES)) {
15991                BufferedReader in = null;
15992                String line = null;
15993                try {
15994                    in = new BufferedReader(new FileReader(getSettingsProblemFile()));
15995                    while ((line = in.readLine()) != null) {
15996                        if (line.contains("ignored: updated version")) continue;
15997                        pw.print("msg,");
15998                        pw.println(line);
15999                    }
16000                } catch (IOException ignored) {
16001                } finally {
16002                    IoUtils.closeQuietly(in);
16003                }
16004            }
16005        }
16006    }
16007
16008    private String dumpDomainString(String packageName) {
16009        List<IntentFilterVerificationInfo> iviList = getIntentFilterVerifications(packageName);
16010        List<IntentFilter> filters = getAllIntentFilters(packageName);
16011
16012        ArraySet<String> result = new ArraySet<>();
16013        if (iviList.size() > 0) {
16014            for (IntentFilterVerificationInfo ivi : iviList) {
16015                for (String host : ivi.getDomains()) {
16016                    result.add(host);
16017                }
16018            }
16019        }
16020        if (filters != null && filters.size() > 0) {
16021            for (IntentFilter filter : filters) {
16022                if (filter.hasCategory(Intent.CATEGORY_BROWSABLE)
16023                        && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) ||
16024                                filter.hasDataScheme(IntentFilter.SCHEME_HTTPS))) {
16025                    result.addAll(filter.getHostsList());
16026                }
16027            }
16028        }
16029
16030        StringBuilder sb = new StringBuilder(result.size() * 16);
16031        for (String domain : result) {
16032            if (sb.length() > 0) sb.append(" ");
16033            sb.append(domain);
16034        }
16035        return sb.toString();
16036    }
16037
16038    // ------- apps on sdcard specific code -------
16039    static final boolean DEBUG_SD_INSTALL = false;
16040
16041    private static final String SD_ENCRYPTION_KEYSTORE_NAME = "AppsOnSD";
16042
16043    private static final String SD_ENCRYPTION_ALGORITHM = "AES";
16044
16045    private boolean mMediaMounted = false;
16046
16047    static String getEncryptKey() {
16048        try {
16049            String sdEncKey = SystemKeyStore.getInstance().retrieveKeyHexString(
16050                    SD_ENCRYPTION_KEYSTORE_NAME);
16051            if (sdEncKey == null) {
16052                sdEncKey = SystemKeyStore.getInstance().generateNewKeyHexString(128,
16053                        SD_ENCRYPTION_ALGORITHM, SD_ENCRYPTION_KEYSTORE_NAME);
16054                if (sdEncKey == null) {
16055                    Slog.e(TAG, "Failed to create encryption keys");
16056                    return null;
16057                }
16058            }
16059            return sdEncKey;
16060        } catch (NoSuchAlgorithmException nsae) {
16061            Slog.e(TAG, "Failed to create encryption keys with exception: " + nsae);
16062            return null;
16063        } catch (IOException ioe) {
16064            Slog.e(TAG, "Failed to retrieve encryption keys with exception: " + ioe);
16065            return null;
16066        }
16067    }
16068
16069    /*
16070     * Update media status on PackageManager.
16071     */
16072    @Override
16073    public void updateExternalMediaStatus(final boolean mediaStatus, final boolean reportStatus) {
16074        int callingUid = Binder.getCallingUid();
16075        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
16076            throw new SecurityException("Media status can only be updated by the system");
16077        }
16078        // reader; this apparently protects mMediaMounted, but should probably
16079        // be a different lock in that case.
16080        synchronized (mPackages) {
16081            Log.i(TAG, "Updating external media status from "
16082                    + (mMediaMounted ? "mounted" : "unmounted") + " to "
16083                    + (mediaStatus ? "mounted" : "unmounted"));
16084            if (DEBUG_SD_INSTALL)
16085                Log.i(TAG, "updateExternalMediaStatus:: mediaStatus=" + mediaStatus
16086                        + ", mMediaMounted=" + mMediaMounted);
16087            if (mediaStatus == mMediaMounted) {
16088                final Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1
16089                        : 0, -1);
16090                mHandler.sendMessage(msg);
16091                return;
16092            }
16093            mMediaMounted = mediaStatus;
16094        }
16095        // Queue up an async operation since the package installation may take a
16096        // little while.
16097        mHandler.post(new Runnable() {
16098            public void run() {
16099                updateExternalMediaStatusInner(mediaStatus, reportStatus, true);
16100            }
16101        });
16102    }
16103
16104    /**
16105     * Called by MountService when the initial ASECs to scan are available.
16106     * Should block until all the ASEC containers are finished being scanned.
16107     */
16108    public void scanAvailableAsecs() {
16109        updateExternalMediaStatusInner(true, false, false);
16110        if (mShouldRestoreconData) {
16111            SELinuxMMAC.setRestoreconDone();
16112            mShouldRestoreconData = false;
16113        }
16114    }
16115
16116    /*
16117     * Collect information of applications on external media, map them against
16118     * existing containers and update information based on current mount status.
16119     * Please note that we always have to report status if reportStatus has been
16120     * set to true especially when unloading packages.
16121     */
16122    private void updateExternalMediaStatusInner(boolean isMounted, boolean reportStatus,
16123            boolean externalStorage) {
16124        ArrayMap<AsecInstallArgs, String> processCids = new ArrayMap<>();
16125        int[] uidArr = EmptyArray.INT;
16126
16127        final String[] list = PackageHelper.getSecureContainerList();
16128        if (ArrayUtils.isEmpty(list)) {
16129            Log.i(TAG, "No secure containers found");
16130        } else {
16131            // Process list of secure containers and categorize them
16132            // as active or stale based on their package internal state.
16133
16134            // reader
16135            synchronized (mPackages) {
16136                for (String cid : list) {
16137                    // Leave stages untouched for now; installer service owns them
16138                    if (PackageInstallerService.isStageName(cid)) continue;
16139
16140                    if (DEBUG_SD_INSTALL)
16141                        Log.i(TAG, "Processing container " + cid);
16142                    String pkgName = getAsecPackageName(cid);
16143                    if (pkgName == null) {
16144                        Slog.i(TAG, "Found stale container " + cid + " with no package name");
16145                        continue;
16146                    }
16147                    if (DEBUG_SD_INSTALL)
16148                        Log.i(TAG, "Looking for pkg : " + pkgName);
16149
16150                    final PackageSetting ps = mSettings.mPackages.get(pkgName);
16151                    if (ps == null) {
16152                        Slog.i(TAG, "Found stale container " + cid + " with no matching settings");
16153                        continue;
16154                    }
16155
16156                    /*
16157                     * Skip packages that are not external if we're unmounting
16158                     * external storage.
16159                     */
16160                    if (externalStorage && !isMounted && !isExternal(ps)) {
16161                        continue;
16162                    }
16163
16164                    final AsecInstallArgs args = new AsecInstallArgs(cid,
16165                            getAppDexInstructionSets(ps), ps.isForwardLocked());
16166                    // The package status is changed only if the code path
16167                    // matches between settings and the container id.
16168                    if (ps.codePathString != null
16169                            && ps.codePathString.startsWith(args.getCodePath())) {
16170                        if (DEBUG_SD_INSTALL) {
16171                            Log.i(TAG, "Container : " + cid + " corresponds to pkg : " + pkgName
16172                                    + " at code path: " + ps.codePathString);
16173                        }
16174
16175                        // We do have a valid package installed on sdcard
16176                        processCids.put(args, ps.codePathString);
16177                        final int uid = ps.appId;
16178                        if (uid != -1) {
16179                            uidArr = ArrayUtils.appendInt(uidArr, uid);
16180                        }
16181                    } else {
16182                        Slog.i(TAG, "Found stale container " + cid + ": expected codePath="
16183                                + ps.codePathString);
16184                    }
16185                }
16186            }
16187
16188            Arrays.sort(uidArr);
16189        }
16190
16191        // Process packages with valid entries.
16192        if (isMounted) {
16193            if (DEBUG_SD_INSTALL)
16194                Log.i(TAG, "Loading packages");
16195            loadMediaPackages(processCids, uidArr, externalStorage);
16196            startCleaningPackages();
16197            mInstallerService.onSecureContainersAvailable();
16198        } else {
16199            if (DEBUG_SD_INSTALL)
16200                Log.i(TAG, "Unloading packages");
16201            unloadMediaPackages(processCids, uidArr, reportStatus);
16202        }
16203    }
16204
16205    private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
16206            ArrayList<ApplicationInfo> infos, IIntentReceiver finishedReceiver) {
16207        final int size = infos.size();
16208        final String[] packageNames = new String[size];
16209        final int[] packageUids = new int[size];
16210        for (int i = 0; i < size; i++) {
16211            final ApplicationInfo info = infos.get(i);
16212            packageNames[i] = info.packageName;
16213            packageUids[i] = info.uid;
16214        }
16215        sendResourcesChangedBroadcast(mediaStatus, replacing, packageNames, packageUids,
16216                finishedReceiver);
16217    }
16218
16219    private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
16220            ArrayList<String> pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
16221        sendResourcesChangedBroadcast(mediaStatus, replacing,
16222                pkgList.toArray(new String[pkgList.size()]), uidArr, finishedReceiver);
16223    }
16224
16225    private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
16226            String[] pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
16227        int size = pkgList.length;
16228        if (size > 0) {
16229            // Send broadcasts here
16230            Bundle extras = new Bundle();
16231            extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
16232            if (uidArr != null) {
16233                extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidArr);
16234            }
16235            if (replacing) {
16236                extras.putBoolean(Intent.EXTRA_REPLACING, replacing);
16237            }
16238            String action = mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE
16239                    : Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE;
16240            sendPackageBroadcast(action, null, extras, 0, null, finishedReceiver, null);
16241        }
16242    }
16243
16244   /*
16245     * Look at potentially valid container ids from processCids If package
16246     * information doesn't match the one on record or package scanning fails,
16247     * the cid is added to list of removeCids. We currently don't delete stale
16248     * containers.
16249     */
16250    private void loadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int[] uidArr,
16251            boolean externalStorage) {
16252        ArrayList<String> pkgList = new ArrayList<String>();
16253        Set<AsecInstallArgs> keys = processCids.keySet();
16254
16255        for (AsecInstallArgs args : keys) {
16256            String codePath = processCids.get(args);
16257            if (DEBUG_SD_INSTALL)
16258                Log.i(TAG, "Loading container : " + args.cid);
16259            int retCode = PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
16260            try {
16261                // Make sure there are no container errors first.
16262                if (args.doPreInstall(PackageManager.INSTALL_SUCCEEDED) != PackageManager.INSTALL_SUCCEEDED) {
16263                    Slog.e(TAG, "Failed to mount cid : " + args.cid
16264                            + " when installing from sdcard");
16265                    continue;
16266                }
16267                // Check code path here.
16268                if (codePath == null || !codePath.startsWith(args.getCodePath())) {
16269                    Slog.e(TAG, "Container " + args.cid + " cachepath " + args.getCodePath()
16270                            + " does not match one in settings " + codePath);
16271                    continue;
16272                }
16273                // Parse package
16274                int parseFlags = mDefParseFlags;
16275                if (args.isExternalAsec()) {
16276                    parseFlags |= PackageParser.PARSE_EXTERNAL_STORAGE;
16277                }
16278                if (args.isFwdLocked()) {
16279                    parseFlags |= PackageParser.PARSE_FORWARD_LOCK;
16280                }
16281
16282                synchronized (mInstallLock) {
16283                    PackageParser.Package pkg = null;
16284                    try {
16285                        pkg = scanPackageTracedLI(new File(codePath), parseFlags, 0, 0, null);
16286                    } catch (PackageManagerException e) {
16287                        Slog.w(TAG, "Failed to scan " + codePath + ": " + e.getMessage());
16288                    }
16289                    // Scan the package
16290                    if (pkg != null) {
16291                        /*
16292                         * TODO why is the lock being held? doPostInstall is
16293                         * called in other places without the lock. This needs
16294                         * to be straightened out.
16295                         */
16296                        // writer
16297                        synchronized (mPackages) {
16298                            retCode = PackageManager.INSTALL_SUCCEEDED;
16299                            pkgList.add(pkg.packageName);
16300                            // Post process args
16301                            args.doPostInstall(PackageManager.INSTALL_SUCCEEDED,
16302                                    pkg.applicationInfo.uid);
16303                        }
16304                    } else {
16305                        Slog.i(TAG, "Failed to install pkg from  " + codePath + " from sdcard");
16306                    }
16307                }
16308
16309            } finally {
16310                if (retCode != PackageManager.INSTALL_SUCCEEDED) {
16311                    Log.w(TAG, "Container " + args.cid + " is stale, retCode=" + retCode);
16312                }
16313            }
16314        }
16315        // writer
16316        synchronized (mPackages) {
16317            // If the platform SDK has changed since the last time we booted,
16318            // we need to re-grant app permission to catch any new ones that
16319            // appear. This is really a hack, and means that apps can in some
16320            // cases get permissions that the user didn't initially explicitly
16321            // allow... it would be nice to have some better way to handle
16322            // this situation.
16323            final VersionInfo ver = externalStorage ? mSettings.getExternalVersion()
16324                    : mSettings.getInternalVersion();
16325            final String volumeUuid = externalStorage ? StorageManager.UUID_PRIMARY_PHYSICAL
16326                    : StorageManager.UUID_PRIVATE_INTERNAL;
16327
16328            int updateFlags = UPDATE_PERMISSIONS_ALL;
16329            if (ver.sdkVersion != mSdkVersion) {
16330                logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to "
16331                        + mSdkVersion + "; regranting permissions for external");
16332                updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
16333            }
16334            updatePermissionsLPw(null, null, volumeUuid, updateFlags);
16335
16336            // Yay, everything is now upgraded
16337            ver.forceCurrent();
16338
16339            // can downgrade to reader
16340            // Persist settings
16341            mSettings.writeLPr();
16342        }
16343        // Send a broadcast to let everyone know we are done processing
16344        if (pkgList.size() > 0) {
16345            sendResourcesChangedBroadcast(true, false, pkgList, uidArr, null);
16346        }
16347    }
16348
16349   /*
16350     * Utility method to unload a list of specified containers
16351     */
16352    private void unloadAllContainers(Set<AsecInstallArgs> cidArgs) {
16353        // Just unmount all valid containers.
16354        for (AsecInstallArgs arg : cidArgs) {
16355            synchronized (mInstallLock) {
16356                arg.doPostDeleteLI(false);
16357           }
16358       }
16359   }
16360
16361    /*
16362     * Unload packages mounted on external media. This involves deleting package
16363     * data from internal structures, sending broadcasts about diabled packages,
16364     * gc'ing to free up references, unmounting all secure containers
16365     * corresponding to packages on external media, and posting a
16366     * UPDATED_MEDIA_STATUS message if status has been requested. Please note
16367     * that we always have to post this message if status has been requested no
16368     * matter what.
16369     */
16370    private void unloadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int uidArr[],
16371            final boolean reportStatus) {
16372        if (DEBUG_SD_INSTALL)
16373            Log.i(TAG, "unloading media packages");
16374        ArrayList<String> pkgList = new ArrayList<String>();
16375        ArrayList<AsecInstallArgs> failedList = new ArrayList<AsecInstallArgs>();
16376        final Set<AsecInstallArgs> keys = processCids.keySet();
16377        for (AsecInstallArgs args : keys) {
16378            String pkgName = args.getPackageName();
16379            if (DEBUG_SD_INSTALL)
16380                Log.i(TAG, "Trying to unload pkg : " + pkgName);
16381            // Delete package internally
16382            PackageRemovedInfo outInfo = new PackageRemovedInfo();
16383            synchronized (mInstallLock) {
16384                boolean res = deletePackageLI(pkgName, null, false, null, null,
16385                        PackageManager.DELETE_KEEP_DATA, outInfo, false);
16386                if (res) {
16387                    pkgList.add(pkgName);
16388                } else {
16389                    Slog.e(TAG, "Failed to delete pkg from sdcard : " + pkgName);
16390                    failedList.add(args);
16391                }
16392            }
16393        }
16394
16395        // reader
16396        synchronized (mPackages) {
16397            // We didn't update the settings after removing each package;
16398            // write them now for all packages.
16399            mSettings.writeLPr();
16400        }
16401
16402        // We have to absolutely send UPDATED_MEDIA_STATUS only
16403        // after confirming that all the receivers processed the ordered
16404        // broadcast when packages get disabled, force a gc to clean things up.
16405        // and unload all the containers.
16406        if (pkgList.size() > 0) {
16407            sendResourcesChangedBroadcast(false, false, pkgList, uidArr,
16408                    new IIntentReceiver.Stub() {
16409                public void performReceive(Intent intent, int resultCode, String data,
16410                        Bundle extras, boolean ordered, boolean sticky,
16411                        int sendingUser) throws RemoteException {
16412                    Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS,
16413                            reportStatus ? 1 : 0, 1, keys);
16414                    mHandler.sendMessage(msg);
16415                }
16416            });
16417        } else {
16418            Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1 : 0, -1,
16419                    keys);
16420            mHandler.sendMessage(msg);
16421        }
16422    }
16423
16424    private void loadPrivatePackages(final VolumeInfo vol) {
16425        mHandler.post(new Runnable() {
16426            @Override
16427            public void run() {
16428                loadPrivatePackagesInner(vol);
16429            }
16430        });
16431    }
16432
16433    private void loadPrivatePackagesInner(VolumeInfo vol) {
16434        final ArrayList<ApplicationInfo> loaded = new ArrayList<>();
16435        final int parseFlags = mDefParseFlags | PackageParser.PARSE_EXTERNAL_STORAGE;
16436
16437        final VersionInfo ver;
16438        final List<PackageSetting> packages;
16439        synchronized (mPackages) {
16440            ver = mSettings.findOrCreateVersion(vol.fsUuid);
16441            packages = mSettings.getVolumePackagesLPr(vol.fsUuid);
16442        }
16443
16444        for (PackageSetting ps : packages) {
16445            synchronized (mInstallLock) {
16446                final PackageParser.Package pkg;
16447                try {
16448                    pkg = scanPackageTracedLI(ps.codePath, parseFlags, SCAN_INITIAL, 0, null);
16449                    loaded.add(pkg.applicationInfo);
16450                } catch (PackageManagerException e) {
16451                    Slog.w(TAG, "Failed to scan " + ps.codePath + ": " + e.getMessage());
16452                }
16453
16454                if (!Build.FINGERPRINT.equals(ver.fingerprint)) {
16455                    deleteCodeCacheDirsLI(ps.volumeUuid, ps.name);
16456                }
16457            }
16458        }
16459
16460        synchronized (mPackages) {
16461            int updateFlags = UPDATE_PERMISSIONS_ALL;
16462            if (ver.sdkVersion != mSdkVersion) {
16463                logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to "
16464                        + mSdkVersion + "; regranting permissions for " + vol.fsUuid);
16465                updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
16466            }
16467            updatePermissionsLPw(null, null, vol.fsUuid, updateFlags);
16468
16469            // Yay, everything is now upgraded
16470            ver.forceCurrent();
16471
16472            mSettings.writeLPr();
16473        }
16474
16475        if (DEBUG_INSTALL) Slog.d(TAG, "Loaded packages " + loaded);
16476        sendResourcesChangedBroadcast(true, false, loaded, null);
16477    }
16478
16479    private void unloadPrivatePackages(final VolumeInfo vol) {
16480        mHandler.post(new Runnable() {
16481            @Override
16482            public void run() {
16483                unloadPrivatePackagesInner(vol);
16484            }
16485        });
16486    }
16487
16488    private void unloadPrivatePackagesInner(VolumeInfo vol) {
16489        final ArrayList<ApplicationInfo> unloaded = new ArrayList<>();
16490        synchronized (mInstallLock) {
16491        synchronized (mPackages) {
16492            final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(vol.fsUuid);
16493            for (PackageSetting ps : packages) {
16494                if (ps.pkg == null) continue;
16495
16496                final ApplicationInfo info = ps.pkg.applicationInfo;
16497                final PackageRemovedInfo outInfo = new PackageRemovedInfo();
16498                if (deletePackageLI(ps.name, null, false, null, null,
16499                        PackageManager.DELETE_KEEP_DATA, outInfo, false)) {
16500                    unloaded.add(info);
16501                } else {
16502                    Slog.w(TAG, "Failed to unload " + ps.codePath);
16503                }
16504            }
16505
16506            mSettings.writeLPr();
16507        }
16508        }
16509
16510        if (DEBUG_INSTALL) Slog.d(TAG, "Unloaded packages " + unloaded);
16511        sendResourcesChangedBroadcast(false, false, unloaded, null);
16512    }
16513
16514    /**
16515     * Examine all users present on given mounted volume, and destroy data
16516     * belonging to users that are no longer valid, or whose user ID has been
16517     * recycled.
16518     */
16519    private void reconcileUsers(String volumeUuid) {
16520        final File[] files = FileUtils
16521                .listFilesOrEmpty(Environment.getDataUserDirectory(volumeUuid));
16522        for (File file : files) {
16523            if (!file.isDirectory()) continue;
16524
16525            final int userId;
16526            final UserInfo info;
16527            try {
16528                userId = Integer.parseInt(file.getName());
16529                info = sUserManager.getUserInfo(userId);
16530            } catch (NumberFormatException e) {
16531                Slog.w(TAG, "Invalid user directory " + file);
16532                continue;
16533            }
16534
16535            boolean destroyUser = false;
16536            if (info == null) {
16537                logCriticalInfo(Log.WARN, "Destroying user directory " + file
16538                        + " because no matching user was found");
16539                destroyUser = true;
16540            } else {
16541                try {
16542                    UserManagerService.enforceSerialNumber(file, info.serialNumber);
16543                } catch (IOException e) {
16544                    logCriticalInfo(Log.WARN, "Destroying user directory " + file
16545                            + " because we failed to enforce serial number: " + e);
16546                    destroyUser = true;
16547                }
16548            }
16549
16550            if (destroyUser) {
16551                synchronized (mInstallLock) {
16552                    mInstaller.removeUserDataDirs(volumeUuid, userId);
16553                }
16554            }
16555        }
16556
16557        final StorageManager sm = mContext.getSystemService(StorageManager.class);
16558        final UserManager um = mContext.getSystemService(UserManager.class);
16559        for (UserInfo user : um.getUsers()) {
16560            final File userDir = Environment.getDataUserDirectory(volumeUuid, user.id);
16561            if (userDir.exists()) continue;
16562
16563            try {
16564                sm.prepareUserStorage(volumeUuid, user.id, user.serialNumber, user.isEphemeral());
16565                UserManagerService.enforceSerialNumber(userDir, user.serialNumber);
16566            } catch (IOException e) {
16567                Log.wtf(TAG, "Failed to create user directory on " + volumeUuid, e);
16568            }
16569        }
16570    }
16571
16572    /**
16573     * Examine all apps present on given mounted volume, and destroy apps that
16574     * aren't expected, either due to uninstallation or reinstallation on
16575     * another volume.
16576     */
16577    private void reconcileApps(String volumeUuid) {
16578        final File[] files = FileUtils
16579                .listFilesOrEmpty(Environment.getDataAppDirectory(volumeUuid));
16580        for (File file : files) {
16581            final boolean isPackage = (isApkFile(file) || file.isDirectory())
16582                    && !PackageInstallerService.isStageName(file.getName());
16583            if (!isPackage) {
16584                // Ignore entries which are not packages
16585                continue;
16586            }
16587
16588            boolean destroyApp = false;
16589            String packageName = null;
16590            try {
16591                final PackageLite pkg = PackageParser.parsePackageLite(file,
16592                        PackageParser.PARSE_MUST_BE_APK);
16593                packageName = pkg.packageName;
16594
16595                synchronized (mPackages) {
16596                    final PackageSetting ps = mSettings.mPackages.get(packageName);
16597                    if (ps == null) {
16598                        logCriticalInfo(Log.WARN, "Destroying " + packageName + " on + "
16599                                + volumeUuid + " because we found no install record");
16600                        destroyApp = true;
16601                    } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) {
16602                        logCriticalInfo(Log.WARN, "Destroying " + packageName + " on "
16603                                + volumeUuid + " because we expected it on " + ps.volumeUuid);
16604                        destroyApp = true;
16605                    }
16606                }
16607
16608            } catch (PackageParserException e) {
16609                logCriticalInfo(Log.WARN, "Destroying " + file + " due to parse failure: " + e);
16610                destroyApp = true;
16611            }
16612
16613            if (destroyApp) {
16614                synchronized (mInstallLock) {
16615                    if (packageName != null) {
16616                        removeDataDirsLI(volumeUuid, packageName);
16617                    }
16618                    if (file.isDirectory()) {
16619                        mInstaller.rmPackageDir(file.getAbsolutePath());
16620                    } else {
16621                        file.delete();
16622                    }
16623                }
16624            }
16625        }
16626    }
16627
16628    private void unfreezePackage(String packageName) {
16629        synchronized (mPackages) {
16630            final PackageSetting ps = mSettings.mPackages.get(packageName);
16631            if (ps != null) {
16632                ps.frozen = false;
16633            }
16634        }
16635    }
16636
16637    @Override
16638    public int movePackage(final String packageName, final String volumeUuid) {
16639        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
16640
16641        final int moveId = mNextMoveId.getAndIncrement();
16642        mHandler.post(new Runnable() {
16643            @Override
16644            public void run() {
16645                try {
16646                    movePackageInternal(packageName, volumeUuid, moveId);
16647                } catch (PackageManagerException e) {
16648                    Slog.w(TAG, "Failed to move " + packageName, e);
16649                    mMoveCallbacks.notifyStatusChanged(moveId,
16650                            PackageManager.MOVE_FAILED_INTERNAL_ERROR);
16651                }
16652            }
16653        });
16654        return moveId;
16655    }
16656
16657    private void movePackageInternal(final String packageName, final String volumeUuid,
16658            final int moveId) throws PackageManagerException {
16659        final UserHandle user = new UserHandle(UserHandle.getCallingUserId());
16660        final StorageManager storage = mContext.getSystemService(StorageManager.class);
16661        final PackageManager pm = mContext.getPackageManager();
16662
16663        final boolean currentAsec;
16664        final String currentVolumeUuid;
16665        final File codeFile;
16666        final String installerPackageName;
16667        final String packageAbiOverride;
16668        final int appId;
16669        final String seinfo;
16670        final String label;
16671
16672        // reader
16673        synchronized (mPackages) {
16674            final PackageParser.Package pkg = mPackages.get(packageName);
16675            final PackageSetting ps = mSettings.mPackages.get(packageName);
16676            if (pkg == null || ps == null) {
16677                throw new PackageManagerException(MOVE_FAILED_DOESNT_EXIST, "Missing package");
16678            }
16679
16680            if (pkg.applicationInfo.isSystemApp()) {
16681                throw new PackageManagerException(MOVE_FAILED_SYSTEM_PACKAGE,
16682                        "Cannot move system application");
16683            }
16684
16685            if (pkg.applicationInfo.isExternalAsec()) {
16686                currentAsec = true;
16687                currentVolumeUuid = StorageManager.UUID_PRIMARY_PHYSICAL;
16688            } else if (pkg.applicationInfo.isForwardLocked()) {
16689                currentAsec = true;
16690                currentVolumeUuid = "forward_locked";
16691            } else {
16692                currentAsec = false;
16693                currentVolumeUuid = ps.volumeUuid;
16694
16695                final File probe = new File(pkg.codePath);
16696                final File probeOat = new File(probe, "oat");
16697                if (!probe.isDirectory() || !probeOat.isDirectory()) {
16698                    throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
16699                            "Move only supported for modern cluster style installs");
16700                }
16701            }
16702
16703            if (Objects.equals(currentVolumeUuid, volumeUuid)) {
16704                throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
16705                        "Package already moved to " + volumeUuid);
16706            }
16707
16708            if (ps.frozen) {
16709                throw new PackageManagerException(MOVE_FAILED_OPERATION_PENDING,
16710                        "Failed to move already frozen package");
16711            }
16712            ps.frozen = true;
16713
16714            codeFile = new File(pkg.codePath);
16715            installerPackageName = ps.installerPackageName;
16716            packageAbiOverride = ps.cpuAbiOverrideString;
16717            appId = UserHandle.getAppId(pkg.applicationInfo.uid);
16718            seinfo = pkg.applicationInfo.seinfo;
16719            label = String.valueOf(pm.getApplicationLabel(pkg.applicationInfo));
16720        }
16721
16722        // Now that we're guarded by frozen state, kill app during move
16723        final long token = Binder.clearCallingIdentity();
16724        try {
16725            killApplication(packageName, appId, "move pkg");
16726        } finally {
16727            Binder.restoreCallingIdentity(token);
16728        }
16729
16730        final Bundle extras = new Bundle();
16731        extras.putString(Intent.EXTRA_PACKAGE_NAME, packageName);
16732        extras.putString(Intent.EXTRA_TITLE, label);
16733        mMoveCallbacks.notifyCreated(moveId, extras);
16734
16735        int installFlags;
16736        final boolean moveCompleteApp;
16737        final File measurePath;
16738
16739        if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, volumeUuid)) {
16740            installFlags = INSTALL_INTERNAL;
16741            moveCompleteApp = !currentAsec;
16742            measurePath = Environment.getDataAppDirectory(volumeUuid);
16743        } else if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, volumeUuid)) {
16744            installFlags = INSTALL_EXTERNAL;
16745            moveCompleteApp = false;
16746            measurePath = storage.getPrimaryPhysicalVolume().getPath();
16747        } else {
16748            final VolumeInfo volume = storage.findVolumeByUuid(volumeUuid);
16749            if (volume == null || volume.getType() != VolumeInfo.TYPE_PRIVATE
16750                    || !volume.isMountedWritable()) {
16751                unfreezePackage(packageName);
16752                throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
16753                        "Move location not mounted private volume");
16754            }
16755
16756            Preconditions.checkState(!currentAsec);
16757
16758            installFlags = INSTALL_INTERNAL;
16759            moveCompleteApp = true;
16760            measurePath = Environment.getDataAppDirectory(volumeUuid);
16761        }
16762
16763        final PackageStats stats = new PackageStats(null, -1);
16764        synchronized (mInstaller) {
16765            if (!getPackageSizeInfoLI(packageName, -1, stats)) {
16766                unfreezePackage(packageName);
16767                throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
16768                        "Failed to measure package size");
16769            }
16770        }
16771
16772        if (DEBUG_INSTALL) Slog.d(TAG, "Measured code size " + stats.codeSize + ", data size "
16773                + stats.dataSize);
16774
16775        final long startFreeBytes = measurePath.getFreeSpace();
16776        final long sizeBytes;
16777        if (moveCompleteApp) {
16778            sizeBytes = stats.codeSize + stats.dataSize;
16779        } else {
16780            sizeBytes = stats.codeSize;
16781        }
16782
16783        if (sizeBytes > storage.getStorageBytesUntilLow(measurePath)) {
16784            unfreezePackage(packageName);
16785            throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
16786                    "Not enough free space to move");
16787        }
16788
16789        mMoveCallbacks.notifyStatusChanged(moveId, 10);
16790
16791        final CountDownLatch installedLatch = new CountDownLatch(1);
16792        final IPackageInstallObserver2 installObserver = new IPackageInstallObserver2.Stub() {
16793            @Override
16794            public void onUserActionRequired(Intent intent) throws RemoteException {
16795                throw new IllegalStateException();
16796            }
16797
16798            @Override
16799            public void onPackageInstalled(String basePackageName, int returnCode, String msg,
16800                    Bundle extras) throws RemoteException {
16801                if (DEBUG_INSTALL) Slog.d(TAG, "Install result for move: "
16802                        + PackageManager.installStatusToString(returnCode, msg));
16803
16804                installedLatch.countDown();
16805
16806                // Regardless of success or failure of the move operation,
16807                // always unfreeze the package
16808                unfreezePackage(packageName);
16809
16810                final int status = PackageManager.installStatusToPublicStatus(returnCode);
16811                switch (status) {
16812                    case PackageInstaller.STATUS_SUCCESS:
16813                        mMoveCallbacks.notifyStatusChanged(moveId,
16814                                PackageManager.MOVE_SUCCEEDED);
16815                        break;
16816                    case PackageInstaller.STATUS_FAILURE_STORAGE:
16817                        mMoveCallbacks.notifyStatusChanged(moveId,
16818                                PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE);
16819                        break;
16820                    default:
16821                        mMoveCallbacks.notifyStatusChanged(moveId,
16822                                PackageManager.MOVE_FAILED_INTERNAL_ERROR);
16823                        break;
16824                }
16825            }
16826        };
16827
16828        final MoveInfo move;
16829        if (moveCompleteApp) {
16830            // Kick off a thread to report progress estimates
16831            new Thread() {
16832                @Override
16833                public void run() {
16834                    while (true) {
16835                        try {
16836                            if (installedLatch.await(1, TimeUnit.SECONDS)) {
16837                                break;
16838                            }
16839                        } catch (InterruptedException ignored) {
16840                        }
16841
16842                        final long deltaFreeBytes = startFreeBytes - measurePath.getFreeSpace();
16843                        final int progress = 10 + (int) MathUtils.constrain(
16844                                ((deltaFreeBytes * 80) / sizeBytes), 0, 80);
16845                        mMoveCallbacks.notifyStatusChanged(moveId, progress);
16846                    }
16847                }
16848            }.start();
16849
16850            final String dataAppName = codeFile.getName();
16851            move = new MoveInfo(moveId, currentVolumeUuid, volumeUuid, packageName,
16852                    dataAppName, appId, seinfo);
16853        } else {
16854            move = null;
16855        }
16856
16857        installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
16858
16859        final Message msg = mHandler.obtainMessage(INIT_COPY);
16860        final OriginInfo origin = OriginInfo.fromExistingFile(codeFile);
16861        final InstallParams params = new InstallParams(origin, move, installObserver, installFlags,
16862                installerPackageName, volumeUuid, null, user, packageAbiOverride, null);
16863        params.setTraceMethod("movePackage").setTraceCookie(System.identityHashCode(params));
16864        msg.obj = params;
16865
16866        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "movePackage",
16867                System.identityHashCode(msg.obj));
16868        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
16869                System.identityHashCode(msg.obj));
16870
16871        mHandler.sendMessage(msg);
16872    }
16873
16874    @Override
16875    public int movePrimaryStorage(String volumeUuid) throws RemoteException {
16876        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
16877
16878        final int realMoveId = mNextMoveId.getAndIncrement();
16879        final Bundle extras = new Bundle();
16880        extras.putString(VolumeRecord.EXTRA_FS_UUID, volumeUuid);
16881        mMoveCallbacks.notifyCreated(realMoveId, extras);
16882
16883        final IPackageMoveObserver callback = new IPackageMoveObserver.Stub() {
16884            @Override
16885            public void onCreated(int moveId, Bundle extras) {
16886                // Ignored
16887            }
16888
16889            @Override
16890            public void onStatusChanged(int moveId, int status, long estMillis) {
16891                mMoveCallbacks.notifyStatusChanged(realMoveId, status, estMillis);
16892            }
16893        };
16894
16895        final StorageManager storage = mContext.getSystemService(StorageManager.class);
16896        storage.setPrimaryStorageUuid(volumeUuid, callback);
16897        return realMoveId;
16898    }
16899
16900    @Override
16901    public int getMoveStatus(int moveId) {
16902        mContext.enforceCallingOrSelfPermission(
16903                android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
16904        return mMoveCallbacks.mLastStatus.get(moveId);
16905    }
16906
16907    @Override
16908    public void registerMoveCallback(IPackageMoveObserver callback) {
16909        mContext.enforceCallingOrSelfPermission(
16910                android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
16911        mMoveCallbacks.register(callback);
16912    }
16913
16914    @Override
16915    public void unregisterMoveCallback(IPackageMoveObserver callback) {
16916        mContext.enforceCallingOrSelfPermission(
16917                android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
16918        mMoveCallbacks.unregister(callback);
16919    }
16920
16921    @Override
16922    public boolean setInstallLocation(int loc) {
16923        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS,
16924                null);
16925        if (getInstallLocation() == loc) {
16926            return true;
16927        }
16928        if (loc == PackageHelper.APP_INSTALL_AUTO || loc == PackageHelper.APP_INSTALL_INTERNAL
16929                || loc == PackageHelper.APP_INSTALL_EXTERNAL) {
16930            android.provider.Settings.Global.putInt(mContext.getContentResolver(),
16931                    android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, loc);
16932            return true;
16933        }
16934        return false;
16935   }
16936
16937    @Override
16938    public int getInstallLocation() {
16939        return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
16940                android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION,
16941                PackageHelper.APP_INSTALL_AUTO);
16942    }
16943
16944    /** Called by UserManagerService */
16945    void cleanUpUser(UserManagerService userManager, int userHandle) {
16946        synchronized (mPackages) {
16947            mDirtyUsers.remove(userHandle);
16948            mUserNeedsBadging.delete(userHandle);
16949            mSettings.removeUserLPw(userHandle);
16950            mPendingBroadcasts.remove(userHandle);
16951            mEphemeralApplicationRegistry.onUserRemovedLPw(userHandle);
16952        }
16953        synchronized (mInstallLock) {
16954            final StorageManager storage = mContext.getSystemService(StorageManager.class);
16955            for (VolumeInfo vol : storage.getWritablePrivateVolumes()) {
16956                final String volumeUuid = vol.getFsUuid();
16957                if (DEBUG_INSTALL) Slog.d(TAG, "Removing user data on volume " + volumeUuid);
16958                mInstaller.removeUserDataDirs(volumeUuid, userHandle);
16959            }
16960            synchronized (mPackages) {
16961                removeUnusedPackagesLILPw(userManager, userHandle);
16962            }
16963        }
16964    }
16965
16966    /**
16967     * We're removing userHandle and would like to remove any downloaded packages
16968     * that are no longer in use by any other user.
16969     * @param userHandle the user being removed
16970     */
16971    private void removeUnusedPackagesLILPw(UserManagerService userManager, final int userHandle) {
16972        final boolean DEBUG_CLEAN_APKS = false;
16973        int [] users = userManager.getUserIds();
16974        Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
16975        while (psit.hasNext()) {
16976            PackageSetting ps = psit.next();
16977            if (ps.pkg == null) {
16978                continue;
16979            }
16980            final String packageName = ps.pkg.packageName;
16981            // Skip over if system app
16982            if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) {
16983                continue;
16984            }
16985            if (DEBUG_CLEAN_APKS) {
16986                Slog.i(TAG, "Checking package " + packageName);
16987            }
16988            boolean keep = shouldKeepUninstalledPackageLPr(packageName);
16989            if (keep) {
16990                if (DEBUG_CLEAN_APKS) {
16991                    Slog.i(TAG, "  Keeping package " + packageName + " - requested by DO");
16992                }
16993            } else {
16994                for (int i = 0; i < users.length; i++) {
16995                    if (users[i] != userHandle && ps.getInstalled(users[i])) {
16996                        keep = true;
16997                        if (DEBUG_CLEAN_APKS) {
16998                            Slog.i(TAG, "  Keeping package " + packageName + " for user "
16999                                    + users[i]);
17000                        }
17001                        break;
17002                    }
17003                }
17004            }
17005            if (!keep) {
17006                if (DEBUG_CLEAN_APKS) {
17007                    Slog.i(TAG, "  Removing package " + packageName);
17008                }
17009                mHandler.post(new Runnable() {
17010                    public void run() {
17011                        deletePackageX(packageName, userHandle, 0);
17012                    } //end run
17013                });
17014            }
17015        }
17016    }
17017
17018    /** Called by UserManagerService */
17019    void createNewUser(int userHandle) {
17020        synchronized (mInstallLock) {
17021            mInstaller.createUserConfig(userHandle);
17022            mSettings.createNewUserLI(this, mInstaller, userHandle);
17023        }
17024        synchronized (mPackages) {
17025            applyFactoryDefaultBrowserLPw(userHandle);
17026            primeDomainVerificationsLPw(userHandle);
17027        }
17028    }
17029
17030    void newUserCreated(final int userHandle) {
17031        mDefaultPermissionPolicy.grantDefaultPermissions(userHandle);
17032        // If permission review for legacy apps is required, we represent
17033        // dagerous permissions for such apps as always granted runtime
17034        // permissions to keep per user flag state whether review is needed.
17035        // Hence, if a new user is added we have to propagate dangerous
17036        // permission grants for these legacy apps.
17037        if (Build.PERMISSIONS_REVIEW_REQUIRED) {
17038            updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL
17039                    | UPDATE_PERMISSIONS_REPLACE_ALL);
17040        }
17041    }
17042
17043    @Override
17044    public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException {
17045        mContext.enforceCallingOrSelfPermission(
17046                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
17047                "Only package verification agents can read the verifier device identity");
17048
17049        synchronized (mPackages) {
17050            return mSettings.getVerifierDeviceIdentityLPw();
17051        }
17052    }
17053
17054    @Override
17055    public void setPermissionEnforced(String permission, boolean enforced) {
17056        // TODO: Now that we no longer change GID for storage, this should to away.
17057        mContext.enforceCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
17058                "setPermissionEnforced");
17059        if (READ_EXTERNAL_STORAGE.equals(permission)) {
17060            synchronized (mPackages) {
17061                if (mSettings.mReadExternalStorageEnforced == null
17062                        || mSettings.mReadExternalStorageEnforced != enforced) {
17063                    mSettings.mReadExternalStorageEnforced = enforced;
17064                    mSettings.writeLPr();
17065                }
17066            }
17067            // kill any non-foreground processes so we restart them and
17068            // grant/revoke the GID.
17069            final IActivityManager am = ActivityManagerNative.getDefault();
17070            if (am != null) {
17071                final long token = Binder.clearCallingIdentity();
17072                try {
17073                    am.killProcessesBelowForeground("setPermissionEnforcement");
17074                } catch (RemoteException e) {
17075                } finally {
17076                    Binder.restoreCallingIdentity(token);
17077                }
17078            }
17079        } else {
17080            throw new IllegalArgumentException("No selective enforcement for " + permission);
17081        }
17082    }
17083
17084    @Override
17085    @Deprecated
17086    public boolean isPermissionEnforced(String permission) {
17087        return true;
17088    }
17089
17090    @Override
17091    public boolean isStorageLow() {
17092        final long token = Binder.clearCallingIdentity();
17093        try {
17094            final DeviceStorageMonitorInternal
17095                    dsm = LocalServices.getService(DeviceStorageMonitorInternal.class);
17096            if (dsm != null) {
17097                return dsm.isMemoryLow();
17098            } else {
17099                return false;
17100            }
17101        } finally {
17102            Binder.restoreCallingIdentity(token);
17103        }
17104    }
17105
17106    @Override
17107    public IPackageInstaller getPackageInstaller() {
17108        return mInstallerService;
17109    }
17110
17111    private boolean userNeedsBadging(int userId) {
17112        int index = mUserNeedsBadging.indexOfKey(userId);
17113        if (index < 0) {
17114            final UserInfo userInfo;
17115            final long token = Binder.clearCallingIdentity();
17116            try {
17117                userInfo = sUserManager.getUserInfo(userId);
17118            } finally {
17119                Binder.restoreCallingIdentity(token);
17120            }
17121            final boolean b;
17122            if (userInfo != null && userInfo.isManagedProfile()) {
17123                b = true;
17124            } else {
17125                b = false;
17126            }
17127            mUserNeedsBadging.put(userId, b);
17128            return b;
17129        }
17130        return mUserNeedsBadging.valueAt(index);
17131    }
17132
17133    @Override
17134    public KeySet getKeySetByAlias(String packageName, String alias) {
17135        if (packageName == null || alias == null) {
17136            return null;
17137        }
17138        synchronized(mPackages) {
17139            final PackageParser.Package pkg = mPackages.get(packageName);
17140            if (pkg == null) {
17141                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
17142                throw new IllegalArgumentException("Unknown package: " + packageName);
17143            }
17144            KeySetManagerService ksms = mSettings.mKeySetManagerService;
17145            return new KeySet(ksms.getKeySetByAliasAndPackageNameLPr(packageName, alias));
17146        }
17147    }
17148
17149    @Override
17150    public KeySet getSigningKeySet(String packageName) {
17151        if (packageName == null) {
17152            return null;
17153        }
17154        synchronized(mPackages) {
17155            final PackageParser.Package pkg = mPackages.get(packageName);
17156            if (pkg == null) {
17157                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
17158                throw new IllegalArgumentException("Unknown package: " + packageName);
17159            }
17160            if (pkg.applicationInfo.uid != Binder.getCallingUid()
17161                    && Process.SYSTEM_UID != Binder.getCallingUid()) {
17162                throw new SecurityException("May not access signing KeySet of other apps.");
17163            }
17164            KeySetManagerService ksms = mSettings.mKeySetManagerService;
17165            return new KeySet(ksms.getSigningKeySetByPackageNameLPr(packageName));
17166        }
17167    }
17168
17169    @Override
17170    public boolean isPackageSignedByKeySet(String packageName, KeySet ks) {
17171        if (packageName == null || ks == null) {
17172            return false;
17173        }
17174        synchronized(mPackages) {
17175            final PackageParser.Package pkg = mPackages.get(packageName);
17176            if (pkg == null) {
17177                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
17178                throw new IllegalArgumentException("Unknown package: " + packageName);
17179            }
17180            IBinder ksh = ks.getToken();
17181            if (ksh instanceof KeySetHandle) {
17182                KeySetManagerService ksms = mSettings.mKeySetManagerService;
17183                return ksms.packageIsSignedByLPr(packageName, (KeySetHandle) ksh);
17184            }
17185            return false;
17186        }
17187    }
17188
17189    @Override
17190    public boolean isPackageSignedByKeySetExactly(String packageName, KeySet ks) {
17191        if (packageName == null || ks == null) {
17192            return false;
17193        }
17194        synchronized(mPackages) {
17195            final PackageParser.Package pkg = mPackages.get(packageName);
17196            if (pkg == null) {
17197                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
17198                throw new IllegalArgumentException("Unknown package: " + packageName);
17199            }
17200            IBinder ksh = ks.getToken();
17201            if (ksh instanceof KeySetHandle) {
17202                KeySetManagerService ksms = mSettings.mKeySetManagerService;
17203                return ksms.packageIsSignedByExactlyLPr(packageName, (KeySetHandle) ksh);
17204            }
17205            return false;
17206        }
17207    }
17208
17209    private void deletePackageIfUnusedLPr(final String packageName) {
17210        PackageSetting ps = mSettings.mPackages.get(packageName);
17211        if (ps == null) {
17212            return;
17213        }
17214        if (!ps.isAnyInstalled(sUserManager.getUserIds())) {
17215            // TODO Implement atomic delete if package is unused
17216            // It is currently possible that the package will be deleted even if it is installed
17217            // after this method returns.
17218            mHandler.post(new Runnable() {
17219                public void run() {
17220                    deletePackageX(packageName, 0, PackageManager.DELETE_ALL_USERS);
17221                }
17222            });
17223        }
17224    }
17225
17226    /**
17227     * Check and throw if the given before/after packages would be considered a
17228     * downgrade.
17229     */
17230    private static void checkDowngrade(PackageParser.Package before, PackageInfoLite after)
17231            throws PackageManagerException {
17232        if (after.versionCode < before.mVersionCode) {
17233            throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
17234                    "Update version code " + after.versionCode + " is older than current "
17235                    + before.mVersionCode);
17236        } else if (after.versionCode == before.mVersionCode) {
17237            if (after.baseRevisionCode < before.baseRevisionCode) {
17238                throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
17239                        "Update base revision code " + after.baseRevisionCode
17240                        + " is older than current " + before.baseRevisionCode);
17241            }
17242
17243            if (!ArrayUtils.isEmpty(after.splitNames)) {
17244                for (int i = 0; i < after.splitNames.length; i++) {
17245                    final String splitName = after.splitNames[i];
17246                    final int j = ArrayUtils.indexOf(before.splitNames, splitName);
17247                    if (j != -1) {
17248                        if (after.splitRevisionCodes[i] < before.splitRevisionCodes[j]) {
17249                            throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
17250                                    "Update split " + splitName + " revision code "
17251                                    + after.splitRevisionCodes[i] + " is older than current "
17252                                    + before.splitRevisionCodes[j]);
17253                        }
17254                    }
17255                }
17256            }
17257        }
17258    }
17259
17260    private static class MoveCallbacks extends Handler {
17261        private static final int MSG_CREATED = 1;
17262        private static final int MSG_STATUS_CHANGED = 2;
17263
17264        private final RemoteCallbackList<IPackageMoveObserver>
17265                mCallbacks = new RemoteCallbackList<>();
17266
17267        private final SparseIntArray mLastStatus = new SparseIntArray();
17268
17269        public MoveCallbacks(Looper looper) {
17270            super(looper);
17271        }
17272
17273        public void register(IPackageMoveObserver callback) {
17274            mCallbacks.register(callback);
17275        }
17276
17277        public void unregister(IPackageMoveObserver callback) {
17278            mCallbacks.unregister(callback);
17279        }
17280
17281        @Override
17282        public void handleMessage(Message msg) {
17283            final SomeArgs args = (SomeArgs) msg.obj;
17284            final int n = mCallbacks.beginBroadcast();
17285            for (int i = 0; i < n; i++) {
17286                final IPackageMoveObserver callback = mCallbacks.getBroadcastItem(i);
17287                try {
17288                    invokeCallback(callback, msg.what, args);
17289                } catch (RemoteException ignored) {
17290                }
17291            }
17292            mCallbacks.finishBroadcast();
17293            args.recycle();
17294        }
17295
17296        private void invokeCallback(IPackageMoveObserver callback, int what, SomeArgs args)
17297                throws RemoteException {
17298            switch (what) {
17299                case MSG_CREATED: {
17300                    callback.onCreated(args.argi1, (Bundle) args.arg2);
17301                    break;
17302                }
17303                case MSG_STATUS_CHANGED: {
17304                    callback.onStatusChanged(args.argi1, args.argi2, (long) args.arg3);
17305                    break;
17306                }
17307            }
17308        }
17309
17310        private void notifyCreated(int moveId, Bundle extras) {
17311            Slog.v(TAG, "Move " + moveId + " created " + extras.toString());
17312
17313            final SomeArgs args = SomeArgs.obtain();
17314            args.argi1 = moveId;
17315            args.arg2 = extras;
17316            obtainMessage(MSG_CREATED, args).sendToTarget();
17317        }
17318
17319        private void notifyStatusChanged(int moveId, int status) {
17320            notifyStatusChanged(moveId, status, -1);
17321        }
17322
17323        private void notifyStatusChanged(int moveId, int status, long estMillis) {
17324            Slog.v(TAG, "Move " + moveId + " status " + status);
17325
17326            final SomeArgs args = SomeArgs.obtain();
17327            args.argi1 = moveId;
17328            args.argi2 = status;
17329            args.arg3 = estMillis;
17330            obtainMessage(MSG_STATUS_CHANGED, args).sendToTarget();
17331
17332            synchronized (mLastStatus) {
17333                mLastStatus.put(moveId, status);
17334            }
17335        }
17336    }
17337
17338    private final static class OnPermissionChangeListeners extends Handler {
17339        private static final int MSG_ON_PERMISSIONS_CHANGED = 1;
17340
17341        private final RemoteCallbackList<IOnPermissionsChangeListener> mPermissionListeners =
17342                new RemoteCallbackList<>();
17343
17344        public OnPermissionChangeListeners(Looper looper) {
17345            super(looper);
17346        }
17347
17348        @Override
17349        public void handleMessage(Message msg) {
17350            switch (msg.what) {
17351                case MSG_ON_PERMISSIONS_CHANGED: {
17352                    final int uid = msg.arg1;
17353                    handleOnPermissionsChanged(uid);
17354                } break;
17355            }
17356        }
17357
17358        public void addListenerLocked(IOnPermissionsChangeListener listener) {
17359            mPermissionListeners.register(listener);
17360
17361        }
17362
17363        public void removeListenerLocked(IOnPermissionsChangeListener listener) {
17364            mPermissionListeners.unregister(listener);
17365        }
17366
17367        public void onPermissionsChanged(int uid) {
17368            if (mPermissionListeners.getRegisteredCallbackCount() > 0) {
17369                obtainMessage(MSG_ON_PERMISSIONS_CHANGED, uid, 0).sendToTarget();
17370            }
17371        }
17372
17373        private void handleOnPermissionsChanged(int uid) {
17374            final int count = mPermissionListeners.beginBroadcast();
17375            try {
17376                for (int i = 0; i < count; i++) {
17377                    IOnPermissionsChangeListener callback = mPermissionListeners
17378                            .getBroadcastItem(i);
17379                    try {
17380                        callback.onPermissionsChanged(uid);
17381                    } catch (RemoteException e) {
17382                        Log.e(TAG, "Permission listener is dead", e);
17383                    }
17384                }
17385            } finally {
17386                mPermissionListeners.finishBroadcast();
17387            }
17388        }
17389    }
17390
17391    private class PackageManagerInternalImpl extends PackageManagerInternal {
17392        @Override
17393        public void setLocationPackagesProvider(PackagesProvider provider) {
17394            synchronized (mPackages) {
17395                mDefaultPermissionPolicy.setLocationPackagesProviderLPw(provider);
17396            }
17397        }
17398
17399        @Override
17400        public void setImePackagesProvider(PackagesProvider provider) {
17401            synchronized (mPackages) {
17402                mDefaultPermissionPolicy.setImePackagesProviderLPr(provider);
17403            }
17404        }
17405
17406        @Override
17407        public void setVoiceInteractionPackagesProvider(PackagesProvider provider) {
17408            synchronized (mPackages) {
17409                mDefaultPermissionPolicy.setVoiceInteractionPackagesProviderLPw(provider);
17410            }
17411        }
17412
17413        @Override
17414        public void setSmsAppPackagesProvider(PackagesProvider provider) {
17415            synchronized (mPackages) {
17416                mDefaultPermissionPolicy.setSmsAppPackagesProviderLPw(provider);
17417            }
17418        }
17419
17420        @Override
17421        public void setDialerAppPackagesProvider(PackagesProvider provider) {
17422            synchronized (mPackages) {
17423                mDefaultPermissionPolicy.setDialerAppPackagesProviderLPw(provider);
17424            }
17425        }
17426
17427        @Override
17428        public void setSimCallManagerPackagesProvider(PackagesProvider provider) {
17429            synchronized (mPackages) {
17430                mDefaultPermissionPolicy.setSimCallManagerPackagesProviderLPw(provider);
17431            }
17432        }
17433
17434        @Override
17435        public void setSyncAdapterPackagesprovider(SyncAdapterPackagesProvider provider) {
17436            synchronized (mPackages) {
17437                mDefaultPermissionPolicy.setSyncAdapterPackagesProviderLPw(provider);
17438            }
17439        }
17440
17441        @Override
17442        public void grantDefaultPermissionsToDefaultSmsApp(String packageName, int userId) {
17443            synchronized (mPackages) {
17444                mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSmsAppLPr(
17445                        packageName, userId);
17446            }
17447        }
17448
17449        @Override
17450        public void grantDefaultPermissionsToDefaultDialerApp(String packageName, int userId) {
17451            synchronized (mPackages) {
17452                mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultDialerAppLPr(
17453                        packageName, userId);
17454            }
17455        }
17456
17457        @Override
17458        public void grantDefaultPermissionsToDefaultSimCallManager(String packageName, int userId) {
17459            synchronized (mPackages) {
17460                mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSimCallManagerLPr(
17461                        packageName, userId);
17462            }
17463        }
17464
17465        @Override
17466        public void setKeepUninstalledPackages(final List<String> packageList) {
17467            Preconditions.checkNotNull(packageList);
17468            List<String> removedFromList = null;
17469            synchronized (mPackages) {
17470                if (mKeepUninstalledPackages != null) {
17471                    final int packagesCount = mKeepUninstalledPackages.size();
17472                    for (int i = 0; i < packagesCount; i++) {
17473                        String oldPackage = mKeepUninstalledPackages.get(i);
17474                        if (packageList != null && packageList.contains(oldPackage)) {
17475                            continue;
17476                        }
17477                        if (removedFromList == null) {
17478                            removedFromList = new ArrayList<>();
17479                        }
17480                        removedFromList.add(oldPackage);
17481                    }
17482                }
17483                mKeepUninstalledPackages = new ArrayList<>(packageList);
17484                if (removedFromList != null) {
17485                    final int removedCount = removedFromList.size();
17486                    for (int i = 0; i < removedCount; i++) {
17487                        deletePackageIfUnusedLPr(removedFromList.get(i));
17488                    }
17489                }
17490            }
17491        }
17492
17493        @Override
17494        public boolean isPermissionsReviewRequired(String packageName, int userId) {
17495            synchronized (mPackages) {
17496                // If we do not support permission review, done.
17497                if (!Build.PERMISSIONS_REVIEW_REQUIRED) {
17498                    return false;
17499                }
17500
17501                PackageSetting packageSetting = mSettings.mPackages.get(packageName);
17502                if (packageSetting == null) {
17503                    return false;
17504                }
17505
17506                // Permission review applies only to apps not supporting the new permission model.
17507                if (packageSetting.pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.M) {
17508                    return false;
17509                }
17510
17511                // Legacy apps have the permission and get user consent on launch.
17512                PermissionsState permissionsState = packageSetting.getPermissionsState();
17513                return permissionsState.isPermissionReviewRequired(userId);
17514            }
17515        }
17516    }
17517
17518    @Override
17519    public void grantDefaultPermissionsToEnabledCarrierApps(String[] packageNames, int userId) {
17520        enforceSystemOrPhoneCaller("grantPermissionsToEnabledCarrierApps");
17521        synchronized (mPackages) {
17522            final long identity = Binder.clearCallingIdentity();
17523            try {
17524                mDefaultPermissionPolicy.grantDefaultPermissionsToEnabledCarrierAppsLPr(
17525                        packageNames, userId);
17526            } finally {
17527                Binder.restoreCallingIdentity(identity);
17528            }
17529        }
17530    }
17531
17532    private static void enforceSystemOrPhoneCaller(String tag) {
17533        int callingUid = Binder.getCallingUid();
17534        if (callingUid != Process.PHONE_UID && callingUid != Process.SYSTEM_UID) {
17535            throw new SecurityException(
17536                    "Cannot call " + tag + " from UID " + callingUid);
17537        }
17538    }
17539}
17540