PackageManagerService.java revision aedb56fd18487d7a34b8ea9f09e4a717afa75a1e
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.GRANT_REVOKE_PERMISSIONS;
20import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
21import static android.Manifest.permission.WRITE_EXTERNAL_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.INSTALL_EXTERNAL;
28import static android.content.pm.PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
29import static android.content.pm.PackageManager.INSTALL_FAILED_CONFLICTING_PROVIDER;
30import static android.content.pm.PackageManager.INSTALL_FAILED_DEXOPT;
31import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE;
32import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION;
33import static android.content.pm.PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
34import static android.content.pm.PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
35import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_APK;
36import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
37import static android.content.pm.PackageManager.INSTALL_FAILED_MISSING_SHARED_LIBRARY;
38import static android.content.pm.PackageManager.INSTALL_FAILED_PACKAGE_CHANGED;
39import static android.content.pm.PackageManager.INSTALL_FAILED_REPLACE_COULDNT_DELETE;
40import static android.content.pm.PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE;
41import static android.content.pm.PackageManager.INSTALL_FAILED_TEST_ONLY;
42import static android.content.pm.PackageManager.INSTALL_FAILED_UID_CHANGED;
43import static android.content.pm.PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE;
44import static android.content.pm.PackageManager.INSTALL_FAILED_USER_RESTRICTED;
45import static android.content.pm.PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
46import static android.content.pm.PackageManager.INSTALL_FORWARD_LOCK;
47import static android.content.pm.PackageManager.INSTALL_INTERNAL;
48import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
49import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
50import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK;
51import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER;
52import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
53import static android.content.pm.PackageManager.MATCH_ALL;
54import static android.content.pm.PackageManager.MOVE_FAILED_DOESNT_EXIST;
55import static android.content.pm.PackageManager.MOVE_FAILED_INTERNAL_ERROR;
56import static android.content.pm.PackageManager.MOVE_FAILED_OPERATION_PENDING;
57import static android.content.pm.PackageManager.MOVE_FAILED_SYSTEM_PACKAGE;
58import static android.content.pm.PackageManager.PERMISSION_GRANTED;
59import static android.content.pm.PackageParser.isApkFile;
60import static android.os.Process.PACKAGE_INFO_GID;
61import static android.os.Process.SYSTEM_UID;
62import static android.system.OsConstants.O_CREAT;
63import static android.system.OsConstants.O_RDWR;
64import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE;
65import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_USER_OWNER;
66import static com.android.internal.content.NativeLibraryHelper.LIB64_DIR_NAME;
67import static com.android.internal.content.NativeLibraryHelper.LIB_DIR_NAME;
68import static com.android.internal.util.ArrayUtils.appendInt;
69import static com.android.server.pm.InstructionSets.getAppDexInstructionSets;
70import static com.android.server.pm.InstructionSets.getDexCodeInstructionSet;
71import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets;
72import static com.android.server.pm.InstructionSets.getPreferredInstructionSet;
73import static com.android.server.pm.InstructionSets.getPrimaryInstructionSet;
74
75import android.Manifest;
76import android.app.ActivityManager;
77import android.app.ActivityManagerNative;
78import android.app.AppGlobals;
79import android.app.IActivityManager;
80import android.app.admin.IDevicePolicyManager;
81import android.app.backup.IBackupManager;
82import android.app.usage.UsageStats;
83import android.app.usage.UsageStatsManager;
84import android.content.BroadcastReceiver;
85import android.content.ComponentName;
86import android.content.Context;
87import android.content.IIntentReceiver;
88import android.content.Intent;
89import android.content.IntentFilter;
90import android.content.IntentSender;
91import android.content.IntentSender.SendIntentException;
92import android.content.ServiceConnection;
93import android.content.pm.ActivityInfo;
94import android.content.pm.ApplicationInfo;
95import android.content.pm.FeatureInfo;
96import android.content.pm.IOnPermissionsChangeListener;
97import android.content.pm.IPackageDataObserver;
98import android.content.pm.IPackageDeleteObserver;
99import android.content.pm.IPackageDeleteObserver2;
100import android.content.pm.IPackageInstallObserver2;
101import android.content.pm.IPackageInstaller;
102import android.content.pm.IPackageManager;
103import android.content.pm.IPackageMoveObserver;
104import android.content.pm.IPackageStatsObserver;
105import android.content.pm.IPackagesProvider;
106import android.content.pm.InstrumentationInfo;
107import android.content.pm.IntentFilterVerificationInfo;
108import android.content.pm.KeySet;
109import android.content.pm.ManifestDigest;
110import android.content.pm.PackageCleanItem;
111import android.content.pm.PackageInfo;
112import android.content.pm.PackageInfoLite;
113import android.content.pm.PackageInstaller;
114import android.content.pm.PackageManager;
115import android.content.pm.PackageManager.LegacyPackageDeleteObserver;
116import android.content.pm.PackageManagerInternal;
117import android.content.pm.PackageParser;
118import android.content.pm.PackageParser.ActivityIntentInfo;
119import android.content.pm.PackageParser.PackageLite;
120import android.content.pm.PackageParser.PackageParserException;
121import android.content.pm.PackageStats;
122import android.content.pm.PackageUserState;
123import android.content.pm.ParceledListSlice;
124import android.content.pm.PermissionGroupInfo;
125import android.content.pm.PermissionInfo;
126import android.content.pm.ProviderInfo;
127import android.content.pm.ResolveInfo;
128import android.content.pm.ServiceInfo;
129import android.content.pm.Signature;
130import android.content.pm.UserInfo;
131import android.content.pm.VerificationParams;
132import android.content.pm.VerifierDeviceIdentity;
133import android.content.pm.VerifierInfo;
134import android.content.res.Resources;
135import android.hardware.display.DisplayManager;
136import android.net.Uri;
137import android.os.Binder;
138import android.os.Build;
139import android.os.Bundle;
140import android.os.Debug;
141import android.os.Environment;
142import android.os.Environment.UserEnvironment;
143import android.os.FileUtils;
144import android.os.Handler;
145import android.os.IBinder;
146import android.os.Looper;
147import android.os.Message;
148import android.os.Parcel;
149import android.os.ParcelFileDescriptor;
150import android.os.Process;
151import android.os.RemoteCallbackList;
152import android.os.RemoteException;
153import android.os.SELinux;
154import android.os.ServiceManager;
155import android.os.SystemClock;
156import android.os.SystemProperties;
157import android.os.UserHandle;
158import android.os.UserManager;
159import android.os.storage.IMountService;
160import android.os.storage.StorageEventListener;
161import android.os.storage.StorageManager;
162import android.os.storage.VolumeInfo;
163import android.os.storage.VolumeRecord;
164import android.security.KeyStore;
165import android.security.SystemKeyStore;
166import android.system.ErrnoException;
167import android.system.Os;
168import android.system.StructStat;
169import android.text.TextUtils;
170import android.text.format.DateUtils;
171import android.util.ArrayMap;
172import android.util.ArraySet;
173import android.util.AtomicFile;
174import android.util.DisplayMetrics;
175import android.util.EventLog;
176import android.util.ExceptionUtils;
177import android.util.Log;
178import android.util.LogPrinter;
179import android.util.MathUtils;
180import android.util.PrintStreamPrinter;
181import android.util.Slog;
182import android.util.SparseArray;
183import android.util.SparseBooleanArray;
184import android.util.SparseIntArray;
185import android.util.Xml;
186import android.view.Display;
187
188import dalvik.system.DexFile;
189import dalvik.system.VMRuntime;
190
191import libcore.io.IoUtils;
192import libcore.util.EmptyArray;
193
194import com.android.internal.R;
195import com.android.internal.app.IMediaContainerService;
196import com.android.internal.app.ResolverActivity;
197import com.android.internal.content.NativeLibraryHelper;
198import com.android.internal.content.PackageHelper;
199import com.android.internal.os.IParcelFileDescriptorFactory;
200import com.android.internal.os.SomeArgs;
201import com.android.internal.os.Zygote;
202import com.android.internal.util.ArrayUtils;
203import com.android.internal.util.FastPrintWriter;
204import com.android.internal.util.FastXmlSerializer;
205import com.android.internal.util.IndentingPrintWriter;
206import com.android.internal.util.Preconditions;
207import com.android.server.EventLogTags;
208import com.android.server.FgThread;
209import com.android.server.IntentResolver;
210import com.android.server.LocalServices;
211import com.android.server.ServiceThread;
212import com.android.server.SystemConfig;
213import com.android.server.Watchdog;
214import com.android.server.pm.PermissionsState.PermissionState;
215import com.android.server.pm.Settings.DatabaseVersion;
216import com.android.server.storage.DeviceStorageMonitorInternal;
217
218import org.xmlpull.v1.XmlPullParser;
219import org.xmlpull.v1.XmlPullParserException;
220import org.xmlpull.v1.XmlSerializer;
221
222import java.io.BufferedInputStream;
223import java.io.BufferedOutputStream;
224import java.io.BufferedReader;
225import java.io.ByteArrayInputStream;
226import java.io.ByteArrayOutputStream;
227import java.io.File;
228import java.io.FileDescriptor;
229import java.io.FileNotFoundException;
230import java.io.FileOutputStream;
231import java.io.FileReader;
232import java.io.FilenameFilter;
233import java.io.IOException;
234import java.io.InputStream;
235import java.io.PrintWriter;
236import java.nio.charset.StandardCharsets;
237import java.security.NoSuchAlgorithmException;
238import java.security.PublicKey;
239import java.security.cert.CertificateEncodingException;
240import java.security.cert.CertificateException;
241import java.text.SimpleDateFormat;
242import java.util.ArrayList;
243import java.util.Arrays;
244import java.util.Collection;
245import java.util.Collections;
246import java.util.Comparator;
247import java.util.Date;
248import java.util.Iterator;
249import java.util.List;
250import java.util.Map;
251import java.util.Objects;
252import java.util.Set;
253import java.util.concurrent.CountDownLatch;
254import java.util.concurrent.TimeUnit;
255import java.util.concurrent.atomic.AtomicBoolean;
256import java.util.concurrent.atomic.AtomicInteger;
257import java.util.concurrent.atomic.AtomicLong;
258
259/**
260 * Keep track of all those .apks everywhere.
261 *
262 * This is very central to the platform's security; please run the unit
263 * tests whenever making modifications here:
264 *
265runtest -c android.content.pm.PackageManagerTests frameworks-core
266 *
267 * {@hide}
268 */
269public class PackageManagerService extends IPackageManager.Stub {
270    static final String TAG = "PackageManager";
271    static final boolean DEBUG_SETTINGS = false;
272    static final boolean DEBUG_PREFERRED = false;
273    static final boolean DEBUG_UPGRADE = false;
274    static final boolean DEBUG_DOMAIN_VERIFICATION = false;
275    private static final boolean DEBUG_BACKUP = true;
276    private static final boolean DEBUG_INSTALL = false;
277    private static final boolean DEBUG_REMOVE = false;
278    private static final boolean DEBUG_BROADCASTS = false;
279    private static final boolean DEBUG_SHOW_INFO = false;
280    private static final boolean DEBUG_PACKAGE_INFO = false;
281    private static final boolean DEBUG_INTENT_MATCHING = false;
282    private static final boolean DEBUG_PACKAGE_SCANNING = false;
283    private static final boolean DEBUG_VERIFY = false;
284    private static final boolean DEBUG_DEXOPT = false;
285    private static final boolean DEBUG_ABI_SELECTION = false;
286
287    static final boolean CLEAR_RUNTIME_PERMISSIONS_ON_UPGRADE = Build.IS_DEBUGGABLE;
288
289    private static final int RADIO_UID = Process.PHONE_UID;
290    private static final int LOG_UID = Process.LOG_UID;
291    private static final int NFC_UID = Process.NFC_UID;
292    private static final int BLUETOOTH_UID = Process.BLUETOOTH_UID;
293    private static final int SHELL_UID = Process.SHELL_UID;
294
295    // Cap the size of permission trees that 3rd party apps can define
296    private static final int MAX_PERMISSION_TREE_FOOTPRINT = 32768;     // characters of text
297
298    // Suffix used during package installation when copying/moving
299    // package apks to install directory.
300    private static final String INSTALL_PACKAGE_SUFFIX = "-";
301
302    static final int SCAN_NO_DEX = 1<<1;
303    static final int SCAN_FORCE_DEX = 1<<2;
304    static final int SCAN_UPDATE_SIGNATURE = 1<<3;
305    static final int SCAN_NEW_INSTALL = 1<<4;
306    static final int SCAN_NO_PATHS = 1<<5;
307    static final int SCAN_UPDATE_TIME = 1<<6;
308    static final int SCAN_DEFER_DEX = 1<<7;
309    static final int SCAN_BOOTING = 1<<8;
310    static final int SCAN_TRUSTED_OVERLAY = 1<<9;
311    static final int SCAN_DELETE_DATA_ON_FAILURES = 1<<10;
312    static final int SCAN_REQUIRE_KNOWN = 1<<12;
313    static final int SCAN_MOVE = 1<<13;
314    static final int SCAN_INITIAL = 1<<14;
315
316    static final int REMOVE_CHATTY = 1<<16;
317
318    private static final int[] EMPTY_INT_ARRAY = new int[0];
319
320    /**
321     * Timeout (in milliseconds) after which the watchdog should declare that
322     * our handler thread is wedged.  The usual default for such things is one
323     * minute but we sometimes do very lengthy I/O operations on this thread,
324     * such as installing multi-gigabyte applications, so ours needs to be longer.
325     */
326    private static final long WATCHDOG_TIMEOUT = 1000*60*10;     // ten minutes
327
328    /**
329     * Wall-clock timeout (in milliseconds) after which we *require* that an fstrim
330     * be run on this device.  We use the value in the Settings.Global.MANDATORY_FSTRIM_INTERVAL
331     * settings entry if available, otherwise we use the hardcoded default.  If it's been
332     * more than this long since the last fstrim, we force one during the boot sequence.
333     *
334     * This backstops other fstrim scheduling:  if the device is alive at midnight+idle,
335     * one gets run at the next available charging+idle time.  This final mandatory
336     * no-fstrim check kicks in only of the other scheduling criteria is never met.
337     */
338    private static final long DEFAULT_MANDATORY_FSTRIM_INTERVAL = 3 * DateUtils.DAY_IN_MILLIS;
339
340    /**
341     * Whether verification is enabled by default.
342     */
343    private static final boolean DEFAULT_VERIFY_ENABLE = true;
344
345    /**
346     * The default maximum time to wait for the verification agent to return in
347     * milliseconds.
348     */
349    private static final long DEFAULT_VERIFICATION_TIMEOUT = 10 * 1000;
350
351    /**
352     * The default response for package verification timeout.
353     *
354     * This can be either PackageManager.VERIFICATION_ALLOW or
355     * PackageManager.VERIFICATION_REJECT.
356     */
357    private static final int DEFAULT_VERIFICATION_RESPONSE = PackageManager.VERIFICATION_ALLOW;
358
359    static final String DEFAULT_CONTAINER_PACKAGE = "com.android.defcontainer";
360
361    static final ComponentName DEFAULT_CONTAINER_COMPONENT = new ComponentName(
362            DEFAULT_CONTAINER_PACKAGE,
363            "com.android.defcontainer.DefaultContainerService");
364
365    private static final String KILL_APP_REASON_GIDS_CHANGED =
366            "permission grant or revoke changed gids";
367
368    private static final String KILL_APP_REASON_PERMISSIONS_REVOKED =
369            "permissions revoked";
370
371    private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive";
372
373    private static final String VENDOR_OVERLAY_DIR = "/vendor/overlay";
374
375    /** Permission grant: not grant the permission. */
376    private static final int GRANT_DENIED = 1;
377
378    /** Permission grant: grant the permission as an install permission. */
379    private static final int GRANT_INSTALL = 2;
380
381    /** Permission grant: grant the permission as an install permission for a legacy app. */
382    private static final int GRANT_INSTALL_LEGACY = 3;
383
384    /** Permission grant: grant the permission as a runtime one. */
385    private static final int GRANT_RUNTIME = 4;
386
387    /** Permission grant: grant as runtime a permission that was granted as an install time one. */
388    private static final int GRANT_UPGRADE = 5;
389
390    final ServiceThread mHandlerThread;
391
392    final PackageHandler mHandler;
393
394    /**
395     * Messages for {@link #mHandler} that need to wait for system ready before
396     * being dispatched.
397     */
398    private ArrayList<Message> mPostSystemReadyMessages;
399
400    final int mSdkVersion = Build.VERSION.SDK_INT;
401
402    final Context mContext;
403    final boolean mFactoryTest;
404    final boolean mOnlyCore;
405    final boolean mLazyDexOpt;
406    final long mDexOptLRUThresholdInMills;
407    final DisplayMetrics mMetrics;
408    final int mDefParseFlags;
409    final String[] mSeparateProcesses;
410    final boolean mIsUpgrade;
411
412    // This is where all application persistent data goes.
413    final File mAppDataDir;
414
415    // This is where all application persistent data goes for secondary users.
416    final File mUserAppDataDir;
417
418    /** The location for ASEC container files on internal storage. */
419    final String mAsecInternalPath;
420
421    // Used for privilege escalation. MUST NOT BE CALLED WITH mPackages
422    // LOCK HELD.  Can be called with mInstallLock held.
423    final Installer mInstaller;
424
425    /** Directory where installed third-party apps stored */
426    final File mAppInstallDir;
427
428    /**
429     * Directory to which applications installed internally have their
430     * 32 bit native libraries copied.
431     */
432    private File mAppLib32InstallDir;
433
434    // Directory containing the private parts (e.g. code and non-resource assets) of forward-locked
435    // apps.
436    final File mDrmAppPrivateInstallDir;
437
438    // ----------------------------------------------------------------
439
440    // Lock for state used when installing and doing other long running
441    // operations.  Methods that must be called with this lock held have
442    // the suffix "LI".
443    final Object mInstallLock = new Object();
444
445    // ----------------------------------------------------------------
446
447    // Keys are String (package name), values are Package.  This also serves
448    // as the lock for the global state.  Methods that must be called with
449    // this lock held have the prefix "LP".
450    final ArrayMap<String, PackageParser.Package> mPackages =
451            new ArrayMap<String, PackageParser.Package>();
452
453    // Tracks available target package names -> overlay package paths.
454    final ArrayMap<String, ArrayMap<String, PackageParser.Package>> mOverlays =
455        new ArrayMap<String, ArrayMap<String, PackageParser.Package>>();
456
457    final Settings mSettings;
458    boolean mRestoredSettings;
459
460    // System configuration read by SystemConfig.
461    final int[] mGlobalGids;
462    final SparseArray<ArraySet<String>> mSystemPermissions;
463    final ArrayMap<String, FeatureInfo> mAvailableFeatures;
464
465    // If mac_permissions.xml was found for seinfo labeling.
466    boolean mFoundPolicyFile;
467
468    // If a recursive restorecon of /data/data/<pkg> is needed.
469    private boolean mShouldRestoreconData = SELinuxMMAC.shouldRestorecon();
470
471    public static final class SharedLibraryEntry {
472        public final String path;
473        public final String apk;
474
475        SharedLibraryEntry(String _path, String _apk) {
476            path = _path;
477            apk = _apk;
478        }
479    }
480
481    // Currently known shared libraries.
482    final ArrayMap<String, SharedLibraryEntry> mSharedLibraries =
483            new ArrayMap<String, SharedLibraryEntry>();
484
485    // All available activities, for your resolving pleasure.
486    final ActivityIntentResolver mActivities =
487            new ActivityIntentResolver();
488
489    // All available receivers, for your resolving pleasure.
490    final ActivityIntentResolver mReceivers =
491            new ActivityIntentResolver();
492
493    // All available services, for your resolving pleasure.
494    final ServiceIntentResolver mServices = new ServiceIntentResolver();
495
496    // All available providers, for your resolving pleasure.
497    final ProviderIntentResolver mProviders = new ProviderIntentResolver();
498
499    // Mapping from provider base names (first directory in content URI codePath)
500    // to the provider information.
501    final ArrayMap<String, PackageParser.Provider> mProvidersByAuthority =
502            new ArrayMap<String, PackageParser.Provider>();
503
504    // Mapping from instrumentation class names to info about them.
505    final ArrayMap<ComponentName, PackageParser.Instrumentation> mInstrumentation =
506            new ArrayMap<ComponentName, PackageParser.Instrumentation>();
507
508    // Mapping from permission names to info about them.
509    final ArrayMap<String, PackageParser.PermissionGroup> mPermissionGroups =
510            new ArrayMap<String, PackageParser.PermissionGroup>();
511
512    // Packages whose data we have transfered into another package, thus
513    // should no longer exist.
514    final ArraySet<String> mTransferedPackages = new ArraySet<String>();
515
516    // Broadcast actions that are only available to the system.
517    final ArraySet<String> mProtectedBroadcasts = new ArraySet<String>();
518
519    /** List of packages waiting for verification. */
520    final SparseArray<PackageVerificationState> mPendingVerification
521            = new SparseArray<PackageVerificationState>();
522
523    /** Set of packages associated with each app op permission. */
524    final ArrayMap<String, ArraySet<String>> mAppOpPermissionPackages = new ArrayMap<>();
525
526    final PackageInstallerService mInstallerService;
527
528    private final PackageDexOptimizer mPackageDexOptimizer;
529
530    private AtomicInteger mNextMoveId = new AtomicInteger();
531    private final MoveCallbacks mMoveCallbacks;
532
533    private final OnPermissionChangeListeners mOnPermissionChangeListeners;
534
535    // Cache of users who need badging.
536    SparseBooleanArray mUserNeedsBadging = new SparseBooleanArray();
537
538    /** Token for keys in mPendingVerification. */
539    private int mPendingVerificationToken = 0;
540
541    volatile boolean mSystemReady;
542    volatile boolean mSafeMode;
543    volatile boolean mHasSystemUidErrors;
544
545    ApplicationInfo mAndroidApplication;
546    final ActivityInfo mResolveActivity = new ActivityInfo();
547    final ResolveInfo mResolveInfo = new ResolveInfo();
548    ComponentName mResolveComponentName;
549    PackageParser.Package mPlatformPackage;
550    ComponentName mCustomResolverComponentName;
551
552    boolean mResolverReplaced = false;
553
554    private final ComponentName mIntentFilterVerifierComponent;
555    private int mIntentFilterVerificationToken = 0;
556
557    final SparseArray<IntentFilterVerificationState> mIntentFilterVerificationStates
558            = new SparseArray<IntentFilterVerificationState>();
559
560    final DefaultPermissionGrantPolicy mDefaultPermissionPolicy =
561            new DefaultPermissionGrantPolicy(this);
562
563    private static class IFVerificationParams {
564        PackageParser.Package pkg;
565        boolean replacing;
566        int userId;
567        int verifierUid;
568
569        public IFVerificationParams(PackageParser.Package _pkg, boolean _replacing,
570                int _userId, int _verifierUid) {
571            pkg = _pkg;
572            replacing = _replacing;
573            userId = _userId;
574            replacing = _replacing;
575            verifierUid = _verifierUid;
576        }
577    }
578
579    private interface IntentFilterVerifier<T extends IntentFilter> {
580        boolean addOneIntentFilterVerification(int verifierId, int userId, int verificationId,
581                                               T filter, String packageName);
582        void startVerifications(int userId);
583        void receiveVerificationResponse(int verificationId);
584    }
585
586    private class IntentVerifierProxy implements IntentFilterVerifier<ActivityIntentInfo> {
587        private Context mContext;
588        private ComponentName mIntentFilterVerifierComponent;
589        private ArrayList<Integer> mCurrentIntentFilterVerifications = new ArrayList<Integer>();
590
591        public IntentVerifierProxy(Context context, ComponentName verifierComponent) {
592            mContext = context;
593            mIntentFilterVerifierComponent = verifierComponent;
594        }
595
596        private String getDefaultScheme() {
597            return IntentFilter.SCHEME_HTTPS;
598        }
599
600        @Override
601        public void startVerifications(int userId) {
602            // Launch verifications requests
603            int count = mCurrentIntentFilterVerifications.size();
604            for (int n=0; n<count; n++) {
605                int verificationId = mCurrentIntentFilterVerifications.get(n);
606                final IntentFilterVerificationState ivs =
607                        mIntentFilterVerificationStates.get(verificationId);
608
609                String packageName = ivs.getPackageName();
610
611                ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters();
612                final int filterCount = filters.size();
613                ArraySet<String> domainsSet = new ArraySet<>();
614                for (int m=0; m<filterCount; m++) {
615                    PackageParser.ActivityIntentInfo filter = filters.get(m);
616                    domainsSet.addAll(filter.getHostsList());
617                }
618                ArrayList<String> domainsList = new ArrayList<>(domainsSet);
619                synchronized (mPackages) {
620                    if (mSettings.createIntentFilterVerificationIfNeededLPw(
621                            packageName, domainsList) != null) {
622                        scheduleWriteSettingsLocked();
623                    }
624                }
625                sendVerificationRequest(userId, verificationId, ivs);
626            }
627            mCurrentIntentFilterVerifications.clear();
628        }
629
630        private void sendVerificationRequest(int userId, int verificationId,
631                IntentFilterVerificationState ivs) {
632
633            Intent verificationIntent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION);
634            verificationIntent.putExtra(
635                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_ID,
636                    verificationId);
637            verificationIntent.putExtra(
638                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_URI_SCHEME,
639                    getDefaultScheme());
640            verificationIntent.putExtra(
641                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_HOSTS,
642                    ivs.getHostsString());
643            verificationIntent.putExtra(
644                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_PACKAGE_NAME,
645                    ivs.getPackageName());
646            verificationIntent.setComponent(mIntentFilterVerifierComponent);
647            verificationIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
648
649            UserHandle user = new UserHandle(userId);
650            mContext.sendBroadcastAsUser(verificationIntent, user);
651            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
652                    "Sending IntentFilter verification broadcast");
653        }
654
655        public void receiveVerificationResponse(int verificationId) {
656            IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId);
657
658            final boolean verified = ivs.isVerified();
659
660            ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters();
661            final int count = filters.size();
662            if (DEBUG_DOMAIN_VERIFICATION) {
663                Slog.i(TAG, "Received verification response " + verificationId
664                        + " for " + count + " filters, verified=" + verified);
665            }
666            for (int n=0; n<count; n++) {
667                PackageParser.ActivityIntentInfo filter = filters.get(n);
668                filter.setVerified(verified);
669
670                if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "IntentFilter " + filter.toString()
671                        + " verified with result:" + verified + " and hosts:"
672                        + ivs.getHostsString());
673            }
674
675            mIntentFilterVerificationStates.remove(verificationId);
676
677            final String packageName = ivs.getPackageName();
678            IntentFilterVerificationInfo ivi = null;
679
680            synchronized (mPackages) {
681                ivi = mSettings.getIntentFilterVerificationLPr(packageName);
682            }
683            if (ivi == null) {
684                Slog.w(TAG, "IntentFilterVerificationInfo not found for verificationId:"
685                        + verificationId + " packageName:" + packageName);
686                return;
687            }
688            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
689                    "Updating IntentFilterVerificationInfo for verificationId:" + verificationId);
690
691            synchronized (mPackages) {
692                if (verified) {
693                    ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS);
694                } else {
695                    ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK);
696                }
697                scheduleWriteSettingsLocked();
698
699                final int userId = ivs.getUserId();
700                if (userId != UserHandle.USER_ALL) {
701                    final int userStatus =
702                            mSettings.getIntentFilterVerificationStatusLPr(packageName, userId);
703
704                    int updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
705                    boolean needUpdate = false;
706
707                    // We cannot override the STATUS_ALWAYS / STATUS_NEVER states if they have
708                    // already been set by the User thru the Disambiguation dialog
709                    switch (userStatus) {
710                        case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED:
711                            if (verified) {
712                                updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
713                            } else {
714                                updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK;
715                            }
716                            needUpdate = true;
717                            break;
718
719                        case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK:
720                            if (verified) {
721                                updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
722                                needUpdate = true;
723                            }
724                            break;
725
726                        default:
727                            // Nothing to do
728                    }
729
730                    if (needUpdate) {
731                        mSettings.updateIntentFilterVerificationStatusLPw(
732                                packageName, updatedStatus, userId);
733                        scheduleWritePackageRestrictionsLocked(userId);
734                    }
735                }
736            }
737        }
738
739        @Override
740        public boolean addOneIntentFilterVerification(int verifierUid, int userId, int verificationId,
741                    ActivityIntentInfo filter, String packageName) {
742            if (!hasValidDomains(filter)) {
743                return false;
744            }
745            IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId);
746            if (ivs == null) {
747                ivs = createDomainVerificationState(verifierUid, userId, verificationId,
748                        packageName);
749            }
750            if (DEBUG_DOMAIN_VERIFICATION) {
751                Slog.d(TAG, "Adding verification filter for " + packageName + " : " + filter);
752            }
753            ivs.addFilter(filter);
754            return true;
755        }
756
757        private IntentFilterVerificationState createDomainVerificationState(int verifierUid,
758                int userId, int verificationId, String packageName) {
759            IntentFilterVerificationState ivs = new IntentFilterVerificationState(
760                    verifierUid, userId, packageName);
761            ivs.setPendingState();
762            synchronized (mPackages) {
763                mIntentFilterVerificationStates.append(verificationId, ivs);
764                mCurrentIntentFilterVerifications.add(verificationId);
765            }
766            return ivs;
767        }
768    }
769
770    private static boolean hasValidDomains(ActivityIntentInfo filter) {
771        boolean hasHTTPorHTTPS = filter.hasDataScheme(IntentFilter.SCHEME_HTTP) ||
772                filter.hasDataScheme(IntentFilter.SCHEME_HTTPS);
773        if (!hasHTTPorHTTPS) {
774            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
775                    "IntentFilter does not contain any HTTP or HTTPS data scheme");
776            return false;
777        }
778        return true;
779    }
780
781    private IntentFilterVerifier mIntentFilterVerifier;
782
783    // Set of pending broadcasts for aggregating enable/disable of components.
784    static class PendingPackageBroadcasts {
785        // for each user id, a map of <package name -> components within that package>
786        final SparseArray<ArrayMap<String, ArrayList<String>>> mUidMap;
787
788        public PendingPackageBroadcasts() {
789            mUidMap = new SparseArray<ArrayMap<String, ArrayList<String>>>(2);
790        }
791
792        public ArrayList<String> get(int userId, String packageName) {
793            ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId);
794            return packages.get(packageName);
795        }
796
797        public void put(int userId, String packageName, ArrayList<String> components) {
798            ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId);
799            packages.put(packageName, components);
800        }
801
802        public void remove(int userId, String packageName) {
803            ArrayMap<String, ArrayList<String>> packages = mUidMap.get(userId);
804            if (packages != null) {
805                packages.remove(packageName);
806            }
807        }
808
809        public void remove(int userId) {
810            mUidMap.remove(userId);
811        }
812
813        public int userIdCount() {
814            return mUidMap.size();
815        }
816
817        public int userIdAt(int n) {
818            return mUidMap.keyAt(n);
819        }
820
821        public ArrayMap<String, ArrayList<String>> packagesForUserId(int userId) {
822            return mUidMap.get(userId);
823        }
824
825        public int size() {
826            // total number of pending broadcast entries across all userIds
827            int num = 0;
828            for (int i = 0; i< mUidMap.size(); i++) {
829                num += mUidMap.valueAt(i).size();
830            }
831            return num;
832        }
833
834        public void clear() {
835            mUidMap.clear();
836        }
837
838        private ArrayMap<String, ArrayList<String>> getOrAllocate(int userId) {
839            ArrayMap<String, ArrayList<String>> map = mUidMap.get(userId);
840            if (map == null) {
841                map = new ArrayMap<String, ArrayList<String>>();
842                mUidMap.put(userId, map);
843            }
844            return map;
845        }
846    }
847    final PendingPackageBroadcasts mPendingBroadcasts = new PendingPackageBroadcasts();
848
849    // Service Connection to remote media container service to copy
850    // package uri's from external media onto secure containers
851    // or internal storage.
852    private IMediaContainerService mContainerService = null;
853
854    static final int SEND_PENDING_BROADCAST = 1;
855    static final int MCS_BOUND = 3;
856    static final int END_COPY = 4;
857    static final int INIT_COPY = 5;
858    static final int MCS_UNBIND = 6;
859    static final int START_CLEANING_PACKAGE = 7;
860    static final int FIND_INSTALL_LOC = 8;
861    static final int POST_INSTALL = 9;
862    static final int MCS_RECONNECT = 10;
863    static final int MCS_GIVE_UP = 11;
864    static final int UPDATED_MEDIA_STATUS = 12;
865    static final int WRITE_SETTINGS = 13;
866    static final int WRITE_PACKAGE_RESTRICTIONS = 14;
867    static final int PACKAGE_VERIFIED = 15;
868    static final int CHECK_PENDING_VERIFICATION = 16;
869    static final int START_INTENT_FILTER_VERIFICATIONS = 17;
870    static final int INTENT_FILTER_VERIFIED = 18;
871
872    static final int WRITE_SETTINGS_DELAY = 10*1000;  // 10 seconds
873
874    // Delay time in millisecs
875    static final int BROADCAST_DELAY = 10 * 1000;
876
877    static UserManagerService sUserManager;
878
879    // Stores a list of users whose package restrictions file needs to be updated
880    private ArraySet<Integer> mDirtyUsers = new ArraySet<Integer>();
881
882    final private DefaultContainerConnection mDefContainerConn =
883            new DefaultContainerConnection();
884    class DefaultContainerConnection implements ServiceConnection {
885        public void onServiceConnected(ComponentName name, IBinder service) {
886            if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceConnected");
887            IMediaContainerService imcs =
888                IMediaContainerService.Stub.asInterface(service);
889            mHandler.sendMessage(mHandler.obtainMessage(MCS_BOUND, imcs));
890        }
891
892        public void onServiceDisconnected(ComponentName name) {
893            if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceDisconnected");
894        }
895    }
896
897    // Recordkeeping of restore-after-install operations that are currently in flight
898    // between the Package Manager and the Backup Manager
899    class PostInstallData {
900        public InstallArgs args;
901        public PackageInstalledInfo res;
902
903        PostInstallData(InstallArgs _a, PackageInstalledInfo _r) {
904            args = _a;
905            res = _r;
906        }
907    }
908
909    final SparseArray<PostInstallData> mRunningInstalls = new SparseArray<PostInstallData>();
910    int mNextInstallToken = 1;  // nonzero; will be wrapped back to 1 when ++ overflows
911
912    // XML tags for backup/restore of various bits of state
913    private static final String TAG_PREFERRED_BACKUP = "pa";
914    private static final String TAG_DEFAULT_APPS = "da";
915    private static final String TAG_INTENT_FILTER_VERIFICATION = "iv";
916
917    private final String mRequiredVerifierPackage;
918
919    private final PackageUsage mPackageUsage = new PackageUsage();
920
921    private class PackageUsage {
922        private static final int WRITE_INTERVAL
923            = (DEBUG_DEXOPT) ? 0 : 30*60*1000; // 30m in ms
924
925        private final Object mFileLock = new Object();
926        private final AtomicLong mLastWritten = new AtomicLong(0);
927        private final AtomicBoolean mBackgroundWriteRunning = new AtomicBoolean(false);
928
929        private boolean mIsHistoricalPackageUsageAvailable = true;
930
931        boolean isHistoricalPackageUsageAvailable() {
932            return mIsHistoricalPackageUsageAvailable;
933        }
934
935        void write(boolean force) {
936            if (force) {
937                writeInternal();
938                return;
939            }
940            if (SystemClock.elapsedRealtime() - mLastWritten.get() < WRITE_INTERVAL
941                && !DEBUG_DEXOPT) {
942                return;
943            }
944            if (mBackgroundWriteRunning.compareAndSet(false, true)) {
945                new Thread("PackageUsage_DiskWriter") {
946                    @Override
947                    public void run() {
948                        try {
949                            writeInternal();
950                        } finally {
951                            mBackgroundWriteRunning.set(false);
952                        }
953                    }
954                }.start();
955            }
956        }
957
958        private void writeInternal() {
959            synchronized (mPackages) {
960                synchronized (mFileLock) {
961                    AtomicFile file = getFile();
962                    FileOutputStream f = null;
963                    try {
964                        f = file.startWrite();
965                        BufferedOutputStream out = new BufferedOutputStream(f);
966                        FileUtils.setPermissions(file.getBaseFile().getPath(), 0640, SYSTEM_UID, PACKAGE_INFO_GID);
967                        StringBuilder sb = new StringBuilder();
968                        for (PackageParser.Package pkg : mPackages.values()) {
969                            if (pkg.mLastPackageUsageTimeInMills == 0) {
970                                continue;
971                            }
972                            sb.setLength(0);
973                            sb.append(pkg.packageName);
974                            sb.append(' ');
975                            sb.append((long)pkg.mLastPackageUsageTimeInMills);
976                            sb.append('\n');
977                            out.write(sb.toString().getBytes(StandardCharsets.US_ASCII));
978                        }
979                        out.flush();
980                        file.finishWrite(f);
981                    } catch (IOException e) {
982                        if (f != null) {
983                            file.failWrite(f);
984                        }
985                        Log.e(TAG, "Failed to write package usage times", e);
986                    }
987                }
988            }
989            mLastWritten.set(SystemClock.elapsedRealtime());
990        }
991
992        void readLP() {
993            synchronized (mFileLock) {
994                AtomicFile file = getFile();
995                BufferedInputStream in = null;
996                try {
997                    in = new BufferedInputStream(file.openRead());
998                    StringBuffer sb = new StringBuffer();
999                    while (true) {
1000                        String packageName = readToken(in, sb, ' ');
1001                        if (packageName == null) {
1002                            break;
1003                        }
1004                        String timeInMillisString = readToken(in, sb, '\n');
1005                        if (timeInMillisString == null) {
1006                            throw new IOException("Failed to find last usage time for package "
1007                                                  + packageName);
1008                        }
1009                        PackageParser.Package pkg = mPackages.get(packageName);
1010                        if (pkg == null) {
1011                            continue;
1012                        }
1013                        long timeInMillis;
1014                        try {
1015                            timeInMillis = Long.parseLong(timeInMillisString.toString());
1016                        } catch (NumberFormatException e) {
1017                            throw new IOException("Failed to parse " + timeInMillisString
1018                                                  + " as a long.", e);
1019                        }
1020                        pkg.mLastPackageUsageTimeInMills = timeInMillis;
1021                    }
1022                } catch (FileNotFoundException expected) {
1023                    mIsHistoricalPackageUsageAvailable = false;
1024                } catch (IOException e) {
1025                    Log.w(TAG, "Failed to read package usage times", e);
1026                } finally {
1027                    IoUtils.closeQuietly(in);
1028                }
1029            }
1030            mLastWritten.set(SystemClock.elapsedRealtime());
1031        }
1032
1033        private String readToken(InputStream in, StringBuffer sb, char endOfToken)
1034                throws IOException {
1035            sb.setLength(0);
1036            while (true) {
1037                int ch = in.read();
1038                if (ch == -1) {
1039                    if (sb.length() == 0) {
1040                        return null;
1041                    }
1042                    throw new IOException("Unexpected EOF");
1043                }
1044                if (ch == endOfToken) {
1045                    return sb.toString();
1046                }
1047                sb.append((char)ch);
1048            }
1049        }
1050
1051        private AtomicFile getFile() {
1052            File dataDir = Environment.getDataDirectory();
1053            File systemDir = new File(dataDir, "system");
1054            File fname = new File(systemDir, "package-usage.list");
1055            return new AtomicFile(fname);
1056        }
1057    }
1058
1059    class PackageHandler extends Handler {
1060        private boolean mBound = false;
1061        final ArrayList<HandlerParams> mPendingInstalls =
1062            new ArrayList<HandlerParams>();
1063
1064        private boolean connectToService() {
1065            if (DEBUG_SD_INSTALL) Log.i(TAG, "Trying to bind to" +
1066                    " DefaultContainerService");
1067            Intent service = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
1068            Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1069            if (mContext.bindServiceAsUser(service, mDefContainerConn,
1070                    Context.BIND_AUTO_CREATE, UserHandle.OWNER)) {
1071                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1072                mBound = true;
1073                return true;
1074            }
1075            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1076            return false;
1077        }
1078
1079        private void disconnectService() {
1080            mContainerService = null;
1081            mBound = false;
1082            Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1083            mContext.unbindService(mDefContainerConn);
1084            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1085        }
1086
1087        PackageHandler(Looper looper) {
1088            super(looper);
1089        }
1090
1091        public void handleMessage(Message msg) {
1092            try {
1093                doHandleMessage(msg);
1094            } finally {
1095                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1096            }
1097        }
1098
1099        void doHandleMessage(Message msg) {
1100            switch (msg.what) {
1101                case INIT_COPY: {
1102                    HandlerParams params = (HandlerParams) msg.obj;
1103                    int idx = mPendingInstalls.size();
1104                    if (DEBUG_INSTALL) Slog.i(TAG, "init_copy idx=" + idx + ": " + params);
1105                    // If a bind was already initiated we dont really
1106                    // need to do anything. The pending install
1107                    // will be processed later on.
1108                    if (!mBound) {
1109                        // If this is the only one pending we might
1110                        // have to bind to the service again.
1111                        if (!connectToService()) {
1112                            Slog.e(TAG, "Failed to bind to media container service");
1113                            params.serviceError();
1114                            return;
1115                        } else {
1116                            // Once we bind to the service, the first
1117                            // pending request will be processed.
1118                            mPendingInstalls.add(idx, params);
1119                        }
1120                    } else {
1121                        mPendingInstalls.add(idx, params);
1122                        // Already bound to the service. Just make
1123                        // sure we trigger off processing the first request.
1124                        if (idx == 0) {
1125                            mHandler.sendEmptyMessage(MCS_BOUND);
1126                        }
1127                    }
1128                    break;
1129                }
1130                case MCS_BOUND: {
1131                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_bound");
1132                    if (msg.obj != null) {
1133                        mContainerService = (IMediaContainerService) msg.obj;
1134                    }
1135                    if (mContainerService == null) {
1136                        if (!mBound) {
1137                            // Something seriously wrong since we are not bound and we are not
1138                            // waiting for connection. Bail out.
1139                            Slog.e(TAG, "Cannot bind to media container service");
1140                            for (HandlerParams params : mPendingInstalls) {
1141                                // Indicate service bind error
1142                                params.serviceError();
1143                            }
1144                            mPendingInstalls.clear();
1145                        } else {
1146                            Slog.w(TAG, "Waiting to connect to media container service");
1147                        }
1148                    } else if (mPendingInstalls.size() > 0) {
1149                        HandlerParams params = mPendingInstalls.get(0);
1150                        if (params != null) {
1151                            if (params.startCopy()) {
1152                                // We are done...  look for more work or to
1153                                // go idle.
1154                                if (DEBUG_SD_INSTALL) Log.i(TAG,
1155                                        "Checking for more work or unbind...");
1156                                // Delete pending install
1157                                if (mPendingInstalls.size() > 0) {
1158                                    mPendingInstalls.remove(0);
1159                                }
1160                                if (mPendingInstalls.size() == 0) {
1161                                    if (mBound) {
1162                                        if (DEBUG_SD_INSTALL) Log.i(TAG,
1163                                                "Posting delayed MCS_UNBIND");
1164                                        removeMessages(MCS_UNBIND);
1165                                        Message ubmsg = obtainMessage(MCS_UNBIND);
1166                                        // Unbind after a little delay, to avoid
1167                                        // continual thrashing.
1168                                        sendMessageDelayed(ubmsg, 10000);
1169                                    }
1170                                } else {
1171                                    // There are more pending requests in queue.
1172                                    // Just post MCS_BOUND message to trigger processing
1173                                    // of next pending install.
1174                                    if (DEBUG_SD_INSTALL) Log.i(TAG,
1175                                            "Posting MCS_BOUND for next work");
1176                                    mHandler.sendEmptyMessage(MCS_BOUND);
1177                                }
1178                            }
1179                        }
1180                    } else {
1181                        // Should never happen ideally.
1182                        Slog.w(TAG, "Empty queue");
1183                    }
1184                    break;
1185                }
1186                case MCS_RECONNECT: {
1187                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_reconnect");
1188                    if (mPendingInstalls.size() > 0) {
1189                        if (mBound) {
1190                            disconnectService();
1191                        }
1192                        if (!connectToService()) {
1193                            Slog.e(TAG, "Failed to bind to media container service");
1194                            for (HandlerParams params : mPendingInstalls) {
1195                                // Indicate service bind error
1196                                params.serviceError();
1197                            }
1198                            mPendingInstalls.clear();
1199                        }
1200                    }
1201                    break;
1202                }
1203                case MCS_UNBIND: {
1204                    // If there is no actual work left, then time to unbind.
1205                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_unbind");
1206
1207                    if (mPendingInstalls.size() == 0 && mPendingVerification.size() == 0) {
1208                        if (mBound) {
1209                            if (DEBUG_INSTALL) Slog.i(TAG, "calling disconnectService()");
1210
1211                            disconnectService();
1212                        }
1213                    } else if (mPendingInstalls.size() > 0) {
1214                        // There are more pending requests in queue.
1215                        // Just post MCS_BOUND message to trigger processing
1216                        // of next pending install.
1217                        mHandler.sendEmptyMessage(MCS_BOUND);
1218                    }
1219
1220                    break;
1221                }
1222                case MCS_GIVE_UP: {
1223                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_giveup too many retries");
1224                    mPendingInstalls.remove(0);
1225                    break;
1226                }
1227                case SEND_PENDING_BROADCAST: {
1228                    String packages[];
1229                    ArrayList<String> components[];
1230                    int size = 0;
1231                    int uids[];
1232                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1233                    synchronized (mPackages) {
1234                        if (mPendingBroadcasts == null) {
1235                            return;
1236                        }
1237                        size = mPendingBroadcasts.size();
1238                        if (size <= 0) {
1239                            // Nothing to be done. Just return
1240                            return;
1241                        }
1242                        packages = new String[size];
1243                        components = new ArrayList[size];
1244                        uids = new int[size];
1245                        int i = 0;  // filling out the above arrays
1246
1247                        for (int n = 0; n < mPendingBroadcasts.userIdCount(); n++) {
1248                            int packageUserId = mPendingBroadcasts.userIdAt(n);
1249                            Iterator<Map.Entry<String, ArrayList<String>>> it
1250                                    = mPendingBroadcasts.packagesForUserId(packageUserId)
1251                                            .entrySet().iterator();
1252                            while (it.hasNext() && i < size) {
1253                                Map.Entry<String, ArrayList<String>> ent = it.next();
1254                                packages[i] = ent.getKey();
1255                                components[i] = ent.getValue();
1256                                PackageSetting ps = mSettings.mPackages.get(ent.getKey());
1257                                uids[i] = (ps != null)
1258                                        ? UserHandle.getUid(packageUserId, ps.appId)
1259                                        : -1;
1260                                i++;
1261                            }
1262                        }
1263                        size = i;
1264                        mPendingBroadcasts.clear();
1265                    }
1266                    // Send broadcasts
1267                    for (int i = 0; i < size; i++) {
1268                        sendPackageChangedBroadcast(packages[i], true, components[i], uids[i]);
1269                    }
1270                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1271                    break;
1272                }
1273                case START_CLEANING_PACKAGE: {
1274                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1275                    final String packageName = (String)msg.obj;
1276                    final int userId = msg.arg1;
1277                    final boolean andCode = msg.arg2 != 0;
1278                    synchronized (mPackages) {
1279                        if (userId == UserHandle.USER_ALL) {
1280                            int[] users = sUserManager.getUserIds();
1281                            for (int user : users) {
1282                                mSettings.addPackageToCleanLPw(
1283                                        new PackageCleanItem(user, packageName, andCode));
1284                            }
1285                        } else {
1286                            mSettings.addPackageToCleanLPw(
1287                                    new PackageCleanItem(userId, packageName, andCode));
1288                        }
1289                    }
1290                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1291                    startCleaningPackages();
1292                } break;
1293                case POST_INSTALL: {
1294                    if (DEBUG_INSTALL) Log.v(TAG, "Handling post-install for " + msg.arg1);
1295                    PostInstallData data = mRunningInstalls.get(msg.arg1);
1296                    mRunningInstalls.delete(msg.arg1);
1297                    boolean deleteOld = false;
1298
1299                    if (data != null) {
1300                        InstallArgs args = data.args;
1301                        PackageInstalledInfo res = data.res;
1302
1303                        if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
1304                            res.removedInfo.sendBroadcast(false, true, false);
1305                            Bundle extras = new Bundle(1);
1306                            extras.putInt(Intent.EXTRA_UID, res.uid);
1307
1308                            // Now that we successfully installed the package, grant runtime
1309                            // permissions if requested before broadcasting the install.
1310                            if ((args.installFlags
1311                                    & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0) {
1312                                grantRequestedRuntimePermissions(res.pkg,
1313                                        args.user.getIdentifier());
1314                            }
1315
1316                            // Determine the set of users who are adding this
1317                            // package for the first time vs. those who are seeing
1318                            // an update.
1319                            int[] firstUsers;
1320                            int[] updateUsers = new int[0];
1321                            if (res.origUsers == null || res.origUsers.length == 0) {
1322                                firstUsers = res.newUsers;
1323                            } else {
1324                                firstUsers = new int[0];
1325                                for (int i=0; i<res.newUsers.length; i++) {
1326                                    int user = res.newUsers[i];
1327                                    boolean isNew = true;
1328                                    for (int j=0; j<res.origUsers.length; j++) {
1329                                        if (res.origUsers[j] == user) {
1330                                            isNew = false;
1331                                            break;
1332                                        }
1333                                    }
1334                                    if (isNew) {
1335                                        int[] newFirst = new int[firstUsers.length+1];
1336                                        System.arraycopy(firstUsers, 0, newFirst, 0,
1337                                                firstUsers.length);
1338                                        newFirst[firstUsers.length] = user;
1339                                        firstUsers = newFirst;
1340                                    } else {
1341                                        int[] newUpdate = new int[updateUsers.length+1];
1342                                        System.arraycopy(updateUsers, 0, newUpdate, 0,
1343                                                updateUsers.length);
1344                                        newUpdate[updateUsers.length] = user;
1345                                        updateUsers = newUpdate;
1346                                    }
1347                                }
1348                            }
1349                            sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
1350                                    res.pkg.applicationInfo.packageName,
1351                                    extras, null, null, firstUsers);
1352                            final boolean update = res.removedInfo.removedPackage != null;
1353                            if (update) {
1354                                extras.putBoolean(Intent.EXTRA_REPLACING, true);
1355                            }
1356                            sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
1357                                    res.pkg.applicationInfo.packageName,
1358                                    extras, null, null, updateUsers);
1359                            if (update) {
1360                                sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
1361                                        res.pkg.applicationInfo.packageName,
1362                                        extras, null, null, updateUsers);
1363                                sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
1364                                        null, null,
1365                                        res.pkg.applicationInfo.packageName, null, updateUsers);
1366
1367                                // treat asec-hosted packages like removable media on upgrade
1368                                if (res.pkg.isForwardLocked() || isExternal(res.pkg)) {
1369                                    if (DEBUG_INSTALL) {
1370                                        Slog.i(TAG, "upgrading pkg " + res.pkg
1371                                                + " is ASEC-hosted -> AVAILABLE");
1372                                    }
1373                                    int[] uidArray = new int[] { res.pkg.applicationInfo.uid };
1374                                    ArrayList<String> pkgList = new ArrayList<String>(1);
1375                                    pkgList.add(res.pkg.applicationInfo.packageName);
1376                                    sendResourcesChangedBroadcast(true, true,
1377                                            pkgList,uidArray, null);
1378                                }
1379                            }
1380                            if (res.removedInfo.args != null) {
1381                                // Remove the replaced package's older resources safely now
1382                                deleteOld = true;
1383                            }
1384
1385                            // Log current value of "unknown sources" setting
1386                            EventLog.writeEvent(EventLogTags.UNKNOWN_SOURCES_ENABLED,
1387                                getUnknownSourcesSettings());
1388                        }
1389                        // Force a gc to clear up things
1390                        Runtime.getRuntime().gc();
1391                        // We delete after a gc for applications  on sdcard.
1392                        if (deleteOld) {
1393                            synchronized (mInstallLock) {
1394                                res.removedInfo.args.doPostDeleteLI(true);
1395                            }
1396                        }
1397                        if (args.observer != null) {
1398                            try {
1399                                Bundle extras = extrasForInstallResult(res);
1400                                args.observer.onPackageInstalled(res.name, res.returnCode,
1401                                        res.returnMsg, extras);
1402                            } catch (RemoteException e) {
1403                                Slog.i(TAG, "Observer no longer exists.");
1404                            }
1405                        }
1406                    } else {
1407                        Slog.e(TAG, "Bogus post-install token " + msg.arg1);
1408                    }
1409                } break;
1410                case UPDATED_MEDIA_STATUS: {
1411                    if (DEBUG_SD_INSTALL) Log.i(TAG, "Got message UPDATED_MEDIA_STATUS");
1412                    boolean reportStatus = msg.arg1 == 1;
1413                    boolean doGc = msg.arg2 == 1;
1414                    if (DEBUG_SD_INSTALL) Log.i(TAG, "reportStatus=" + reportStatus + ", doGc = " + doGc);
1415                    if (doGc) {
1416                        // Force a gc to clear up stale containers.
1417                        Runtime.getRuntime().gc();
1418                    }
1419                    if (msg.obj != null) {
1420                        @SuppressWarnings("unchecked")
1421                        Set<AsecInstallArgs> args = (Set<AsecInstallArgs>) msg.obj;
1422                        if (DEBUG_SD_INSTALL) Log.i(TAG, "Unloading all containers");
1423                        // Unload containers
1424                        unloadAllContainers(args);
1425                    }
1426                    if (reportStatus) {
1427                        try {
1428                            if (DEBUG_SD_INSTALL) Log.i(TAG, "Invoking MountService call back");
1429                            PackageHelper.getMountService().finishMediaUpdate();
1430                        } catch (RemoteException e) {
1431                            Log.e(TAG, "MountService not running?");
1432                        }
1433                    }
1434                } break;
1435                case WRITE_SETTINGS: {
1436                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1437                    synchronized (mPackages) {
1438                        removeMessages(WRITE_SETTINGS);
1439                        removeMessages(WRITE_PACKAGE_RESTRICTIONS);
1440                        mSettings.writeLPr();
1441                        mDirtyUsers.clear();
1442                    }
1443                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1444                } break;
1445                case WRITE_PACKAGE_RESTRICTIONS: {
1446                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1447                    synchronized (mPackages) {
1448                        removeMessages(WRITE_PACKAGE_RESTRICTIONS);
1449                        for (int userId : mDirtyUsers) {
1450                            mSettings.writePackageRestrictionsLPr(userId);
1451                        }
1452                        mDirtyUsers.clear();
1453                    }
1454                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1455                } break;
1456                case CHECK_PENDING_VERIFICATION: {
1457                    final int verificationId = msg.arg1;
1458                    final PackageVerificationState state = mPendingVerification.get(verificationId);
1459
1460                    if ((state != null) && !state.timeoutExtended()) {
1461                        final InstallArgs args = state.getInstallArgs();
1462                        final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
1463
1464                        Slog.i(TAG, "Verification timed out for " + originUri);
1465                        mPendingVerification.remove(verificationId);
1466
1467                        int ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
1468
1469                        if (getDefaultVerificationResponse() == PackageManager.VERIFICATION_ALLOW) {
1470                            Slog.i(TAG, "Continuing with installation of " + originUri);
1471                            state.setVerifierResponse(Binder.getCallingUid(),
1472                                    PackageManager.VERIFICATION_ALLOW_WITHOUT_SUFFICIENT);
1473                            broadcastPackageVerified(verificationId, originUri,
1474                                    PackageManager.VERIFICATION_ALLOW,
1475                                    state.getInstallArgs().getUser());
1476                            try {
1477                                ret = args.copyApk(mContainerService, true);
1478                            } catch (RemoteException e) {
1479                                Slog.e(TAG, "Could not contact the ContainerService");
1480                            }
1481                        } else {
1482                            broadcastPackageVerified(verificationId, originUri,
1483                                    PackageManager.VERIFICATION_REJECT,
1484                                    state.getInstallArgs().getUser());
1485                        }
1486
1487                        processPendingInstall(args, ret);
1488                        mHandler.sendEmptyMessage(MCS_UNBIND);
1489                    }
1490                    break;
1491                }
1492                case PACKAGE_VERIFIED: {
1493                    final int verificationId = msg.arg1;
1494
1495                    final PackageVerificationState state = mPendingVerification.get(verificationId);
1496                    if (state == null) {
1497                        Slog.w(TAG, "Invalid verification token " + verificationId + " received");
1498                        break;
1499                    }
1500
1501                    final PackageVerificationResponse response = (PackageVerificationResponse) msg.obj;
1502
1503                    state.setVerifierResponse(response.callerUid, response.code);
1504
1505                    if (state.isVerificationComplete()) {
1506                        mPendingVerification.remove(verificationId);
1507
1508                        final InstallArgs args = state.getInstallArgs();
1509                        final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
1510
1511                        int ret;
1512                        if (state.isInstallAllowed()) {
1513                            ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
1514                            broadcastPackageVerified(verificationId, originUri,
1515                                    response.code, state.getInstallArgs().getUser());
1516                            try {
1517                                ret = args.copyApk(mContainerService, true);
1518                            } catch (RemoteException e) {
1519                                Slog.e(TAG, "Could not contact the ContainerService");
1520                            }
1521                        } else {
1522                            ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
1523                        }
1524
1525                        processPendingInstall(args, ret);
1526
1527                        mHandler.sendEmptyMessage(MCS_UNBIND);
1528                    }
1529
1530                    break;
1531                }
1532                case START_INTENT_FILTER_VERIFICATIONS: {
1533                    IFVerificationParams params = (IFVerificationParams) msg.obj;
1534                    verifyIntentFiltersIfNeeded(params.userId, params.verifierUid,
1535                            params.replacing, params.pkg);
1536                    break;
1537                }
1538                case INTENT_FILTER_VERIFIED: {
1539                    final int verificationId = msg.arg1;
1540
1541                    final IntentFilterVerificationState state = mIntentFilterVerificationStates.get(
1542                            verificationId);
1543                    if (state == null) {
1544                        Slog.w(TAG, "Invalid IntentFilter verification token "
1545                                + verificationId + " received");
1546                        break;
1547                    }
1548
1549                    final int userId = state.getUserId();
1550
1551                    if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1552                            "Processing IntentFilter verification with token:"
1553                            + verificationId + " and userId:" + userId);
1554
1555                    final IntentFilterVerificationResponse response =
1556                            (IntentFilterVerificationResponse) msg.obj;
1557
1558                    state.setVerifierResponse(response.callerUid, response.code);
1559
1560                    if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1561                            "IntentFilter verification with token:" + verificationId
1562                            + " and userId:" + userId
1563                            + " is settings verifier response with response code:"
1564                            + response.code);
1565
1566                    if (response.code == PackageManager.INTENT_FILTER_VERIFICATION_FAILURE) {
1567                        if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Domains failing verification: "
1568                                + response.getFailedDomainsString());
1569                    }
1570
1571                    if (state.isVerificationComplete()) {
1572                        mIntentFilterVerifier.receiveVerificationResponse(verificationId);
1573                    } else {
1574                        if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1575                                "IntentFilter verification with token:" + verificationId
1576                                + " was not said to be complete");
1577                    }
1578
1579                    break;
1580                }
1581            }
1582        }
1583    }
1584
1585    private StorageEventListener mStorageListener = new StorageEventListener() {
1586        @Override
1587        public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState) {
1588            if (vol.type == VolumeInfo.TYPE_PRIVATE) {
1589                if (vol.state == VolumeInfo.STATE_MOUNTED) {
1590                    // TODO: ensure that private directories exist for all active users
1591                    // TODO: remove user data whose serial number doesn't match
1592                    loadPrivatePackages(vol);
1593                } else if (vol.state == VolumeInfo.STATE_EJECTING) {
1594                    unloadPrivatePackages(vol);
1595                }
1596            }
1597
1598            if (vol.type == VolumeInfo.TYPE_PUBLIC && vol.isPrimary()) {
1599                if (vol.state == VolumeInfo.STATE_MOUNTED) {
1600                    updateExternalMediaStatus(true, false);
1601                } else if (vol.state == VolumeInfo.STATE_EJECTING) {
1602                    updateExternalMediaStatus(false, false);
1603                }
1604            }
1605        }
1606
1607        @Override
1608        public void onVolumeForgotten(String fsUuid) {
1609            // TODO: remove all packages hosted on this uuid
1610        }
1611    };
1612
1613    private void grantRequestedRuntimePermissions(PackageParser.Package pkg, int userId) {
1614        if (userId >= UserHandle.USER_OWNER) {
1615            grantRequestedRuntimePermissionsForUser(pkg, userId);
1616        } else if (userId == UserHandle.USER_ALL) {
1617            for (int someUserId : UserManagerService.getInstance().getUserIds()) {
1618                grantRequestedRuntimePermissionsForUser(pkg, someUserId);
1619            }
1620        }
1621
1622        // We could have touched GID membership, so flush out packages.list
1623        synchronized (mPackages) {
1624            mSettings.writePackageListLPr();
1625        }
1626    }
1627
1628    private void grantRequestedRuntimePermissionsForUser(PackageParser.Package pkg, int userId) {
1629        SettingBase sb = (SettingBase) pkg.mExtras;
1630        if (sb == null) {
1631            return;
1632        }
1633
1634        PermissionsState permissionsState = sb.getPermissionsState();
1635
1636        for (String permission : pkg.requestedPermissions) {
1637            BasePermission bp = mSettings.mPermissions.get(permission);
1638            if (bp != null && bp.isRuntime()) {
1639                permissionsState.grantRuntimePermission(bp, userId);
1640            }
1641        }
1642    }
1643
1644    Bundle extrasForInstallResult(PackageInstalledInfo res) {
1645        Bundle extras = null;
1646        switch (res.returnCode) {
1647            case PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION: {
1648                extras = new Bundle();
1649                extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PERMISSION,
1650                        res.origPermission);
1651                extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PACKAGE,
1652                        res.origPackage);
1653                break;
1654            }
1655            case PackageManager.INSTALL_SUCCEEDED: {
1656                extras = new Bundle();
1657                extras.putBoolean(Intent.EXTRA_REPLACING,
1658                        res.removedInfo != null && res.removedInfo.removedPackage != null);
1659                break;
1660            }
1661        }
1662        return extras;
1663    }
1664
1665    void scheduleWriteSettingsLocked() {
1666        if (!mHandler.hasMessages(WRITE_SETTINGS)) {
1667            mHandler.sendEmptyMessageDelayed(WRITE_SETTINGS, WRITE_SETTINGS_DELAY);
1668        }
1669    }
1670
1671    void scheduleWritePackageRestrictionsLocked(int userId) {
1672        if (!sUserManager.exists(userId)) return;
1673        mDirtyUsers.add(userId);
1674        if (!mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) {
1675            mHandler.sendEmptyMessageDelayed(WRITE_PACKAGE_RESTRICTIONS, WRITE_SETTINGS_DELAY);
1676        }
1677    }
1678
1679    public static PackageManagerService main(Context context, Installer installer,
1680            boolean factoryTest, boolean onlyCore) {
1681        PackageManagerService m = new PackageManagerService(context, installer,
1682                factoryTest, onlyCore);
1683        ServiceManager.addService("package", m);
1684        return m;
1685    }
1686
1687    static String[] splitString(String str, char sep) {
1688        int count = 1;
1689        int i = 0;
1690        while ((i=str.indexOf(sep, i)) >= 0) {
1691            count++;
1692            i++;
1693        }
1694
1695        String[] res = new String[count];
1696        i=0;
1697        count = 0;
1698        int lastI=0;
1699        while ((i=str.indexOf(sep, i)) >= 0) {
1700            res[count] = str.substring(lastI, i);
1701            count++;
1702            i++;
1703            lastI = i;
1704        }
1705        res[count] = str.substring(lastI, str.length());
1706        return res;
1707    }
1708
1709    private static void getDefaultDisplayMetrics(Context context, DisplayMetrics metrics) {
1710        DisplayManager displayManager = (DisplayManager) context.getSystemService(
1711                Context.DISPLAY_SERVICE);
1712        displayManager.getDisplay(Display.DEFAULT_DISPLAY).getMetrics(metrics);
1713    }
1714
1715    public PackageManagerService(Context context, Installer installer,
1716            boolean factoryTest, boolean onlyCore) {
1717        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START,
1718                SystemClock.uptimeMillis());
1719
1720        if (mSdkVersion <= 0) {
1721            Slog.w(TAG, "**** ro.build.version.sdk not set!");
1722        }
1723
1724        mContext = context;
1725        mFactoryTest = factoryTest;
1726        mOnlyCore = onlyCore;
1727        mLazyDexOpt = "eng".equals(SystemProperties.get("ro.build.type"));
1728        mMetrics = new DisplayMetrics();
1729        mSettings = new Settings(mPackages);
1730        mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID,
1731                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
1732        mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID,
1733                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
1734        mSettings.addSharedUserLPw("android.uid.log", LOG_UID,
1735                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
1736        mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID,
1737                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
1738        mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID,
1739                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
1740        mSettings.addSharedUserLPw("android.uid.shell", SHELL_UID,
1741                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
1742
1743        // TODO: add a property to control this?
1744        long dexOptLRUThresholdInMinutes;
1745        if (mLazyDexOpt) {
1746            dexOptLRUThresholdInMinutes = 30; // only last 30 minutes of apps for eng builds.
1747        } else {
1748            dexOptLRUThresholdInMinutes = 7 * 24 * 60; // apps used in the 7 days for users.
1749        }
1750        mDexOptLRUThresholdInMills = dexOptLRUThresholdInMinutes * 60 * 1000;
1751
1752        String separateProcesses = SystemProperties.get("debug.separate_processes");
1753        if (separateProcesses != null && separateProcesses.length() > 0) {
1754            if ("*".equals(separateProcesses)) {
1755                mDefParseFlags = PackageParser.PARSE_IGNORE_PROCESSES;
1756                mSeparateProcesses = null;
1757                Slog.w(TAG, "Running with debug.separate_processes: * (ALL)");
1758            } else {
1759                mDefParseFlags = 0;
1760                mSeparateProcesses = separateProcesses.split(",");
1761                Slog.w(TAG, "Running with debug.separate_processes: "
1762                        + separateProcesses);
1763            }
1764        } else {
1765            mDefParseFlags = 0;
1766            mSeparateProcesses = null;
1767        }
1768
1769        mInstaller = installer;
1770        mPackageDexOptimizer = new PackageDexOptimizer(this);
1771        mMoveCallbacks = new MoveCallbacks(FgThread.get().getLooper());
1772
1773        mOnPermissionChangeListeners = new OnPermissionChangeListeners(
1774                FgThread.get().getLooper());
1775
1776        getDefaultDisplayMetrics(context, mMetrics);
1777
1778        SystemConfig systemConfig = SystemConfig.getInstance();
1779        mGlobalGids = systemConfig.getGlobalGids();
1780        mSystemPermissions = systemConfig.getSystemPermissions();
1781        mAvailableFeatures = systemConfig.getAvailableFeatures();
1782
1783        synchronized (mInstallLock) {
1784        // writer
1785        synchronized (mPackages) {
1786            mHandlerThread = new ServiceThread(TAG,
1787                    Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
1788            mHandlerThread.start();
1789            mHandler = new PackageHandler(mHandlerThread.getLooper());
1790            Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT);
1791
1792            File dataDir = Environment.getDataDirectory();
1793            mAppDataDir = new File(dataDir, "data");
1794            mAppInstallDir = new File(dataDir, "app");
1795            mAppLib32InstallDir = new File(dataDir, "app-lib");
1796            mAsecInternalPath = new File(dataDir, "app-asec").getPath();
1797            mUserAppDataDir = new File(dataDir, "user");
1798            mDrmAppPrivateInstallDir = new File(dataDir, "app-private");
1799
1800            sUserManager = new UserManagerService(context, this,
1801                    mInstallLock, mPackages);
1802
1803            // Propagate permission configuration in to package manager.
1804            ArrayMap<String, SystemConfig.PermissionEntry> permConfig
1805                    = systemConfig.getPermissions();
1806            for (int i=0; i<permConfig.size(); i++) {
1807                SystemConfig.PermissionEntry perm = permConfig.valueAt(i);
1808                BasePermission bp = mSettings.mPermissions.get(perm.name);
1809                if (bp == null) {
1810                    bp = new BasePermission(perm.name, "android", BasePermission.TYPE_BUILTIN);
1811                    mSettings.mPermissions.put(perm.name, bp);
1812                }
1813                if (perm.gids != null) {
1814                    bp.setGids(perm.gids, perm.perUser);
1815                }
1816            }
1817
1818            ArrayMap<String, String> libConfig = systemConfig.getSharedLibraries();
1819            for (int i=0; i<libConfig.size(); i++) {
1820                mSharedLibraries.put(libConfig.keyAt(i),
1821                        new SharedLibraryEntry(libConfig.valueAt(i), null));
1822            }
1823
1824            mFoundPolicyFile = SELinuxMMAC.readInstallPolicy();
1825
1826            mRestoredSettings = mSettings.readLPw(this, sUserManager.getUsers(false),
1827                    mSdkVersion, mOnlyCore);
1828
1829            String customResolverActivity = Resources.getSystem().getString(
1830                    R.string.config_customResolverActivity);
1831            if (TextUtils.isEmpty(customResolverActivity)) {
1832                customResolverActivity = null;
1833            } else {
1834                mCustomResolverComponentName = ComponentName.unflattenFromString(
1835                        customResolverActivity);
1836            }
1837
1838            long startTime = SystemClock.uptimeMillis();
1839
1840            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START,
1841                    startTime);
1842
1843            // Set flag to monitor and not change apk file paths when
1844            // scanning install directories.
1845            final int scanFlags = SCAN_NO_PATHS | SCAN_DEFER_DEX | SCAN_BOOTING | SCAN_INITIAL;
1846
1847            final ArraySet<String> alreadyDexOpted = new ArraySet<String>();
1848
1849            /**
1850             * Add everything in the in the boot class path to the
1851             * list of process files because dexopt will have been run
1852             * if necessary during zygote startup.
1853             */
1854            final String bootClassPath = System.getenv("BOOTCLASSPATH");
1855            final String systemServerClassPath = System.getenv("SYSTEMSERVERCLASSPATH");
1856
1857            if (bootClassPath != null) {
1858                String[] bootClassPathElements = splitString(bootClassPath, ':');
1859                for (String element : bootClassPathElements) {
1860                    alreadyDexOpted.add(element);
1861                }
1862            } else {
1863                Slog.w(TAG, "No BOOTCLASSPATH found!");
1864            }
1865
1866            if (systemServerClassPath != null) {
1867                String[] systemServerClassPathElements = splitString(systemServerClassPath, ':');
1868                for (String element : systemServerClassPathElements) {
1869                    alreadyDexOpted.add(element);
1870                }
1871            } else {
1872                Slog.w(TAG, "No SYSTEMSERVERCLASSPATH found!");
1873            }
1874
1875            final List<String> allInstructionSets = InstructionSets.getAllInstructionSets();
1876            final String[] dexCodeInstructionSets =
1877                    getDexCodeInstructionSets(
1878                            allInstructionSets.toArray(new String[allInstructionSets.size()]));
1879
1880            /**
1881             * Ensure all external libraries have had dexopt run on them.
1882             */
1883            if (mSharedLibraries.size() > 0) {
1884                // NOTE: For now, we're compiling these system "shared libraries"
1885                // (and framework jars) into all available architectures. It's possible
1886                // to compile them only when we come across an app that uses them (there's
1887                // already logic for that in scanPackageLI) but that adds some complexity.
1888                for (String dexCodeInstructionSet : dexCodeInstructionSets) {
1889                    for (SharedLibraryEntry libEntry : mSharedLibraries.values()) {
1890                        final String lib = libEntry.path;
1891                        if (lib == null) {
1892                            continue;
1893                        }
1894
1895                        try {
1896                            int dexoptNeeded = DexFile.getDexOptNeeded(lib, null, dexCodeInstructionSet, false);
1897                            if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) {
1898                                alreadyDexOpted.add(lib);
1899                                mInstaller.dexopt(lib, Process.SYSTEM_UID, true, dexCodeInstructionSet, dexoptNeeded);
1900                            }
1901                        } catch (FileNotFoundException e) {
1902                            Slog.w(TAG, "Library not found: " + lib);
1903                        } catch (IOException e) {
1904                            Slog.w(TAG, "Cannot dexopt " + lib + "; is it an APK or JAR? "
1905                                    + e.getMessage());
1906                        }
1907                    }
1908                }
1909            }
1910
1911            File frameworkDir = new File(Environment.getRootDirectory(), "framework");
1912
1913            // Gross hack for now: we know this file doesn't contain any
1914            // code, so don't dexopt it to avoid the resulting log spew.
1915            alreadyDexOpted.add(frameworkDir.getPath() + "/framework-res.apk");
1916
1917            // Gross hack for now: we know this file is only part of
1918            // the boot class path for art, so don't dexopt it to
1919            // avoid the resulting log spew.
1920            alreadyDexOpted.add(frameworkDir.getPath() + "/core-libart.jar");
1921
1922            /**
1923             * There are a number of commands implemented in Java, which
1924             * we currently need to do the dexopt on so that they can be
1925             * run from a non-root shell.
1926             */
1927            String[] frameworkFiles = frameworkDir.list();
1928            if (frameworkFiles != null) {
1929                // TODO: We could compile these only for the most preferred ABI. We should
1930                // first double check that the dex files for these commands are not referenced
1931                // by other system apps.
1932                for (String dexCodeInstructionSet : dexCodeInstructionSets) {
1933                    for (int i=0; i<frameworkFiles.length; i++) {
1934                        File libPath = new File(frameworkDir, frameworkFiles[i]);
1935                        String path = libPath.getPath();
1936                        // Skip the file if we already did it.
1937                        if (alreadyDexOpted.contains(path)) {
1938                            continue;
1939                        }
1940                        // Skip the file if it is not a type we want to dexopt.
1941                        if (!path.endsWith(".apk") && !path.endsWith(".jar")) {
1942                            continue;
1943                        }
1944                        try {
1945                            int dexoptNeeded = DexFile.getDexOptNeeded(path, null, dexCodeInstructionSet, false);
1946                            if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) {
1947                                mInstaller.dexopt(path, Process.SYSTEM_UID, true, dexCodeInstructionSet, dexoptNeeded);
1948                            }
1949                        } catch (FileNotFoundException e) {
1950                            Slog.w(TAG, "Jar not found: " + path);
1951                        } catch (IOException e) {
1952                            Slog.w(TAG, "Exception reading jar: " + path, e);
1953                        }
1954                    }
1955                }
1956            }
1957
1958            // Collect vendor overlay packages.
1959            // (Do this before scanning any apps.)
1960            // For security and version matching reason, only consider
1961            // overlay packages if they reside in VENDOR_OVERLAY_DIR.
1962            File vendorOverlayDir = new File(VENDOR_OVERLAY_DIR);
1963            scanDirLI(vendorOverlayDir, PackageParser.PARSE_IS_SYSTEM
1964                    | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags | SCAN_TRUSTED_OVERLAY, 0);
1965
1966            // Find base frameworks (resource packages without code).
1967            scanDirLI(frameworkDir, PackageParser.PARSE_IS_SYSTEM
1968                    | PackageParser.PARSE_IS_SYSTEM_DIR
1969                    | PackageParser.PARSE_IS_PRIVILEGED,
1970                    scanFlags | SCAN_NO_DEX, 0);
1971
1972            // Collected privileged system packages.
1973            final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app");
1974            scanDirLI(privilegedAppDir, PackageParser.PARSE_IS_SYSTEM
1975                    | PackageParser.PARSE_IS_SYSTEM_DIR
1976                    | PackageParser.PARSE_IS_PRIVILEGED, scanFlags, 0);
1977
1978            // Collect ordinary system packages.
1979            final File systemAppDir = new File(Environment.getRootDirectory(), "app");
1980            scanDirLI(systemAppDir, PackageParser.PARSE_IS_SYSTEM
1981                    | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
1982
1983            // Collect all vendor packages.
1984            File vendorAppDir = new File("/vendor/app");
1985            try {
1986                vendorAppDir = vendorAppDir.getCanonicalFile();
1987            } catch (IOException e) {
1988                // failed to look up canonical path, continue with original one
1989            }
1990            scanDirLI(vendorAppDir, PackageParser.PARSE_IS_SYSTEM
1991                    | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
1992
1993            // Collect all OEM packages.
1994            final File oemAppDir = new File(Environment.getOemDirectory(), "app");
1995            scanDirLI(oemAppDir, PackageParser.PARSE_IS_SYSTEM
1996                    | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
1997
1998            if (DEBUG_UPGRADE) Log.v(TAG, "Running installd update commands");
1999            mInstaller.moveFiles();
2000
2001            // Prune any system packages that no longer exist.
2002            final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<String>();
2003            final ArrayMap<String, File> expectingBetter = new ArrayMap<>();
2004            if (!mOnlyCore) {
2005                Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
2006                while (psit.hasNext()) {
2007                    PackageSetting ps = psit.next();
2008
2009                    /*
2010                     * If this is not a system app, it can't be a
2011                     * disable system app.
2012                     */
2013                    if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
2014                        continue;
2015                    }
2016
2017                    /*
2018                     * If the package is scanned, it's not erased.
2019                     */
2020                    final PackageParser.Package scannedPkg = mPackages.get(ps.name);
2021                    if (scannedPkg != null) {
2022                        /*
2023                         * If the system app is both scanned and in the
2024                         * disabled packages list, then it must have been
2025                         * added via OTA. Remove it from the currently
2026                         * scanned package so the previously user-installed
2027                         * application can be scanned.
2028                         */
2029                        if (mSettings.isDisabledSystemPackageLPr(ps.name)) {
2030                            logCriticalInfo(Log.WARN, "Expecting better updated system app for "
2031                                    + ps.name + "; removing system app.  Last known codePath="
2032                                    + ps.codePathString + ", installStatus=" + ps.installStatus
2033                                    + ", versionCode=" + ps.versionCode + "; scanned versionCode="
2034                                    + scannedPkg.mVersionCode);
2035                            removePackageLI(ps, true);
2036                            expectingBetter.put(ps.name, ps.codePath);
2037                        }
2038
2039                        continue;
2040                    }
2041
2042                    if (!mSettings.isDisabledSystemPackageLPr(ps.name)) {
2043                        psit.remove();
2044                        logCriticalInfo(Log.WARN, "System package " + ps.name
2045                                + " no longer exists; wiping its data");
2046                        removeDataDirsLI(null, ps.name);
2047                    } else {
2048                        final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(ps.name);
2049                        if (disabledPs.codePath == null || !disabledPs.codePath.exists()) {
2050                            possiblyDeletedUpdatedSystemApps.add(ps.name);
2051                        }
2052                    }
2053                }
2054            }
2055
2056            //look for any incomplete package installations
2057            ArrayList<PackageSetting> deletePkgsList = mSettings.getListOfIncompleteInstallPackagesLPr();
2058            //clean up list
2059            for(int i = 0; i < deletePkgsList.size(); i++) {
2060                //clean up here
2061                cleanupInstallFailedPackage(deletePkgsList.get(i));
2062            }
2063            //delete tmp files
2064            deleteTempPackageFiles();
2065
2066            // Remove any shared userIDs that have no associated packages
2067            mSettings.pruneSharedUsersLPw();
2068
2069            if (!mOnlyCore) {
2070                EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,
2071                        SystemClock.uptimeMillis());
2072                scanDirLI(mAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0);
2073
2074                scanDirLI(mDrmAppPrivateInstallDir, PackageParser.PARSE_FORWARD_LOCK,
2075                        scanFlags | SCAN_REQUIRE_KNOWN, 0);
2076
2077                /**
2078                 * Remove disable package settings for any updated system
2079                 * apps that were removed via an OTA. If they're not a
2080                 * previously-updated app, remove them completely.
2081                 * Otherwise, just revoke their system-level permissions.
2082                 */
2083                for (String deletedAppName : possiblyDeletedUpdatedSystemApps) {
2084                    PackageParser.Package deletedPkg = mPackages.get(deletedAppName);
2085                    mSettings.removeDisabledSystemPackageLPw(deletedAppName);
2086
2087                    String msg;
2088                    if (deletedPkg == null) {
2089                        msg = "Updated system package " + deletedAppName
2090                                + " no longer exists; wiping its data";
2091                        removeDataDirsLI(null, deletedAppName);
2092                    } else {
2093                        msg = "Updated system app + " + deletedAppName
2094                                + " no longer present; removing system privileges for "
2095                                + deletedAppName;
2096
2097                        deletedPkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM;
2098
2099                        PackageSetting deletedPs = mSettings.mPackages.get(deletedAppName);
2100                        deletedPs.pkgFlags &= ~ApplicationInfo.FLAG_SYSTEM;
2101                    }
2102                    logCriticalInfo(Log.WARN, msg);
2103                }
2104
2105                /**
2106                 * Make sure all system apps that we expected to appear on
2107                 * the userdata partition actually showed up. If they never
2108                 * appeared, crawl back and revive the system version.
2109                 */
2110                for (int i = 0; i < expectingBetter.size(); i++) {
2111                    final String packageName = expectingBetter.keyAt(i);
2112                    if (!mPackages.containsKey(packageName)) {
2113                        final File scanFile = expectingBetter.valueAt(i);
2114
2115                        logCriticalInfo(Log.WARN, "Expected better " + packageName
2116                                + " but never showed up; reverting to system");
2117
2118                        final int reparseFlags;
2119                        if (FileUtils.contains(privilegedAppDir, scanFile)) {
2120                            reparseFlags = PackageParser.PARSE_IS_SYSTEM
2121                                    | PackageParser.PARSE_IS_SYSTEM_DIR
2122                                    | PackageParser.PARSE_IS_PRIVILEGED;
2123                        } else if (FileUtils.contains(systemAppDir, scanFile)) {
2124                            reparseFlags = PackageParser.PARSE_IS_SYSTEM
2125                                    | PackageParser.PARSE_IS_SYSTEM_DIR;
2126                        } else if (FileUtils.contains(vendorAppDir, scanFile)) {
2127                            reparseFlags = PackageParser.PARSE_IS_SYSTEM
2128                                    | PackageParser.PARSE_IS_SYSTEM_DIR;
2129                        } else if (FileUtils.contains(oemAppDir, scanFile)) {
2130                            reparseFlags = PackageParser.PARSE_IS_SYSTEM
2131                                    | PackageParser.PARSE_IS_SYSTEM_DIR;
2132                        } else {
2133                            Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile);
2134                            continue;
2135                        }
2136
2137                        mSettings.enableSystemPackageLPw(packageName);
2138
2139                        try {
2140                            scanPackageLI(scanFile, reparseFlags, scanFlags, 0, null);
2141                        } catch (PackageManagerException e) {
2142                            Slog.e(TAG, "Failed to parse original system package: "
2143                                    + e.getMessage());
2144                        }
2145                    }
2146                }
2147            }
2148
2149            // Now that we know all of the shared libraries, update all clients to have
2150            // the correct library paths.
2151            updateAllSharedLibrariesLPw();
2152
2153            for (SharedUserSetting setting : mSettings.getAllSharedUsersLPw()) {
2154                // NOTE: We ignore potential failures here during a system scan (like
2155                // the rest of the commands above) because there's precious little we
2156                // can do about it. A settings error is reported, though.
2157                adjustCpuAbisForSharedUserLPw(setting.packages, null /* scanned package */,
2158                        false /* force dexopt */, false /* defer dexopt */);
2159            }
2160
2161            // Now that we know all the packages we are keeping,
2162            // read and update their last usage times.
2163            mPackageUsage.readLP();
2164
2165            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END,
2166                    SystemClock.uptimeMillis());
2167            Slog.i(TAG, "Time to scan packages: "
2168                    + ((SystemClock.uptimeMillis()-startTime)/1000f)
2169                    + " seconds");
2170
2171            // If the platform SDK has changed since the last time we booted,
2172            // we need to re-grant app permission to catch any new ones that
2173            // appear.  This is really a hack, and means that apps can in some
2174            // cases get permissions that the user didn't initially explicitly
2175            // allow...  it would be nice to have some better way to handle
2176            // this situation.
2177            final boolean regrantPermissions = mSettings.mInternalSdkPlatform
2178                    != mSdkVersion;
2179            if (regrantPermissions) Slog.i(TAG, "Platform changed from "
2180                    + mSettings.mInternalSdkPlatform + " to " + mSdkVersion
2181                    + "; regranting permissions for internal storage");
2182            mSettings.mInternalSdkPlatform = mSdkVersion;
2183
2184            updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL
2185                    | (regrantPermissions
2186                            ? (UPDATE_PERMISSIONS_REPLACE_PKG|UPDATE_PERMISSIONS_REPLACE_ALL)
2187                            : 0));
2188
2189            // If this is the first boot, and it is a normal boot, then
2190            // we need to initialize the default preferred apps.
2191            if (!mRestoredSettings && !onlyCore) {
2192                mSettings.readDefaultPreferredAppsLPw(this, 0);
2193            }
2194
2195            // If this is first boot after an OTA, and a normal boot, then
2196            // we need to clear code cache directories.
2197            mIsUpgrade = !Build.FINGERPRINT.equals(mSettings.mFingerprint);
2198            if (mIsUpgrade && !onlyCore) {
2199                Slog.i(TAG, "Build fingerprint changed; clearing code caches");
2200                for (int i = 0; i < mSettings.mPackages.size(); i++) {
2201                    final PackageSetting ps = mSettings.mPackages.valueAt(i);
2202                    deleteCodeCacheDirsLI(ps.volumeUuid, ps.name);
2203                }
2204                mSettings.mFingerprint = Build.FINGERPRINT;
2205            }
2206
2207            primeDomainVerificationsLPw();
2208            checkDefaultBrowser();
2209
2210            // All the changes are done during package scanning.
2211            mSettings.updateInternalDatabaseVersion();
2212
2213            // can downgrade to reader
2214            mSettings.writeLPr();
2215
2216            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY,
2217                    SystemClock.uptimeMillis());
2218
2219            mRequiredVerifierPackage = getRequiredVerifierLPr();
2220
2221            mInstallerService = new PackageInstallerService(context, this);
2222
2223            mIntentFilterVerifierComponent = getIntentFilterVerifierComponentNameLPr();
2224            mIntentFilterVerifier = new IntentVerifierProxy(mContext,
2225                    mIntentFilterVerifierComponent);
2226
2227        } // synchronized (mPackages)
2228        } // synchronized (mInstallLock)
2229
2230        // Now after opening every single application zip, make sure they
2231        // are all flushed.  Not really needed, but keeps things nice and
2232        // tidy.
2233        Runtime.getRuntime().gc();
2234
2235        // Expose private service for system components to use.
2236        LocalServices.addService(PackageManagerInternal.class, new PackageManagerInternalImpl());
2237    }
2238
2239    @Override
2240    public boolean isFirstBoot() {
2241        return !mRestoredSettings;
2242    }
2243
2244    @Override
2245    public boolean isOnlyCoreApps() {
2246        return mOnlyCore;
2247    }
2248
2249    @Override
2250    public boolean isUpgrade() {
2251        return mIsUpgrade;
2252    }
2253
2254    private String getRequiredVerifierLPr() {
2255        final Intent verification = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
2256        final List<ResolveInfo> receivers = queryIntentReceivers(verification, PACKAGE_MIME_TYPE,
2257                PackageManager.GET_DISABLED_COMPONENTS, 0 /* TODO: Which userId? */);
2258
2259        String requiredVerifier = null;
2260
2261        final int N = receivers.size();
2262        for (int i = 0; i < N; i++) {
2263            final ResolveInfo info = receivers.get(i);
2264
2265            if (info.activityInfo == null) {
2266                continue;
2267            }
2268
2269            final String packageName = info.activityInfo.packageName;
2270
2271            if (checkPermission(android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
2272                    packageName, UserHandle.USER_OWNER) != PackageManager.PERMISSION_GRANTED) {
2273                continue;
2274            }
2275
2276            if (requiredVerifier != null) {
2277                throw new RuntimeException("There can be only one required verifier");
2278            }
2279
2280            requiredVerifier = packageName;
2281        }
2282
2283        return requiredVerifier;
2284    }
2285
2286    private ComponentName getIntentFilterVerifierComponentNameLPr() {
2287        final Intent verification = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION);
2288        final List<ResolveInfo> receivers = queryIntentReceivers(verification, PACKAGE_MIME_TYPE,
2289                PackageManager.GET_DISABLED_COMPONENTS, 0 /* userId */);
2290
2291        ComponentName verifierComponentName = null;
2292
2293        int priority = -1000;
2294        final int N = receivers.size();
2295        for (int i = 0; i < N; i++) {
2296            final ResolveInfo info = receivers.get(i);
2297
2298            if (info.activityInfo == null) {
2299                continue;
2300            }
2301
2302            final String packageName = info.activityInfo.packageName;
2303
2304            final PackageSetting ps = mSettings.mPackages.get(packageName);
2305            if (ps == null) {
2306                continue;
2307            }
2308
2309            if (checkPermission(android.Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT,
2310                    packageName, UserHandle.USER_OWNER) != PackageManager.PERMISSION_GRANTED) {
2311                continue;
2312            }
2313
2314            // Select the IntentFilterVerifier with the highest priority
2315            if (priority < info.priority) {
2316                priority = info.priority;
2317                verifierComponentName = new ComponentName(packageName, info.activityInfo.name);
2318                if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Selecting IntentFilterVerifier: "
2319                        + verifierComponentName + " with priority: " + info.priority);
2320            }
2321        }
2322
2323        return verifierComponentName;
2324    }
2325
2326    private void primeDomainVerificationsLPw() {
2327        if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Start priming domain verifications");
2328        boolean updated = false;
2329        ArraySet<String> allHostsSet = new ArraySet<>();
2330        for (PackageParser.Package pkg : mPackages.values()) {
2331            final String packageName = pkg.packageName;
2332            if (!hasDomainURLs(pkg)) {
2333                if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "No priming domain verifications for " +
2334                            "package with no domain URLs: " + packageName);
2335                continue;
2336            }
2337            if (!pkg.isSystemApp()) {
2338                if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
2339                        "No priming domain verifications for a non system package : " +
2340                                packageName);
2341                continue;
2342            }
2343            for (PackageParser.Activity a : pkg.activities) {
2344                for (ActivityIntentInfo filter : a.intents) {
2345                    if (hasValidDomains(filter)) {
2346                        allHostsSet.addAll(filter.getHostsList());
2347                    }
2348                }
2349            }
2350            if (allHostsSet.size() == 0) {
2351                allHostsSet.add("*");
2352            }
2353            ArrayList<String> allHostsList = new ArrayList<>(allHostsSet);
2354            IntentFilterVerificationInfo ivi =
2355                    mSettings.createIntentFilterVerificationIfNeededLPw(packageName, allHostsList);
2356            if (ivi != null) {
2357                if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
2358                        "Priming domain verifications for package: " + packageName +
2359                        " with hosts:" + ivi.getDomainsString());
2360                ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS);
2361                updated = true;
2362            }
2363            else {
2364                if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
2365                        "No priming domain verifications for package: " + packageName);
2366            }
2367            allHostsSet.clear();
2368        }
2369        if (updated) {
2370            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
2371                    "Will need to write primed domain verifications");
2372        }
2373        if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "End priming domain verifications");
2374    }
2375
2376    private void checkDefaultBrowser() {
2377        final int myUserId = UserHandle.myUserId();
2378        final String packageName = getDefaultBrowserPackageName(myUserId);
2379        PackageInfo info = getPackageInfo(packageName, 0, myUserId);
2380        if (info == null) {
2381            Slog.w(TAG, "Default browser no longer installed: " + packageName);
2382            setDefaultBrowserPackageName(null, myUserId);
2383        }
2384    }
2385
2386    @Override
2387    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2388            throws RemoteException {
2389        try {
2390            return super.onTransact(code, data, reply, flags);
2391        } catch (RuntimeException e) {
2392            if (!(e instanceof SecurityException) && !(e instanceof IllegalArgumentException)) {
2393                Slog.wtf(TAG, "Package Manager Crash", e);
2394            }
2395            throw e;
2396        }
2397    }
2398
2399    void cleanupInstallFailedPackage(PackageSetting ps) {
2400        logCriticalInfo(Log.WARN, "Cleaning up incompletely installed app: " + ps.name);
2401
2402        removeDataDirsLI(ps.volumeUuid, ps.name);
2403        if (ps.codePath != null) {
2404            if (ps.codePath.isDirectory()) {
2405                mInstaller.rmPackageDir(ps.codePath.getAbsolutePath());
2406            } else {
2407                ps.codePath.delete();
2408            }
2409        }
2410        if (ps.resourcePath != null && !ps.resourcePath.equals(ps.codePath)) {
2411            if (ps.resourcePath.isDirectory()) {
2412                FileUtils.deleteContents(ps.resourcePath);
2413            }
2414            ps.resourcePath.delete();
2415        }
2416        mSettings.removePackageLPw(ps.name);
2417    }
2418
2419    static int[] appendInts(int[] cur, int[] add) {
2420        if (add == null) return cur;
2421        if (cur == null) return add;
2422        final int N = add.length;
2423        for (int i=0; i<N; i++) {
2424            cur = appendInt(cur, add[i]);
2425        }
2426        return cur;
2427    }
2428
2429    PackageInfo generatePackageInfo(PackageParser.Package p, int flags, int userId) {
2430        if (!sUserManager.exists(userId)) return null;
2431        final PackageSetting ps = (PackageSetting) p.mExtras;
2432        if (ps == null) {
2433            return null;
2434        }
2435
2436        final PermissionsState permissionsState = ps.getPermissionsState();
2437
2438        final int[] gids = permissionsState.computeGids(userId);
2439        final Set<String> permissions = permissionsState.getPermissions(userId);
2440        final PackageUserState state = ps.readUserState(userId);
2441
2442        return PackageParser.generatePackageInfo(p, gids, flags,
2443                ps.firstInstallTime, ps.lastUpdateTime, permissions, state, userId);
2444    }
2445
2446    @Override
2447    public boolean isPackageFrozen(String packageName) {
2448        synchronized (mPackages) {
2449            final PackageSetting ps = mSettings.mPackages.get(packageName);
2450            if (ps != null) {
2451                return ps.frozen;
2452            }
2453        }
2454        Slog.w(TAG, "Package " + packageName + " is missing; assuming frozen");
2455        return true;
2456    }
2457
2458    @Override
2459    public boolean isPackageAvailable(String packageName, int userId) {
2460        if (!sUserManager.exists(userId)) return false;
2461        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "is package available");
2462        synchronized (mPackages) {
2463            PackageParser.Package p = mPackages.get(packageName);
2464            if (p != null) {
2465                final PackageSetting ps = (PackageSetting) p.mExtras;
2466                if (ps != null) {
2467                    final PackageUserState state = ps.readUserState(userId);
2468                    if (state != null) {
2469                        return PackageParser.isAvailable(state);
2470                    }
2471                }
2472            }
2473        }
2474        return false;
2475    }
2476
2477    @Override
2478    public PackageInfo getPackageInfo(String packageName, int flags, int userId) {
2479        if (!sUserManager.exists(userId)) return null;
2480        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get package info");
2481        // reader
2482        synchronized (mPackages) {
2483            PackageParser.Package p = mPackages.get(packageName);
2484            if (DEBUG_PACKAGE_INFO)
2485                Log.v(TAG, "getPackageInfo " + packageName + ": " + p);
2486            if (p != null) {
2487                return generatePackageInfo(p, flags, userId);
2488            }
2489            if((flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0) {
2490                return generatePackageInfoFromSettingsLPw(packageName, flags, userId);
2491            }
2492        }
2493        return null;
2494    }
2495
2496    @Override
2497    public String[] currentToCanonicalPackageNames(String[] names) {
2498        String[] out = new String[names.length];
2499        // reader
2500        synchronized (mPackages) {
2501            for (int i=names.length-1; i>=0; i--) {
2502                PackageSetting ps = mSettings.mPackages.get(names[i]);
2503                out[i] = ps != null && ps.realName != null ? ps.realName : names[i];
2504            }
2505        }
2506        return out;
2507    }
2508
2509    @Override
2510    public String[] canonicalToCurrentPackageNames(String[] names) {
2511        String[] out = new String[names.length];
2512        // reader
2513        synchronized (mPackages) {
2514            for (int i=names.length-1; i>=0; i--) {
2515                String cur = mSettings.mRenamedPackages.get(names[i]);
2516                out[i] = cur != null ? cur : names[i];
2517            }
2518        }
2519        return out;
2520    }
2521
2522    @Override
2523    public int getPackageUid(String packageName, int userId) {
2524        if (!sUserManager.exists(userId)) return -1;
2525        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get package uid");
2526
2527        // reader
2528        synchronized (mPackages) {
2529            PackageParser.Package p = mPackages.get(packageName);
2530            if(p != null) {
2531                return UserHandle.getUid(userId, p.applicationInfo.uid);
2532            }
2533            PackageSetting ps = mSettings.mPackages.get(packageName);
2534            if((ps == null) || (ps.pkg == null) || (ps.pkg.applicationInfo == null)) {
2535                return -1;
2536            }
2537            p = ps.pkg;
2538            return p != null ? UserHandle.getUid(userId, p.applicationInfo.uid) : -1;
2539        }
2540    }
2541
2542    @Override
2543    public int[] getPackageGids(String packageName, int userId) throws RemoteException {
2544        if (!sUserManager.exists(userId)) {
2545            return null;
2546        }
2547
2548        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false,
2549                "getPackageGids");
2550
2551        // reader
2552        synchronized (mPackages) {
2553            PackageParser.Package p = mPackages.get(packageName);
2554            if (DEBUG_PACKAGE_INFO) {
2555                Log.v(TAG, "getPackageGids" + packageName + ": " + p);
2556            }
2557            if (p != null) {
2558                PackageSetting ps = (PackageSetting) p.mExtras;
2559                return ps.getPermissionsState().computeGids(userId);
2560            }
2561        }
2562
2563        return null;
2564    }
2565
2566    @Override
2567    public int getMountExternalMode(int uid) {
2568        if (Process.isIsolated(uid)) {
2569            return Zygote.MOUNT_EXTERNAL_NONE;
2570        } else {
2571            if (checkUidPermission(WRITE_EXTERNAL_STORAGE, uid) == PERMISSION_GRANTED) {
2572                return Zygote.MOUNT_EXTERNAL_WRITE;
2573            } else if (checkUidPermission(READ_EXTERNAL_STORAGE, uid) == PERMISSION_GRANTED) {
2574                return Zygote.MOUNT_EXTERNAL_READ;
2575            } else {
2576                return Zygote.MOUNT_EXTERNAL_DEFAULT;
2577            }
2578        }
2579    }
2580
2581    static PermissionInfo generatePermissionInfo(
2582            BasePermission bp, int flags) {
2583        if (bp.perm != null) {
2584            return PackageParser.generatePermissionInfo(bp.perm, flags);
2585        }
2586        PermissionInfo pi = new PermissionInfo();
2587        pi.name = bp.name;
2588        pi.packageName = bp.sourcePackage;
2589        pi.nonLocalizedLabel = bp.name;
2590        pi.protectionLevel = bp.protectionLevel;
2591        return pi;
2592    }
2593
2594    @Override
2595    public PermissionInfo getPermissionInfo(String name, int flags) {
2596        // reader
2597        synchronized (mPackages) {
2598            final BasePermission p = mSettings.mPermissions.get(name);
2599            if (p != null) {
2600                return generatePermissionInfo(p, flags);
2601            }
2602            return null;
2603        }
2604    }
2605
2606    @Override
2607    public List<PermissionInfo> queryPermissionsByGroup(String group, int flags) {
2608        // reader
2609        synchronized (mPackages) {
2610            ArrayList<PermissionInfo> out = new ArrayList<PermissionInfo>(10);
2611            for (BasePermission p : mSettings.mPermissions.values()) {
2612                if (group == null) {
2613                    if (p.perm == null || p.perm.info.group == null) {
2614                        out.add(generatePermissionInfo(p, flags));
2615                    }
2616                } else {
2617                    if (p.perm != null && group.equals(p.perm.info.group)) {
2618                        out.add(PackageParser.generatePermissionInfo(p.perm, flags));
2619                    }
2620                }
2621            }
2622
2623            if (out.size() > 0) {
2624                return out;
2625            }
2626            return mPermissionGroups.containsKey(group) ? out : null;
2627        }
2628    }
2629
2630    @Override
2631    public PermissionGroupInfo getPermissionGroupInfo(String name, int flags) {
2632        // reader
2633        synchronized (mPackages) {
2634            return PackageParser.generatePermissionGroupInfo(
2635                    mPermissionGroups.get(name), flags);
2636        }
2637    }
2638
2639    @Override
2640    public List<PermissionGroupInfo> getAllPermissionGroups(int flags) {
2641        // reader
2642        synchronized (mPackages) {
2643            final int N = mPermissionGroups.size();
2644            ArrayList<PermissionGroupInfo> out
2645                    = new ArrayList<PermissionGroupInfo>(N);
2646            for (PackageParser.PermissionGroup pg : mPermissionGroups.values()) {
2647                out.add(PackageParser.generatePermissionGroupInfo(pg, flags));
2648            }
2649            return out;
2650        }
2651    }
2652
2653    private ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName, int flags,
2654            int userId) {
2655        if (!sUserManager.exists(userId)) return null;
2656        PackageSetting ps = mSettings.mPackages.get(packageName);
2657        if (ps != null) {
2658            if (ps.pkg == null) {
2659                PackageInfo pInfo = generatePackageInfoFromSettingsLPw(packageName,
2660                        flags, userId);
2661                if (pInfo != null) {
2662                    return pInfo.applicationInfo;
2663                }
2664                return null;
2665            }
2666            return PackageParser.generateApplicationInfo(ps.pkg, flags,
2667                    ps.readUserState(userId), userId);
2668        }
2669        return null;
2670    }
2671
2672    private PackageInfo generatePackageInfoFromSettingsLPw(String packageName, int flags,
2673            int userId) {
2674        if (!sUserManager.exists(userId)) return null;
2675        PackageSetting ps = mSettings.mPackages.get(packageName);
2676        if (ps != null) {
2677            PackageParser.Package pkg = ps.pkg;
2678            if (pkg == null) {
2679                if ((flags & PackageManager.GET_UNINSTALLED_PACKAGES) == 0) {
2680                    return null;
2681                }
2682                // Only data remains, so we aren't worried about code paths
2683                pkg = new PackageParser.Package(packageName);
2684                pkg.applicationInfo.packageName = packageName;
2685                pkg.applicationInfo.flags = ps.pkgFlags | ApplicationInfo.FLAG_IS_DATA_ONLY;
2686                pkg.applicationInfo.privateFlags = ps.pkgPrivateFlags;
2687                pkg.applicationInfo.dataDir = PackageManager.getDataDirForUser(ps.volumeUuid,
2688                        packageName, userId).getAbsolutePath();
2689                pkg.applicationInfo.primaryCpuAbi = ps.primaryCpuAbiString;
2690                pkg.applicationInfo.secondaryCpuAbi = ps.secondaryCpuAbiString;
2691            }
2692            return generatePackageInfo(pkg, flags, userId);
2693        }
2694        return null;
2695    }
2696
2697    @Override
2698    public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) {
2699        if (!sUserManager.exists(userId)) return null;
2700        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get application info");
2701        // writer
2702        synchronized (mPackages) {
2703            PackageParser.Package p = mPackages.get(packageName);
2704            if (DEBUG_PACKAGE_INFO) Log.v(
2705                    TAG, "getApplicationInfo " + packageName
2706                    + ": " + p);
2707            if (p != null) {
2708                PackageSetting ps = mSettings.mPackages.get(packageName);
2709                if (ps == null) return null;
2710                // Note: isEnabledLP() does not apply here - always return info
2711                return PackageParser.generateApplicationInfo(
2712                        p, flags, ps.readUserState(userId), userId);
2713            }
2714            if ("android".equals(packageName)||"system".equals(packageName)) {
2715                return mAndroidApplication;
2716            }
2717            if ((flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0) {
2718                return generateApplicationInfoFromSettingsLPw(packageName, flags, userId);
2719            }
2720        }
2721        return null;
2722    }
2723
2724    @Override
2725    public void freeStorageAndNotify(final String volumeUuid, final long freeStorageSize,
2726            final IPackageDataObserver observer) {
2727        mContext.enforceCallingOrSelfPermission(
2728                android.Manifest.permission.CLEAR_APP_CACHE, null);
2729        // Queue up an async operation since clearing cache may take a little while.
2730        mHandler.post(new Runnable() {
2731            public void run() {
2732                mHandler.removeCallbacks(this);
2733                int retCode = -1;
2734                synchronized (mInstallLock) {
2735                    retCode = mInstaller.freeCache(volumeUuid, freeStorageSize);
2736                    if (retCode < 0) {
2737                        Slog.w(TAG, "Couldn't clear application caches");
2738                    }
2739                }
2740                if (observer != null) {
2741                    try {
2742                        observer.onRemoveCompleted(null, (retCode >= 0));
2743                    } catch (RemoteException e) {
2744                        Slog.w(TAG, "RemoveException when invoking call back");
2745                    }
2746                }
2747            }
2748        });
2749    }
2750
2751    @Override
2752    public void freeStorage(final String volumeUuid, final long freeStorageSize,
2753            final IntentSender pi) {
2754        mContext.enforceCallingOrSelfPermission(
2755                android.Manifest.permission.CLEAR_APP_CACHE, null);
2756        // Queue up an async operation since clearing cache may take a little while.
2757        mHandler.post(new Runnable() {
2758            public void run() {
2759                mHandler.removeCallbacks(this);
2760                int retCode = -1;
2761                synchronized (mInstallLock) {
2762                    retCode = mInstaller.freeCache(volumeUuid, freeStorageSize);
2763                    if (retCode < 0) {
2764                        Slog.w(TAG, "Couldn't clear application caches");
2765                    }
2766                }
2767                if(pi != null) {
2768                    try {
2769                        // Callback via pending intent
2770                        int code = (retCode >= 0) ? 1 : 0;
2771                        pi.sendIntent(null, code, null,
2772                                null, null);
2773                    } catch (SendIntentException e1) {
2774                        Slog.i(TAG, "Failed to send pending intent");
2775                    }
2776                }
2777            }
2778        });
2779    }
2780
2781    void freeStorage(String volumeUuid, long freeStorageSize) throws IOException {
2782        synchronized (mInstallLock) {
2783            if (mInstaller.freeCache(volumeUuid, freeStorageSize) < 0) {
2784                throw new IOException("Failed to free enough space");
2785            }
2786        }
2787    }
2788
2789    @Override
2790    public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) {
2791        if (!sUserManager.exists(userId)) return null;
2792        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get activity info");
2793        synchronized (mPackages) {
2794            PackageParser.Activity a = mActivities.mActivities.get(component);
2795
2796            if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a);
2797            if (a != null && mSettings.isEnabledLPr(a.info, flags, userId)) {
2798                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
2799                if (ps == null) return null;
2800                return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId),
2801                        userId);
2802            }
2803            if (mResolveComponentName.equals(component)) {
2804                return PackageParser.generateActivityInfo(mResolveActivity, flags,
2805                        new PackageUserState(), userId);
2806            }
2807        }
2808        return null;
2809    }
2810
2811    @Override
2812    public boolean activitySupportsIntent(ComponentName component, Intent intent,
2813            String resolvedType) {
2814        synchronized (mPackages) {
2815            PackageParser.Activity a = mActivities.mActivities.get(component);
2816            if (a == null) {
2817                return false;
2818            }
2819            for (int i=0; i<a.intents.size(); i++) {
2820                if (a.intents.get(i).match(intent.getAction(), resolvedType, intent.getScheme(),
2821                        intent.getData(), intent.getCategories(), TAG) >= 0) {
2822                    return true;
2823                }
2824            }
2825            return false;
2826        }
2827    }
2828
2829    @Override
2830    public ActivityInfo getReceiverInfo(ComponentName component, int flags, int userId) {
2831        if (!sUserManager.exists(userId)) return null;
2832        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get receiver info");
2833        synchronized (mPackages) {
2834            PackageParser.Activity a = mReceivers.mActivities.get(component);
2835            if (DEBUG_PACKAGE_INFO) Log.v(
2836                TAG, "getReceiverInfo " + component + ": " + a);
2837            if (a != null && mSettings.isEnabledLPr(a.info, flags, userId)) {
2838                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
2839                if (ps == null) return null;
2840                return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId),
2841                        userId);
2842            }
2843        }
2844        return null;
2845    }
2846
2847    @Override
2848    public ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) {
2849        if (!sUserManager.exists(userId)) return null;
2850        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get service info");
2851        synchronized (mPackages) {
2852            PackageParser.Service s = mServices.mServices.get(component);
2853            if (DEBUG_PACKAGE_INFO) Log.v(
2854                TAG, "getServiceInfo " + component + ": " + s);
2855            if (s != null && mSettings.isEnabledLPr(s.info, flags, userId)) {
2856                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
2857                if (ps == null) return null;
2858                return PackageParser.generateServiceInfo(s, flags, ps.readUserState(userId),
2859                        userId);
2860            }
2861        }
2862        return null;
2863    }
2864
2865    @Override
2866    public ProviderInfo getProviderInfo(ComponentName component, int flags, int userId) {
2867        if (!sUserManager.exists(userId)) return null;
2868        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get provider info");
2869        synchronized (mPackages) {
2870            PackageParser.Provider p = mProviders.mProviders.get(component);
2871            if (DEBUG_PACKAGE_INFO) Log.v(
2872                TAG, "getProviderInfo " + component + ": " + p);
2873            if (p != null && mSettings.isEnabledLPr(p.info, flags, userId)) {
2874                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
2875                if (ps == null) return null;
2876                return PackageParser.generateProviderInfo(p, flags, ps.readUserState(userId),
2877                        userId);
2878            }
2879        }
2880        return null;
2881    }
2882
2883    @Override
2884    public String[] getSystemSharedLibraryNames() {
2885        Set<String> libSet;
2886        synchronized (mPackages) {
2887            libSet = mSharedLibraries.keySet();
2888            int size = libSet.size();
2889            if (size > 0) {
2890                String[] libs = new String[size];
2891                libSet.toArray(libs);
2892                return libs;
2893            }
2894        }
2895        return null;
2896    }
2897
2898    /**
2899     * @hide
2900     */
2901    PackageParser.Package findSharedNonSystemLibrary(String libName) {
2902        synchronized (mPackages) {
2903            PackageManagerService.SharedLibraryEntry lib = mSharedLibraries.get(libName);
2904            if (lib != null && lib.apk != null) {
2905                return mPackages.get(lib.apk);
2906            }
2907        }
2908        return null;
2909    }
2910
2911    @Override
2912    public FeatureInfo[] getSystemAvailableFeatures() {
2913        Collection<FeatureInfo> featSet;
2914        synchronized (mPackages) {
2915            featSet = mAvailableFeatures.values();
2916            int size = featSet.size();
2917            if (size > 0) {
2918                FeatureInfo[] features = new FeatureInfo[size+1];
2919                featSet.toArray(features);
2920                FeatureInfo fi = new FeatureInfo();
2921                fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version",
2922                        FeatureInfo.GL_ES_VERSION_UNDEFINED);
2923                features[size] = fi;
2924                return features;
2925            }
2926        }
2927        return null;
2928    }
2929
2930    @Override
2931    public boolean hasSystemFeature(String name) {
2932        synchronized (mPackages) {
2933            return mAvailableFeatures.containsKey(name);
2934        }
2935    }
2936
2937    private void checkValidCaller(int uid, int userId) {
2938        if (UserHandle.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0)
2939            return;
2940
2941        throw new SecurityException("Caller uid=" + uid
2942                + " is not privileged to communicate with user=" + userId);
2943    }
2944
2945    @Override
2946    public int checkPermission(String permName, String pkgName, int userId) {
2947        if (!sUserManager.exists(userId)) {
2948            return PackageManager.PERMISSION_DENIED;
2949        }
2950
2951        synchronized (mPackages) {
2952            final PackageParser.Package p = mPackages.get(pkgName);
2953            if (p != null && p.mExtras != null) {
2954                final PackageSetting ps = (PackageSetting) p.mExtras;
2955                if (ps.getPermissionsState().hasPermission(permName, userId)) {
2956                    return PackageManager.PERMISSION_GRANTED;
2957                }
2958            }
2959        }
2960
2961        return PackageManager.PERMISSION_DENIED;
2962    }
2963
2964    @Override
2965    public int checkUidPermission(String permName, int uid) {
2966        final int userId = UserHandle.getUserId(uid);
2967
2968        if (!sUserManager.exists(userId)) {
2969            return PackageManager.PERMISSION_DENIED;
2970        }
2971
2972        synchronized (mPackages) {
2973            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
2974            if (obj != null) {
2975                final SettingBase ps = (SettingBase) obj;
2976                if (ps.getPermissionsState().hasPermission(permName, userId)) {
2977                    return PackageManager.PERMISSION_GRANTED;
2978                }
2979            } else {
2980                ArraySet<String> perms = mSystemPermissions.get(uid);
2981                if (perms != null && perms.contains(permName)) {
2982                    return PackageManager.PERMISSION_GRANTED;
2983                }
2984            }
2985        }
2986
2987        return PackageManager.PERMISSION_DENIED;
2988    }
2989
2990    /**
2991     * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS
2992     * or INTERACT_ACROSS_USERS_FULL permissions, if the userid is not for the caller.
2993     * @param checkShell TODO(yamasani):
2994     * @param message the message to log on security exception
2995     */
2996    void enforceCrossUserPermission(int callingUid, int userId, boolean requireFullPermission,
2997            boolean checkShell, String message) {
2998        if (userId < 0) {
2999            throw new IllegalArgumentException("Invalid userId " + userId);
3000        }
3001        if (checkShell) {
3002            enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId);
3003        }
3004        if (userId == UserHandle.getUserId(callingUid)) return;
3005        if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
3006            if (requireFullPermission) {
3007                mContext.enforceCallingOrSelfPermission(
3008                        android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
3009            } else {
3010                try {
3011                    mContext.enforceCallingOrSelfPermission(
3012                            android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
3013                } catch (SecurityException se) {
3014                    mContext.enforceCallingOrSelfPermission(
3015                            android.Manifest.permission.INTERACT_ACROSS_USERS, message);
3016                }
3017            }
3018        }
3019    }
3020
3021    void enforceShellRestriction(String restriction, int callingUid, int userHandle) {
3022        if (callingUid == Process.SHELL_UID) {
3023            if (userHandle >= 0
3024                    && sUserManager.hasUserRestriction(restriction, userHandle)) {
3025                throw new SecurityException("Shell does not have permission to access user "
3026                        + userHandle);
3027            } else if (userHandle < 0) {
3028                Slog.e(TAG, "Unable to check shell permission for user " + userHandle + "\n\t"
3029                        + Debug.getCallers(3));
3030            }
3031        }
3032    }
3033
3034    private BasePermission findPermissionTreeLP(String permName) {
3035        for(BasePermission bp : mSettings.mPermissionTrees.values()) {
3036            if (permName.startsWith(bp.name) &&
3037                    permName.length() > bp.name.length() &&
3038                    permName.charAt(bp.name.length()) == '.') {
3039                return bp;
3040            }
3041        }
3042        return null;
3043    }
3044
3045    private BasePermission checkPermissionTreeLP(String permName) {
3046        if (permName != null) {
3047            BasePermission bp = findPermissionTreeLP(permName);
3048            if (bp != null) {
3049                if (bp.uid == UserHandle.getAppId(Binder.getCallingUid())) {
3050                    return bp;
3051                }
3052                throw new SecurityException("Calling uid "
3053                        + Binder.getCallingUid()
3054                        + " is not allowed to add to permission tree "
3055                        + bp.name + " owned by uid " + bp.uid);
3056            }
3057        }
3058        throw new SecurityException("No permission tree found for " + permName);
3059    }
3060
3061    static boolean compareStrings(CharSequence s1, CharSequence s2) {
3062        if (s1 == null) {
3063            return s2 == null;
3064        }
3065        if (s2 == null) {
3066            return false;
3067        }
3068        if (s1.getClass() != s2.getClass()) {
3069            return false;
3070        }
3071        return s1.equals(s2);
3072    }
3073
3074    static boolean comparePermissionInfos(PermissionInfo pi1, PermissionInfo pi2) {
3075        if (pi1.icon != pi2.icon) return false;
3076        if (pi1.logo != pi2.logo) return false;
3077        if (pi1.protectionLevel != pi2.protectionLevel) return false;
3078        if (!compareStrings(pi1.name, pi2.name)) return false;
3079        if (!compareStrings(pi1.nonLocalizedLabel, pi2.nonLocalizedLabel)) return false;
3080        // We'll take care of setting this one.
3081        if (!compareStrings(pi1.packageName, pi2.packageName)) return false;
3082        // These are not currently stored in settings.
3083        //if (!compareStrings(pi1.group, pi2.group)) return false;
3084        //if (!compareStrings(pi1.nonLocalizedDescription, pi2.nonLocalizedDescription)) return false;
3085        //if (pi1.labelRes != pi2.labelRes) return false;
3086        //if (pi1.descriptionRes != pi2.descriptionRes) return false;
3087        return true;
3088    }
3089
3090    int permissionInfoFootprint(PermissionInfo info) {
3091        int size = info.name.length();
3092        if (info.nonLocalizedLabel != null) size += info.nonLocalizedLabel.length();
3093        if (info.nonLocalizedDescription != null) size += info.nonLocalizedDescription.length();
3094        return size;
3095    }
3096
3097    int calculateCurrentPermissionFootprintLocked(BasePermission tree) {
3098        int size = 0;
3099        for (BasePermission perm : mSettings.mPermissions.values()) {
3100            if (perm.uid == tree.uid) {
3101                size += perm.name.length() + permissionInfoFootprint(perm.perm.info);
3102            }
3103        }
3104        return size;
3105    }
3106
3107    void enforcePermissionCapLocked(PermissionInfo info, BasePermission tree) {
3108        // We calculate the max size of permissions defined by this uid and throw
3109        // if that plus the size of 'info' would exceed our stated maximum.
3110        if (tree.uid != Process.SYSTEM_UID) {
3111            final int curTreeSize = calculateCurrentPermissionFootprintLocked(tree);
3112            if (curTreeSize + permissionInfoFootprint(info) > MAX_PERMISSION_TREE_FOOTPRINT) {
3113                throw new SecurityException("Permission tree size cap exceeded");
3114            }
3115        }
3116    }
3117
3118    boolean addPermissionLocked(PermissionInfo info, boolean async) {
3119        if (info.labelRes == 0 && info.nonLocalizedLabel == null) {
3120            throw new SecurityException("Label must be specified in permission");
3121        }
3122        BasePermission tree = checkPermissionTreeLP(info.name);
3123        BasePermission bp = mSettings.mPermissions.get(info.name);
3124        boolean added = bp == null;
3125        boolean changed = true;
3126        int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel);
3127        if (added) {
3128            enforcePermissionCapLocked(info, tree);
3129            bp = new BasePermission(info.name, tree.sourcePackage,
3130                    BasePermission.TYPE_DYNAMIC);
3131        } else if (bp.type != BasePermission.TYPE_DYNAMIC) {
3132            throw new SecurityException(
3133                    "Not allowed to modify non-dynamic permission "
3134                    + info.name);
3135        } else {
3136            if (bp.protectionLevel == fixedLevel
3137                    && bp.perm.owner.equals(tree.perm.owner)
3138                    && bp.uid == tree.uid
3139                    && comparePermissionInfos(bp.perm.info, info)) {
3140                changed = false;
3141            }
3142        }
3143        bp.protectionLevel = fixedLevel;
3144        info = new PermissionInfo(info);
3145        info.protectionLevel = fixedLevel;
3146        bp.perm = new PackageParser.Permission(tree.perm.owner, info);
3147        bp.perm.info.packageName = tree.perm.info.packageName;
3148        bp.uid = tree.uid;
3149        if (added) {
3150            mSettings.mPermissions.put(info.name, bp);
3151        }
3152        if (changed) {
3153            if (!async) {
3154                mSettings.writeLPr();
3155            } else {
3156                scheduleWriteSettingsLocked();
3157            }
3158        }
3159        return added;
3160    }
3161
3162    @Override
3163    public boolean addPermission(PermissionInfo info) {
3164        synchronized (mPackages) {
3165            return addPermissionLocked(info, false);
3166        }
3167    }
3168
3169    @Override
3170    public boolean addPermissionAsync(PermissionInfo info) {
3171        synchronized (mPackages) {
3172            return addPermissionLocked(info, true);
3173        }
3174    }
3175
3176    @Override
3177    public void removePermission(String name) {
3178        synchronized (mPackages) {
3179            checkPermissionTreeLP(name);
3180            BasePermission bp = mSettings.mPermissions.get(name);
3181            if (bp != null) {
3182                if (bp.type != BasePermission.TYPE_DYNAMIC) {
3183                    throw new SecurityException(
3184                            "Not allowed to modify non-dynamic permission "
3185                            + name);
3186                }
3187                mSettings.mPermissions.remove(name);
3188                mSettings.writeLPr();
3189            }
3190        }
3191    }
3192
3193    private static void enforceDeclaredAsUsedAndRuntimePermission(PackageParser.Package pkg,
3194            BasePermission bp) {
3195        int index = pkg.requestedPermissions.indexOf(bp.name);
3196        if (index == -1) {
3197            throw new SecurityException("Package " + pkg.packageName
3198                    + " has not requested permission " + bp.name);
3199        }
3200        if (!bp.isRuntime()) {
3201            throw new SecurityException("Permission " + bp.name
3202                    + " is not a changeable permission type");
3203        }
3204    }
3205
3206    @Override
3207    public void grantRuntimePermission(String packageName, String name, final int userId) {
3208        if (!sUserManager.exists(userId)) {
3209            Log.e(TAG, "No such user:" + userId);
3210            return;
3211        }
3212
3213        mContext.enforceCallingOrSelfPermission(
3214                android.Manifest.permission.GRANT_REVOKE_PERMISSIONS,
3215                "grantRuntimePermission");
3216
3217        enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false,
3218                "grantRuntimePermission");
3219
3220        final int uid;
3221        final SettingBase sb;
3222
3223        synchronized (mPackages) {
3224            final PackageParser.Package pkg = mPackages.get(packageName);
3225            if (pkg == null) {
3226                throw new IllegalArgumentException("Unknown package: " + packageName);
3227            }
3228
3229            final BasePermission bp = mSettings.mPermissions.get(name);
3230            if (bp == null) {
3231                throw new IllegalArgumentException("Unknown permission: " + name);
3232            }
3233
3234            enforceDeclaredAsUsedAndRuntimePermission(pkg, bp);
3235
3236            uid = pkg.applicationInfo.uid;
3237            sb = (SettingBase) pkg.mExtras;
3238            if (sb == null) {
3239                throw new IllegalArgumentException("Unknown package: " + packageName);
3240            }
3241
3242            final PermissionsState permissionsState = sb.getPermissionsState();
3243
3244            final int flags = permissionsState.getPermissionFlags(name, userId);
3245            if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
3246                throw new SecurityException("Cannot grant system fixed permission: "
3247                        + name + " for package: " + packageName);
3248            }
3249
3250            final int result = permissionsState.grantRuntimePermission(bp, userId);
3251            switch (result) {
3252                case PermissionsState.PERMISSION_OPERATION_FAILURE: {
3253                    return;
3254                }
3255
3256                case PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
3257                    mHandler.post(new Runnable() {
3258                        @Override
3259                        public void run() {
3260                            killSettingPackagesForUser(sb, userId, KILL_APP_REASON_GIDS_CHANGED);
3261                        }
3262                    });
3263                } break;
3264            }
3265
3266            mOnPermissionChangeListeners.onPermissionsChanged(uid);
3267
3268            // Not critical if that is lost - app has to request again.
3269            mSettings.writeRuntimePermissionsForUserLPr(userId, false);
3270        }
3271
3272        if (READ_EXTERNAL_STORAGE.equals(name)
3273                || WRITE_EXTERNAL_STORAGE.equals(name)) {
3274            final long token = Binder.clearCallingIdentity();
3275            try {
3276                final StorageManager storage = mContext.getSystemService(StorageManager.class);
3277                storage.remountUid(uid);
3278            } finally {
3279                Binder.restoreCallingIdentity(token);
3280            }
3281        }
3282    }
3283
3284    @Override
3285    public void revokeRuntimePermission(String packageName, String name, int userId) {
3286        if (!sUserManager.exists(userId)) {
3287            Log.e(TAG, "No such user:" + userId);
3288            return;
3289        }
3290
3291        mContext.enforceCallingOrSelfPermission(
3292                android.Manifest.permission.GRANT_REVOKE_PERMISSIONS,
3293                "revokeRuntimePermission");
3294
3295        enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false,
3296                "revokeRuntimePermission");
3297
3298        final SettingBase sb;
3299
3300        synchronized (mPackages) {
3301            final PackageParser.Package pkg = mPackages.get(packageName);
3302            if (pkg == null) {
3303                throw new IllegalArgumentException("Unknown package: " + packageName);
3304            }
3305
3306            final BasePermission bp = mSettings.mPermissions.get(name);
3307            if (bp == null) {
3308                throw new IllegalArgumentException("Unknown permission: " + name);
3309            }
3310
3311            enforceDeclaredAsUsedAndRuntimePermission(pkg, bp);
3312
3313            sb = (SettingBase) pkg.mExtras;
3314            if (sb == null) {
3315                throw new IllegalArgumentException("Unknown package: " + packageName);
3316            }
3317
3318            final PermissionsState permissionsState = sb.getPermissionsState();
3319
3320            final int flags = permissionsState.getPermissionFlags(name, userId);
3321            if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
3322                throw new SecurityException("Cannot revoke system fixed permission: "
3323                        + name + " for package: " + packageName);
3324            }
3325
3326            if (permissionsState.revokeRuntimePermission(bp, userId) ==
3327                    PermissionsState.PERMISSION_OPERATION_FAILURE) {
3328                return;
3329            }
3330
3331            mOnPermissionChangeListeners.onPermissionsChanged(pkg.applicationInfo.uid);
3332
3333            // Critical, after this call app should never have the permission.
3334            mSettings.writeRuntimePermissionsForUserLPr(userId, true);
3335        }
3336
3337        killSettingPackagesForUser(sb, userId, KILL_APP_REASON_PERMISSIONS_REVOKED);
3338    }
3339
3340    @Override
3341    public int getPermissionFlags(String name, String packageName, int userId) {
3342        if (!sUserManager.exists(userId)) {
3343            return 0;
3344        }
3345
3346        mContext.enforceCallingOrSelfPermission(
3347                android.Manifest.permission.GRANT_REVOKE_PERMISSIONS,
3348                "getPermissionFlags");
3349
3350        enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false,
3351                "getPermissionFlags");
3352
3353        synchronized (mPackages) {
3354            final PackageParser.Package pkg = mPackages.get(packageName);
3355            if (pkg == null) {
3356                throw new IllegalArgumentException("Unknown package: " + packageName);
3357            }
3358
3359            final BasePermission bp = mSettings.mPermissions.get(name);
3360            if (bp == null) {
3361                throw new IllegalArgumentException("Unknown permission: " + name);
3362            }
3363
3364            SettingBase sb = (SettingBase) pkg.mExtras;
3365            if (sb == null) {
3366                throw new IllegalArgumentException("Unknown package: " + packageName);
3367            }
3368
3369            PermissionsState permissionsState = sb.getPermissionsState();
3370            return permissionsState.getPermissionFlags(name, userId);
3371        }
3372    }
3373
3374    @Override
3375    public void updatePermissionFlags(String name, String packageName, int flagMask,
3376            int flagValues, int userId) {
3377        if (!sUserManager.exists(userId)) {
3378            return;
3379        }
3380
3381        mContext.enforceCallingOrSelfPermission(
3382                android.Manifest.permission.GRANT_REVOKE_PERMISSIONS,
3383                "updatePermissionFlags");
3384
3385        enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false,
3386                "updatePermissionFlags");
3387
3388        // Only the system can change system fixed flags.
3389        if (getCallingUid() != Process.SYSTEM_UID) {
3390            flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
3391            flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
3392        }
3393
3394        synchronized (mPackages) {
3395            final PackageParser.Package pkg = mPackages.get(packageName);
3396            if (pkg == null) {
3397                throw new IllegalArgumentException("Unknown package: " + packageName);
3398            }
3399
3400            final BasePermission bp = mSettings.mPermissions.get(name);
3401            if (bp == null) {
3402                throw new IllegalArgumentException("Unknown permission: " + name);
3403            }
3404
3405            SettingBase sb = (SettingBase) pkg.mExtras;
3406            if (sb == null) {
3407                throw new IllegalArgumentException("Unknown package: " + packageName);
3408            }
3409
3410            PermissionsState permissionsState = sb.getPermissionsState();
3411
3412            // Only the package manager can change flags for system component permissions.
3413            final int flags = permissionsState.getPermissionFlags(bp.name, userId);
3414            if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
3415                return;
3416            }
3417
3418            boolean hadState = permissionsState.getRuntimePermissionState(name, userId) != null;
3419
3420            if (permissionsState.updatePermissionFlags(bp, userId, flagMask, flagValues)) {
3421                // Install and runtime permissions are stored in different places,
3422                // so figure out what permission changed and persist the change.
3423                if (permissionsState.getInstallPermissionState(name) != null) {
3424                    scheduleWriteSettingsLocked();
3425                } else if (permissionsState.getRuntimePermissionState(name, userId) != null
3426                        || hadState) {
3427                    mSettings.writeRuntimePermissionsForUserLPr(userId, false);
3428                }
3429            }
3430        }
3431    }
3432
3433    /**
3434     * Update the permission flags for all packages and runtime permissions of a user in order
3435     * to allow device or profile owner to remove POLICY_FIXED.
3436     */
3437    @Override
3438    public void updatePermissionFlagsForAllApps(int flagMask, int flagValues, int userId) {
3439        if (!sUserManager.exists(userId)) {
3440            return;
3441        }
3442
3443        mContext.enforceCallingOrSelfPermission(
3444                android.Manifest.permission.GRANT_REVOKE_PERMISSIONS,
3445                "updatePermissionFlagsForAllApps");
3446
3447        enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false,
3448                "updatePermissionFlagsForAllApps");
3449
3450        // Only the system can change system fixed flags.
3451        if (getCallingUid() != Process.SYSTEM_UID) {
3452            flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
3453            flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
3454        }
3455
3456        synchronized (mPackages) {
3457            boolean changed = false;
3458            final int packageCount = mPackages.size();
3459            for (int pkgIndex = 0; pkgIndex < packageCount; pkgIndex++) {
3460                final PackageParser.Package pkg = mPackages.valueAt(pkgIndex);
3461                SettingBase sb = (SettingBase) pkg.mExtras;
3462                if (sb == null) {
3463                    continue;
3464                }
3465                PermissionsState permissionsState = sb.getPermissionsState();
3466                changed |= permissionsState.updatePermissionFlagsForAllPermissions(
3467                        userId, flagMask, flagValues);
3468            }
3469            if (changed) {
3470                mSettings.writeRuntimePermissionsForUserLPr(userId, false);
3471            }
3472        }
3473    }
3474
3475    @Override
3476    public boolean shouldShowRequestPermissionRationale(String permissionName,
3477            String packageName, int userId) {
3478        if (UserHandle.getCallingUserId() != userId) {
3479            mContext.enforceCallingPermission(
3480                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
3481                    "canShowRequestPermissionRationale for user " + userId);
3482        }
3483
3484        final int uid = getPackageUid(packageName, userId);
3485        if (UserHandle.getAppId(getCallingUid()) != UserHandle.getAppId(uid)) {
3486            return false;
3487        }
3488
3489        if (checkPermission(permissionName, packageName, userId)
3490                == PackageManager.PERMISSION_GRANTED) {
3491            return false;
3492        }
3493
3494        final int flags;
3495
3496        final long identity = Binder.clearCallingIdentity();
3497        try {
3498            flags = getPermissionFlags(permissionName,
3499                    packageName, userId);
3500        } finally {
3501            Binder.restoreCallingIdentity(identity);
3502        }
3503
3504        final int fixedFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
3505                | PackageManager.FLAG_PERMISSION_POLICY_FIXED
3506                | PackageManager.FLAG_PERMISSION_USER_FIXED;
3507
3508        if ((flags & fixedFlags) != 0) {
3509            return false;
3510        }
3511
3512        return (flags & PackageManager.FLAG_PERMISSION_USER_SET) != 0;
3513    }
3514
3515    void grantInstallPermissionLPw(String permission, PackageParser.Package pkg) {
3516        BasePermission bp = mSettings.mPermissions.get(permission);
3517        if (bp == null) {
3518            throw new SecurityException("Missing " + permission + " permission");
3519        }
3520
3521        SettingBase sb = (SettingBase) pkg.mExtras;
3522        PermissionsState permissionsState = sb.getPermissionsState();
3523
3524        if (permissionsState.grantInstallPermission(bp) !=
3525                PermissionsState.PERMISSION_OPERATION_FAILURE) {
3526            scheduleWriteSettingsLocked();
3527        }
3528    }
3529
3530    @Override
3531    public void addOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
3532        mContext.enforceCallingOrSelfPermission(
3533                Manifest.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS,
3534                "addOnPermissionsChangeListener");
3535
3536        synchronized (mPackages) {
3537            mOnPermissionChangeListeners.addListenerLocked(listener);
3538        }
3539    }
3540
3541    @Override
3542    public void removeOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
3543        synchronized (mPackages) {
3544            mOnPermissionChangeListeners.removeListenerLocked(listener);
3545        }
3546    }
3547
3548    @Override
3549    public boolean isProtectedBroadcast(String actionName) {
3550        synchronized (mPackages) {
3551            return mProtectedBroadcasts.contains(actionName);
3552        }
3553    }
3554
3555    @Override
3556    public int checkSignatures(String pkg1, String pkg2) {
3557        synchronized (mPackages) {
3558            final PackageParser.Package p1 = mPackages.get(pkg1);
3559            final PackageParser.Package p2 = mPackages.get(pkg2);
3560            if (p1 == null || p1.mExtras == null
3561                    || p2 == null || p2.mExtras == null) {
3562                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
3563            }
3564            return compareSignatures(p1.mSignatures, p2.mSignatures);
3565        }
3566    }
3567
3568    @Override
3569    public int checkUidSignatures(int uid1, int uid2) {
3570        // Map to base uids.
3571        uid1 = UserHandle.getAppId(uid1);
3572        uid2 = UserHandle.getAppId(uid2);
3573        // reader
3574        synchronized (mPackages) {
3575            Signature[] s1;
3576            Signature[] s2;
3577            Object obj = mSettings.getUserIdLPr(uid1);
3578            if (obj != null) {
3579                if (obj instanceof SharedUserSetting) {
3580                    s1 = ((SharedUserSetting)obj).signatures.mSignatures;
3581                } else if (obj instanceof PackageSetting) {
3582                    s1 = ((PackageSetting)obj).signatures.mSignatures;
3583                } else {
3584                    return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
3585                }
3586            } else {
3587                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
3588            }
3589            obj = mSettings.getUserIdLPr(uid2);
3590            if (obj != null) {
3591                if (obj instanceof SharedUserSetting) {
3592                    s2 = ((SharedUserSetting)obj).signatures.mSignatures;
3593                } else if (obj instanceof PackageSetting) {
3594                    s2 = ((PackageSetting)obj).signatures.mSignatures;
3595                } else {
3596                    return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
3597                }
3598            } else {
3599                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
3600            }
3601            return compareSignatures(s1, s2);
3602        }
3603    }
3604
3605    private void killSettingPackagesForUser(SettingBase sb, int userId, String reason) {
3606        final long identity = Binder.clearCallingIdentity();
3607        try {
3608            if (sb instanceof SharedUserSetting) {
3609                SharedUserSetting sus = (SharedUserSetting) sb;
3610                final int packageCount = sus.packages.size();
3611                for (int i = 0; i < packageCount; i++) {
3612                    PackageSetting susPs = sus.packages.valueAt(i);
3613                    if (userId == UserHandle.USER_ALL) {
3614                        killApplication(susPs.pkg.packageName, susPs.appId, reason);
3615                    } else {
3616                        final int uid = UserHandle.getUid(userId, susPs.appId);
3617                        killUid(uid, reason);
3618                    }
3619                }
3620            } else if (sb instanceof PackageSetting) {
3621                PackageSetting ps = (PackageSetting) sb;
3622                if (userId == UserHandle.USER_ALL) {
3623                    killApplication(ps.pkg.packageName, ps.appId, reason);
3624                } else {
3625                    final int uid = UserHandle.getUid(userId, ps.appId);
3626                    killUid(uid, reason);
3627                }
3628            }
3629        } finally {
3630            Binder.restoreCallingIdentity(identity);
3631        }
3632    }
3633
3634    private static void killUid(int uid, String reason) {
3635        IActivityManager am = ActivityManagerNative.getDefault();
3636        if (am != null) {
3637            try {
3638                am.killUid(uid, reason);
3639            } catch (RemoteException e) {
3640                /* ignore - same process */
3641            }
3642        }
3643    }
3644
3645    /**
3646     * Compares two sets of signatures. Returns:
3647     * <br />
3648     * {@link PackageManager#SIGNATURE_NEITHER_SIGNED}: if both signature sets are null,
3649     * <br />
3650     * {@link PackageManager#SIGNATURE_FIRST_NOT_SIGNED}: if the first signature set is null,
3651     * <br />
3652     * {@link PackageManager#SIGNATURE_SECOND_NOT_SIGNED}: if the second signature set is null,
3653     * <br />
3654     * {@link PackageManager#SIGNATURE_MATCH}: if the two signature sets are identical,
3655     * <br />
3656     * {@link PackageManager#SIGNATURE_NO_MATCH}: if the two signature sets differ.
3657     */
3658    static int compareSignatures(Signature[] s1, Signature[] s2) {
3659        if (s1 == null) {
3660            return s2 == null
3661                    ? PackageManager.SIGNATURE_NEITHER_SIGNED
3662                    : PackageManager.SIGNATURE_FIRST_NOT_SIGNED;
3663        }
3664
3665        if (s2 == null) {
3666            return PackageManager.SIGNATURE_SECOND_NOT_SIGNED;
3667        }
3668
3669        if (s1.length != s2.length) {
3670            return PackageManager.SIGNATURE_NO_MATCH;
3671        }
3672
3673        // Since both signature sets are of size 1, we can compare without HashSets.
3674        if (s1.length == 1) {
3675            return s1[0].equals(s2[0]) ?
3676                    PackageManager.SIGNATURE_MATCH :
3677                    PackageManager.SIGNATURE_NO_MATCH;
3678        }
3679
3680        ArraySet<Signature> set1 = new ArraySet<Signature>();
3681        for (Signature sig : s1) {
3682            set1.add(sig);
3683        }
3684        ArraySet<Signature> set2 = new ArraySet<Signature>();
3685        for (Signature sig : s2) {
3686            set2.add(sig);
3687        }
3688        // Make sure s2 contains all signatures in s1.
3689        if (set1.equals(set2)) {
3690            return PackageManager.SIGNATURE_MATCH;
3691        }
3692        return PackageManager.SIGNATURE_NO_MATCH;
3693    }
3694
3695    /**
3696     * If the database version for this type of package (internal storage or
3697     * external storage) is less than the version where package signatures
3698     * were updated, return true.
3699     */
3700    private boolean isCompatSignatureUpdateNeeded(PackageParser.Package scannedPkg) {
3701        return (isExternal(scannedPkg) && mSettings.isExternalDatabaseVersionOlderThan(
3702                DatabaseVersion.SIGNATURE_END_ENTITY))
3703                || (!isExternal(scannedPkg) && mSettings.isInternalDatabaseVersionOlderThan(
3704                        DatabaseVersion.SIGNATURE_END_ENTITY));
3705    }
3706
3707    /**
3708     * Used for backward compatibility to make sure any packages with
3709     * certificate chains get upgraded to the new style. {@code existingSigs}
3710     * will be in the old format (since they were stored on disk from before the
3711     * system upgrade) and {@code scannedSigs} will be in the newer format.
3712     */
3713    private int compareSignaturesCompat(PackageSignatures existingSigs,
3714            PackageParser.Package scannedPkg) {
3715        if (!isCompatSignatureUpdateNeeded(scannedPkg)) {
3716            return PackageManager.SIGNATURE_NO_MATCH;
3717        }
3718
3719        ArraySet<Signature> existingSet = new ArraySet<Signature>();
3720        for (Signature sig : existingSigs.mSignatures) {
3721            existingSet.add(sig);
3722        }
3723        ArraySet<Signature> scannedCompatSet = new ArraySet<Signature>();
3724        for (Signature sig : scannedPkg.mSignatures) {
3725            try {
3726                Signature[] chainSignatures = sig.getChainSignatures();
3727                for (Signature chainSig : chainSignatures) {
3728                    scannedCompatSet.add(chainSig);
3729                }
3730            } catch (CertificateEncodingException e) {
3731                scannedCompatSet.add(sig);
3732            }
3733        }
3734        /*
3735         * Make sure the expanded scanned set contains all signatures in the
3736         * existing one.
3737         */
3738        if (scannedCompatSet.equals(existingSet)) {
3739            // Migrate the old signatures to the new scheme.
3740            existingSigs.assignSignatures(scannedPkg.mSignatures);
3741            // The new KeySets will be re-added later in the scanning process.
3742            synchronized (mPackages) {
3743                mSettings.mKeySetManagerService.removeAppKeySetDataLPw(scannedPkg.packageName);
3744            }
3745            return PackageManager.SIGNATURE_MATCH;
3746        }
3747        return PackageManager.SIGNATURE_NO_MATCH;
3748    }
3749
3750    private boolean isRecoverSignatureUpdateNeeded(PackageParser.Package scannedPkg) {
3751        if (isExternal(scannedPkg)) {
3752            return mSettings.isExternalDatabaseVersionOlderThan(
3753                    DatabaseVersion.SIGNATURE_MALFORMED_RECOVER);
3754        } else {
3755            return mSettings.isInternalDatabaseVersionOlderThan(
3756                    DatabaseVersion.SIGNATURE_MALFORMED_RECOVER);
3757        }
3758    }
3759
3760    private int compareSignaturesRecover(PackageSignatures existingSigs,
3761            PackageParser.Package scannedPkg) {
3762        if (!isRecoverSignatureUpdateNeeded(scannedPkg)) {
3763            return PackageManager.SIGNATURE_NO_MATCH;
3764        }
3765
3766        String msg = null;
3767        try {
3768            if (Signature.areEffectiveMatch(existingSigs.mSignatures, scannedPkg.mSignatures)) {
3769                logCriticalInfo(Log.INFO, "Recovered effectively matching certificates for "
3770                        + scannedPkg.packageName);
3771                return PackageManager.SIGNATURE_MATCH;
3772            }
3773        } catch (CertificateException e) {
3774            msg = e.getMessage();
3775        }
3776
3777        logCriticalInfo(Log.INFO,
3778                "Failed to recover certificates for " + scannedPkg.packageName + ": " + msg);
3779        return PackageManager.SIGNATURE_NO_MATCH;
3780    }
3781
3782    @Override
3783    public String[] getPackagesForUid(int uid) {
3784        uid = UserHandle.getAppId(uid);
3785        // reader
3786        synchronized (mPackages) {
3787            Object obj = mSettings.getUserIdLPr(uid);
3788            if (obj instanceof SharedUserSetting) {
3789                final SharedUserSetting sus = (SharedUserSetting) obj;
3790                final int N = sus.packages.size();
3791                final String[] res = new String[N];
3792                final Iterator<PackageSetting> it = sus.packages.iterator();
3793                int i = 0;
3794                while (it.hasNext()) {
3795                    res[i++] = it.next().name;
3796                }
3797                return res;
3798            } else if (obj instanceof PackageSetting) {
3799                final PackageSetting ps = (PackageSetting) obj;
3800                return new String[] { ps.name };
3801            }
3802        }
3803        return null;
3804    }
3805
3806    @Override
3807    public String getNameForUid(int uid) {
3808        // reader
3809        synchronized (mPackages) {
3810            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
3811            if (obj instanceof SharedUserSetting) {
3812                final SharedUserSetting sus = (SharedUserSetting) obj;
3813                return sus.name + ":" + sus.userId;
3814            } else if (obj instanceof PackageSetting) {
3815                final PackageSetting ps = (PackageSetting) obj;
3816                return ps.name;
3817            }
3818        }
3819        return null;
3820    }
3821
3822    @Override
3823    public int getUidForSharedUser(String sharedUserName) {
3824        if(sharedUserName == null) {
3825            return -1;
3826        }
3827        // reader
3828        synchronized (mPackages) {
3829            final SharedUserSetting suid = mSettings.getSharedUserLPw(sharedUserName, 0, 0, false);
3830            if (suid == null) {
3831                return -1;
3832            }
3833            return suid.userId;
3834        }
3835    }
3836
3837    @Override
3838    public int getFlagsForUid(int uid) {
3839        synchronized (mPackages) {
3840            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
3841            if (obj instanceof SharedUserSetting) {
3842                final SharedUserSetting sus = (SharedUserSetting) obj;
3843                return sus.pkgFlags;
3844            } else if (obj instanceof PackageSetting) {
3845                final PackageSetting ps = (PackageSetting) obj;
3846                return ps.pkgFlags;
3847            }
3848        }
3849        return 0;
3850    }
3851
3852    @Override
3853    public int getPrivateFlagsForUid(int uid) {
3854        synchronized (mPackages) {
3855            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
3856            if (obj instanceof SharedUserSetting) {
3857                final SharedUserSetting sus = (SharedUserSetting) obj;
3858                return sus.pkgPrivateFlags;
3859            } else if (obj instanceof PackageSetting) {
3860                final PackageSetting ps = (PackageSetting) obj;
3861                return ps.pkgPrivateFlags;
3862            }
3863        }
3864        return 0;
3865    }
3866
3867    @Override
3868    public boolean isUidPrivileged(int uid) {
3869        uid = UserHandle.getAppId(uid);
3870        // reader
3871        synchronized (mPackages) {
3872            Object obj = mSettings.getUserIdLPr(uid);
3873            if (obj instanceof SharedUserSetting) {
3874                final SharedUserSetting sus = (SharedUserSetting) obj;
3875                final Iterator<PackageSetting> it = sus.packages.iterator();
3876                while (it.hasNext()) {
3877                    if (it.next().isPrivileged()) {
3878                        return true;
3879                    }
3880                }
3881            } else if (obj instanceof PackageSetting) {
3882                final PackageSetting ps = (PackageSetting) obj;
3883                return ps.isPrivileged();
3884            }
3885        }
3886        return false;
3887    }
3888
3889    @Override
3890    public String[] getAppOpPermissionPackages(String permissionName) {
3891        synchronized (mPackages) {
3892            ArraySet<String> pkgs = mAppOpPermissionPackages.get(permissionName);
3893            if (pkgs == null) {
3894                return null;
3895            }
3896            return pkgs.toArray(new String[pkgs.size()]);
3897        }
3898    }
3899
3900    @Override
3901    public ResolveInfo resolveIntent(Intent intent, String resolvedType,
3902            int flags, int userId) {
3903        if (!sUserManager.exists(userId)) return null;
3904        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "resolve intent");
3905        List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId);
3906        return chooseBestActivity(intent, resolvedType, flags, query, userId);
3907    }
3908
3909    @Override
3910    public void setLastChosenActivity(Intent intent, String resolvedType, int flags,
3911            IntentFilter filter, int match, ComponentName activity) {
3912        final int userId = UserHandle.getCallingUserId();
3913        if (DEBUG_PREFERRED) {
3914            Log.v(TAG, "setLastChosenActivity intent=" + intent
3915                + " resolvedType=" + resolvedType
3916                + " flags=" + flags
3917                + " filter=" + filter
3918                + " match=" + match
3919                + " activity=" + activity);
3920            filter.dump(new PrintStreamPrinter(System.out), "    ");
3921        }
3922        intent.setComponent(null);
3923        List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId);
3924        // Find any earlier preferred or last chosen entries and nuke them
3925        findPreferredActivity(intent, resolvedType,
3926                flags, query, 0, false, true, false, userId);
3927        // Add the new activity as the last chosen for this filter
3928        addPreferredActivityInternal(filter, match, null, activity, false, userId,
3929                "Setting last chosen");
3930    }
3931
3932    @Override
3933    public ResolveInfo getLastChosenActivity(Intent intent, String resolvedType, int flags) {
3934        final int userId = UserHandle.getCallingUserId();
3935        if (DEBUG_PREFERRED) Log.v(TAG, "Querying last chosen activity for " + intent);
3936        List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId);
3937        return findPreferredActivity(intent, resolvedType, flags, query, 0,
3938                false, false, false, userId);
3939    }
3940
3941    private ResolveInfo chooseBestActivity(Intent intent, String resolvedType,
3942            int flags, List<ResolveInfo> query, int userId) {
3943        if (query != null) {
3944            final int N = query.size();
3945            if (N == 1) {
3946                return query.get(0);
3947            } else if (N > 1) {
3948                final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3949                // If there is more than one activity with the same priority,
3950                // then let the user decide between them.
3951                ResolveInfo r0 = query.get(0);
3952                ResolveInfo r1 = query.get(1);
3953                if (DEBUG_INTENT_MATCHING || debug) {
3954                    Slog.v(TAG, r0.activityInfo.name + "=" + r0.priority + " vs "
3955                            + r1.activityInfo.name + "=" + r1.priority);
3956                }
3957                // If the first activity has a higher priority, or a different
3958                // default, then it is always desireable to pick it.
3959                if (r0.priority != r1.priority
3960                        || r0.preferredOrder != r1.preferredOrder
3961                        || r0.isDefault != r1.isDefault) {
3962                    return query.get(0);
3963                }
3964                // If we have saved a preference for a preferred activity for
3965                // this Intent, use that.
3966                ResolveInfo ri = findPreferredActivity(intent, resolvedType,
3967                        flags, query, r0.priority, true, false, debug, userId);
3968                if (ri != null) {
3969                    return ri;
3970                }
3971                if (userId != 0) {
3972                    ri = new ResolveInfo(mResolveInfo);
3973                    ri.activityInfo = new ActivityInfo(ri.activityInfo);
3974                    ri.activityInfo.applicationInfo = new ApplicationInfo(
3975                            ri.activityInfo.applicationInfo);
3976                    ri.activityInfo.applicationInfo.uid = UserHandle.getUid(userId,
3977                            UserHandle.getAppId(ri.activityInfo.applicationInfo.uid));
3978                    return ri;
3979                }
3980                return mResolveInfo;
3981            }
3982        }
3983        return null;
3984    }
3985
3986    private ResolveInfo findPersistentPreferredActivityLP(Intent intent, String resolvedType,
3987            int flags, List<ResolveInfo> query, boolean debug, int userId) {
3988        final int N = query.size();
3989        PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
3990                .get(userId);
3991        // Get the list of persistent preferred activities that handle the intent
3992        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for presistent preferred activities...");
3993        List<PersistentPreferredActivity> pprefs = ppir != null
3994                ? ppir.queryIntent(intent, resolvedType,
3995                        (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId)
3996                : null;
3997        if (pprefs != null && pprefs.size() > 0) {
3998            final int M = pprefs.size();
3999            for (int i=0; i<M; i++) {
4000                final PersistentPreferredActivity ppa = pprefs.get(i);
4001                if (DEBUG_PREFERRED || debug) {
4002                    Slog.v(TAG, "Checking PersistentPreferredActivity ds="
4003                            + (ppa.countDataSchemes() > 0 ? ppa.getDataScheme(0) : "<none>")
4004                            + "\n  component=" + ppa.mComponent);
4005                    ppa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
4006                }
4007                final ActivityInfo ai = getActivityInfo(ppa.mComponent,
4008                        flags | PackageManager.GET_DISABLED_COMPONENTS, userId);
4009                if (DEBUG_PREFERRED || debug) {
4010                    Slog.v(TAG, "Found persistent preferred activity:");
4011                    if (ai != null) {
4012                        ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
4013                    } else {
4014                        Slog.v(TAG, "  null");
4015                    }
4016                }
4017                if (ai == null) {
4018                    // This previously registered persistent preferred activity
4019                    // component is no longer known. Ignore it and do NOT remove it.
4020                    continue;
4021                }
4022                for (int j=0; j<N; j++) {
4023                    final ResolveInfo ri = query.get(j);
4024                    if (!ri.activityInfo.applicationInfo.packageName
4025                            .equals(ai.applicationInfo.packageName)) {
4026                        continue;
4027                    }
4028                    if (!ri.activityInfo.name.equals(ai.name)) {
4029                        continue;
4030                    }
4031                    //  Found a persistent preference that can handle the intent.
4032                    if (DEBUG_PREFERRED || debug) {
4033                        Slog.v(TAG, "Returning persistent preferred activity: " +
4034                                ri.activityInfo.packageName + "/" + ri.activityInfo.name);
4035                    }
4036                    return ri;
4037                }
4038            }
4039        }
4040        return null;
4041    }
4042
4043    ResolveInfo findPreferredActivity(Intent intent, String resolvedType, int flags,
4044            List<ResolveInfo> query, int priority, boolean always,
4045            boolean removeMatches, boolean debug, int userId) {
4046        if (!sUserManager.exists(userId)) return null;
4047        // writer
4048        synchronized (mPackages) {
4049            if (intent.getSelector() != null) {
4050                intent = intent.getSelector();
4051            }
4052            if (DEBUG_PREFERRED) intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION);
4053
4054            // Try to find a matching persistent preferred activity.
4055            ResolveInfo pri = findPersistentPreferredActivityLP(intent, resolvedType, flags, query,
4056                    debug, userId);
4057
4058            // If a persistent preferred activity matched, use it.
4059            if (pri != null) {
4060                return pri;
4061            }
4062
4063            PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
4064            // Get the list of preferred activities that handle the intent
4065            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for preferred activities...");
4066            List<PreferredActivity> prefs = pir != null
4067                    ? pir.queryIntent(intent, resolvedType,
4068                            (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId)
4069                    : null;
4070            if (prefs != null && prefs.size() > 0) {
4071                boolean changed = false;
4072                try {
4073                    // First figure out how good the original match set is.
4074                    // We will only allow preferred activities that came
4075                    // from the same match quality.
4076                    int match = 0;
4077
4078                    if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Figuring out best match...");
4079
4080                    final int N = query.size();
4081                    for (int j=0; j<N; j++) {
4082                        final ResolveInfo ri = query.get(j);
4083                        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Match for " + ri.activityInfo
4084                                + ": 0x" + Integer.toHexString(match));
4085                        if (ri.match > match) {
4086                            match = ri.match;
4087                        }
4088                    }
4089
4090                    if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Best match: 0x"
4091                            + Integer.toHexString(match));
4092
4093                    match &= IntentFilter.MATCH_CATEGORY_MASK;
4094                    final int M = prefs.size();
4095                    for (int i=0; i<M; i++) {
4096                        final PreferredActivity pa = prefs.get(i);
4097                        if (DEBUG_PREFERRED || debug) {
4098                            Slog.v(TAG, "Checking PreferredActivity ds="
4099                                    + (pa.countDataSchemes() > 0 ? pa.getDataScheme(0) : "<none>")
4100                                    + "\n  component=" + pa.mPref.mComponent);
4101                            pa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
4102                        }
4103                        if (pa.mPref.mMatch != match) {
4104                            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping bad match "
4105                                    + Integer.toHexString(pa.mPref.mMatch));
4106                            continue;
4107                        }
4108                        // If it's not an "always" type preferred activity and that's what we're
4109                        // looking for, skip it.
4110                        if (always && !pa.mPref.mAlways) {
4111                            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping mAlways=false entry");
4112                            continue;
4113                        }
4114                        final ActivityInfo ai = getActivityInfo(pa.mPref.mComponent,
4115                                flags | PackageManager.GET_DISABLED_COMPONENTS, userId);
4116                        if (DEBUG_PREFERRED || debug) {
4117                            Slog.v(TAG, "Found preferred activity:");
4118                            if (ai != null) {
4119                                ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
4120                            } else {
4121                                Slog.v(TAG, "  null");
4122                            }
4123                        }
4124                        if (ai == null) {
4125                            // This previously registered preferred activity
4126                            // component is no longer known.  Most likely an update
4127                            // to the app was installed and in the new version this
4128                            // component no longer exists.  Clean it up by removing
4129                            // it from the preferred activities list, and skip it.
4130                            Slog.w(TAG, "Removing dangling preferred activity: "
4131                                    + pa.mPref.mComponent);
4132                            pir.removeFilter(pa);
4133                            changed = true;
4134                            continue;
4135                        }
4136                        for (int j=0; j<N; j++) {
4137                            final ResolveInfo ri = query.get(j);
4138                            if (!ri.activityInfo.applicationInfo.packageName
4139                                    .equals(ai.applicationInfo.packageName)) {
4140                                continue;
4141                            }
4142                            if (!ri.activityInfo.name.equals(ai.name)) {
4143                                continue;
4144                            }
4145
4146                            if (removeMatches) {
4147                                pir.removeFilter(pa);
4148                                changed = true;
4149                                if (DEBUG_PREFERRED) {
4150                                    Slog.v(TAG, "Removing match " + pa.mPref.mComponent);
4151                                }
4152                                break;
4153                            }
4154
4155                            // Okay we found a previously set preferred or last chosen app.
4156                            // If the result set is different from when this
4157                            // was created, we need to clear it and re-ask the
4158                            // user their preference, if we're looking for an "always" type entry.
4159                            if (always && !pa.mPref.sameSet(query)) {
4160                                Slog.i(TAG, "Result set changed, dropping preferred activity for "
4161                                        + intent + " type " + resolvedType);
4162                                if (DEBUG_PREFERRED) {
4163                                    Slog.v(TAG, "Removing preferred activity since set changed "
4164                                            + pa.mPref.mComponent);
4165                                }
4166                                pir.removeFilter(pa);
4167                                // Re-add the filter as a "last chosen" entry (!always)
4168                                PreferredActivity lastChosen = new PreferredActivity(
4169                                        pa, pa.mPref.mMatch, null, pa.mPref.mComponent, false);
4170                                pir.addFilter(lastChosen);
4171                                changed = true;
4172                                return null;
4173                            }
4174
4175                            // Yay! Either the set matched or we're looking for the last chosen
4176                            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Returning preferred activity: "
4177                                    + ri.activityInfo.packageName + "/" + ri.activityInfo.name);
4178                            return ri;
4179                        }
4180                    }
4181                } finally {
4182                    if (changed) {
4183                        if (DEBUG_PREFERRED) {
4184                            Slog.v(TAG, "Preferred activity bookkeeping changed; writing restrictions");
4185                        }
4186                        scheduleWritePackageRestrictionsLocked(userId);
4187                    }
4188                }
4189            }
4190        }
4191        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "No preferred activity to return");
4192        return null;
4193    }
4194
4195    /*
4196     * Returns if intent can be forwarded from the sourceUserId to the targetUserId
4197     */
4198    @Override
4199    public boolean canForwardTo(Intent intent, String resolvedType, int sourceUserId,
4200            int targetUserId) {
4201        mContext.enforceCallingOrSelfPermission(
4202                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
4203        List<CrossProfileIntentFilter> matches =
4204                getMatchingCrossProfileIntentFilters(intent, resolvedType, sourceUserId);
4205        if (matches != null) {
4206            int size = matches.size();
4207            for (int i = 0; i < size; i++) {
4208                if (matches.get(i).getTargetUserId() == targetUserId) return true;
4209            }
4210        }
4211        if (hasWebURI(intent)) {
4212            // cross-profile app linking works only towards the parent.
4213            final UserInfo parent = getProfileParent(sourceUserId);
4214            synchronized(mPackages) {
4215                return getCrossProfileDomainPreferredLpr(intent, resolvedType, 0, sourceUserId,
4216                        parent.id) != null;
4217            }
4218        }
4219        return false;
4220    }
4221
4222    private UserInfo getProfileParent(int userId) {
4223        final long identity = Binder.clearCallingIdentity();
4224        try {
4225            return sUserManager.getProfileParent(userId);
4226        } finally {
4227            Binder.restoreCallingIdentity(identity);
4228        }
4229    }
4230
4231    private List<CrossProfileIntentFilter> getMatchingCrossProfileIntentFilters(Intent intent,
4232            String resolvedType, int userId) {
4233        CrossProfileIntentResolver resolver = mSettings.mCrossProfileIntentResolvers.get(userId);
4234        if (resolver != null) {
4235            return resolver.queryIntent(intent, resolvedType, false, userId);
4236        }
4237        return null;
4238    }
4239
4240    @Override
4241    public List<ResolveInfo> queryIntentActivities(Intent intent,
4242            String resolvedType, int flags, int userId) {
4243        if (!sUserManager.exists(userId)) return Collections.emptyList();
4244        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "query intent activities");
4245        ComponentName comp = intent.getComponent();
4246        if (comp == null) {
4247            if (intent.getSelector() != null) {
4248                intent = intent.getSelector();
4249                comp = intent.getComponent();
4250            }
4251        }
4252
4253        if (comp != null) {
4254            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
4255            final ActivityInfo ai = getActivityInfo(comp, flags, userId);
4256            if (ai != null) {
4257                final ResolveInfo ri = new ResolveInfo();
4258                ri.activityInfo = ai;
4259                list.add(ri);
4260            }
4261            return list;
4262        }
4263
4264        // reader
4265        synchronized (mPackages) {
4266            final String pkgName = intent.getPackage();
4267            if (pkgName == null) {
4268                List<CrossProfileIntentFilter> matchingFilters =
4269                        getMatchingCrossProfileIntentFilters(intent, resolvedType, userId);
4270                // Check for results that need to skip the current profile.
4271                ResolveInfo xpResolveInfo  = querySkipCurrentProfileIntents(matchingFilters, intent,
4272                        resolvedType, flags, userId);
4273                if (xpResolveInfo != null && isUserEnabled(xpResolveInfo.targetUserId)) {
4274                    List<ResolveInfo> result = new ArrayList<ResolveInfo>(1);
4275                    result.add(xpResolveInfo);
4276                    return filterIfNotPrimaryUser(result, userId);
4277                }
4278
4279                // Check for results in the current profile.
4280                List<ResolveInfo> result = mActivities.queryIntent(
4281                        intent, resolvedType, flags, userId);
4282
4283                // Check for cross profile results.
4284                xpResolveInfo = queryCrossProfileIntents(
4285                        matchingFilters, intent, resolvedType, flags, userId);
4286                if (xpResolveInfo != null && isUserEnabled(xpResolveInfo.targetUserId)) {
4287                    result.add(xpResolveInfo);
4288                    Collections.sort(result, mResolvePrioritySorter);
4289                }
4290                result = filterIfNotPrimaryUser(result, userId);
4291                if (hasWebURI(intent)) {
4292                    CrossProfileDomainInfo xpDomainInfo = null;
4293                    final UserInfo parent = getProfileParent(userId);
4294                    if (parent != null) {
4295                        xpDomainInfo = getCrossProfileDomainPreferredLpr(intent, resolvedType,
4296                                flags, userId, parent.id);
4297                    }
4298                    if (xpDomainInfo != null) {
4299                        if (xpResolveInfo != null) {
4300                            // If we didn't remove it, the cross-profile ResolveInfo would be twice
4301                            // in the result.
4302                            result.remove(xpResolveInfo);
4303                        }
4304                        if (result.size() == 0) {
4305                            result.add(xpDomainInfo.resolveInfo);
4306                            return result;
4307                        }
4308                    } else if (result.size() <= 1) {
4309                        return result;
4310                    }
4311                    result = filterCandidatesWithDomainPreferredActivitiesLPr(flags, result,
4312                            xpDomainInfo);
4313                    Collections.sort(result, mResolvePrioritySorter);
4314                }
4315                return result;
4316            }
4317            final PackageParser.Package pkg = mPackages.get(pkgName);
4318            if (pkg != null) {
4319                return filterIfNotPrimaryUser(
4320                        mActivities.queryIntentForPackage(
4321                                intent, resolvedType, flags, pkg.activities, userId),
4322                        userId);
4323            }
4324            return new ArrayList<ResolveInfo>();
4325        }
4326    }
4327
4328    private static class CrossProfileDomainInfo {
4329        /* ResolveInfo for IntentForwarderActivity to send the intent to the other profile */
4330        ResolveInfo resolveInfo;
4331        /* Best domain verification status of the activities found in the other profile */
4332        int bestDomainVerificationStatus;
4333    }
4334
4335    private CrossProfileDomainInfo getCrossProfileDomainPreferredLpr(Intent intent,
4336            String resolvedType, int flags, int sourceUserId, int parentUserId) {
4337        if (!sUserManager.hasUserRestriction(UserManager.ALLOW_PARENT_APP_LINKING,
4338                sourceUserId)) {
4339            return null;
4340        }
4341        List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent,
4342                resolvedType, flags, parentUserId);
4343
4344        if (resultTargetUser == null || resultTargetUser.isEmpty()) {
4345            return null;
4346        }
4347        CrossProfileDomainInfo result = null;
4348        int size = resultTargetUser.size();
4349        for (int i = 0; i < size; i++) {
4350            ResolveInfo riTargetUser = resultTargetUser.get(i);
4351            // Intent filter verification is only for filters that specify a host. So don't return
4352            // those that handle all web uris.
4353            if (riTargetUser.handleAllWebDataURI) {
4354                continue;
4355            }
4356            String packageName = riTargetUser.activityInfo.packageName;
4357            PackageSetting ps = mSettings.mPackages.get(packageName);
4358            if (ps == null) {
4359                continue;
4360            }
4361            int status = getDomainVerificationStatusLPr(ps, parentUserId);
4362            if (result == null) {
4363                result = new CrossProfileDomainInfo();
4364                result.resolveInfo =
4365                        createForwardingResolveInfo(null, sourceUserId, parentUserId);
4366                result.bestDomainVerificationStatus = status;
4367            } else {
4368                result.bestDomainVerificationStatus = bestDomainVerificationStatus(status,
4369                        result.bestDomainVerificationStatus);
4370            }
4371        }
4372        return result;
4373    }
4374
4375    /**
4376     * Verification statuses are ordered from the worse to the best, except for
4377     * INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER, which is the worse.
4378     */
4379    private int bestDomainVerificationStatus(int status1, int status2) {
4380        if (status1 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
4381            return status2;
4382        }
4383        if (status2 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
4384            return status1;
4385        }
4386        return (int) MathUtils.max(status1, status2);
4387    }
4388
4389    private boolean isUserEnabled(int userId) {
4390        long callingId = Binder.clearCallingIdentity();
4391        try {
4392            UserInfo userInfo = sUserManager.getUserInfo(userId);
4393            return userInfo != null && userInfo.isEnabled();
4394        } finally {
4395            Binder.restoreCallingIdentity(callingId);
4396        }
4397    }
4398
4399    /**
4400     * Filter out activities with primaryUserOnly flag set, when current user is not the owner.
4401     *
4402     * @return filtered list
4403     */
4404    private List<ResolveInfo> filterIfNotPrimaryUser(List<ResolveInfo> resolveInfos, int userId) {
4405        if (userId == UserHandle.USER_OWNER) {
4406            return resolveInfos;
4407        }
4408        for (int i = resolveInfos.size() - 1; i >= 0; i--) {
4409            ResolveInfo info = resolveInfos.get(i);
4410            if ((info.activityInfo.flags & ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
4411                resolveInfos.remove(i);
4412            }
4413        }
4414        return resolveInfos;
4415    }
4416
4417    private static boolean hasWebURI(Intent intent) {
4418        if (intent.getData() == null) {
4419            return false;
4420        }
4421        final String scheme = intent.getScheme();
4422        if (TextUtils.isEmpty(scheme)) {
4423            return false;
4424        }
4425        return scheme.equals(IntentFilter.SCHEME_HTTP) || scheme.equals(IntentFilter.SCHEME_HTTPS);
4426    }
4427
4428    private List<ResolveInfo> filterCandidatesWithDomainPreferredActivitiesLPr(
4429            int flags, List<ResolveInfo> candidates, CrossProfileDomainInfo xpDomainInfo) {
4430        if (DEBUG_PREFERRED) {
4431            Slog.v("TAG", "Filtering results with prefered activities. Candidates count: " +
4432                    candidates.size());
4433        }
4434
4435        final int userId = UserHandle.getCallingUserId();
4436        ArrayList<ResolveInfo> result = new ArrayList<ResolveInfo>();
4437        ArrayList<ResolveInfo> alwaysList = new ArrayList<ResolveInfo>();
4438        ArrayList<ResolveInfo> undefinedList = new ArrayList<ResolveInfo>();
4439        ArrayList<ResolveInfo> neverList = new ArrayList<ResolveInfo>();
4440        ArrayList<ResolveInfo> matchAllList = new ArrayList<ResolveInfo>();
4441
4442        synchronized (mPackages) {
4443            final int count = candidates.size();
4444            // First, try to use the domain prefered App. Partition the candidates into four lists:
4445            // one for the final results, one for the "do not use ever", one for "undefined status"
4446            // and finally one for "Browser App type".
4447            for (int n=0; n<count; n++) {
4448                ResolveInfo info = candidates.get(n);
4449                String packageName = info.activityInfo.packageName;
4450                PackageSetting ps = mSettings.mPackages.get(packageName);
4451                if (ps != null) {
4452                    // Add to the special match all list (Browser use case)
4453                    if (info.handleAllWebDataURI) {
4454                        matchAllList.add(info);
4455                        continue;
4456                    }
4457                    // Try to get the status from User settings first
4458                    int status = getDomainVerificationStatusLPr(ps, userId);
4459                    if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) {
4460                        alwaysList.add(info);
4461                    } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
4462                        neverList.add(info);
4463                    } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED ||
4464                            status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK) {
4465                        undefinedList.add(info);
4466                    }
4467                }
4468            }
4469            // First try to add the "always" resolution for the current user if there is any
4470            if (alwaysList.size() > 0) {
4471                result.addAll(alwaysList);
4472            // if there is an "always" for the parent user, add it.
4473            } else if (xpDomainInfo != null && xpDomainInfo.bestDomainVerificationStatus
4474                    == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) {
4475                result.add(xpDomainInfo.resolveInfo);
4476            } else {
4477                // Add all undefined Apps as we want them to appear in the Disambiguation dialog.
4478                result.addAll(undefinedList);
4479                if (xpDomainInfo != null && (
4480                        xpDomainInfo.bestDomainVerificationStatus
4481                        == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED
4482                        || xpDomainInfo.bestDomainVerificationStatus
4483                        == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK)) {
4484                    result.add(xpDomainInfo.resolveInfo);
4485                }
4486                // Also add Browsers (all of them or only the default one)
4487                if ((flags & MATCH_ALL) != 0) {
4488                    result.addAll(matchAllList);
4489                } else {
4490                    // Try to add the Default Browser if we can
4491                    final String defaultBrowserPackageName = getDefaultBrowserPackageName(
4492                            UserHandle.myUserId());
4493                    if (!TextUtils.isEmpty(defaultBrowserPackageName)) {
4494                        boolean defaultBrowserFound = false;
4495                        final int browserCount = matchAllList.size();
4496                        for (int n=0; n<browserCount; n++) {
4497                            ResolveInfo browser = matchAllList.get(n);
4498                            if (browser.activityInfo.packageName.equals(defaultBrowserPackageName)) {
4499                                result.add(browser);
4500                                defaultBrowserFound = true;
4501                                break;
4502                            }
4503                        }
4504                        if (!defaultBrowserFound) {
4505                            result.addAll(matchAllList);
4506                        }
4507                    } else {
4508                        result.addAll(matchAllList);
4509                    }
4510                }
4511
4512                // If there is nothing selected, add all candidates and remove the ones that the User
4513                // has explicitely put into the INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER state
4514                if (result.size() == 0) {
4515                    result.addAll(candidates);
4516                    result.removeAll(neverList);
4517                }
4518            }
4519        }
4520        if (DEBUG_PREFERRED) {
4521            Slog.v("TAG", "Filtered results with prefered activities. New candidates count: " +
4522                    result.size());
4523        }
4524        return result;
4525    }
4526
4527    private int getDomainVerificationStatusLPr(PackageSetting ps, int userId) {
4528        int status = ps.getDomainVerificationStatusForUser(userId);
4529        // if none available, get the master status
4530        if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) {
4531            if (ps.getIntentFilterVerificationInfo() != null) {
4532                status = ps.getIntentFilterVerificationInfo().getStatus();
4533            }
4534        }
4535        return status;
4536    }
4537
4538    private ResolveInfo querySkipCurrentProfileIntents(
4539            List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
4540            int flags, int sourceUserId) {
4541        if (matchingFilters != null) {
4542            int size = matchingFilters.size();
4543            for (int i = 0; i < size; i ++) {
4544                CrossProfileIntentFilter filter = matchingFilters.get(i);
4545                if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0) {
4546                    // Checking if there are activities in the target user that can handle the
4547                    // intent.
4548                    ResolveInfo resolveInfo = checkTargetCanHandle(filter, intent, resolvedType,
4549                            flags, sourceUserId);
4550                    if (resolveInfo != null) {
4551                        return resolveInfo;
4552                    }
4553                }
4554            }
4555        }
4556        return null;
4557    }
4558
4559    // Return matching ResolveInfo if any for skip current profile intent filters.
4560    private ResolveInfo queryCrossProfileIntents(
4561            List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
4562            int flags, int sourceUserId) {
4563        if (matchingFilters != null) {
4564            // Two {@link CrossProfileIntentFilter}s can have the same targetUserId and
4565            // match the same intent. For performance reasons, it is better not to
4566            // run queryIntent twice for the same userId
4567            SparseBooleanArray alreadyTriedUserIds = new SparseBooleanArray();
4568            int size = matchingFilters.size();
4569            for (int i = 0; i < size; i++) {
4570                CrossProfileIntentFilter filter = matchingFilters.get(i);
4571                int targetUserId = filter.getTargetUserId();
4572                if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) == 0
4573                        && !alreadyTriedUserIds.get(targetUserId)) {
4574                    // Checking if there are activities in the target user that can handle the
4575                    // intent.
4576                    ResolveInfo resolveInfo = checkTargetCanHandle(filter, intent, resolvedType,
4577                            flags, sourceUserId);
4578                    if (resolveInfo != null) return resolveInfo;
4579                    alreadyTriedUserIds.put(targetUserId, true);
4580                }
4581            }
4582        }
4583        return null;
4584    }
4585
4586    private ResolveInfo checkTargetCanHandle(CrossProfileIntentFilter filter, Intent intent,
4587            String resolvedType, int flags, int sourceUserId) {
4588        List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent,
4589                resolvedType, flags, filter.getTargetUserId());
4590        if (resultTargetUser != null && !resultTargetUser.isEmpty()) {
4591            return createForwardingResolveInfo(filter, sourceUserId, filter.getTargetUserId());
4592        }
4593        return null;
4594    }
4595
4596    private ResolveInfo createForwardingResolveInfo(IntentFilter filter,
4597            int sourceUserId, int targetUserId) {
4598        ResolveInfo forwardingResolveInfo = new ResolveInfo();
4599        String className;
4600        if (targetUserId == UserHandle.USER_OWNER) {
4601            className = FORWARD_INTENT_TO_USER_OWNER;
4602        } else {
4603            className = FORWARD_INTENT_TO_MANAGED_PROFILE;
4604        }
4605        ComponentName forwardingActivityComponentName = new ComponentName(
4606                mAndroidApplication.packageName, className);
4607        ActivityInfo forwardingActivityInfo = getActivityInfo(forwardingActivityComponentName, 0,
4608                sourceUserId);
4609        if (targetUserId == UserHandle.USER_OWNER) {
4610            forwardingActivityInfo.showUserIcon = UserHandle.USER_OWNER;
4611            forwardingResolveInfo.noResourceId = true;
4612        }
4613        forwardingResolveInfo.activityInfo = forwardingActivityInfo;
4614        forwardingResolveInfo.priority = 0;
4615        forwardingResolveInfo.preferredOrder = 0;
4616        forwardingResolveInfo.match = 0;
4617        forwardingResolveInfo.isDefault = true;
4618        forwardingResolveInfo.filter = filter;
4619        forwardingResolveInfo.targetUserId = targetUserId;
4620        return forwardingResolveInfo;
4621    }
4622
4623    @Override
4624    public List<ResolveInfo> queryIntentActivityOptions(ComponentName caller,
4625            Intent[] specifics, String[] specificTypes, Intent intent,
4626            String resolvedType, int flags, int userId) {
4627        if (!sUserManager.exists(userId)) return Collections.emptyList();
4628        enforceCrossUserPermission(Binder.getCallingUid(), userId, false,
4629                false, "query intent activity options");
4630        final String resultsAction = intent.getAction();
4631
4632        List<ResolveInfo> results = queryIntentActivities(intent, resolvedType, flags
4633                | PackageManager.GET_RESOLVED_FILTER, userId);
4634
4635        if (DEBUG_INTENT_MATCHING) {
4636            Log.v(TAG, "Query " + intent + ": " + results);
4637        }
4638
4639        int specificsPos = 0;
4640        int N;
4641
4642        // todo: note that the algorithm used here is O(N^2).  This
4643        // isn't a problem in our current environment, but if we start running
4644        // into situations where we have more than 5 or 10 matches then this
4645        // should probably be changed to something smarter...
4646
4647        // First we go through and resolve each of the specific items
4648        // that were supplied, taking care of removing any corresponding
4649        // duplicate items in the generic resolve list.
4650        if (specifics != null) {
4651            for (int i=0; i<specifics.length; i++) {
4652                final Intent sintent = specifics[i];
4653                if (sintent == null) {
4654                    continue;
4655                }
4656
4657                if (DEBUG_INTENT_MATCHING) {
4658                    Log.v(TAG, "Specific #" + i + ": " + sintent);
4659                }
4660
4661                String action = sintent.getAction();
4662                if (resultsAction != null && resultsAction.equals(action)) {
4663                    // If this action was explicitly requested, then don't
4664                    // remove things that have it.
4665                    action = null;
4666                }
4667
4668                ResolveInfo ri = null;
4669                ActivityInfo ai = null;
4670
4671                ComponentName comp = sintent.getComponent();
4672                if (comp == null) {
4673                    ri = resolveIntent(
4674                        sintent,
4675                        specificTypes != null ? specificTypes[i] : null,
4676                            flags, userId);
4677                    if (ri == null) {
4678                        continue;
4679                    }
4680                    if (ri == mResolveInfo) {
4681                        // ACK!  Must do something better with this.
4682                    }
4683                    ai = ri.activityInfo;
4684                    comp = new ComponentName(ai.applicationInfo.packageName,
4685                            ai.name);
4686                } else {
4687                    ai = getActivityInfo(comp, flags, userId);
4688                    if (ai == null) {
4689                        continue;
4690                    }
4691                }
4692
4693                // Look for any generic query activities that are duplicates
4694                // of this specific one, and remove them from the results.
4695                if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Specific #" + i + ": " + ai);
4696                N = results.size();
4697                int j;
4698                for (j=specificsPos; j<N; j++) {
4699                    ResolveInfo sri = results.get(j);
4700                    if ((sri.activityInfo.name.equals(comp.getClassName())
4701                            && sri.activityInfo.applicationInfo.packageName.equals(
4702                                    comp.getPackageName()))
4703                        || (action != null && sri.filter.matchAction(action))) {
4704                        results.remove(j);
4705                        if (DEBUG_INTENT_MATCHING) Log.v(
4706                            TAG, "Removing duplicate item from " + j
4707                            + " due to specific " + specificsPos);
4708                        if (ri == null) {
4709                            ri = sri;
4710                        }
4711                        j--;
4712                        N--;
4713                    }
4714                }
4715
4716                // Add this specific item to its proper place.
4717                if (ri == null) {
4718                    ri = new ResolveInfo();
4719                    ri.activityInfo = ai;
4720                }
4721                results.add(specificsPos, ri);
4722                ri.specificIndex = i;
4723                specificsPos++;
4724            }
4725        }
4726
4727        // Now we go through the remaining generic results and remove any
4728        // duplicate actions that are found here.
4729        N = results.size();
4730        for (int i=specificsPos; i<N-1; i++) {
4731            final ResolveInfo rii = results.get(i);
4732            if (rii.filter == null) {
4733                continue;
4734            }
4735
4736            // Iterate over all of the actions of this result's intent
4737            // filter...  typically this should be just one.
4738            final Iterator<String> it = rii.filter.actionsIterator();
4739            if (it == null) {
4740                continue;
4741            }
4742            while (it.hasNext()) {
4743                final String action = it.next();
4744                if (resultsAction != null && resultsAction.equals(action)) {
4745                    // If this action was explicitly requested, then don't
4746                    // remove things that have it.
4747                    continue;
4748                }
4749                for (int j=i+1; j<N; j++) {
4750                    final ResolveInfo rij = results.get(j);
4751                    if (rij.filter != null && rij.filter.hasAction(action)) {
4752                        results.remove(j);
4753                        if (DEBUG_INTENT_MATCHING) Log.v(
4754                            TAG, "Removing duplicate item from " + j
4755                            + " due to action " + action + " at " + i);
4756                        j--;
4757                        N--;
4758                    }
4759                }
4760            }
4761
4762            // If the caller didn't request filter information, drop it now
4763            // so we don't have to marshall/unmarshall it.
4764            if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
4765                rii.filter = null;
4766            }
4767        }
4768
4769        // Filter out the caller activity if so requested.
4770        if (caller != null) {
4771            N = results.size();
4772            for (int i=0; i<N; i++) {
4773                ActivityInfo ainfo = results.get(i).activityInfo;
4774                if (caller.getPackageName().equals(ainfo.applicationInfo.packageName)
4775                        && caller.getClassName().equals(ainfo.name)) {
4776                    results.remove(i);
4777                    break;
4778                }
4779            }
4780        }
4781
4782        // If the caller didn't request filter information,
4783        // drop them now so we don't have to
4784        // marshall/unmarshall it.
4785        if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
4786            N = results.size();
4787            for (int i=0; i<N; i++) {
4788                results.get(i).filter = null;
4789            }
4790        }
4791
4792        if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Result: " + results);
4793        return results;
4794    }
4795
4796    @Override
4797    public List<ResolveInfo> queryIntentReceivers(Intent intent, String resolvedType, int flags,
4798            int userId) {
4799        if (!sUserManager.exists(userId)) return Collections.emptyList();
4800        ComponentName comp = intent.getComponent();
4801        if (comp == null) {
4802            if (intent.getSelector() != null) {
4803                intent = intent.getSelector();
4804                comp = intent.getComponent();
4805            }
4806        }
4807        if (comp != null) {
4808            List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
4809            ActivityInfo ai = getReceiverInfo(comp, flags, userId);
4810            if (ai != null) {
4811                ResolveInfo ri = new ResolveInfo();
4812                ri.activityInfo = ai;
4813                list.add(ri);
4814            }
4815            return list;
4816        }
4817
4818        // reader
4819        synchronized (mPackages) {
4820            String pkgName = intent.getPackage();
4821            if (pkgName == null) {
4822                return mReceivers.queryIntent(intent, resolvedType, flags, userId);
4823            }
4824            final PackageParser.Package pkg = mPackages.get(pkgName);
4825            if (pkg != null) {
4826                return mReceivers.queryIntentForPackage(intent, resolvedType, flags, pkg.receivers,
4827                        userId);
4828            }
4829            return null;
4830        }
4831    }
4832
4833    @Override
4834    public ResolveInfo resolveService(Intent intent, String resolvedType, int flags, int userId) {
4835        List<ResolveInfo> query = queryIntentServices(intent, resolvedType, flags, userId);
4836        if (!sUserManager.exists(userId)) return null;
4837        if (query != null) {
4838            if (query.size() >= 1) {
4839                // If there is more than one service with the same priority,
4840                // just arbitrarily pick the first one.
4841                return query.get(0);
4842            }
4843        }
4844        return null;
4845    }
4846
4847    @Override
4848    public List<ResolveInfo> queryIntentServices(Intent intent, String resolvedType, int flags,
4849            int userId) {
4850        if (!sUserManager.exists(userId)) return Collections.emptyList();
4851        ComponentName comp = intent.getComponent();
4852        if (comp == null) {
4853            if (intent.getSelector() != null) {
4854                intent = intent.getSelector();
4855                comp = intent.getComponent();
4856            }
4857        }
4858        if (comp != null) {
4859            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
4860            final ServiceInfo si = getServiceInfo(comp, flags, userId);
4861            if (si != null) {
4862                final ResolveInfo ri = new ResolveInfo();
4863                ri.serviceInfo = si;
4864                list.add(ri);
4865            }
4866            return list;
4867        }
4868
4869        // reader
4870        synchronized (mPackages) {
4871            String pkgName = intent.getPackage();
4872            if (pkgName == null) {
4873                return mServices.queryIntent(intent, resolvedType, flags, userId);
4874            }
4875            final PackageParser.Package pkg = mPackages.get(pkgName);
4876            if (pkg != null) {
4877                return mServices.queryIntentForPackage(intent, resolvedType, flags, pkg.services,
4878                        userId);
4879            }
4880            return null;
4881        }
4882    }
4883
4884    @Override
4885    public List<ResolveInfo> queryIntentContentProviders(
4886            Intent intent, String resolvedType, int flags, int userId) {
4887        if (!sUserManager.exists(userId)) return Collections.emptyList();
4888        ComponentName comp = intent.getComponent();
4889        if (comp == null) {
4890            if (intent.getSelector() != null) {
4891                intent = intent.getSelector();
4892                comp = intent.getComponent();
4893            }
4894        }
4895        if (comp != null) {
4896            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
4897            final ProviderInfo pi = getProviderInfo(comp, flags, userId);
4898            if (pi != null) {
4899                final ResolveInfo ri = new ResolveInfo();
4900                ri.providerInfo = pi;
4901                list.add(ri);
4902            }
4903            return list;
4904        }
4905
4906        // reader
4907        synchronized (mPackages) {
4908            String pkgName = intent.getPackage();
4909            if (pkgName == null) {
4910                return mProviders.queryIntent(intent, resolvedType, flags, userId);
4911            }
4912            final PackageParser.Package pkg = mPackages.get(pkgName);
4913            if (pkg != null) {
4914                return mProviders.queryIntentForPackage(
4915                        intent, resolvedType, flags, pkg.providers, userId);
4916            }
4917            return null;
4918        }
4919    }
4920
4921    @Override
4922    public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) {
4923        final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0;
4924
4925        enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, "get installed packages");
4926
4927        // writer
4928        synchronized (mPackages) {
4929            ArrayList<PackageInfo> list;
4930            if (listUninstalled) {
4931                list = new ArrayList<PackageInfo>(mSettings.mPackages.size());
4932                for (PackageSetting ps : mSettings.mPackages.values()) {
4933                    PackageInfo pi;
4934                    if (ps.pkg != null) {
4935                        pi = generatePackageInfo(ps.pkg, flags, userId);
4936                    } else {
4937                        pi = generatePackageInfoFromSettingsLPw(ps.name, flags, userId);
4938                    }
4939                    if (pi != null) {
4940                        list.add(pi);
4941                    }
4942                }
4943            } else {
4944                list = new ArrayList<PackageInfo>(mPackages.size());
4945                for (PackageParser.Package p : mPackages.values()) {
4946                    PackageInfo pi = generatePackageInfo(p, flags, userId);
4947                    if (pi != null) {
4948                        list.add(pi);
4949                    }
4950                }
4951            }
4952
4953            return new ParceledListSlice<PackageInfo>(list);
4954        }
4955    }
4956
4957    private void addPackageHoldingPermissions(ArrayList<PackageInfo> list, PackageSetting ps,
4958            String[] permissions, boolean[] tmp, int flags, int userId) {
4959        int numMatch = 0;
4960        final PermissionsState permissionsState = ps.getPermissionsState();
4961        for (int i=0; i<permissions.length; i++) {
4962            final String permission = permissions[i];
4963            if (permissionsState.hasPermission(permission, userId)) {
4964                tmp[i] = true;
4965                numMatch++;
4966            } else {
4967                tmp[i] = false;
4968            }
4969        }
4970        if (numMatch == 0) {
4971            return;
4972        }
4973        PackageInfo pi;
4974        if (ps.pkg != null) {
4975            pi = generatePackageInfo(ps.pkg, flags, userId);
4976        } else {
4977            pi = generatePackageInfoFromSettingsLPw(ps.name, flags, userId);
4978        }
4979        // The above might return null in cases of uninstalled apps or install-state
4980        // skew across users/profiles.
4981        if (pi != null) {
4982            if ((flags&PackageManager.GET_PERMISSIONS) == 0) {
4983                if (numMatch == permissions.length) {
4984                    pi.requestedPermissions = permissions;
4985                } else {
4986                    pi.requestedPermissions = new String[numMatch];
4987                    numMatch = 0;
4988                    for (int i=0; i<permissions.length; i++) {
4989                        if (tmp[i]) {
4990                            pi.requestedPermissions[numMatch] = permissions[i];
4991                            numMatch++;
4992                        }
4993                    }
4994                }
4995            }
4996            list.add(pi);
4997        }
4998    }
4999
5000    @Override
5001    public ParceledListSlice<PackageInfo> getPackagesHoldingPermissions(
5002            String[] permissions, int flags, int userId) {
5003        if (!sUserManager.exists(userId)) return null;
5004        final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0;
5005
5006        // writer
5007        synchronized (mPackages) {
5008            ArrayList<PackageInfo> list = new ArrayList<PackageInfo>();
5009            boolean[] tmpBools = new boolean[permissions.length];
5010            if (listUninstalled) {
5011                for (PackageSetting ps : mSettings.mPackages.values()) {
5012                    addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags, userId);
5013                }
5014            } else {
5015                for (PackageParser.Package pkg : mPackages.values()) {
5016                    PackageSetting ps = (PackageSetting)pkg.mExtras;
5017                    if (ps != null) {
5018                        addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags,
5019                                userId);
5020                    }
5021                }
5022            }
5023
5024            return new ParceledListSlice<PackageInfo>(list);
5025        }
5026    }
5027
5028    @Override
5029    public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags, int userId) {
5030        if (!sUserManager.exists(userId)) return null;
5031        final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0;
5032
5033        // writer
5034        synchronized (mPackages) {
5035            ArrayList<ApplicationInfo> list;
5036            if (listUninstalled) {
5037                list = new ArrayList<ApplicationInfo>(mSettings.mPackages.size());
5038                for (PackageSetting ps : mSettings.mPackages.values()) {
5039                    ApplicationInfo ai;
5040                    if (ps.pkg != null) {
5041                        ai = PackageParser.generateApplicationInfo(ps.pkg, flags,
5042                                ps.readUserState(userId), userId);
5043                    } else {
5044                        ai = generateApplicationInfoFromSettingsLPw(ps.name, flags, userId);
5045                    }
5046                    if (ai != null) {
5047                        list.add(ai);
5048                    }
5049                }
5050            } else {
5051                list = new ArrayList<ApplicationInfo>(mPackages.size());
5052                for (PackageParser.Package p : mPackages.values()) {
5053                    if (p.mExtras != null) {
5054                        ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
5055                                ((PackageSetting)p.mExtras).readUserState(userId), userId);
5056                        if (ai != null) {
5057                            list.add(ai);
5058                        }
5059                    }
5060                }
5061            }
5062
5063            return new ParceledListSlice<ApplicationInfo>(list);
5064        }
5065    }
5066
5067    public List<ApplicationInfo> getPersistentApplications(int flags) {
5068        final ArrayList<ApplicationInfo> finalList = new ArrayList<ApplicationInfo>();
5069
5070        // reader
5071        synchronized (mPackages) {
5072            final Iterator<PackageParser.Package> i = mPackages.values().iterator();
5073            final int userId = UserHandle.getCallingUserId();
5074            while (i.hasNext()) {
5075                final PackageParser.Package p = i.next();
5076                if (p.applicationInfo != null
5077                        && (p.applicationInfo.flags&ApplicationInfo.FLAG_PERSISTENT) != 0
5078                        && (!mSafeMode || isSystemApp(p))) {
5079                    PackageSetting ps = mSettings.mPackages.get(p.packageName);
5080                    if (ps != null) {
5081                        ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
5082                                ps.readUserState(userId), userId);
5083                        if (ai != null) {
5084                            finalList.add(ai);
5085                        }
5086                    }
5087                }
5088            }
5089        }
5090
5091        return finalList;
5092    }
5093
5094    @Override
5095    public ProviderInfo resolveContentProvider(String name, int flags, int userId) {
5096        if (!sUserManager.exists(userId)) return null;
5097        // reader
5098        synchronized (mPackages) {
5099            final PackageParser.Provider provider = mProvidersByAuthority.get(name);
5100            PackageSetting ps = provider != null
5101                    ? mSettings.mPackages.get(provider.owner.packageName)
5102                    : null;
5103            return ps != null
5104                    && mSettings.isEnabledLPr(provider.info, flags, userId)
5105                    && (!mSafeMode || (provider.info.applicationInfo.flags
5106                            &ApplicationInfo.FLAG_SYSTEM) != 0)
5107                    ? PackageParser.generateProviderInfo(provider, flags,
5108                            ps.readUserState(userId), userId)
5109                    : null;
5110        }
5111    }
5112
5113    /**
5114     * @deprecated
5115     */
5116    @Deprecated
5117    public void querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo) {
5118        // reader
5119        synchronized (mPackages) {
5120            final Iterator<Map.Entry<String, PackageParser.Provider>> i = mProvidersByAuthority
5121                    .entrySet().iterator();
5122            final int userId = UserHandle.getCallingUserId();
5123            while (i.hasNext()) {
5124                Map.Entry<String, PackageParser.Provider> entry = i.next();
5125                PackageParser.Provider p = entry.getValue();
5126                PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
5127
5128                if (ps != null && p.syncable
5129                        && (!mSafeMode || (p.info.applicationInfo.flags
5130                                &ApplicationInfo.FLAG_SYSTEM) != 0)) {
5131                    ProviderInfo info = PackageParser.generateProviderInfo(p, 0,
5132                            ps.readUserState(userId), userId);
5133                    if (info != null) {
5134                        outNames.add(entry.getKey());
5135                        outInfo.add(info);
5136                    }
5137                }
5138            }
5139        }
5140    }
5141
5142    @Override
5143    public List<ProviderInfo> queryContentProviders(String processName,
5144            int uid, int flags) {
5145        ArrayList<ProviderInfo> finalList = null;
5146        // reader
5147        synchronized (mPackages) {
5148            final Iterator<PackageParser.Provider> i = mProviders.mProviders.values().iterator();
5149            final int userId = processName != null ?
5150                    UserHandle.getUserId(uid) : UserHandle.getCallingUserId();
5151            while (i.hasNext()) {
5152                final PackageParser.Provider p = i.next();
5153                PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
5154                if (ps != null && p.info.authority != null
5155                        && (processName == null
5156                                || (p.info.processName.equals(processName)
5157                                        && UserHandle.isSameApp(p.info.applicationInfo.uid, uid)))
5158                        && mSettings.isEnabledLPr(p.info, flags, userId)
5159                        && (!mSafeMode
5160                                || (p.info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0)) {
5161                    if (finalList == null) {
5162                        finalList = new ArrayList<ProviderInfo>(3);
5163                    }
5164                    ProviderInfo info = PackageParser.generateProviderInfo(p, flags,
5165                            ps.readUserState(userId), userId);
5166                    if (info != null) {
5167                        finalList.add(info);
5168                    }
5169                }
5170            }
5171        }
5172
5173        if (finalList != null) {
5174            Collections.sort(finalList, mProviderInitOrderSorter);
5175        }
5176
5177        return finalList;
5178    }
5179
5180    @Override
5181    public InstrumentationInfo getInstrumentationInfo(ComponentName name,
5182            int flags) {
5183        // reader
5184        synchronized (mPackages) {
5185            final PackageParser.Instrumentation i = mInstrumentation.get(name);
5186            return PackageParser.generateInstrumentationInfo(i, flags);
5187        }
5188    }
5189
5190    @Override
5191    public List<InstrumentationInfo> queryInstrumentation(String targetPackage,
5192            int flags) {
5193        ArrayList<InstrumentationInfo> finalList =
5194            new ArrayList<InstrumentationInfo>();
5195
5196        // reader
5197        synchronized (mPackages) {
5198            final Iterator<PackageParser.Instrumentation> i = mInstrumentation.values().iterator();
5199            while (i.hasNext()) {
5200                final PackageParser.Instrumentation p = i.next();
5201                if (targetPackage == null
5202                        || targetPackage.equals(p.info.targetPackage)) {
5203                    InstrumentationInfo ii = PackageParser.generateInstrumentationInfo(p,
5204                            flags);
5205                    if (ii != null) {
5206                        finalList.add(ii);
5207                    }
5208                }
5209            }
5210        }
5211
5212        return finalList;
5213    }
5214
5215    private void createIdmapsForPackageLI(PackageParser.Package pkg) {
5216        ArrayMap<String, PackageParser.Package> overlays = mOverlays.get(pkg.packageName);
5217        if (overlays == null) {
5218            Slog.w(TAG, "Unable to create idmap for " + pkg.packageName + ": no overlay packages");
5219            return;
5220        }
5221        for (PackageParser.Package opkg : overlays.values()) {
5222            // Not much to do if idmap fails: we already logged the error
5223            // and we certainly don't want to abort installation of pkg simply
5224            // because an overlay didn't fit properly. For these reasons,
5225            // ignore the return value of createIdmapForPackagePairLI.
5226            createIdmapForPackagePairLI(pkg, opkg);
5227        }
5228    }
5229
5230    private boolean createIdmapForPackagePairLI(PackageParser.Package pkg,
5231            PackageParser.Package opkg) {
5232        if (!opkg.mTrustedOverlay) {
5233            Slog.w(TAG, "Skipping target and overlay pair " + pkg.baseCodePath + " and " +
5234                    opkg.baseCodePath + ": overlay not trusted");
5235            return false;
5236        }
5237        ArrayMap<String, PackageParser.Package> overlaySet = mOverlays.get(pkg.packageName);
5238        if (overlaySet == null) {
5239            Slog.e(TAG, "was about to create idmap for " + pkg.baseCodePath + " and " +
5240                    opkg.baseCodePath + " but target package has no known overlays");
5241            return false;
5242        }
5243        final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
5244        // TODO: generate idmap for split APKs
5245        if (mInstaller.idmap(pkg.baseCodePath, opkg.baseCodePath, sharedGid) != 0) {
5246            Slog.e(TAG, "Failed to generate idmap for " + pkg.baseCodePath + " and "
5247                    + opkg.baseCodePath);
5248            return false;
5249        }
5250        PackageParser.Package[] overlayArray =
5251            overlaySet.values().toArray(new PackageParser.Package[0]);
5252        Comparator<PackageParser.Package> cmp = new Comparator<PackageParser.Package>() {
5253            public int compare(PackageParser.Package p1, PackageParser.Package p2) {
5254                return p1.mOverlayPriority - p2.mOverlayPriority;
5255            }
5256        };
5257        Arrays.sort(overlayArray, cmp);
5258
5259        pkg.applicationInfo.resourceDirs = new String[overlayArray.length];
5260        int i = 0;
5261        for (PackageParser.Package p : overlayArray) {
5262            pkg.applicationInfo.resourceDirs[i++] = p.baseCodePath;
5263        }
5264        return true;
5265    }
5266
5267    private void scanDirLI(File dir, int parseFlags, int scanFlags, long currentTime) {
5268        final File[] files = dir.listFiles();
5269        if (ArrayUtils.isEmpty(files)) {
5270            Log.d(TAG, "No files in app dir " + dir);
5271            return;
5272        }
5273
5274        if (DEBUG_PACKAGE_SCANNING) {
5275            Log.d(TAG, "Scanning app dir " + dir + " scanFlags=" + scanFlags
5276                    + " flags=0x" + Integer.toHexString(parseFlags));
5277        }
5278
5279        for (File file : files) {
5280            final boolean isPackage = (isApkFile(file) || file.isDirectory())
5281                    && !PackageInstallerService.isStageName(file.getName());
5282            if (!isPackage) {
5283                // Ignore entries which are not packages
5284                continue;
5285            }
5286            try {
5287                scanPackageLI(file, parseFlags | PackageParser.PARSE_MUST_BE_APK,
5288                        scanFlags, currentTime, null);
5289            } catch (PackageManagerException e) {
5290                Slog.w(TAG, "Failed to parse " + file + ": " + e.getMessage());
5291
5292                // Delete invalid userdata apps
5293                if ((parseFlags & PackageParser.PARSE_IS_SYSTEM) == 0 &&
5294                        e.error == PackageManager.INSTALL_FAILED_INVALID_APK) {
5295                    logCriticalInfo(Log.WARN, "Deleting invalid package at " + file);
5296                    if (file.isDirectory()) {
5297                        mInstaller.rmPackageDir(file.getAbsolutePath());
5298                    } else {
5299                        file.delete();
5300                    }
5301                }
5302            }
5303        }
5304    }
5305
5306    private static File getSettingsProblemFile() {
5307        File dataDir = Environment.getDataDirectory();
5308        File systemDir = new File(dataDir, "system");
5309        File fname = new File(systemDir, "uiderrors.txt");
5310        return fname;
5311    }
5312
5313    static void reportSettingsProblem(int priority, String msg) {
5314        logCriticalInfo(priority, msg);
5315    }
5316
5317    static void logCriticalInfo(int priority, String msg) {
5318        Slog.println(priority, TAG, msg);
5319        EventLogTags.writePmCriticalInfo(msg);
5320        try {
5321            File fname = getSettingsProblemFile();
5322            FileOutputStream out = new FileOutputStream(fname, true);
5323            PrintWriter pw = new FastPrintWriter(out);
5324            SimpleDateFormat formatter = new SimpleDateFormat();
5325            String dateString = formatter.format(new Date(System.currentTimeMillis()));
5326            pw.println(dateString + ": " + msg);
5327            pw.close();
5328            FileUtils.setPermissions(
5329                    fname.toString(),
5330                    FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IROTH,
5331                    -1, -1);
5332        } catch (java.io.IOException e) {
5333        }
5334    }
5335
5336    private void collectCertificatesLI(PackageParser pp, PackageSetting ps,
5337            PackageParser.Package pkg, File srcFile, int parseFlags)
5338            throws PackageManagerException {
5339        if (ps != null
5340                && ps.codePath.equals(srcFile)
5341                && ps.timeStamp == srcFile.lastModified()
5342                && !isCompatSignatureUpdateNeeded(pkg)
5343                && !isRecoverSignatureUpdateNeeded(pkg)) {
5344            long mSigningKeySetId = ps.keySetData.getProperSigningKeySet();
5345            KeySetManagerService ksms = mSettings.mKeySetManagerService;
5346            ArraySet<PublicKey> signingKs;
5347            synchronized (mPackages) {
5348                signingKs = ksms.getPublicKeysFromKeySetLPr(mSigningKeySetId);
5349            }
5350            if (ps.signatures.mSignatures != null
5351                    && ps.signatures.mSignatures.length != 0
5352                    && signingKs != null) {
5353                // Optimization: reuse the existing cached certificates
5354                // if the package appears to be unchanged.
5355                pkg.mSignatures = ps.signatures.mSignatures;
5356                pkg.mSigningKeys = signingKs;
5357                return;
5358            }
5359
5360            Slog.w(TAG, "PackageSetting for " + ps.name
5361                    + " is missing signatures.  Collecting certs again to recover them.");
5362        } else {
5363            Log.i(TAG, srcFile.toString() + " changed; collecting certs");
5364        }
5365
5366        try {
5367            pp.collectCertificates(pkg, parseFlags);
5368            pp.collectManifestDigest(pkg);
5369        } catch (PackageParserException e) {
5370            throw PackageManagerException.from(e);
5371        }
5372    }
5373
5374    /*
5375     *  Scan a package and return the newly parsed package.
5376     *  Returns null in case of errors and the error code is stored in mLastScanError
5377     */
5378    private PackageParser.Package scanPackageLI(File scanFile, int parseFlags, int scanFlags,
5379            long currentTime, UserHandle user) throws PackageManagerException {
5380        if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanFile);
5381        parseFlags |= mDefParseFlags;
5382        PackageParser pp = new PackageParser();
5383        pp.setSeparateProcesses(mSeparateProcesses);
5384        pp.setOnlyCoreApps(mOnlyCore);
5385        pp.setDisplayMetrics(mMetrics);
5386
5387        if ((scanFlags & SCAN_TRUSTED_OVERLAY) != 0) {
5388            parseFlags |= PackageParser.PARSE_TRUSTED_OVERLAY;
5389        }
5390
5391        final PackageParser.Package pkg;
5392        try {
5393            pkg = pp.parsePackage(scanFile, parseFlags);
5394        } catch (PackageParserException e) {
5395            throw PackageManagerException.from(e);
5396        }
5397
5398        PackageSetting ps = null;
5399        PackageSetting updatedPkg;
5400        // reader
5401        synchronized (mPackages) {
5402            // Look to see if we already know about this package.
5403            String oldName = mSettings.mRenamedPackages.get(pkg.packageName);
5404            if (pkg.mOriginalPackages != null && pkg.mOriginalPackages.contains(oldName)) {
5405                // This package has been renamed to its original name.  Let's
5406                // use that.
5407                ps = mSettings.peekPackageLPr(oldName);
5408            }
5409            // If there was no original package, see one for the real package name.
5410            if (ps == null) {
5411                ps = mSettings.peekPackageLPr(pkg.packageName);
5412            }
5413            // Check to see if this package could be hiding/updating a system
5414            // package.  Must look for it either under the original or real
5415            // package name depending on our state.
5416            updatedPkg = mSettings.getDisabledSystemPkgLPr(ps != null ? ps.name : pkg.packageName);
5417            if (DEBUG_INSTALL && updatedPkg != null) Slog.d(TAG, "updatedPkg = " + updatedPkg);
5418        }
5419        boolean updatedPkgBetter = false;
5420        // First check if this is a system package that may involve an update
5421        if (updatedPkg != null && (parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) {
5422            // If new package is not located in "/system/priv-app" (e.g. due to an OTA),
5423            // it needs to drop FLAG_PRIVILEGED.
5424            if (locationIsPrivileged(scanFile)) {
5425                updatedPkg.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
5426            } else {
5427                updatedPkg.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
5428            }
5429
5430            if (ps != null && !ps.codePath.equals(scanFile)) {
5431                // The path has changed from what was last scanned...  check the
5432                // version of the new path against what we have stored to determine
5433                // what to do.
5434                if (DEBUG_INSTALL) Slog.d(TAG, "Path changing from " + ps.codePath);
5435                if (pkg.mVersionCode <= ps.versionCode) {
5436                    // The system package has been updated and the code path does not match
5437                    // Ignore entry. Skip it.
5438                    Slog.i(TAG, "Package " + ps.name + " at " + scanFile
5439                            + " ignored: updated version " + ps.versionCode
5440                            + " better than this " + pkg.mVersionCode);
5441                    if (!updatedPkg.codePath.equals(scanFile)) {
5442                        Slog.w(PackageManagerService.TAG, "Code path for hidden system pkg : "
5443                                + ps.name + " changing from " + updatedPkg.codePathString
5444                                + " to " + scanFile);
5445                        updatedPkg.codePath = scanFile;
5446                        updatedPkg.codePathString = scanFile.toString();
5447                        updatedPkg.resourcePath = scanFile;
5448                        updatedPkg.resourcePathString = scanFile.toString();
5449                    }
5450                    updatedPkg.pkg = pkg;
5451                    throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE, null);
5452                } else {
5453                    // The current app on the system partition is better than
5454                    // what we have updated to on the data partition; switch
5455                    // back to the system partition version.
5456                    // At this point, its safely assumed that package installation for
5457                    // apps in system partition will go through. If not there won't be a working
5458                    // version of the app
5459                    // writer
5460                    synchronized (mPackages) {
5461                        // Just remove the loaded entries from package lists.
5462                        mPackages.remove(ps.name);
5463                    }
5464
5465                    logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile
5466                            + " reverting from " + ps.codePathString
5467                            + ": new version " + pkg.mVersionCode
5468                            + " better than installed " + ps.versionCode);
5469
5470                    InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
5471                            ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
5472                    synchronized (mInstallLock) {
5473                        args.cleanUpResourcesLI();
5474                    }
5475                    synchronized (mPackages) {
5476                        mSettings.enableSystemPackageLPw(ps.name);
5477                    }
5478                    updatedPkgBetter = true;
5479                }
5480            }
5481        }
5482
5483        if (updatedPkg != null) {
5484            // An updated system app will not have the PARSE_IS_SYSTEM flag set
5485            // initially
5486            parseFlags |= PackageParser.PARSE_IS_SYSTEM;
5487
5488            // An updated privileged app will not have the PARSE_IS_PRIVILEGED
5489            // flag set initially
5490            if ((updatedPkg.pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0) {
5491                parseFlags |= PackageParser.PARSE_IS_PRIVILEGED;
5492            }
5493        }
5494
5495        // Verify certificates against what was last scanned
5496        collectCertificatesLI(pp, ps, pkg, scanFile, parseFlags);
5497
5498        /*
5499         * A new system app appeared, but we already had a non-system one of the
5500         * same name installed earlier.
5501         */
5502        boolean shouldHideSystemApp = false;
5503        if (updatedPkg == null && ps != null
5504                && (parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0 && !isSystemApp(ps)) {
5505            /*
5506             * Check to make sure the signatures match first. If they don't,
5507             * wipe the installed application and its data.
5508             */
5509            if (compareSignatures(ps.signatures.mSignatures, pkg.mSignatures)
5510                    != PackageManager.SIGNATURE_MATCH) {
5511                logCriticalInfo(Log.WARN, "Package " + ps.name + " appeared on system, but"
5512                        + " signatures don't match existing userdata copy; removing");
5513                deletePackageLI(pkg.packageName, null, true, null, null, 0, null, false);
5514                ps = null;
5515            } else {
5516                /*
5517                 * If the newly-added system app is an older version than the
5518                 * already installed version, hide it. It will be scanned later
5519                 * and re-added like an update.
5520                 */
5521                if (pkg.mVersionCode <= ps.versionCode) {
5522                    shouldHideSystemApp = true;
5523                    logCriticalInfo(Log.INFO, "Package " + ps.name + " appeared at " + scanFile
5524                            + " but new version " + pkg.mVersionCode + " better than installed "
5525                            + ps.versionCode + "; hiding system");
5526                } else {
5527                    /*
5528                     * The newly found system app is a newer version that the
5529                     * one previously installed. Simply remove the
5530                     * already-installed application and replace it with our own
5531                     * while keeping the application data.
5532                     */
5533                    logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile
5534                            + " reverting from " + ps.codePathString + ": new version "
5535                            + pkg.mVersionCode + " better than installed " + ps.versionCode);
5536                    InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
5537                            ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
5538                    synchronized (mInstallLock) {
5539                        args.cleanUpResourcesLI();
5540                    }
5541                }
5542            }
5543        }
5544
5545        // The apk is forward locked (not public) if its code and resources
5546        // are kept in different files. (except for app in either system or
5547        // vendor path).
5548        // TODO grab this value from PackageSettings
5549        if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
5550            if (ps != null && !ps.codePath.equals(ps.resourcePath)) {
5551                parseFlags |= PackageParser.PARSE_FORWARD_LOCK;
5552            }
5553        }
5554
5555        // TODO: extend to support forward-locked splits
5556        String resourcePath = null;
5557        String baseResourcePath = null;
5558        if ((parseFlags & PackageParser.PARSE_FORWARD_LOCK) != 0 && !updatedPkgBetter) {
5559            if (ps != null && ps.resourcePathString != null) {
5560                resourcePath = ps.resourcePathString;
5561                baseResourcePath = ps.resourcePathString;
5562            } else {
5563                // Should not happen at all. Just log an error.
5564                Slog.e(TAG, "Resource path not set for pkg : " + pkg.packageName);
5565            }
5566        } else {
5567            resourcePath = pkg.codePath;
5568            baseResourcePath = pkg.baseCodePath;
5569        }
5570
5571        // Set application objects path explicitly.
5572        pkg.applicationInfo.volumeUuid = pkg.volumeUuid;
5573        pkg.applicationInfo.setCodePath(pkg.codePath);
5574        pkg.applicationInfo.setBaseCodePath(pkg.baseCodePath);
5575        pkg.applicationInfo.setSplitCodePaths(pkg.splitCodePaths);
5576        pkg.applicationInfo.setResourcePath(resourcePath);
5577        pkg.applicationInfo.setBaseResourcePath(baseResourcePath);
5578        pkg.applicationInfo.setSplitResourcePaths(pkg.splitCodePaths);
5579
5580        // Note that we invoke the following method only if we are about to unpack an application
5581        PackageParser.Package scannedPkg = scanPackageLI(pkg, parseFlags, scanFlags
5582                | SCAN_UPDATE_SIGNATURE, currentTime, user);
5583
5584        /*
5585         * If the system app should be overridden by a previously installed
5586         * data, hide the system app now and let the /data/app scan pick it up
5587         * again.
5588         */
5589        if (shouldHideSystemApp) {
5590            synchronized (mPackages) {
5591                /*
5592                 * We have to grant systems permissions before we hide, because
5593                 * grantPermissions will assume the package update is trying to
5594                 * expand its permissions.
5595                 */
5596                grantPermissionsLPw(pkg, true, pkg.packageName);
5597                mSettings.disableSystemPackageLPw(pkg.packageName);
5598            }
5599        }
5600
5601        return scannedPkg;
5602    }
5603
5604    private static String fixProcessName(String defProcessName,
5605            String processName, int uid) {
5606        if (processName == null) {
5607            return defProcessName;
5608        }
5609        return processName;
5610    }
5611
5612    private void verifySignaturesLP(PackageSetting pkgSetting, PackageParser.Package pkg)
5613            throws PackageManagerException {
5614        if (pkgSetting.signatures.mSignatures != null) {
5615            // Already existing package. Make sure signatures match
5616            boolean match = compareSignatures(pkgSetting.signatures.mSignatures, pkg.mSignatures)
5617                    == PackageManager.SIGNATURE_MATCH;
5618            if (!match) {
5619                match = compareSignaturesCompat(pkgSetting.signatures, pkg)
5620                        == PackageManager.SIGNATURE_MATCH;
5621            }
5622            if (!match) {
5623                match = compareSignaturesRecover(pkgSetting.signatures, pkg)
5624                        == PackageManager.SIGNATURE_MATCH;
5625            }
5626            if (!match) {
5627                throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
5628                        + pkg.packageName + " signatures do not match the "
5629                        + "previously installed version; ignoring!");
5630            }
5631        }
5632
5633        // Check for shared user signatures
5634        if (pkgSetting.sharedUser != null && pkgSetting.sharedUser.signatures.mSignatures != null) {
5635            // Already existing package. Make sure signatures match
5636            boolean match = compareSignatures(pkgSetting.sharedUser.signatures.mSignatures,
5637                    pkg.mSignatures) == PackageManager.SIGNATURE_MATCH;
5638            if (!match) {
5639                match = compareSignaturesCompat(pkgSetting.sharedUser.signatures, pkg)
5640                        == PackageManager.SIGNATURE_MATCH;
5641            }
5642            if (!match) {
5643                match = compareSignaturesRecover(pkgSetting.sharedUser.signatures, pkg)
5644                        == PackageManager.SIGNATURE_MATCH;
5645            }
5646            if (!match) {
5647                throw new PackageManagerException(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
5648                        "Package " + pkg.packageName
5649                        + " has no signatures that match those in shared user "
5650                        + pkgSetting.sharedUser.name + "; ignoring!");
5651            }
5652        }
5653    }
5654
5655    /**
5656     * Enforces that only the system UID or root's UID can call a method exposed
5657     * via Binder.
5658     *
5659     * @param message used as message if SecurityException is thrown
5660     * @throws SecurityException if the caller is not system or root
5661     */
5662    private static final void enforceSystemOrRoot(String message) {
5663        final int uid = Binder.getCallingUid();
5664        if (uid != Process.SYSTEM_UID && uid != 0) {
5665            throw new SecurityException(message);
5666        }
5667    }
5668
5669    @Override
5670    public void performBootDexOpt() {
5671        enforceSystemOrRoot("Only the system can request dexopt be performed");
5672
5673        // Before everything else, see whether we need to fstrim.
5674        try {
5675            IMountService ms = PackageHelper.getMountService();
5676            if (ms != null) {
5677                final boolean isUpgrade = isUpgrade();
5678                boolean doTrim = isUpgrade;
5679                if (doTrim) {
5680                    Slog.w(TAG, "Running disk maintenance immediately due to system update");
5681                } else {
5682                    final long interval = android.provider.Settings.Global.getLong(
5683                            mContext.getContentResolver(),
5684                            android.provider.Settings.Global.FSTRIM_MANDATORY_INTERVAL,
5685                            DEFAULT_MANDATORY_FSTRIM_INTERVAL);
5686                    if (interval > 0) {
5687                        final long timeSinceLast = System.currentTimeMillis() - ms.lastMaintenance();
5688                        if (timeSinceLast > interval) {
5689                            doTrim = true;
5690                            Slog.w(TAG, "No disk maintenance in " + timeSinceLast
5691                                    + "; running immediately");
5692                        }
5693                    }
5694                }
5695                if (doTrim) {
5696                    if (!isFirstBoot()) {
5697                        try {
5698                            ActivityManagerNative.getDefault().showBootMessage(
5699                                    mContext.getResources().getString(
5700                                            R.string.android_upgrading_fstrim), true);
5701                        } catch (RemoteException e) {
5702                        }
5703                    }
5704                    ms.runMaintenance();
5705                }
5706            } else {
5707                Slog.e(TAG, "Mount service unavailable!");
5708            }
5709        } catch (RemoteException e) {
5710            // Can't happen; MountService is local
5711        }
5712
5713        final ArraySet<PackageParser.Package> pkgs;
5714        synchronized (mPackages) {
5715            pkgs = mPackageDexOptimizer.clearDeferredDexOptPackages();
5716        }
5717
5718        if (pkgs != null) {
5719            // Sort apps by importance for dexopt ordering. Important apps are given more priority
5720            // in case the device runs out of space.
5721            ArrayList<PackageParser.Package> sortedPkgs = new ArrayList<PackageParser.Package>();
5722            // Give priority to core apps.
5723            for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) {
5724                PackageParser.Package pkg = it.next();
5725                if (pkg.coreApp) {
5726                    if (DEBUG_DEXOPT) {
5727                        Log.i(TAG, "Adding core app " + sortedPkgs.size() + ": " + pkg.packageName);
5728                    }
5729                    sortedPkgs.add(pkg);
5730                    it.remove();
5731                }
5732            }
5733            // Give priority to system apps that listen for pre boot complete.
5734            Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
5735            ArraySet<String> pkgNames = getPackageNamesForIntent(intent);
5736            for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) {
5737                PackageParser.Package pkg = it.next();
5738                if (pkgNames.contains(pkg.packageName)) {
5739                    if (DEBUG_DEXOPT) {
5740                        Log.i(TAG, "Adding pre boot system app " + sortedPkgs.size() + ": " + pkg.packageName);
5741                    }
5742                    sortedPkgs.add(pkg);
5743                    it.remove();
5744                }
5745            }
5746            // Give priority to system apps.
5747            for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) {
5748                PackageParser.Package pkg = it.next();
5749                if (isSystemApp(pkg) && !pkg.isUpdatedSystemApp()) {
5750                    if (DEBUG_DEXOPT) {
5751                        Log.i(TAG, "Adding system app " + sortedPkgs.size() + ": " + pkg.packageName);
5752                    }
5753                    sortedPkgs.add(pkg);
5754                    it.remove();
5755                }
5756            }
5757            // Give priority to updated system apps.
5758            for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) {
5759                PackageParser.Package pkg = it.next();
5760                if (pkg.isUpdatedSystemApp()) {
5761                    if (DEBUG_DEXOPT) {
5762                        Log.i(TAG, "Adding updated system app " + sortedPkgs.size() + ": " + pkg.packageName);
5763                    }
5764                    sortedPkgs.add(pkg);
5765                    it.remove();
5766                }
5767            }
5768            // Give priority to apps that listen for boot complete.
5769            intent = new Intent(Intent.ACTION_BOOT_COMPLETED);
5770            pkgNames = getPackageNamesForIntent(intent);
5771            for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) {
5772                PackageParser.Package pkg = it.next();
5773                if (pkgNames.contains(pkg.packageName)) {
5774                    if (DEBUG_DEXOPT) {
5775                        Log.i(TAG, "Adding boot app " + sortedPkgs.size() + ": " + pkg.packageName);
5776                    }
5777                    sortedPkgs.add(pkg);
5778                    it.remove();
5779                }
5780            }
5781            // Filter out packages that aren't recently used.
5782            filterRecentlyUsedApps(pkgs);
5783            // Add all remaining apps.
5784            for (PackageParser.Package pkg : pkgs) {
5785                if (DEBUG_DEXOPT) {
5786                    Log.i(TAG, "Adding app " + sortedPkgs.size() + ": " + pkg.packageName);
5787                }
5788                sortedPkgs.add(pkg);
5789            }
5790
5791            // If we want to be lazy, filter everything that wasn't recently used.
5792            if (mLazyDexOpt) {
5793                filterRecentlyUsedApps(sortedPkgs);
5794            }
5795
5796            int i = 0;
5797            int total = sortedPkgs.size();
5798            File dataDir = Environment.getDataDirectory();
5799            long lowThreshold = StorageManager.from(mContext).getStorageLowBytes(dataDir);
5800            if (lowThreshold == 0) {
5801                throw new IllegalStateException("Invalid low memory threshold");
5802            }
5803            for (PackageParser.Package pkg : sortedPkgs) {
5804                long usableSpace = dataDir.getUsableSpace();
5805                if (usableSpace < lowThreshold) {
5806                    Log.w(TAG, "Not running dexopt on remaining apps due to low memory: " + usableSpace);
5807                    break;
5808                }
5809                performBootDexOpt(pkg, ++i, total);
5810            }
5811        }
5812    }
5813
5814    private void filterRecentlyUsedApps(Collection<PackageParser.Package> pkgs) {
5815        // Filter out packages that aren't recently used.
5816        //
5817        // The exception is first boot of a non-eng device (aka !mLazyDexOpt), which
5818        // should do a full dexopt.
5819        if (mLazyDexOpt || (!isFirstBoot() && mPackageUsage.isHistoricalPackageUsageAvailable())) {
5820            int total = pkgs.size();
5821            int skipped = 0;
5822            long now = System.currentTimeMillis();
5823            for (Iterator<PackageParser.Package> i = pkgs.iterator(); i.hasNext();) {
5824                PackageParser.Package pkg = i.next();
5825                long then = pkg.mLastPackageUsageTimeInMills;
5826                if (then + mDexOptLRUThresholdInMills < now) {
5827                    if (DEBUG_DEXOPT) {
5828                        Log.i(TAG, "Skipping dexopt of " + pkg.packageName + " last resumed: " +
5829                              ((then == 0) ? "never" : new Date(then)));
5830                    }
5831                    i.remove();
5832                    skipped++;
5833                }
5834            }
5835            if (DEBUG_DEXOPT) {
5836                Log.i(TAG, "Skipped optimizing " + skipped + " of " + total);
5837            }
5838        }
5839    }
5840
5841    private ArraySet<String> getPackageNamesForIntent(Intent intent) {
5842        List<ResolveInfo> ris = null;
5843        try {
5844            ris = AppGlobals.getPackageManager().queryIntentReceivers(
5845                    intent, null, 0, UserHandle.USER_OWNER);
5846        } catch (RemoteException e) {
5847        }
5848        ArraySet<String> pkgNames = new ArraySet<String>();
5849        if (ris != null) {
5850            for (ResolveInfo ri : ris) {
5851                pkgNames.add(ri.activityInfo.packageName);
5852            }
5853        }
5854        return pkgNames;
5855    }
5856
5857    private void performBootDexOpt(PackageParser.Package pkg, int curr, int total) {
5858        if (DEBUG_DEXOPT) {
5859            Log.i(TAG, "Optimizing app " + curr + " of " + total + ": " + pkg.packageName);
5860        }
5861        if (!isFirstBoot()) {
5862            try {
5863                ActivityManagerNative.getDefault().showBootMessage(
5864                        mContext.getResources().getString(R.string.android_upgrading_apk,
5865                                curr, total), true);
5866            } catch (RemoteException e) {
5867            }
5868        }
5869        PackageParser.Package p = pkg;
5870        synchronized (mInstallLock) {
5871            mPackageDexOptimizer.performDexOpt(p, null /* instruction sets */,
5872                    false /* force dex */, false /* defer */, true /* include dependencies */);
5873        }
5874    }
5875
5876    @Override
5877    public boolean performDexOptIfNeeded(String packageName, String instructionSet) {
5878        return performDexOpt(packageName, instructionSet, false);
5879    }
5880
5881    public boolean performDexOpt(String packageName, String instructionSet, boolean backgroundDexopt) {
5882        boolean dexopt = mLazyDexOpt || backgroundDexopt;
5883        boolean updateUsage = !backgroundDexopt;  // Don't update usage if this is just a backgroundDexopt
5884        if (!dexopt && !updateUsage) {
5885            // We aren't going to dexopt or update usage, so bail early.
5886            return false;
5887        }
5888        PackageParser.Package p;
5889        final String targetInstructionSet;
5890        synchronized (mPackages) {
5891            p = mPackages.get(packageName);
5892            if (p == null) {
5893                return false;
5894            }
5895            if (updateUsage) {
5896                p.mLastPackageUsageTimeInMills = System.currentTimeMillis();
5897            }
5898            mPackageUsage.write(false);
5899            if (!dexopt) {
5900                // We aren't going to dexopt, so bail early.
5901                return false;
5902            }
5903
5904            targetInstructionSet = instructionSet != null ? instructionSet :
5905                    getPrimaryInstructionSet(p.applicationInfo);
5906            if (p.mDexOptPerformed.contains(targetInstructionSet)) {
5907                return false;
5908            }
5909        }
5910
5911        synchronized (mInstallLock) {
5912            final String[] instructionSets = new String[] { targetInstructionSet };
5913            int result = mPackageDexOptimizer.performDexOpt(p, instructionSets,
5914                    false /* forceDex */, false /* defer */, true /* inclDependencies */);
5915            return result == PackageDexOptimizer.DEX_OPT_PERFORMED;
5916        }
5917    }
5918
5919    public ArraySet<String> getPackagesThatNeedDexOpt() {
5920        ArraySet<String> pkgs = null;
5921        synchronized (mPackages) {
5922            for (PackageParser.Package p : mPackages.values()) {
5923                if (DEBUG_DEXOPT) {
5924                    Log.i(TAG, p.packageName + " mDexOptPerformed=" + p.mDexOptPerformed.toArray());
5925                }
5926                if (!p.mDexOptPerformed.isEmpty()) {
5927                    continue;
5928                }
5929                if (pkgs == null) {
5930                    pkgs = new ArraySet<String>();
5931                }
5932                pkgs.add(p.packageName);
5933            }
5934        }
5935        return pkgs;
5936    }
5937
5938    public void shutdown() {
5939        mPackageUsage.write(true);
5940    }
5941
5942    @Override
5943    public void forceDexOpt(String packageName) {
5944        enforceSystemOrRoot("forceDexOpt");
5945
5946        PackageParser.Package pkg;
5947        synchronized (mPackages) {
5948            pkg = mPackages.get(packageName);
5949            if (pkg == null) {
5950                throw new IllegalArgumentException("Missing package: " + packageName);
5951            }
5952        }
5953
5954        synchronized (mInstallLock) {
5955            final String[] instructionSets = new String[] {
5956                    getPrimaryInstructionSet(pkg.applicationInfo) };
5957            final int res = mPackageDexOptimizer.performDexOpt(pkg, instructionSets,
5958                    true /*forceDex*/, false /* defer */, true /* inclDependencies */);
5959            if (res != PackageDexOptimizer.DEX_OPT_PERFORMED) {
5960                throw new IllegalStateException("Failed to dexopt: " + res);
5961            }
5962        }
5963    }
5964
5965    private boolean verifyPackageUpdateLPr(PackageSetting oldPkg, PackageParser.Package newPkg) {
5966        if ((oldPkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) {
5967            Slog.w(TAG, "Unable to update from " + oldPkg.name
5968                    + " to " + newPkg.packageName
5969                    + ": old package not in system partition");
5970            return false;
5971        } else if (mPackages.get(oldPkg.name) != null) {
5972            Slog.w(TAG, "Unable to update from " + oldPkg.name
5973                    + " to " + newPkg.packageName
5974                    + ": old package still exists");
5975            return false;
5976        }
5977        return true;
5978    }
5979
5980    private int createDataDirsLI(String volumeUuid, String packageName, int uid, String seinfo) {
5981        int[] users = sUserManager.getUserIds();
5982        int res = mInstaller.install(volumeUuid, packageName, uid, uid, seinfo);
5983        if (res < 0) {
5984            return res;
5985        }
5986        for (int user : users) {
5987            if (user != 0) {
5988                res = mInstaller.createUserData(volumeUuid, packageName,
5989                        UserHandle.getUid(user, uid), user, seinfo);
5990                if (res < 0) {
5991                    return res;
5992                }
5993            }
5994        }
5995        return res;
5996    }
5997
5998    private int removeDataDirsLI(String volumeUuid, String packageName) {
5999        int[] users = sUserManager.getUserIds();
6000        int res = 0;
6001        for (int user : users) {
6002            int resInner = mInstaller.remove(volumeUuid, packageName, user);
6003            if (resInner < 0) {
6004                res = resInner;
6005            }
6006        }
6007
6008        return res;
6009    }
6010
6011    private int deleteCodeCacheDirsLI(String volumeUuid, String packageName) {
6012        int[] users = sUserManager.getUserIds();
6013        int res = 0;
6014        for (int user : users) {
6015            int resInner = mInstaller.deleteCodeCacheFiles(volumeUuid, packageName, user);
6016            if (resInner < 0) {
6017                res = resInner;
6018            }
6019        }
6020        return res;
6021    }
6022
6023    private void addSharedLibraryLPw(ArraySet<String> usesLibraryFiles, SharedLibraryEntry file,
6024            PackageParser.Package changingLib) {
6025        if (file.path != null) {
6026            usesLibraryFiles.add(file.path);
6027            return;
6028        }
6029        PackageParser.Package p = mPackages.get(file.apk);
6030        if (changingLib != null && changingLib.packageName.equals(file.apk)) {
6031            // If we are doing this while in the middle of updating a library apk,
6032            // then we need to make sure to use that new apk for determining the
6033            // dependencies here.  (We haven't yet finished committing the new apk
6034            // to the package manager state.)
6035            if (p == null || p.packageName.equals(changingLib.packageName)) {
6036                p = changingLib;
6037            }
6038        }
6039        if (p != null) {
6040            usesLibraryFiles.addAll(p.getAllCodePaths());
6041        }
6042    }
6043
6044    private void updateSharedLibrariesLPw(PackageParser.Package pkg,
6045            PackageParser.Package changingLib) throws PackageManagerException {
6046        if (pkg.usesLibraries != null || pkg.usesOptionalLibraries != null) {
6047            final ArraySet<String> usesLibraryFiles = new ArraySet<>();
6048            int N = pkg.usesLibraries != null ? pkg.usesLibraries.size() : 0;
6049            for (int i=0; i<N; i++) {
6050                final SharedLibraryEntry file = mSharedLibraries.get(pkg.usesLibraries.get(i));
6051                if (file == null) {
6052                    throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
6053                            "Package " + pkg.packageName + " requires unavailable shared library "
6054                            + pkg.usesLibraries.get(i) + "; failing!");
6055                }
6056                addSharedLibraryLPw(usesLibraryFiles, file, changingLib);
6057            }
6058            N = pkg.usesOptionalLibraries != null ? pkg.usesOptionalLibraries.size() : 0;
6059            for (int i=0; i<N; i++) {
6060                final SharedLibraryEntry file = mSharedLibraries.get(pkg.usesOptionalLibraries.get(i));
6061                if (file == null) {
6062                    Slog.w(TAG, "Package " + pkg.packageName
6063                            + " desires unavailable shared library "
6064                            + pkg.usesOptionalLibraries.get(i) + "; ignoring!");
6065                } else {
6066                    addSharedLibraryLPw(usesLibraryFiles, file, changingLib);
6067                }
6068            }
6069            N = usesLibraryFiles.size();
6070            if (N > 0) {
6071                pkg.usesLibraryFiles = usesLibraryFiles.toArray(new String[N]);
6072            } else {
6073                pkg.usesLibraryFiles = null;
6074            }
6075        }
6076    }
6077
6078    private static boolean hasString(List<String> list, List<String> which) {
6079        if (list == null) {
6080            return false;
6081        }
6082        for (int i=list.size()-1; i>=0; i--) {
6083            for (int j=which.size()-1; j>=0; j--) {
6084                if (which.get(j).equals(list.get(i))) {
6085                    return true;
6086                }
6087            }
6088        }
6089        return false;
6090    }
6091
6092    private void updateAllSharedLibrariesLPw() {
6093        for (PackageParser.Package pkg : mPackages.values()) {
6094            try {
6095                updateSharedLibrariesLPw(pkg, null);
6096            } catch (PackageManagerException e) {
6097                Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
6098            }
6099        }
6100    }
6101
6102    private ArrayList<PackageParser.Package> updateAllSharedLibrariesLPw(
6103            PackageParser.Package changingPkg) {
6104        ArrayList<PackageParser.Package> res = null;
6105        for (PackageParser.Package pkg : mPackages.values()) {
6106            if (hasString(pkg.usesLibraries, changingPkg.libraryNames)
6107                    || hasString(pkg.usesOptionalLibraries, changingPkg.libraryNames)) {
6108                if (res == null) {
6109                    res = new ArrayList<PackageParser.Package>();
6110                }
6111                res.add(pkg);
6112                try {
6113                    updateSharedLibrariesLPw(pkg, changingPkg);
6114                } catch (PackageManagerException e) {
6115                    Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
6116                }
6117            }
6118        }
6119        return res;
6120    }
6121
6122    /**
6123     * Derive the value of the {@code cpuAbiOverride} based on the provided
6124     * value and an optional stored value from the package settings.
6125     */
6126    private static String deriveAbiOverride(String abiOverride, PackageSetting settings) {
6127        String cpuAbiOverride = null;
6128
6129        if (NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(abiOverride)) {
6130            cpuAbiOverride = null;
6131        } else if (abiOverride != null) {
6132            cpuAbiOverride = abiOverride;
6133        } else if (settings != null) {
6134            cpuAbiOverride = settings.cpuAbiOverrideString;
6135        }
6136
6137        return cpuAbiOverride;
6138    }
6139
6140    private PackageParser.Package scanPackageLI(PackageParser.Package pkg, int parseFlags,
6141            int scanFlags, long currentTime, UserHandle user) throws PackageManagerException {
6142        boolean success = false;
6143        try {
6144            final PackageParser.Package res = scanPackageDirtyLI(pkg, parseFlags, scanFlags,
6145                    currentTime, user);
6146            success = true;
6147            return res;
6148        } finally {
6149            if (!success && (scanFlags & SCAN_DELETE_DATA_ON_FAILURES) != 0) {
6150                removeDataDirsLI(pkg.volumeUuid, pkg.packageName);
6151            }
6152        }
6153    }
6154
6155    private PackageParser.Package scanPackageDirtyLI(PackageParser.Package pkg, int parseFlags,
6156            int scanFlags, long currentTime, UserHandle user) throws PackageManagerException {
6157        final File scanFile = new File(pkg.codePath);
6158        if (pkg.applicationInfo.getCodePath() == null ||
6159                pkg.applicationInfo.getResourcePath() == null) {
6160            // Bail out. The resource and code paths haven't been set.
6161            throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
6162                    "Code and resource paths haven't been set correctly");
6163        }
6164
6165        if ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) {
6166            pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
6167        } else {
6168            // Only allow system apps to be flagged as core apps.
6169            pkg.coreApp = false;
6170        }
6171
6172        if ((parseFlags&PackageParser.PARSE_IS_PRIVILEGED) != 0) {
6173            pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
6174        }
6175
6176        if (mCustomResolverComponentName != null &&
6177                mCustomResolverComponentName.getPackageName().equals(pkg.packageName)) {
6178            setUpCustomResolverActivity(pkg);
6179        }
6180
6181        if (pkg.packageName.equals("android")) {
6182            synchronized (mPackages) {
6183                if (mAndroidApplication != null) {
6184                    Slog.w(TAG, "*************************************************");
6185                    Slog.w(TAG, "Core android package being redefined.  Skipping.");
6186                    Slog.w(TAG, " file=" + scanFile);
6187                    Slog.w(TAG, "*************************************************");
6188                    throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
6189                            "Core android package being redefined.  Skipping.");
6190                }
6191
6192                // Set up information for our fall-back user intent resolution activity.
6193                mPlatformPackage = pkg;
6194                pkg.mVersionCode = mSdkVersion;
6195                mAndroidApplication = pkg.applicationInfo;
6196
6197                if (!mResolverReplaced) {
6198                    mResolveActivity.applicationInfo = mAndroidApplication;
6199                    mResolveActivity.name = ResolverActivity.class.getName();
6200                    mResolveActivity.packageName = mAndroidApplication.packageName;
6201                    mResolveActivity.processName = "system:ui";
6202                    mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
6203                    mResolveActivity.documentLaunchMode = ActivityInfo.DOCUMENT_LAUNCH_NEVER;
6204                    mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS;
6205                    mResolveActivity.theme = R.style.Theme_Holo_Dialog_Alert;
6206                    mResolveActivity.exported = true;
6207                    mResolveActivity.enabled = true;
6208                    mResolveInfo.activityInfo = mResolveActivity;
6209                    mResolveInfo.priority = 0;
6210                    mResolveInfo.preferredOrder = 0;
6211                    mResolveInfo.match = 0;
6212                    mResolveComponentName = new ComponentName(
6213                            mAndroidApplication.packageName, mResolveActivity.name);
6214                }
6215            }
6216        }
6217
6218        if (DEBUG_PACKAGE_SCANNING) {
6219            if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
6220                Log.d(TAG, "Scanning package " + pkg.packageName);
6221        }
6222
6223        if (mPackages.containsKey(pkg.packageName)
6224                || mSharedLibraries.containsKey(pkg.packageName)) {
6225            throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
6226                    "Application package " + pkg.packageName
6227                    + " already installed.  Skipping duplicate.");
6228        }
6229
6230        // If we're only installing presumed-existing packages, require that the
6231        // scanned APK is both already known and at the path previously established
6232        // for it.  Previously unknown packages we pick up normally, but if we have an
6233        // a priori expectation about this package's install presence, enforce it.
6234        if ((scanFlags & SCAN_REQUIRE_KNOWN) != 0) {
6235            PackageSetting known = mSettings.peekPackageLPr(pkg.packageName);
6236            if (known != null) {
6237                if (DEBUG_PACKAGE_SCANNING) {
6238                    Log.d(TAG, "Examining " + pkg.codePath
6239                            + " and requiring known paths " + known.codePathString
6240                            + " & " + known.resourcePathString);
6241                }
6242                if (!pkg.applicationInfo.getCodePath().equals(known.codePathString)
6243                        || !pkg.applicationInfo.getResourcePath().equals(known.resourcePathString)) {
6244                    throw new PackageManagerException(INSTALL_FAILED_PACKAGE_CHANGED,
6245                            "Application package " + pkg.packageName
6246                            + " found at " + pkg.applicationInfo.getCodePath()
6247                            + " but expected at " + known.codePathString + "; ignoring.");
6248                }
6249            }
6250        }
6251
6252        // Initialize package source and resource directories
6253        File destCodeFile = new File(pkg.applicationInfo.getCodePath());
6254        File destResourceFile = new File(pkg.applicationInfo.getResourcePath());
6255
6256        SharedUserSetting suid = null;
6257        PackageSetting pkgSetting = null;
6258
6259        if (!isSystemApp(pkg)) {
6260            // Only system apps can use these features.
6261            pkg.mOriginalPackages = null;
6262            pkg.mRealPackage = null;
6263            pkg.mAdoptPermissions = null;
6264        }
6265
6266        // writer
6267        synchronized (mPackages) {
6268            if (pkg.mSharedUserId != null) {
6269                suid = mSettings.getSharedUserLPw(pkg.mSharedUserId, 0, 0, true);
6270                if (suid == null) {
6271                    throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE,
6272                            "Creating application package " + pkg.packageName
6273                            + " for shared user failed");
6274                }
6275                if (DEBUG_PACKAGE_SCANNING) {
6276                    if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
6277                        Log.d(TAG, "Shared UserID " + pkg.mSharedUserId + " (uid=" + suid.userId
6278                                + "): packages=" + suid.packages);
6279                }
6280            }
6281
6282            // Check if we are renaming from an original package name.
6283            PackageSetting origPackage = null;
6284            String realName = null;
6285            if (pkg.mOriginalPackages != null) {
6286                // This package may need to be renamed to a previously
6287                // installed name.  Let's check on that...
6288                final String renamed = mSettings.mRenamedPackages.get(pkg.mRealPackage);
6289                if (pkg.mOriginalPackages.contains(renamed)) {
6290                    // This package had originally been installed as the
6291                    // original name, and we have already taken care of
6292                    // transitioning to the new one.  Just update the new
6293                    // one to continue using the old name.
6294                    realName = pkg.mRealPackage;
6295                    if (!pkg.packageName.equals(renamed)) {
6296                        // Callers into this function may have already taken
6297                        // care of renaming the package; only do it here if
6298                        // it is not already done.
6299                        pkg.setPackageName(renamed);
6300                    }
6301
6302                } else {
6303                    for (int i=pkg.mOriginalPackages.size()-1; i>=0; i--) {
6304                        if ((origPackage = mSettings.peekPackageLPr(
6305                                pkg.mOriginalPackages.get(i))) != null) {
6306                            // We do have the package already installed under its
6307                            // original name...  should we use it?
6308                            if (!verifyPackageUpdateLPr(origPackage, pkg)) {
6309                                // New package is not compatible with original.
6310                                origPackage = null;
6311                                continue;
6312                            } else if (origPackage.sharedUser != null) {
6313                                // Make sure uid is compatible between packages.
6314                                if (!origPackage.sharedUser.name.equals(pkg.mSharedUserId)) {
6315                                    Slog.w(TAG, "Unable to migrate data from " + origPackage.name
6316                                            + " to " + pkg.packageName + ": old uid "
6317                                            + origPackage.sharedUser.name
6318                                            + " differs from " + pkg.mSharedUserId);
6319                                    origPackage = null;
6320                                    continue;
6321                                }
6322                            } else {
6323                                if (DEBUG_UPGRADE) Log.v(TAG, "Renaming new package "
6324                                        + pkg.packageName + " to old name " + origPackage.name);
6325                            }
6326                            break;
6327                        }
6328                    }
6329                }
6330            }
6331
6332            if (mTransferedPackages.contains(pkg.packageName)) {
6333                Slog.w(TAG, "Package " + pkg.packageName
6334                        + " was transferred to another, but its .apk remains");
6335            }
6336
6337            // Just create the setting, don't add it yet. For already existing packages
6338            // the PkgSetting exists already and doesn't have to be created.
6339            pkgSetting = mSettings.getPackageLPw(pkg, origPackage, realName, suid, destCodeFile,
6340                    destResourceFile, pkg.applicationInfo.nativeLibraryRootDir,
6341                    pkg.applicationInfo.primaryCpuAbi,
6342                    pkg.applicationInfo.secondaryCpuAbi,
6343                    pkg.applicationInfo.flags, pkg.applicationInfo.privateFlags,
6344                    user, false);
6345            if (pkgSetting == null) {
6346                throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE,
6347                        "Creating application package " + pkg.packageName + " failed");
6348            }
6349
6350            if (pkgSetting.origPackage != null) {
6351                // If we are first transitioning from an original package,
6352                // fix up the new package's name now.  We need to do this after
6353                // looking up the package under its new name, so getPackageLP
6354                // can take care of fiddling things correctly.
6355                pkg.setPackageName(origPackage.name);
6356
6357                // File a report about this.
6358                String msg = "New package " + pkgSetting.realName
6359                        + " renamed to replace old package " + pkgSetting.name;
6360                reportSettingsProblem(Log.WARN, msg);
6361
6362                // Make a note of it.
6363                mTransferedPackages.add(origPackage.name);
6364
6365                // No longer need to retain this.
6366                pkgSetting.origPackage = null;
6367            }
6368
6369            if (realName != null) {
6370                // Make a note of it.
6371                mTransferedPackages.add(pkg.packageName);
6372            }
6373
6374            if (mSettings.isDisabledSystemPackageLPr(pkg.packageName)) {
6375                pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
6376            }
6377
6378            if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
6379                // Check all shared libraries and map to their actual file path.
6380                // We only do this here for apps not on a system dir, because those
6381                // are the only ones that can fail an install due to this.  We
6382                // will take care of the system apps by updating all of their
6383                // library paths after the scan is done.
6384                updateSharedLibrariesLPw(pkg, null);
6385            }
6386
6387            if (mFoundPolicyFile) {
6388                SELinuxMMAC.assignSeinfoValue(pkg);
6389            }
6390
6391            pkg.applicationInfo.uid = pkgSetting.appId;
6392            pkg.mExtras = pkgSetting;
6393            if (shouldCheckUpgradeKeySetLP(pkgSetting, scanFlags)) {
6394                if (checkUpgradeKeySetLP(pkgSetting, pkg)) {
6395                    // We just determined the app is signed correctly, so bring
6396                    // over the latest parsed certs.
6397                    pkgSetting.signatures.mSignatures = pkg.mSignatures;
6398                } else {
6399                    if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
6400                        throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
6401                                "Package " + pkg.packageName + " upgrade keys do not match the "
6402                                + "previously installed version");
6403                    } else {
6404                        pkgSetting.signatures.mSignatures = pkg.mSignatures;
6405                        String msg = "System package " + pkg.packageName
6406                            + " signature changed; retaining data.";
6407                        reportSettingsProblem(Log.WARN, msg);
6408                    }
6409                }
6410            } else {
6411                try {
6412                    verifySignaturesLP(pkgSetting, pkg);
6413                    // We just determined the app is signed correctly, so bring
6414                    // over the latest parsed certs.
6415                    pkgSetting.signatures.mSignatures = pkg.mSignatures;
6416                } catch (PackageManagerException e) {
6417                    if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
6418                        throw e;
6419                    }
6420                    // The signature has changed, but this package is in the system
6421                    // image...  let's recover!
6422                    pkgSetting.signatures.mSignatures = pkg.mSignatures;
6423                    // However...  if this package is part of a shared user, but it
6424                    // doesn't match the signature of the shared user, let's fail.
6425                    // What this means is that you can't change the signatures
6426                    // associated with an overall shared user, which doesn't seem all
6427                    // that unreasonable.
6428                    if (pkgSetting.sharedUser != null) {
6429                        if (compareSignatures(pkgSetting.sharedUser.signatures.mSignatures,
6430                                              pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) {
6431                            throw new PackageManagerException(
6432                                    INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES,
6433                                            "Signature mismatch for shared user : "
6434                                            + pkgSetting.sharedUser);
6435                        }
6436                    }
6437                    // File a report about this.
6438                    String msg = "System package " + pkg.packageName
6439                        + " signature changed; retaining data.";
6440                    reportSettingsProblem(Log.WARN, msg);
6441                }
6442            }
6443            // Verify that this new package doesn't have any content providers
6444            // that conflict with existing packages.  Only do this if the
6445            // package isn't already installed, since we don't want to break
6446            // things that are installed.
6447            if ((scanFlags & SCAN_NEW_INSTALL) != 0) {
6448                final int N = pkg.providers.size();
6449                int i;
6450                for (i=0; i<N; i++) {
6451                    PackageParser.Provider p = pkg.providers.get(i);
6452                    if (p.info.authority != null) {
6453                        String names[] = p.info.authority.split(";");
6454                        for (int j = 0; j < names.length; j++) {
6455                            if (mProvidersByAuthority.containsKey(names[j])) {
6456                                PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
6457                                final String otherPackageName =
6458                                        ((other != null && other.getComponentName() != null) ?
6459                                                other.getComponentName().getPackageName() : "?");
6460                                throw new PackageManagerException(
6461                                        INSTALL_FAILED_CONFLICTING_PROVIDER,
6462                                                "Can't install because provider name " + names[j]
6463                                                + " (in package " + pkg.applicationInfo.packageName
6464                                                + ") is already used by " + otherPackageName);
6465                            }
6466                        }
6467                    }
6468                }
6469            }
6470
6471            if (pkg.mAdoptPermissions != null) {
6472                // This package wants to adopt ownership of permissions from
6473                // another package.
6474                for (int i = pkg.mAdoptPermissions.size() - 1; i >= 0; i--) {
6475                    final String origName = pkg.mAdoptPermissions.get(i);
6476                    final PackageSetting orig = mSettings.peekPackageLPr(origName);
6477                    if (orig != null) {
6478                        if (verifyPackageUpdateLPr(orig, pkg)) {
6479                            Slog.i(TAG, "Adopting permissions from " + origName + " to "
6480                                    + pkg.packageName);
6481                            mSettings.transferPermissionsLPw(origName, pkg.packageName);
6482                        }
6483                    }
6484                }
6485            }
6486        }
6487
6488        final String pkgName = pkg.packageName;
6489
6490        final long scanFileTime = scanFile.lastModified();
6491        final boolean forceDex = (scanFlags & SCAN_FORCE_DEX) != 0;
6492        pkg.applicationInfo.processName = fixProcessName(
6493                pkg.applicationInfo.packageName,
6494                pkg.applicationInfo.processName,
6495                pkg.applicationInfo.uid);
6496
6497        File dataPath;
6498        if (mPlatformPackage == pkg) {
6499            // The system package is special.
6500            dataPath = new File(Environment.getDataDirectory(), "system");
6501
6502            pkg.applicationInfo.dataDir = dataPath.getPath();
6503
6504        } else {
6505            // This is a normal package, need to make its data directory.
6506            dataPath = PackageManager.getDataDirForUser(pkg.volumeUuid, pkg.packageName,
6507                    UserHandle.USER_OWNER);
6508
6509            boolean uidError = false;
6510            if (dataPath.exists()) {
6511                int currentUid = 0;
6512                try {
6513                    StructStat stat = Os.stat(dataPath.getPath());
6514                    currentUid = stat.st_uid;
6515                } catch (ErrnoException e) {
6516                    Slog.e(TAG, "Couldn't stat path " + dataPath.getPath(), e);
6517                }
6518
6519                // If we have mismatched owners for the data path, we have a problem.
6520                if (currentUid != pkg.applicationInfo.uid) {
6521                    boolean recovered = false;
6522                    if (currentUid == 0) {
6523                        // The directory somehow became owned by root.  Wow.
6524                        // This is probably because the system was stopped while
6525                        // installd was in the middle of messing with its libs
6526                        // directory.  Ask installd to fix that.
6527                        int ret = mInstaller.fixUid(pkg.volumeUuid, pkgName,
6528                                pkg.applicationInfo.uid, pkg.applicationInfo.uid);
6529                        if (ret >= 0) {
6530                            recovered = true;
6531                            String msg = "Package " + pkg.packageName
6532                                    + " unexpectedly changed to uid 0; recovered to " +
6533                                    + pkg.applicationInfo.uid;
6534                            reportSettingsProblem(Log.WARN, msg);
6535                        }
6536                    }
6537                    if (!recovered && ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0
6538                            || (scanFlags&SCAN_BOOTING) != 0)) {
6539                        // If this is a system app, we can at least delete its
6540                        // current data so the application will still work.
6541                        int ret = removeDataDirsLI(pkg.volumeUuid, pkgName);
6542                        if (ret >= 0) {
6543                            // TODO: Kill the processes first
6544                            // Old data gone!
6545                            String prefix = (parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0
6546                                    ? "System package " : "Third party package ";
6547                            String msg = prefix + pkg.packageName
6548                                    + " has changed from uid: "
6549                                    + currentUid + " to "
6550                                    + pkg.applicationInfo.uid + "; old data erased";
6551                            reportSettingsProblem(Log.WARN, msg);
6552                            recovered = true;
6553
6554                            // And now re-install the app.
6555                            ret = createDataDirsLI(pkg.volumeUuid, pkgName, pkg.applicationInfo.uid,
6556                                    pkg.applicationInfo.seinfo);
6557                            if (ret == -1) {
6558                                // Ack should not happen!
6559                                msg = prefix + pkg.packageName
6560                                        + " could not have data directory re-created after delete.";
6561                                reportSettingsProblem(Log.WARN, msg);
6562                                throw new PackageManagerException(
6563                                        INSTALL_FAILED_INSUFFICIENT_STORAGE, msg);
6564                            }
6565                        }
6566                        if (!recovered) {
6567                            mHasSystemUidErrors = true;
6568                        }
6569                    } else if (!recovered) {
6570                        // If we allow this install to proceed, we will be broken.
6571                        // Abort, abort!
6572                        throw new PackageManagerException(INSTALL_FAILED_UID_CHANGED,
6573                                "scanPackageLI");
6574                    }
6575                    if (!recovered) {
6576                        pkg.applicationInfo.dataDir = "/mismatched_uid/settings_"
6577                            + pkg.applicationInfo.uid + "/fs_"
6578                            + currentUid;
6579                        pkg.applicationInfo.nativeLibraryDir = pkg.applicationInfo.dataDir;
6580                        pkg.applicationInfo.nativeLibraryRootDir = pkg.applicationInfo.dataDir;
6581                        String msg = "Package " + pkg.packageName
6582                                + " has mismatched uid: "
6583                                + currentUid + " on disk, "
6584                                + pkg.applicationInfo.uid + " in settings";
6585                        // writer
6586                        synchronized (mPackages) {
6587                            mSettings.mReadMessages.append(msg);
6588                            mSettings.mReadMessages.append('\n');
6589                            uidError = true;
6590                            if (!pkgSetting.uidError) {
6591                                reportSettingsProblem(Log.ERROR, msg);
6592                            }
6593                        }
6594                    }
6595                }
6596                pkg.applicationInfo.dataDir = dataPath.getPath();
6597                if (mShouldRestoreconData) {
6598                    Slog.i(TAG, "SELinux relabeling of " + pkg.packageName + " issued.");
6599                    mInstaller.restoreconData(pkg.volumeUuid, pkg.packageName,
6600                            pkg.applicationInfo.seinfo, pkg.applicationInfo.uid);
6601                }
6602            } else {
6603                if (DEBUG_PACKAGE_SCANNING) {
6604                    if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
6605                        Log.v(TAG, "Want this data dir: " + dataPath);
6606                }
6607                //invoke installer to do the actual installation
6608                int ret = createDataDirsLI(pkg.volumeUuid, pkgName, pkg.applicationInfo.uid,
6609                        pkg.applicationInfo.seinfo);
6610                if (ret < 0) {
6611                    // Error from installer
6612                    throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE,
6613                            "Unable to create data dirs [errorCode=" + ret + "]");
6614                }
6615
6616                if (dataPath.exists()) {
6617                    pkg.applicationInfo.dataDir = dataPath.getPath();
6618                } else {
6619                    Slog.w(TAG, "Unable to create data directory: " + dataPath);
6620                    pkg.applicationInfo.dataDir = null;
6621                }
6622            }
6623
6624            pkgSetting.uidError = uidError;
6625        }
6626
6627        final String path = scanFile.getPath();
6628        final String cpuAbiOverride = deriveAbiOverride(pkg.cpuAbiOverride, pkgSetting);
6629
6630        if ((scanFlags & SCAN_NEW_INSTALL) == 0) {
6631            derivePackageAbi(pkg, scanFile, cpuAbiOverride, true /* extract libs */);
6632
6633            // Some system apps still use directory structure for native libraries
6634            // in which case we might end up not detecting abi solely based on apk
6635            // structure. Try to detect abi based on directory structure.
6636            if (isSystemApp(pkg) && !pkg.isUpdatedSystemApp() &&
6637                    pkg.applicationInfo.primaryCpuAbi == null) {
6638                setBundledAppAbisAndRoots(pkg, pkgSetting);
6639                setNativeLibraryPaths(pkg);
6640            }
6641
6642        } else {
6643            if ((scanFlags & SCAN_MOVE) != 0) {
6644                // We haven't run dex-opt for this move (since we've moved the compiled output too)
6645                // but we already have this packages package info in the PackageSetting. We just
6646                // use that and derive the native library path based on the new codepath.
6647                pkg.applicationInfo.primaryCpuAbi = pkgSetting.primaryCpuAbiString;
6648                pkg.applicationInfo.secondaryCpuAbi = pkgSetting.secondaryCpuAbiString;
6649            }
6650
6651            // Set native library paths again. For moves, the path will be updated based on the
6652            // ABIs we've determined above. For non-moves, the path will be updated based on the
6653            // ABIs we determined during compilation, but the path will depend on the final
6654            // package path (after the rename away from the stage path).
6655            setNativeLibraryPaths(pkg);
6656        }
6657
6658        if (DEBUG_INSTALL) Slog.i(TAG, "Linking native library dir for " + path);
6659        final int[] userIds = sUserManager.getUserIds();
6660        synchronized (mInstallLock) {
6661            // Create a native library symlink only if we have native libraries
6662            // and if the native libraries are 32 bit libraries. We do not provide
6663            // this symlink for 64 bit libraries.
6664            if (pkg.applicationInfo.primaryCpuAbi != null &&
6665                    !VMRuntime.is64BitAbi(pkg.applicationInfo.primaryCpuAbi)) {
6666                final String nativeLibPath = pkg.applicationInfo.nativeLibraryDir;
6667                for (int userId : userIds) {
6668                    if (mInstaller.linkNativeLibraryDirectory(pkg.volumeUuid, pkg.packageName,
6669                            nativeLibPath, userId) < 0) {
6670                        throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
6671                                "Failed linking native library dir (user=" + userId + ")");
6672                    }
6673                }
6674            }
6675        }
6676
6677        // This is a special case for the "system" package, where the ABI is
6678        // dictated by the zygote configuration (and init.rc). We should keep track
6679        // of this ABI so that we can deal with "normal" applications that run under
6680        // the same UID correctly.
6681        if (mPlatformPackage == pkg) {
6682            pkg.applicationInfo.primaryCpuAbi = VMRuntime.getRuntime().is64Bit() ?
6683                    Build.SUPPORTED_64_BIT_ABIS[0] : Build.SUPPORTED_32_BIT_ABIS[0];
6684        }
6685
6686        // If there's a mismatch between the abi-override in the package setting
6687        // and the abiOverride specified for the install. Warn about this because we
6688        // would've already compiled the app without taking the package setting into
6689        // account.
6690        if ((scanFlags & SCAN_NO_DEX) == 0 && (scanFlags & SCAN_NEW_INSTALL) != 0) {
6691            if (cpuAbiOverride == null && pkgSetting.cpuAbiOverrideString != null) {
6692                Slog.w(TAG, "Ignoring persisted ABI override " + cpuAbiOverride +
6693                        " for package: " + pkg.packageName);
6694            }
6695        }
6696
6697        pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
6698        pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
6699        pkgSetting.cpuAbiOverrideString = cpuAbiOverride;
6700
6701        // Copy the derived override back to the parsed package, so that we can
6702        // update the package settings accordingly.
6703        pkg.cpuAbiOverride = cpuAbiOverride;
6704
6705        if (DEBUG_ABI_SELECTION) {
6706            Slog.d(TAG, "Resolved nativeLibraryRoot for " + pkg.applicationInfo.packageName
6707                    + " to root=" + pkg.applicationInfo.nativeLibraryRootDir + ", isa="
6708                    + pkg.applicationInfo.nativeLibraryRootRequiresIsa);
6709        }
6710
6711        // Push the derived path down into PackageSettings so we know what to
6712        // clean up at uninstall time.
6713        pkgSetting.legacyNativeLibraryPathString = pkg.applicationInfo.nativeLibraryRootDir;
6714
6715        if (DEBUG_ABI_SELECTION) {
6716            Log.d(TAG, "Abis for package[" + pkg.packageName + "] are" +
6717                    " primary=" + pkg.applicationInfo.primaryCpuAbi +
6718                    " secondary=" + pkg.applicationInfo.secondaryCpuAbi);
6719        }
6720
6721        if ((scanFlags&SCAN_BOOTING) == 0 && pkgSetting.sharedUser != null) {
6722            // We don't do this here during boot because we can do it all
6723            // at once after scanning all existing packages.
6724            //
6725            // We also do this *before* we perform dexopt on this package, so that
6726            // we can avoid redundant dexopts, and also to make sure we've got the
6727            // code and package path correct.
6728            adjustCpuAbisForSharedUserLPw(pkgSetting.sharedUser.packages,
6729                    pkg, forceDex, (scanFlags & SCAN_DEFER_DEX) != 0);
6730        }
6731
6732        if ((scanFlags & SCAN_NO_DEX) == 0) {
6733            int result = mPackageDexOptimizer.performDexOpt(pkg, null /* instruction sets */,
6734                    forceDex, (scanFlags & SCAN_DEFER_DEX) != 0, false /* inclDependencies */);
6735            if (result == PackageDexOptimizer.DEX_OPT_FAILED) {
6736                throw new PackageManagerException(INSTALL_FAILED_DEXOPT, "scanPackageLI");
6737            }
6738        }
6739        if (mFactoryTest && pkg.requestedPermissions.contains(
6740                android.Manifest.permission.FACTORY_TEST)) {
6741            pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST;
6742        }
6743
6744        ArrayList<PackageParser.Package> clientLibPkgs = null;
6745
6746        // writer
6747        synchronized (mPackages) {
6748            if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
6749                // Only system apps can add new shared libraries.
6750                if (pkg.libraryNames != null) {
6751                    for (int i=0; i<pkg.libraryNames.size(); i++) {
6752                        String name = pkg.libraryNames.get(i);
6753                        boolean allowed = false;
6754                        if (pkg.isUpdatedSystemApp()) {
6755                            // New library entries can only be added through the
6756                            // system image.  This is important to get rid of a lot
6757                            // of nasty edge cases: for example if we allowed a non-
6758                            // system update of the app to add a library, then uninstalling
6759                            // the update would make the library go away, and assumptions
6760                            // we made such as through app install filtering would now
6761                            // have allowed apps on the device which aren't compatible
6762                            // with it.  Better to just have the restriction here, be
6763                            // conservative, and create many fewer cases that can negatively
6764                            // impact the user experience.
6765                            final PackageSetting sysPs = mSettings
6766                                    .getDisabledSystemPkgLPr(pkg.packageName);
6767                            if (sysPs.pkg != null && sysPs.pkg.libraryNames != null) {
6768                                for (int j=0; j<sysPs.pkg.libraryNames.size(); j++) {
6769                                    if (name.equals(sysPs.pkg.libraryNames.get(j))) {
6770                                        allowed = true;
6771                                        allowed = true;
6772                                        break;
6773                                    }
6774                                }
6775                            }
6776                        } else {
6777                            allowed = true;
6778                        }
6779                        if (allowed) {
6780                            if (!mSharedLibraries.containsKey(name)) {
6781                                mSharedLibraries.put(name, new SharedLibraryEntry(null, pkg.packageName));
6782                            } else if (!name.equals(pkg.packageName)) {
6783                                Slog.w(TAG, "Package " + pkg.packageName + " library "
6784                                        + name + " already exists; skipping");
6785                            }
6786                        } else {
6787                            Slog.w(TAG, "Package " + pkg.packageName + " declares lib "
6788                                    + name + " that is not declared on system image; skipping");
6789                        }
6790                    }
6791                    if ((scanFlags&SCAN_BOOTING) == 0) {
6792                        // If we are not booting, we need to update any applications
6793                        // that are clients of our shared library.  If we are booting,
6794                        // this will all be done once the scan is complete.
6795                        clientLibPkgs = updateAllSharedLibrariesLPw(pkg);
6796                    }
6797                }
6798            }
6799        }
6800
6801        // We also need to dexopt any apps that are dependent on this library.  Note that
6802        // if these fail, we should abort the install since installing the library will
6803        // result in some apps being broken.
6804        if (clientLibPkgs != null) {
6805            if ((scanFlags & SCAN_NO_DEX) == 0) {
6806                for (int i = 0; i < clientLibPkgs.size(); i++) {
6807                    PackageParser.Package clientPkg = clientLibPkgs.get(i);
6808                    int result = mPackageDexOptimizer.performDexOpt(clientPkg,
6809                            null /* instruction sets */, forceDex,
6810                            (scanFlags & SCAN_DEFER_DEX) != 0, false);
6811                    if (result == PackageDexOptimizer.DEX_OPT_FAILED) {
6812                        throw new PackageManagerException(INSTALL_FAILED_DEXOPT,
6813                                "scanPackageLI failed to dexopt clientLibPkgs");
6814                    }
6815                }
6816            }
6817        }
6818
6819        // Also need to kill any apps that are dependent on the library.
6820        if (clientLibPkgs != null) {
6821            for (int i=0; i<clientLibPkgs.size(); i++) {
6822                PackageParser.Package clientPkg = clientLibPkgs.get(i);
6823                killApplication(clientPkg.applicationInfo.packageName,
6824                        clientPkg.applicationInfo.uid, "update lib");
6825            }
6826        }
6827
6828        // Make sure we're not adding any bogus keyset info
6829        KeySetManagerService ksms = mSettings.mKeySetManagerService;
6830        ksms.assertScannedPackageValid(pkg);
6831
6832        // writer
6833        synchronized (mPackages) {
6834            // We don't expect installation to fail beyond this point
6835
6836            // Add the new setting to mSettings
6837            mSettings.insertPackageSettingLPw(pkgSetting, pkg);
6838            // Add the new setting to mPackages
6839            mPackages.put(pkg.applicationInfo.packageName, pkg);
6840            // Make sure we don't accidentally delete its data.
6841            final Iterator<PackageCleanItem> iter = mSettings.mPackagesToBeCleaned.iterator();
6842            while (iter.hasNext()) {
6843                PackageCleanItem item = iter.next();
6844                if (pkgName.equals(item.packageName)) {
6845                    iter.remove();
6846                }
6847            }
6848
6849            // Take care of first install / last update times.
6850            if (currentTime != 0) {
6851                if (pkgSetting.firstInstallTime == 0) {
6852                    pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = currentTime;
6853                } else if ((scanFlags&SCAN_UPDATE_TIME) != 0) {
6854                    pkgSetting.lastUpdateTime = currentTime;
6855                }
6856            } else if (pkgSetting.firstInstallTime == 0) {
6857                // We need *something*.  Take time time stamp of the file.
6858                pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = scanFileTime;
6859            } else if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) != 0) {
6860                if (scanFileTime != pkgSetting.timeStamp) {
6861                    // A package on the system image has changed; consider this
6862                    // to be an update.
6863                    pkgSetting.lastUpdateTime = scanFileTime;
6864                }
6865            }
6866
6867            // Add the package's KeySets to the global KeySetManagerService
6868            ksms.addScannedPackageLPw(pkg);
6869
6870            int N = pkg.providers.size();
6871            StringBuilder r = null;
6872            int i;
6873            for (i=0; i<N; i++) {
6874                PackageParser.Provider p = pkg.providers.get(i);
6875                p.info.processName = fixProcessName(pkg.applicationInfo.processName,
6876                        p.info.processName, pkg.applicationInfo.uid);
6877                mProviders.addProvider(p);
6878                p.syncable = p.info.isSyncable;
6879                if (p.info.authority != null) {
6880                    String names[] = p.info.authority.split(";");
6881                    p.info.authority = null;
6882                    for (int j = 0; j < names.length; j++) {
6883                        if (j == 1 && p.syncable) {
6884                            // We only want the first authority for a provider to possibly be
6885                            // syncable, so if we already added this provider using a different
6886                            // authority clear the syncable flag. We copy the provider before
6887                            // changing it because the mProviders object contains a reference
6888                            // to a provider that we don't want to change.
6889                            // Only do this for the second authority since the resulting provider
6890                            // object can be the same for all future authorities for this provider.
6891                            p = new PackageParser.Provider(p);
6892                            p.syncable = false;
6893                        }
6894                        if (!mProvidersByAuthority.containsKey(names[j])) {
6895                            mProvidersByAuthority.put(names[j], p);
6896                            if (p.info.authority == null) {
6897                                p.info.authority = names[j];
6898                            } else {
6899                                p.info.authority = p.info.authority + ";" + names[j];
6900                            }
6901                            if (DEBUG_PACKAGE_SCANNING) {
6902                                if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
6903                                    Log.d(TAG, "Registered content provider: " + names[j]
6904                                            + ", className = " + p.info.name + ", isSyncable = "
6905                                            + p.info.isSyncable);
6906                            }
6907                        } else {
6908                            PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
6909                            Slog.w(TAG, "Skipping provider name " + names[j] +
6910                                    " (in package " + pkg.applicationInfo.packageName +
6911                                    "): name already used by "
6912                                    + ((other != null && other.getComponentName() != null)
6913                                            ? other.getComponentName().getPackageName() : "?"));
6914                        }
6915                    }
6916                }
6917                if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
6918                    if (r == null) {
6919                        r = new StringBuilder(256);
6920                    } else {
6921                        r.append(' ');
6922                    }
6923                    r.append(p.info.name);
6924                }
6925            }
6926            if (r != null) {
6927                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Providers: " + r);
6928            }
6929
6930            N = pkg.services.size();
6931            r = null;
6932            for (i=0; i<N; i++) {
6933                PackageParser.Service s = pkg.services.get(i);
6934                s.info.processName = fixProcessName(pkg.applicationInfo.processName,
6935                        s.info.processName, pkg.applicationInfo.uid);
6936                mServices.addService(s);
6937                if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
6938                    if (r == null) {
6939                        r = new StringBuilder(256);
6940                    } else {
6941                        r.append(' ');
6942                    }
6943                    r.append(s.info.name);
6944                }
6945            }
6946            if (r != null) {
6947                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Services: " + r);
6948            }
6949
6950            N = pkg.receivers.size();
6951            r = null;
6952            for (i=0; i<N; i++) {
6953                PackageParser.Activity a = pkg.receivers.get(i);
6954                a.info.processName = fixProcessName(pkg.applicationInfo.processName,
6955                        a.info.processName, pkg.applicationInfo.uid);
6956                mReceivers.addActivity(a, "receiver");
6957                if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
6958                    if (r == null) {
6959                        r = new StringBuilder(256);
6960                    } else {
6961                        r.append(' ');
6962                    }
6963                    r.append(a.info.name);
6964                }
6965            }
6966            if (r != null) {
6967                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Receivers: " + r);
6968            }
6969
6970            N = pkg.activities.size();
6971            r = null;
6972            for (i=0; i<N; i++) {
6973                PackageParser.Activity a = pkg.activities.get(i);
6974                a.info.processName = fixProcessName(pkg.applicationInfo.processName,
6975                        a.info.processName, pkg.applicationInfo.uid);
6976                mActivities.addActivity(a, "activity");
6977                if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
6978                    if (r == null) {
6979                        r = new StringBuilder(256);
6980                    } else {
6981                        r.append(' ');
6982                    }
6983                    r.append(a.info.name);
6984                }
6985            }
6986            if (r != null) {
6987                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Activities: " + r);
6988            }
6989
6990            N = pkg.permissionGroups.size();
6991            r = null;
6992            for (i=0; i<N; i++) {
6993                PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i);
6994                PackageParser.PermissionGroup cur = mPermissionGroups.get(pg.info.name);
6995                if (cur == null) {
6996                    mPermissionGroups.put(pg.info.name, pg);
6997                    if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
6998                        if (r == null) {
6999                            r = new StringBuilder(256);
7000                        } else {
7001                            r.append(' ');
7002                        }
7003                        r.append(pg.info.name);
7004                    }
7005                } else {
7006                    Slog.w(TAG, "Permission group " + pg.info.name + " from package "
7007                            + pg.info.packageName + " ignored: original from "
7008                            + cur.info.packageName);
7009                    if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
7010                        if (r == null) {
7011                            r = new StringBuilder(256);
7012                        } else {
7013                            r.append(' ');
7014                        }
7015                        r.append("DUP:");
7016                        r.append(pg.info.name);
7017                    }
7018                }
7019            }
7020            if (r != null) {
7021                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Permission Groups: " + r);
7022            }
7023
7024            N = pkg.permissions.size();
7025            r = null;
7026            for (i=0; i<N; i++) {
7027                PackageParser.Permission p = pkg.permissions.get(i);
7028
7029                // Now that permission groups have a special meaning, we ignore permission
7030                // groups for legacy apps to prevent unexpected behavior. In particular,
7031                // permissions for one app being granted to someone just becuase they happen
7032                // to be in a group defined by another app (before this had no implications).
7033                if (pkg.applicationInfo.targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1) {
7034                    p.group = mPermissionGroups.get(p.info.group);
7035                    // Warn for a permission in an unknown group.
7036                    if (p.info.group != null && p.group == null) {
7037                        Slog.w(TAG, "Permission " + p.info.name + " from package "
7038                                + p.info.packageName + " in an unknown group " + p.info.group);
7039                    }
7040                }
7041
7042                ArrayMap<String, BasePermission> permissionMap =
7043                        p.tree ? mSettings.mPermissionTrees
7044                                : mSettings.mPermissions;
7045                BasePermission bp = permissionMap.get(p.info.name);
7046
7047                // Allow system apps to redefine non-system permissions
7048                if (bp != null && !Objects.equals(bp.sourcePackage, p.info.packageName)) {
7049                    final boolean currentOwnerIsSystem = (bp.perm != null
7050                            && isSystemApp(bp.perm.owner));
7051                    if (isSystemApp(p.owner)) {
7052                        if (bp.type == BasePermission.TYPE_BUILTIN && bp.perm == null) {
7053                            // It's a built-in permission and no owner, take ownership now
7054                            bp.packageSetting = pkgSetting;
7055                            bp.perm = p;
7056                            bp.uid = pkg.applicationInfo.uid;
7057                            bp.sourcePackage = p.info.packageName;
7058                        } else if (!currentOwnerIsSystem) {
7059                            String msg = "New decl " + p.owner + " of permission  "
7060                                    + p.info.name + " is system; overriding " + bp.sourcePackage;
7061                            reportSettingsProblem(Log.WARN, msg);
7062                            bp = null;
7063                        }
7064                    }
7065                }
7066
7067                if (bp == null) {
7068                    bp = new BasePermission(p.info.name, p.info.packageName,
7069                            BasePermission.TYPE_NORMAL);
7070                    permissionMap.put(p.info.name, bp);
7071                }
7072
7073                if (bp.perm == null) {
7074                    if (bp.sourcePackage == null
7075                            || bp.sourcePackage.equals(p.info.packageName)) {
7076                        BasePermission tree = findPermissionTreeLP(p.info.name);
7077                        if (tree == null
7078                                || tree.sourcePackage.equals(p.info.packageName)) {
7079                            bp.packageSetting = pkgSetting;
7080                            bp.perm = p;
7081                            bp.uid = pkg.applicationInfo.uid;
7082                            bp.sourcePackage = p.info.packageName;
7083                            if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
7084                                if (r == null) {
7085                                    r = new StringBuilder(256);
7086                                } else {
7087                                    r.append(' ');
7088                                }
7089                                r.append(p.info.name);
7090                            }
7091                        } else {
7092                            Slog.w(TAG, "Permission " + p.info.name + " from package "
7093                                    + p.info.packageName + " ignored: base tree "
7094                                    + tree.name + " is from package "
7095                                    + tree.sourcePackage);
7096                        }
7097                    } else {
7098                        Slog.w(TAG, "Permission " + p.info.name + " from package "
7099                                + p.info.packageName + " ignored: original from "
7100                                + bp.sourcePackage);
7101                    }
7102                } else if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
7103                    if (r == null) {
7104                        r = new StringBuilder(256);
7105                    } else {
7106                        r.append(' ');
7107                    }
7108                    r.append("DUP:");
7109                    r.append(p.info.name);
7110                }
7111                if (bp.perm == p) {
7112                    bp.protectionLevel = p.info.protectionLevel;
7113                }
7114            }
7115
7116            if (r != null) {
7117                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Permissions: " + r);
7118            }
7119
7120            N = pkg.instrumentation.size();
7121            r = null;
7122            for (i=0; i<N; i++) {
7123                PackageParser.Instrumentation a = pkg.instrumentation.get(i);
7124                a.info.packageName = pkg.applicationInfo.packageName;
7125                a.info.sourceDir = pkg.applicationInfo.sourceDir;
7126                a.info.publicSourceDir = pkg.applicationInfo.publicSourceDir;
7127                a.info.splitSourceDirs = pkg.applicationInfo.splitSourceDirs;
7128                a.info.splitPublicSourceDirs = pkg.applicationInfo.splitPublicSourceDirs;
7129                a.info.dataDir = pkg.applicationInfo.dataDir;
7130
7131                // TODO: Update instrumentation.nativeLibraryDir as well ? Does it
7132                // need other information about the application, like the ABI and what not ?
7133                a.info.nativeLibraryDir = pkg.applicationInfo.nativeLibraryDir;
7134                mInstrumentation.put(a.getComponentName(), a);
7135                if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
7136                    if (r == null) {
7137                        r = new StringBuilder(256);
7138                    } else {
7139                        r.append(' ');
7140                    }
7141                    r.append(a.info.name);
7142                }
7143            }
7144            if (r != null) {
7145                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Instrumentation: " + r);
7146            }
7147
7148            if (pkg.protectedBroadcasts != null) {
7149                N = pkg.protectedBroadcasts.size();
7150                for (i=0; i<N; i++) {
7151                    mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i));
7152                }
7153            }
7154
7155            pkgSetting.setTimeStamp(scanFileTime);
7156
7157            // Create idmap files for pairs of (packages, overlay packages).
7158            // Note: "android", ie framework-res.apk, is handled by native layers.
7159            if (pkg.mOverlayTarget != null) {
7160                // This is an overlay package.
7161                if (pkg.mOverlayTarget != null && !pkg.mOverlayTarget.equals("android")) {
7162                    if (!mOverlays.containsKey(pkg.mOverlayTarget)) {
7163                        mOverlays.put(pkg.mOverlayTarget,
7164                                new ArrayMap<String, PackageParser.Package>());
7165                    }
7166                    ArrayMap<String, PackageParser.Package> map = mOverlays.get(pkg.mOverlayTarget);
7167                    map.put(pkg.packageName, pkg);
7168                    PackageParser.Package orig = mPackages.get(pkg.mOverlayTarget);
7169                    if (orig != null && !createIdmapForPackagePairLI(orig, pkg)) {
7170                        throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
7171                                "scanPackageLI failed to createIdmap");
7172                    }
7173                }
7174            } else if (mOverlays.containsKey(pkg.packageName) &&
7175                    !pkg.packageName.equals("android")) {
7176                // This is a regular package, with one or more known overlay packages.
7177                createIdmapsForPackageLI(pkg);
7178            }
7179        }
7180
7181        return pkg;
7182    }
7183
7184    /**
7185     * Derive the ABI of a non-system package located at {@code scanFile}. This information
7186     * is derived purely on the basis of the contents of {@code scanFile} and
7187     * {@code cpuAbiOverride}.
7188     *
7189     * If {@code extractLibs} is true, native libraries are extracted from the app if required.
7190     */
7191    public void derivePackageAbi(PackageParser.Package pkg, File scanFile,
7192                                 String cpuAbiOverride, boolean extractLibs)
7193            throws PackageManagerException {
7194        // TODO: We can probably be smarter about this stuff. For installed apps,
7195        // we can calculate this information at install time once and for all. For
7196        // system apps, we can probably assume that this information doesn't change
7197        // after the first boot scan. As things stand, we do lots of unnecessary work.
7198
7199        // Give ourselves some initial paths; we'll come back for another
7200        // pass once we've determined ABI below.
7201        setNativeLibraryPaths(pkg);
7202
7203        // We would never need to extract libs for forward-locked and external packages,
7204        // since the container service will do it for us. We shouldn't attempt to
7205        // extract libs from system app when it was not updated.
7206        if (pkg.isForwardLocked() || isExternal(pkg) ||
7207            (isSystemApp(pkg) && !pkg.isUpdatedSystemApp()) ) {
7208            extractLibs = false;
7209        }
7210
7211        final String nativeLibraryRootStr = pkg.applicationInfo.nativeLibraryRootDir;
7212        final boolean useIsaSpecificSubdirs = pkg.applicationInfo.nativeLibraryRootRequiresIsa;
7213
7214        NativeLibraryHelper.Handle handle = null;
7215        try {
7216            handle = NativeLibraryHelper.Handle.create(pkg);
7217            // TODO(multiArch): This can be null for apps that didn't go through the
7218            // usual installation process. We can calculate it again, like we
7219            // do during install time.
7220            //
7221            // TODO(multiArch): Why do we need to rescan ASEC apps again ? It seems totally
7222            // unnecessary.
7223            final File nativeLibraryRoot = new File(nativeLibraryRootStr);
7224
7225            // Null out the abis so that they can be recalculated.
7226            pkg.applicationInfo.primaryCpuAbi = null;
7227            pkg.applicationInfo.secondaryCpuAbi = null;
7228            if (isMultiArch(pkg.applicationInfo)) {
7229                // Warn if we've set an abiOverride for multi-lib packages..
7230                // By definition, we need to copy both 32 and 64 bit libraries for
7231                // such packages.
7232                if (pkg.cpuAbiOverride != null
7233                        && !NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(pkg.cpuAbiOverride)) {
7234                    Slog.w(TAG, "Ignoring abiOverride for multi arch application.");
7235                }
7236
7237                int abi32 = PackageManager.NO_NATIVE_LIBRARIES;
7238                int abi64 = PackageManager.NO_NATIVE_LIBRARIES;
7239                if (Build.SUPPORTED_32_BIT_ABIS.length > 0) {
7240                    if (extractLibs) {
7241                        abi32 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
7242                                nativeLibraryRoot, Build.SUPPORTED_32_BIT_ABIS,
7243                                useIsaSpecificSubdirs);
7244                    } else {
7245                        abi32 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_32_BIT_ABIS);
7246                    }
7247                }
7248
7249                maybeThrowExceptionForMultiArchCopy(
7250                        "Error unpackaging 32 bit native libs for multiarch app.", abi32);
7251
7252                if (Build.SUPPORTED_64_BIT_ABIS.length > 0) {
7253                    if (extractLibs) {
7254                        abi64 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
7255                                nativeLibraryRoot, Build.SUPPORTED_64_BIT_ABIS,
7256                                useIsaSpecificSubdirs);
7257                    } else {
7258                        abi64 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_64_BIT_ABIS);
7259                    }
7260                }
7261
7262                maybeThrowExceptionForMultiArchCopy(
7263                        "Error unpackaging 64 bit native libs for multiarch app.", abi64);
7264
7265                if (abi64 >= 0) {
7266                    pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[abi64];
7267                }
7268
7269                if (abi32 >= 0) {
7270                    final String abi = Build.SUPPORTED_32_BIT_ABIS[abi32];
7271                    if (abi64 >= 0) {
7272                        pkg.applicationInfo.secondaryCpuAbi = abi;
7273                    } else {
7274                        pkg.applicationInfo.primaryCpuAbi = abi;
7275                    }
7276                }
7277            } else {
7278                String[] abiList = (cpuAbiOverride != null) ?
7279                        new String[] { cpuAbiOverride } : Build.SUPPORTED_ABIS;
7280
7281                // Enable gross and lame hacks for apps that are built with old
7282                // SDK tools. We must scan their APKs for renderscript bitcode and
7283                // not launch them if it's present. Don't bother checking on devices
7284                // that don't have 64 bit support.
7285                boolean needsRenderScriptOverride = false;
7286                if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && cpuAbiOverride == null &&
7287                        NativeLibraryHelper.hasRenderscriptBitcode(handle)) {
7288                    abiList = Build.SUPPORTED_32_BIT_ABIS;
7289                    needsRenderScriptOverride = true;
7290                }
7291
7292                final int copyRet;
7293                if (extractLibs) {
7294                    copyRet = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
7295                            nativeLibraryRoot, abiList, useIsaSpecificSubdirs);
7296                } else {
7297                    copyRet = NativeLibraryHelper.findSupportedAbi(handle, abiList);
7298                }
7299
7300                if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) {
7301                    throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
7302                            "Error unpackaging native libs for app, errorCode=" + copyRet);
7303                }
7304
7305                if (copyRet >= 0) {
7306                    pkg.applicationInfo.primaryCpuAbi = abiList[copyRet];
7307                } else if (copyRet == PackageManager.NO_NATIVE_LIBRARIES && cpuAbiOverride != null) {
7308                    pkg.applicationInfo.primaryCpuAbi = cpuAbiOverride;
7309                } else if (needsRenderScriptOverride) {
7310                    pkg.applicationInfo.primaryCpuAbi = abiList[0];
7311                }
7312            }
7313        } catch (IOException ioe) {
7314            Slog.e(TAG, "Unable to get canonical file " + ioe.toString());
7315        } finally {
7316            IoUtils.closeQuietly(handle);
7317        }
7318
7319        // Now that we've calculated the ABIs and determined if it's an internal app,
7320        // we will go ahead and populate the nativeLibraryPath.
7321        setNativeLibraryPaths(pkg);
7322    }
7323
7324    /**
7325     * Adjusts ABIs for a set of packages belonging to a shared user so that they all match.
7326     * i.e, so that all packages can be run inside a single process if required.
7327     *
7328     * Optionally, callers can pass in a parsed package via {@code newPackage} in which case
7329     * this function will either try and make the ABI for all packages in {@code packagesForUser}
7330     * match {@code scannedPackage} or will update the ABI of {@code scannedPackage} to match
7331     * the ABI selected for {@code packagesForUser}. This variant is used when installing or
7332     * updating a package that belongs to a shared user.
7333     *
7334     * NOTE: We currently only match for the primary CPU abi string. Matching the secondary
7335     * adds unnecessary complexity.
7336     */
7337    private void adjustCpuAbisForSharedUserLPw(Set<PackageSetting> packagesForUser,
7338            PackageParser.Package scannedPackage, boolean forceDexOpt, boolean deferDexOpt) {
7339        String requiredInstructionSet = null;
7340        if (scannedPackage != null && scannedPackage.applicationInfo.primaryCpuAbi != null) {
7341            requiredInstructionSet = VMRuntime.getInstructionSet(
7342                     scannedPackage.applicationInfo.primaryCpuAbi);
7343        }
7344
7345        PackageSetting requirer = null;
7346        for (PackageSetting ps : packagesForUser) {
7347            // If packagesForUser contains scannedPackage, we skip it. This will happen
7348            // when scannedPackage is an update of an existing package. Without this check,
7349            // we will never be able to change the ABI of any package belonging to a shared
7350            // user, even if it's compatible with other packages.
7351            if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
7352                if (ps.primaryCpuAbiString == null) {
7353                    continue;
7354                }
7355
7356                final String instructionSet = VMRuntime.getInstructionSet(ps.primaryCpuAbiString);
7357                if (requiredInstructionSet != null && !instructionSet.equals(requiredInstructionSet)) {
7358                    // We have a mismatch between instruction sets (say arm vs arm64) warn about
7359                    // this but there's not much we can do.
7360                    String errorMessage = "Instruction set mismatch, "
7361                            + ((requirer == null) ? "[caller]" : requirer)
7362                            + " requires " + requiredInstructionSet + " whereas " + ps
7363                            + " requires " + instructionSet;
7364                    Slog.w(TAG, errorMessage);
7365                }
7366
7367                if (requiredInstructionSet == null) {
7368                    requiredInstructionSet = instructionSet;
7369                    requirer = ps;
7370                }
7371            }
7372        }
7373
7374        if (requiredInstructionSet != null) {
7375            String adjustedAbi;
7376            if (requirer != null) {
7377                // requirer != null implies that either scannedPackage was null or that scannedPackage
7378                // did not require an ABI, in which case we have to adjust scannedPackage to match
7379                // the ABI of the set (which is the same as requirer's ABI)
7380                adjustedAbi = requirer.primaryCpuAbiString;
7381                if (scannedPackage != null) {
7382                    scannedPackage.applicationInfo.primaryCpuAbi = adjustedAbi;
7383                }
7384            } else {
7385                // requirer == null implies that we're updating all ABIs in the set to
7386                // match scannedPackage.
7387                adjustedAbi =  scannedPackage.applicationInfo.primaryCpuAbi;
7388            }
7389
7390            for (PackageSetting ps : packagesForUser) {
7391                if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
7392                    if (ps.primaryCpuAbiString != null) {
7393                        continue;
7394                    }
7395
7396                    ps.primaryCpuAbiString = adjustedAbi;
7397                    if (ps.pkg != null && ps.pkg.applicationInfo != null) {
7398                        ps.pkg.applicationInfo.primaryCpuAbi = adjustedAbi;
7399                        Slog.i(TAG, "Adjusting ABI for : " + ps.name + " to " + adjustedAbi);
7400
7401                        int result = mPackageDexOptimizer.performDexOpt(ps.pkg,
7402                                null /* instruction sets */, forceDexOpt, deferDexOpt, true);
7403                        if (result == PackageDexOptimizer.DEX_OPT_FAILED) {
7404                            ps.primaryCpuAbiString = null;
7405                            ps.pkg.applicationInfo.primaryCpuAbi = null;
7406                            return;
7407                        } else {
7408                            mInstaller.rmdex(ps.codePathString,
7409                                    getDexCodeInstructionSet(getPreferredInstructionSet()));
7410                        }
7411                    }
7412                }
7413            }
7414        }
7415    }
7416
7417    private void setUpCustomResolverActivity(PackageParser.Package pkg) {
7418        synchronized (mPackages) {
7419            mResolverReplaced = true;
7420            // Set up information for custom user intent resolution activity.
7421            mResolveActivity.applicationInfo = pkg.applicationInfo;
7422            mResolveActivity.name = mCustomResolverComponentName.getClassName();
7423            mResolveActivity.packageName = pkg.applicationInfo.packageName;
7424            mResolveActivity.processName = pkg.applicationInfo.packageName;
7425            mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
7426            mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS |
7427                    ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
7428            mResolveActivity.theme = 0;
7429            mResolveActivity.exported = true;
7430            mResolveActivity.enabled = true;
7431            mResolveInfo.activityInfo = mResolveActivity;
7432            mResolveInfo.priority = 0;
7433            mResolveInfo.preferredOrder = 0;
7434            mResolveInfo.match = 0;
7435            mResolveComponentName = mCustomResolverComponentName;
7436            Slog.i(TAG, "Replacing default ResolverActivity with custom activity: " +
7437                    mResolveComponentName);
7438        }
7439    }
7440
7441    private static String calculateBundledApkRoot(final String codePathString) {
7442        final File codePath = new File(codePathString);
7443        final File codeRoot;
7444        if (FileUtils.contains(Environment.getRootDirectory(), codePath)) {
7445            codeRoot = Environment.getRootDirectory();
7446        } else if (FileUtils.contains(Environment.getOemDirectory(), codePath)) {
7447            codeRoot = Environment.getOemDirectory();
7448        } else if (FileUtils.contains(Environment.getVendorDirectory(), codePath)) {
7449            codeRoot = Environment.getVendorDirectory();
7450        } else {
7451            // Unrecognized code path; take its top real segment as the apk root:
7452            // e.g. /something/app/blah.apk => /something
7453            try {
7454                File f = codePath.getCanonicalFile();
7455                File parent = f.getParentFile();    // non-null because codePath is a file
7456                File tmp;
7457                while ((tmp = parent.getParentFile()) != null) {
7458                    f = parent;
7459                    parent = tmp;
7460                }
7461                codeRoot = f;
7462                Slog.w(TAG, "Unrecognized code path "
7463                        + codePath + " - using " + codeRoot);
7464            } catch (IOException e) {
7465                // Can't canonicalize the code path -- shenanigans?
7466                Slog.w(TAG, "Can't canonicalize code path " + codePath);
7467                return Environment.getRootDirectory().getPath();
7468            }
7469        }
7470        return codeRoot.getPath();
7471    }
7472
7473    /**
7474     * Derive and set the location of native libraries for the given package,
7475     * which varies depending on where and how the package was installed.
7476     */
7477    private void setNativeLibraryPaths(PackageParser.Package pkg) {
7478        final ApplicationInfo info = pkg.applicationInfo;
7479        final String codePath = pkg.codePath;
7480        final File codeFile = new File(codePath);
7481        final boolean bundledApp = info.isSystemApp() && !info.isUpdatedSystemApp();
7482        final boolean asecApp = info.isForwardLocked() || isExternal(info);
7483
7484        info.nativeLibraryRootDir = null;
7485        info.nativeLibraryRootRequiresIsa = false;
7486        info.nativeLibraryDir = null;
7487        info.secondaryNativeLibraryDir = null;
7488
7489        if (isApkFile(codeFile)) {
7490            // Monolithic install
7491            if (bundledApp) {
7492                // If "/system/lib64/apkname" exists, assume that is the per-package
7493                // native library directory to use; otherwise use "/system/lib/apkname".
7494                final String apkRoot = calculateBundledApkRoot(info.sourceDir);
7495                final boolean is64Bit = VMRuntime.is64BitInstructionSet(
7496                        getPrimaryInstructionSet(info));
7497
7498                // This is a bundled system app so choose the path based on the ABI.
7499                // if it's a 64 bit abi, use lib64 otherwise use lib32. Note that this
7500                // is just the default path.
7501                final String apkName = deriveCodePathName(codePath);
7502                final String libDir = is64Bit ? LIB64_DIR_NAME : LIB_DIR_NAME;
7503                info.nativeLibraryRootDir = Environment.buildPath(new File(apkRoot), libDir,
7504                        apkName).getAbsolutePath();
7505
7506                if (info.secondaryCpuAbi != null) {
7507                    final String secondaryLibDir = is64Bit ? LIB_DIR_NAME : LIB64_DIR_NAME;
7508                    info.secondaryNativeLibraryDir = Environment.buildPath(new File(apkRoot),
7509                            secondaryLibDir, apkName).getAbsolutePath();
7510                }
7511            } else if (asecApp) {
7512                info.nativeLibraryRootDir = new File(codeFile.getParentFile(), LIB_DIR_NAME)
7513                        .getAbsolutePath();
7514            } else {
7515                final String apkName = deriveCodePathName(codePath);
7516                info.nativeLibraryRootDir = new File(mAppLib32InstallDir, apkName)
7517                        .getAbsolutePath();
7518            }
7519
7520            info.nativeLibraryRootRequiresIsa = false;
7521            info.nativeLibraryDir = info.nativeLibraryRootDir;
7522        } else {
7523            // Cluster install
7524            info.nativeLibraryRootDir = new File(codeFile, LIB_DIR_NAME).getAbsolutePath();
7525            info.nativeLibraryRootRequiresIsa = true;
7526
7527            info.nativeLibraryDir = new File(info.nativeLibraryRootDir,
7528                    getPrimaryInstructionSet(info)).getAbsolutePath();
7529
7530            if (info.secondaryCpuAbi != null) {
7531                info.secondaryNativeLibraryDir = new File(info.nativeLibraryRootDir,
7532                        VMRuntime.getInstructionSet(info.secondaryCpuAbi)).getAbsolutePath();
7533            }
7534        }
7535    }
7536
7537    /**
7538     * Calculate the abis and roots for a bundled app. These can uniquely
7539     * be determined from the contents of the system partition, i.e whether
7540     * it contains 64 or 32 bit shared libraries etc. We do not validate any
7541     * of this information, and instead assume that the system was built
7542     * sensibly.
7543     */
7544    private void setBundledAppAbisAndRoots(PackageParser.Package pkg,
7545                                           PackageSetting pkgSetting) {
7546        final String apkName = deriveCodePathName(pkg.applicationInfo.getCodePath());
7547
7548        // If "/system/lib64/apkname" exists, assume that is the per-package
7549        // native library directory to use; otherwise use "/system/lib/apkname".
7550        final String apkRoot = calculateBundledApkRoot(pkg.applicationInfo.sourceDir);
7551        setBundledAppAbi(pkg, apkRoot, apkName);
7552        // pkgSetting might be null during rescan following uninstall of updates
7553        // to a bundled app, so accommodate that possibility.  The settings in
7554        // that case will be established later from the parsed package.
7555        //
7556        // If the settings aren't null, sync them up with what we've just derived.
7557        // note that apkRoot isn't stored in the package settings.
7558        if (pkgSetting != null) {
7559            pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
7560            pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
7561        }
7562    }
7563
7564    /**
7565     * Deduces the ABI of a bundled app and sets the relevant fields on the
7566     * parsed pkg object.
7567     *
7568     * @param apkRoot the root of the installed apk, something like {@code /system} or {@code /oem}
7569     *        under which system libraries are installed.
7570     * @param apkName the name of the installed package.
7571     */
7572    private static void setBundledAppAbi(PackageParser.Package pkg, String apkRoot, String apkName) {
7573        final File codeFile = new File(pkg.codePath);
7574
7575        final boolean has64BitLibs;
7576        final boolean has32BitLibs;
7577        if (isApkFile(codeFile)) {
7578            // Monolithic install
7579            has64BitLibs = (new File(apkRoot, new File(LIB64_DIR_NAME, apkName).getPath())).exists();
7580            has32BitLibs = (new File(apkRoot, new File(LIB_DIR_NAME, apkName).getPath())).exists();
7581        } else {
7582            // Cluster install
7583            final File rootDir = new File(codeFile, LIB_DIR_NAME);
7584            if (!ArrayUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS)
7585                    && !TextUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS[0])) {
7586                final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_64_BIT_ABIS[0]);
7587                has64BitLibs = (new File(rootDir, isa)).exists();
7588            } else {
7589                has64BitLibs = false;
7590            }
7591            if (!ArrayUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS)
7592                    && !TextUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS[0])) {
7593                final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_32_BIT_ABIS[0]);
7594                has32BitLibs = (new File(rootDir, isa)).exists();
7595            } else {
7596                has32BitLibs = false;
7597            }
7598        }
7599
7600        if (has64BitLibs && !has32BitLibs) {
7601            // The package has 64 bit libs, but not 32 bit libs. Its primary
7602            // ABI should be 64 bit. We can safely assume here that the bundled
7603            // native libraries correspond to the most preferred ABI in the list.
7604
7605            pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
7606            pkg.applicationInfo.secondaryCpuAbi = null;
7607        } else if (has32BitLibs && !has64BitLibs) {
7608            // The package has 32 bit libs but not 64 bit libs. Its primary
7609            // ABI should be 32 bit.
7610
7611            pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
7612            pkg.applicationInfo.secondaryCpuAbi = null;
7613        } else if (has32BitLibs && has64BitLibs) {
7614            // The application has both 64 and 32 bit bundled libraries. We check
7615            // here that the app declares multiArch support, and warn if it doesn't.
7616            //
7617            // We will be lenient here and record both ABIs. The primary will be the
7618            // ABI that's higher on the list, i.e, a device that's configured to prefer
7619            // 64 bit apps will see a 64 bit primary ABI,
7620
7621            if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) == 0) {
7622                Slog.e(TAG, "Package: " + pkg + " has multiple bundled libs, but is not multiarch.");
7623            }
7624
7625            if (VMRuntime.is64BitInstructionSet(getPreferredInstructionSet())) {
7626                pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
7627                pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
7628            } else {
7629                pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
7630                pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
7631            }
7632        } else {
7633            pkg.applicationInfo.primaryCpuAbi = null;
7634            pkg.applicationInfo.secondaryCpuAbi = null;
7635        }
7636    }
7637
7638    private void killApplication(String pkgName, int appId, String reason) {
7639        // Request the ActivityManager to kill the process(only for existing packages)
7640        // so that we do not end up in a confused state while the user is still using the older
7641        // version of the application while the new one gets installed.
7642        IActivityManager am = ActivityManagerNative.getDefault();
7643        if (am != null) {
7644            try {
7645                am.killApplicationWithAppId(pkgName, appId, reason);
7646            } catch (RemoteException e) {
7647            }
7648        }
7649    }
7650
7651    void removePackageLI(PackageSetting ps, boolean chatty) {
7652        if (DEBUG_INSTALL) {
7653            if (chatty)
7654                Log.d(TAG, "Removing package " + ps.name);
7655        }
7656
7657        // writer
7658        synchronized (mPackages) {
7659            mPackages.remove(ps.name);
7660            final PackageParser.Package pkg = ps.pkg;
7661            if (pkg != null) {
7662                cleanPackageDataStructuresLILPw(pkg, chatty);
7663            }
7664        }
7665    }
7666
7667    void removeInstalledPackageLI(PackageParser.Package pkg, boolean chatty) {
7668        if (DEBUG_INSTALL) {
7669            if (chatty)
7670                Log.d(TAG, "Removing package " + pkg.applicationInfo.packageName);
7671        }
7672
7673        // writer
7674        synchronized (mPackages) {
7675            mPackages.remove(pkg.applicationInfo.packageName);
7676            cleanPackageDataStructuresLILPw(pkg, chatty);
7677        }
7678    }
7679
7680    void cleanPackageDataStructuresLILPw(PackageParser.Package pkg, boolean chatty) {
7681        int N = pkg.providers.size();
7682        StringBuilder r = null;
7683        int i;
7684        for (i=0; i<N; i++) {
7685            PackageParser.Provider p = pkg.providers.get(i);
7686            mProviders.removeProvider(p);
7687            if (p.info.authority == null) {
7688
7689                /* There was another ContentProvider with this authority when
7690                 * this app was installed so this authority is null,
7691                 * Ignore it as we don't have to unregister the provider.
7692                 */
7693                continue;
7694            }
7695            String names[] = p.info.authority.split(";");
7696            for (int j = 0; j < names.length; j++) {
7697                if (mProvidersByAuthority.get(names[j]) == p) {
7698                    mProvidersByAuthority.remove(names[j]);
7699                    if (DEBUG_REMOVE) {
7700                        if (chatty)
7701                            Log.d(TAG, "Unregistered content provider: " + names[j]
7702                                    + ", className = " + p.info.name + ", isSyncable = "
7703                                    + p.info.isSyncable);
7704                    }
7705                }
7706            }
7707            if (DEBUG_REMOVE && chatty) {
7708                if (r == null) {
7709                    r = new StringBuilder(256);
7710                } else {
7711                    r.append(' ');
7712                }
7713                r.append(p.info.name);
7714            }
7715        }
7716        if (r != null) {
7717            if (DEBUG_REMOVE) Log.d(TAG, "  Providers: " + r);
7718        }
7719
7720        N = pkg.services.size();
7721        r = null;
7722        for (i=0; i<N; i++) {
7723            PackageParser.Service s = pkg.services.get(i);
7724            mServices.removeService(s);
7725            if (chatty) {
7726                if (r == null) {
7727                    r = new StringBuilder(256);
7728                } else {
7729                    r.append(' ');
7730                }
7731                r.append(s.info.name);
7732            }
7733        }
7734        if (r != null) {
7735            if (DEBUG_REMOVE) Log.d(TAG, "  Services: " + r);
7736        }
7737
7738        N = pkg.receivers.size();
7739        r = null;
7740        for (i=0; i<N; i++) {
7741            PackageParser.Activity a = pkg.receivers.get(i);
7742            mReceivers.removeActivity(a, "receiver");
7743            if (DEBUG_REMOVE && chatty) {
7744                if (r == null) {
7745                    r = new StringBuilder(256);
7746                } else {
7747                    r.append(' ');
7748                }
7749                r.append(a.info.name);
7750            }
7751        }
7752        if (r != null) {
7753            if (DEBUG_REMOVE) Log.d(TAG, "  Receivers: " + r);
7754        }
7755
7756        N = pkg.activities.size();
7757        r = null;
7758        for (i=0; i<N; i++) {
7759            PackageParser.Activity a = pkg.activities.get(i);
7760            mActivities.removeActivity(a, "activity");
7761            if (DEBUG_REMOVE && chatty) {
7762                if (r == null) {
7763                    r = new StringBuilder(256);
7764                } else {
7765                    r.append(' ');
7766                }
7767                r.append(a.info.name);
7768            }
7769        }
7770        if (r != null) {
7771            if (DEBUG_REMOVE) Log.d(TAG, "  Activities: " + r);
7772        }
7773
7774        N = pkg.permissions.size();
7775        r = null;
7776        for (i=0; i<N; i++) {
7777            PackageParser.Permission p = pkg.permissions.get(i);
7778            BasePermission bp = mSettings.mPermissions.get(p.info.name);
7779            if (bp == null) {
7780                bp = mSettings.mPermissionTrees.get(p.info.name);
7781            }
7782            if (bp != null && bp.perm == p) {
7783                bp.perm = null;
7784                if (DEBUG_REMOVE && chatty) {
7785                    if (r == null) {
7786                        r = new StringBuilder(256);
7787                    } else {
7788                        r.append(' ');
7789                    }
7790                    r.append(p.info.name);
7791                }
7792            }
7793            if ((p.info.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
7794                ArraySet<String> appOpPerms = mAppOpPermissionPackages.get(p.info.name);
7795                if (appOpPerms != null) {
7796                    appOpPerms.remove(pkg.packageName);
7797                }
7798            }
7799        }
7800        if (r != null) {
7801            if (DEBUG_REMOVE) Log.d(TAG, "  Permissions: " + r);
7802        }
7803
7804        N = pkg.requestedPermissions.size();
7805        r = null;
7806        for (i=0; i<N; i++) {
7807            String perm = pkg.requestedPermissions.get(i);
7808            BasePermission bp = mSettings.mPermissions.get(perm);
7809            if (bp != null && (bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
7810                ArraySet<String> appOpPerms = mAppOpPermissionPackages.get(perm);
7811                if (appOpPerms != null) {
7812                    appOpPerms.remove(pkg.packageName);
7813                    if (appOpPerms.isEmpty()) {
7814                        mAppOpPermissionPackages.remove(perm);
7815                    }
7816                }
7817            }
7818        }
7819        if (r != null) {
7820            if (DEBUG_REMOVE) Log.d(TAG, "  Permissions: " + r);
7821        }
7822
7823        N = pkg.instrumentation.size();
7824        r = null;
7825        for (i=0; i<N; i++) {
7826            PackageParser.Instrumentation a = pkg.instrumentation.get(i);
7827            mInstrumentation.remove(a.getComponentName());
7828            if (DEBUG_REMOVE && chatty) {
7829                if (r == null) {
7830                    r = new StringBuilder(256);
7831                } else {
7832                    r.append(' ');
7833                }
7834                r.append(a.info.name);
7835            }
7836        }
7837        if (r != null) {
7838            if (DEBUG_REMOVE) Log.d(TAG, "  Instrumentation: " + r);
7839        }
7840
7841        r = null;
7842        if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
7843            // Only system apps can hold shared libraries.
7844            if (pkg.libraryNames != null) {
7845                for (i=0; i<pkg.libraryNames.size(); i++) {
7846                    String name = pkg.libraryNames.get(i);
7847                    SharedLibraryEntry cur = mSharedLibraries.get(name);
7848                    if (cur != null && cur.apk != null && cur.apk.equals(pkg.packageName)) {
7849                        mSharedLibraries.remove(name);
7850                        if (DEBUG_REMOVE && chatty) {
7851                            if (r == null) {
7852                                r = new StringBuilder(256);
7853                            } else {
7854                                r.append(' ');
7855                            }
7856                            r.append(name);
7857                        }
7858                    }
7859                }
7860            }
7861        }
7862        if (r != null) {
7863            if (DEBUG_REMOVE) Log.d(TAG, "  Libraries: " + r);
7864        }
7865    }
7866
7867    private static boolean hasPermission(PackageParser.Package pkgInfo, String perm) {
7868        for (int i=pkgInfo.permissions.size()-1; i>=0; i--) {
7869            if (pkgInfo.permissions.get(i).info.name.equals(perm)) {
7870                return true;
7871            }
7872        }
7873        return false;
7874    }
7875
7876    static final int UPDATE_PERMISSIONS_ALL = 1<<0;
7877    static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1<<1;
7878    static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1<<2;
7879
7880    private void updatePermissionsLPw(String changingPkg,
7881            PackageParser.Package pkgInfo, int flags) {
7882        // Make sure there are no dangling permission trees.
7883        Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator();
7884        while (it.hasNext()) {
7885            final BasePermission bp = it.next();
7886            if (bp.packageSetting == null) {
7887                // We may not yet have parsed the package, so just see if
7888                // we still know about its settings.
7889                bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage);
7890            }
7891            if (bp.packageSetting == null) {
7892                Slog.w(TAG, "Removing dangling permission tree: " + bp.name
7893                        + " from package " + bp.sourcePackage);
7894                it.remove();
7895            } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) {
7896                if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
7897                    Slog.i(TAG, "Removing old permission tree: " + bp.name
7898                            + " from package " + bp.sourcePackage);
7899                    flags |= UPDATE_PERMISSIONS_ALL;
7900                    it.remove();
7901                }
7902            }
7903        }
7904
7905        // Make sure all dynamic permissions have been assigned to a package,
7906        // and make sure there are no dangling permissions.
7907        it = mSettings.mPermissions.values().iterator();
7908        while (it.hasNext()) {
7909            final BasePermission bp = it.next();
7910            if (bp.type == BasePermission.TYPE_DYNAMIC) {
7911                if (DEBUG_SETTINGS) Log.v(TAG, "Dynamic permission: name="
7912                        + bp.name + " pkg=" + bp.sourcePackage
7913                        + " info=" + bp.pendingInfo);
7914                if (bp.packageSetting == null && bp.pendingInfo != null) {
7915                    final BasePermission tree = findPermissionTreeLP(bp.name);
7916                    if (tree != null && tree.perm != null) {
7917                        bp.packageSetting = tree.packageSetting;
7918                        bp.perm = new PackageParser.Permission(tree.perm.owner,
7919                                new PermissionInfo(bp.pendingInfo));
7920                        bp.perm.info.packageName = tree.perm.info.packageName;
7921                        bp.perm.info.name = bp.name;
7922                        bp.uid = tree.uid;
7923                    }
7924                }
7925            }
7926            if (bp.packageSetting == null) {
7927                // We may not yet have parsed the package, so just see if
7928                // we still know about its settings.
7929                bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage);
7930            }
7931            if (bp.packageSetting == null) {
7932                Slog.w(TAG, "Removing dangling permission: " + bp.name
7933                        + " from package " + bp.sourcePackage);
7934                it.remove();
7935            } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) {
7936                if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
7937                    Slog.i(TAG, "Removing old permission: " + bp.name
7938                            + " from package " + bp.sourcePackage);
7939                    flags |= UPDATE_PERMISSIONS_ALL;
7940                    it.remove();
7941                }
7942            }
7943        }
7944
7945        // Now update the permissions for all packages, in particular
7946        // replace the granted permissions of the system packages.
7947        if ((flags&UPDATE_PERMISSIONS_ALL) != 0) {
7948            for (PackageParser.Package pkg : mPackages.values()) {
7949                if (pkg != pkgInfo) {
7950                    grantPermissionsLPw(pkg, (flags&UPDATE_PERMISSIONS_REPLACE_ALL) != 0,
7951                            changingPkg);
7952                }
7953            }
7954        }
7955
7956        if (pkgInfo != null) {
7957            grantPermissionsLPw(pkgInfo, (flags&UPDATE_PERMISSIONS_REPLACE_PKG) != 0, changingPkg);
7958        }
7959    }
7960
7961    private void grantPermissionsLPw(PackageParser.Package pkg, boolean replace,
7962            String packageOfInterest) {
7963        // IMPORTANT: There are two types of permissions: install and runtime.
7964        // Install time permissions are granted when the app is installed to
7965        // all device users and users added in the future. Runtime permissions
7966        // are granted at runtime explicitly to specific users. Normal and signature
7967        // protected permissions are install time permissions. Dangerous permissions
7968        // are install permissions if the app's target SDK is Lollipop MR1 or older,
7969        // otherwise they are runtime permissions. This function does not manage
7970        // runtime permissions except for the case an app targeting Lollipop MR1
7971        // being upgraded to target a newer SDK, in which case dangerous permissions
7972        // are transformed from install time to runtime ones.
7973
7974        final PackageSetting ps = (PackageSetting) pkg.mExtras;
7975        if (ps == null) {
7976            return;
7977        }
7978
7979        PermissionsState permissionsState = ps.getPermissionsState();
7980        PermissionsState origPermissions = permissionsState;
7981
7982        final int[] currentUserIds = UserManagerService.getInstance().getUserIds();
7983
7984        int[] changedRuntimePermissionUserIds = EMPTY_INT_ARRAY;
7985
7986        boolean changedInstallPermission = false;
7987
7988        if (replace) {
7989            ps.installPermissionsFixed = false;
7990            if (!ps.isSharedUser()) {
7991                origPermissions = new PermissionsState(permissionsState);
7992                permissionsState.reset();
7993            }
7994        }
7995
7996        permissionsState.setGlobalGids(mGlobalGids);
7997
7998        final int N = pkg.requestedPermissions.size();
7999        for (int i=0; i<N; i++) {
8000            final String name = pkg.requestedPermissions.get(i);
8001            final BasePermission bp = mSettings.mPermissions.get(name);
8002
8003            if (DEBUG_INSTALL) {
8004                Log.i(TAG, "Package " + pkg.packageName + " checking " + name + ": " + bp);
8005            }
8006
8007            if (bp == null || bp.packageSetting == null) {
8008                if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) {
8009                    Slog.w(TAG, "Unknown permission " + name
8010                            + " in package " + pkg.packageName);
8011                }
8012                continue;
8013            }
8014
8015            final String perm = bp.name;
8016            boolean allowedSig = false;
8017            int grant = GRANT_DENIED;
8018
8019            // Keep track of app op permissions.
8020            if ((bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
8021                ArraySet<String> pkgs = mAppOpPermissionPackages.get(bp.name);
8022                if (pkgs == null) {
8023                    pkgs = new ArraySet<>();
8024                    mAppOpPermissionPackages.put(bp.name, pkgs);
8025                }
8026                pkgs.add(pkg.packageName);
8027            }
8028
8029            final int level = bp.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE;
8030            switch (level) {
8031                case PermissionInfo.PROTECTION_NORMAL: {
8032                    // For all apps normal permissions are install time ones.
8033                    grant = GRANT_INSTALL;
8034                } break;
8035
8036                case PermissionInfo.PROTECTION_DANGEROUS: {
8037                    if (pkg.applicationInfo.targetSdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1) {
8038                        // For legacy apps dangerous permissions are install time ones.
8039                        grant = GRANT_INSTALL_LEGACY;
8040                    } else if (origPermissions.hasInstallPermission(bp.name)) {
8041                        // For legacy apps that became modern, install becomes runtime.
8042                        grant = GRANT_UPGRADE;
8043                    } else {
8044                        // For modern apps keep runtime permissions unchanged.
8045                        grant = GRANT_RUNTIME;
8046                    }
8047                } break;
8048
8049                case PermissionInfo.PROTECTION_SIGNATURE: {
8050                    // For all apps signature permissions are install time ones.
8051                    allowedSig = grantSignaturePermission(perm, pkg, bp, origPermissions);
8052                    if (allowedSig) {
8053                        grant = GRANT_INSTALL;
8054                    }
8055                } break;
8056            }
8057
8058            if (DEBUG_INSTALL) {
8059                Log.i(TAG, "Package " + pkg.packageName + " granting " + perm);
8060            }
8061
8062            if (grant != GRANT_DENIED) {
8063                if (!isSystemApp(ps) && ps.installPermissionsFixed) {
8064                    // If this is an existing, non-system package, then
8065                    // we can't add any new permissions to it.
8066                    if (!allowedSig && !origPermissions.hasInstallPermission(perm)) {
8067                        // Except...  if this is a permission that was added
8068                        // to the platform (note: need to only do this when
8069                        // updating the platform).
8070                        if (!isNewPlatformPermissionForPackage(perm, pkg)) {
8071                            grant = GRANT_DENIED;
8072                        }
8073                    }
8074                }
8075
8076                switch (grant) {
8077                    case GRANT_INSTALL: {
8078                        // Revoke this as runtime permission to handle the case of
8079                        // a runtime permission being downgraded to an install one.
8080                        for (int userId : UserManagerService.getInstance().getUserIds()) {
8081                            if (origPermissions.getRuntimePermissionState(
8082                                    bp.name, userId) != null) {
8083                                // Revoke the runtime permission and clear the flags.
8084                                origPermissions.revokeRuntimePermission(bp, userId);
8085                                origPermissions.updatePermissionFlags(bp, userId,
8086                                      PackageManager.MASK_PERMISSION_FLAGS, 0);
8087                                // If we revoked a permission permission, we have to write.
8088                                changedRuntimePermissionUserIds = ArrayUtils.appendInt(
8089                                        changedRuntimePermissionUserIds, userId);
8090                            }
8091                        }
8092                        // Grant an install permission.
8093                        if (permissionsState.grantInstallPermission(bp) !=
8094                                PermissionsState.PERMISSION_OPERATION_FAILURE) {
8095                            changedInstallPermission = true;
8096                        }
8097                    } break;
8098
8099                    case GRANT_INSTALL_LEGACY: {
8100                        // Grant an install permission.
8101                        if (permissionsState.grantInstallPermission(bp) !=
8102                                PermissionsState.PERMISSION_OPERATION_FAILURE) {
8103                            changedInstallPermission = true;
8104                        }
8105                    } break;
8106
8107                    case GRANT_RUNTIME: {
8108                        // Grant previously granted runtime permissions.
8109                        for (int userId : UserManagerService.getInstance().getUserIds()) {
8110                            PermissionState permissionState = origPermissions
8111                                    .getRuntimePermissionState(bp.name, userId);
8112                            final int flags = permissionState != null
8113                                    ? permissionState.getFlags() : 0;
8114                            if (origPermissions.hasRuntimePermission(bp.name, userId)) {
8115                                if (permissionsState.grantRuntimePermission(bp, userId) ==
8116                                        PermissionsState.PERMISSION_OPERATION_FAILURE) {
8117                                    // If we cannot put the permission as it was, we have to write.
8118                                    changedRuntimePermissionUserIds = ArrayUtils.appendInt(
8119                                            changedRuntimePermissionUserIds, userId);
8120                                }
8121                            }
8122                            // Propagate the permission flags.
8123                            permissionsState.updatePermissionFlags(bp, userId, flags, flags);
8124                        }
8125                    } break;
8126
8127                    case GRANT_UPGRADE: {
8128                        // Grant runtime permissions for a previously held install permission.
8129                        PermissionState permissionState = origPermissions
8130                                .getInstallPermissionState(bp.name);
8131                        final int flags = permissionState != null ? permissionState.getFlags() : 0;
8132
8133                        if (origPermissions.revokeInstallPermission(bp)
8134                                != PermissionsState.PERMISSION_OPERATION_FAILURE) {
8135                            // We will be transferring the permission flags, so clear them.
8136                            origPermissions.updatePermissionFlags(bp, UserHandle.USER_ALL,
8137                                    PackageManager.MASK_PERMISSION_FLAGS, 0);
8138                            changedInstallPermission = true;
8139                        }
8140
8141                        // If the permission is not to be promoted to runtime we ignore it and
8142                        // also its other flags as they are not applicable to install permissions.
8143                        if ((flags & PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE) == 0) {
8144                            for (int userId : currentUserIds) {
8145                                if (permissionsState.grantRuntimePermission(bp, userId) !=
8146                                        PermissionsState.PERMISSION_OPERATION_FAILURE) {
8147                                    // Transfer the permission flags.
8148                                    permissionsState.updatePermissionFlags(bp, userId,
8149                                            flags, flags);
8150                                    // If we granted the permission, we have to write.
8151                                    changedRuntimePermissionUserIds = ArrayUtils.appendInt(
8152                                            changedRuntimePermissionUserIds, userId);
8153                                }
8154                            }
8155                        }
8156                    } break;
8157
8158                    default: {
8159                        if (packageOfInterest == null
8160                                || packageOfInterest.equals(pkg.packageName)) {
8161                            Slog.w(TAG, "Not granting permission " + perm
8162                                    + " to package " + pkg.packageName
8163                                    + " because it was previously installed without");
8164                        }
8165                    } break;
8166                }
8167            } else {
8168                if (permissionsState.revokeInstallPermission(bp) !=
8169                        PermissionsState.PERMISSION_OPERATION_FAILURE) {
8170                    // Also drop the permission flags.
8171                    permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
8172                            PackageManager.MASK_PERMISSION_FLAGS, 0);
8173                    changedInstallPermission = true;
8174                    Slog.i(TAG, "Un-granting permission " + perm
8175                            + " from package " + pkg.packageName
8176                            + " (protectionLevel=" + bp.protectionLevel
8177                            + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
8178                            + ")");
8179                } else if ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) == 0) {
8180                    // Don't print warning for app op permissions, since it is fine for them
8181                    // not to be granted, there is a UI for the user to decide.
8182                    if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) {
8183                        Slog.w(TAG, "Not granting permission " + perm
8184                                + " to package " + pkg.packageName
8185                                + " (protectionLevel=" + bp.protectionLevel
8186                                + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
8187                                + ")");
8188                    }
8189                }
8190            }
8191        }
8192
8193        if ((changedInstallPermission || replace) && !ps.installPermissionsFixed &&
8194                !isSystemApp(ps) || isUpdatedSystemApp(ps)){
8195            // This is the first that we have heard about this package, so the
8196            // permissions we have now selected are fixed until explicitly
8197            // changed.
8198            ps.installPermissionsFixed = true;
8199        }
8200
8201        // Persist the runtime permissions state for users with changes.
8202        for (int userId : changedRuntimePermissionUserIds) {
8203            mSettings.writeRuntimePermissionsForUserLPr(userId, false);
8204        }
8205    }
8206
8207    private boolean isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg) {
8208        boolean allowed = false;
8209        final int NP = PackageParser.NEW_PERMISSIONS.length;
8210        for (int ip=0; ip<NP; ip++) {
8211            final PackageParser.NewPermissionInfo npi
8212                    = PackageParser.NEW_PERMISSIONS[ip];
8213            if (npi.name.equals(perm)
8214                    && pkg.applicationInfo.targetSdkVersion < npi.sdkVersion) {
8215                allowed = true;
8216                Log.i(TAG, "Auto-granting " + perm + " to old pkg "
8217                        + pkg.packageName);
8218                break;
8219            }
8220        }
8221        return allowed;
8222    }
8223
8224    private boolean grantSignaturePermission(String perm, PackageParser.Package pkg,
8225            BasePermission bp, PermissionsState origPermissions) {
8226        boolean allowed;
8227        allowed = (compareSignatures(
8228                bp.packageSetting.signatures.mSignatures, pkg.mSignatures)
8229                        == PackageManager.SIGNATURE_MATCH)
8230                || (compareSignatures(mPlatformPackage.mSignatures, pkg.mSignatures)
8231                        == PackageManager.SIGNATURE_MATCH);
8232        if (!allowed && (bp.protectionLevel
8233                & PermissionInfo.PROTECTION_FLAG_SYSTEM) != 0) {
8234            if (isSystemApp(pkg)) {
8235                // For updated system applications, a system permission
8236                // is granted only if it had been defined by the original application.
8237                if (pkg.isUpdatedSystemApp()) {
8238                    final PackageSetting sysPs = mSettings
8239                            .getDisabledSystemPkgLPr(pkg.packageName);
8240                    if (sysPs.getPermissionsState().hasInstallPermission(perm)) {
8241                        // If the original was granted this permission, we take
8242                        // that grant decision as read and propagate it to the
8243                        // update.
8244                        if (sysPs.isPrivileged()) {
8245                            allowed = true;
8246                        }
8247                    } else {
8248                        // The system apk may have been updated with an older
8249                        // version of the one on the data partition, but which
8250                        // granted a new system permission that it didn't have
8251                        // before.  In this case we do want to allow the app to
8252                        // now get the new permission if the ancestral apk is
8253                        // privileged to get it.
8254                        if (sysPs.pkg != null && sysPs.isPrivileged()) {
8255                            for (int j=0;
8256                                    j<sysPs.pkg.requestedPermissions.size(); j++) {
8257                                if (perm.equals(
8258                                        sysPs.pkg.requestedPermissions.get(j))) {
8259                                    allowed = true;
8260                                    break;
8261                                }
8262                            }
8263                        }
8264                    }
8265                } else {
8266                    allowed = isPrivilegedApp(pkg);
8267                }
8268            }
8269        }
8270        if (!allowed && (bp.protectionLevel
8271                & PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0) {
8272            // For development permissions, a development permission
8273            // is granted only if it was already granted.
8274            allowed = origPermissions.hasInstallPermission(perm);
8275        }
8276        return allowed;
8277    }
8278
8279    final class ActivityIntentResolver
8280            extends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo> {
8281        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
8282                boolean defaultOnly, int userId) {
8283            if (!sUserManager.exists(userId)) return null;
8284            mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
8285            return super.queryIntent(intent, resolvedType, defaultOnly, userId);
8286        }
8287
8288        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
8289                int userId) {
8290            if (!sUserManager.exists(userId)) return null;
8291            mFlags = flags;
8292            return super.queryIntent(intent, resolvedType,
8293                    (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId);
8294        }
8295
8296        public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
8297                int flags, ArrayList<PackageParser.Activity> packageActivities, int userId) {
8298            if (!sUserManager.exists(userId)) return null;
8299            if (packageActivities == null) {
8300                return null;
8301            }
8302            mFlags = flags;
8303            final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0;
8304            final int N = packageActivities.size();
8305            ArrayList<PackageParser.ActivityIntentInfo[]> listCut =
8306                new ArrayList<PackageParser.ActivityIntentInfo[]>(N);
8307
8308            ArrayList<PackageParser.ActivityIntentInfo> intentFilters;
8309            for (int i = 0; i < N; ++i) {
8310                intentFilters = packageActivities.get(i).intents;
8311                if (intentFilters != null && intentFilters.size() > 0) {
8312                    PackageParser.ActivityIntentInfo[] array =
8313                            new PackageParser.ActivityIntentInfo[intentFilters.size()];
8314                    intentFilters.toArray(array);
8315                    listCut.add(array);
8316                }
8317            }
8318            return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
8319        }
8320
8321        public final void addActivity(PackageParser.Activity a, String type) {
8322            final boolean systemApp = a.info.applicationInfo.isSystemApp();
8323            mActivities.put(a.getComponentName(), a);
8324            if (DEBUG_SHOW_INFO)
8325                Log.v(
8326                TAG, "  " + type + " " +
8327                (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel : a.info.name) + ":");
8328            if (DEBUG_SHOW_INFO)
8329                Log.v(TAG, "    Class=" + a.info.name);
8330            final int NI = a.intents.size();
8331            for (int j=0; j<NI; j++) {
8332                PackageParser.ActivityIntentInfo intent = a.intents.get(j);
8333                if (!systemApp && intent.getPriority() > 0 && "activity".equals(type)) {
8334                    intent.setPriority(0);
8335                    Log.w(TAG, "Package " + a.info.applicationInfo.packageName + " has activity "
8336                            + a.className + " with priority > 0, forcing to 0");
8337                }
8338                if (DEBUG_SHOW_INFO) {
8339                    Log.v(TAG, "    IntentFilter:");
8340                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
8341                }
8342                if (!intent.debugCheck()) {
8343                    Log.w(TAG, "==> For Activity " + a.info.name);
8344                }
8345                addFilter(intent);
8346            }
8347        }
8348
8349        public final void removeActivity(PackageParser.Activity a, String type) {
8350            mActivities.remove(a.getComponentName());
8351            if (DEBUG_SHOW_INFO) {
8352                Log.v(TAG, "  " + type + " "
8353                        + (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel
8354                                : a.info.name) + ":");
8355                Log.v(TAG, "    Class=" + a.info.name);
8356            }
8357            final int NI = a.intents.size();
8358            for (int j=0; j<NI; j++) {
8359                PackageParser.ActivityIntentInfo intent = a.intents.get(j);
8360                if (DEBUG_SHOW_INFO) {
8361                    Log.v(TAG, "    IntentFilter:");
8362                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
8363                }
8364                removeFilter(intent);
8365            }
8366        }
8367
8368        @Override
8369        protected boolean allowFilterResult(
8370                PackageParser.ActivityIntentInfo filter, List<ResolveInfo> dest) {
8371            ActivityInfo filterAi = filter.activity.info;
8372            for (int i=dest.size()-1; i>=0; i--) {
8373                ActivityInfo destAi = dest.get(i).activityInfo;
8374                if (destAi.name == filterAi.name
8375                        && destAi.packageName == filterAi.packageName) {
8376                    return false;
8377                }
8378            }
8379            return true;
8380        }
8381
8382        @Override
8383        protected ActivityIntentInfo[] newArray(int size) {
8384            return new ActivityIntentInfo[size];
8385        }
8386
8387        @Override
8388        protected boolean isFilterStopped(PackageParser.ActivityIntentInfo filter, int userId) {
8389            if (!sUserManager.exists(userId)) return true;
8390            PackageParser.Package p = filter.activity.owner;
8391            if (p != null) {
8392                PackageSetting ps = (PackageSetting)p.mExtras;
8393                if (ps != null) {
8394                    // System apps are never considered stopped for purposes of
8395                    // filtering, because there may be no way for the user to
8396                    // actually re-launch them.
8397                    return (ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0
8398                            && ps.getStopped(userId);
8399                }
8400            }
8401            return false;
8402        }
8403
8404        @Override
8405        protected boolean isPackageForFilter(String packageName,
8406                PackageParser.ActivityIntentInfo info) {
8407            return packageName.equals(info.activity.owner.packageName);
8408        }
8409
8410        @Override
8411        protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info,
8412                int match, int userId) {
8413            if (!sUserManager.exists(userId)) return null;
8414            if (!mSettings.isEnabledLPr(info.activity.info, mFlags, userId)) {
8415                return null;
8416            }
8417            final PackageParser.Activity activity = info.activity;
8418            if (mSafeMode && (activity.info.applicationInfo.flags
8419                    &ApplicationInfo.FLAG_SYSTEM) == 0) {
8420                return null;
8421            }
8422            PackageSetting ps = (PackageSetting) activity.owner.mExtras;
8423            if (ps == null) {
8424                return null;
8425            }
8426            ActivityInfo ai = PackageParser.generateActivityInfo(activity, mFlags,
8427                    ps.readUserState(userId), userId);
8428            if (ai == null) {
8429                return null;
8430            }
8431            final ResolveInfo res = new ResolveInfo();
8432            res.activityInfo = ai;
8433            if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
8434                res.filter = info;
8435            }
8436            if (info != null) {
8437                res.handleAllWebDataURI = info.handleAllWebDataURI();
8438            }
8439            res.priority = info.getPriority();
8440            res.preferredOrder = activity.owner.mPreferredOrder;
8441            //System.out.println("Result: " + res.activityInfo.className +
8442            //                   " = " + res.priority);
8443            res.match = match;
8444            res.isDefault = info.hasDefault;
8445            res.labelRes = info.labelRes;
8446            res.nonLocalizedLabel = info.nonLocalizedLabel;
8447            if (userNeedsBadging(userId)) {
8448                res.noResourceId = true;
8449            } else {
8450                res.icon = info.icon;
8451            }
8452            res.iconResourceId = info.icon;
8453            res.system = res.activityInfo.applicationInfo.isSystemApp();
8454            return res;
8455        }
8456
8457        @Override
8458        protected void sortResults(List<ResolveInfo> results) {
8459            Collections.sort(results, mResolvePrioritySorter);
8460        }
8461
8462        @Override
8463        protected void dumpFilter(PrintWriter out, String prefix,
8464                PackageParser.ActivityIntentInfo filter) {
8465            out.print(prefix); out.print(
8466                    Integer.toHexString(System.identityHashCode(filter.activity)));
8467                    out.print(' ');
8468                    filter.activity.printComponentShortName(out);
8469                    out.print(" filter ");
8470                    out.println(Integer.toHexString(System.identityHashCode(filter)));
8471        }
8472
8473        @Override
8474        protected Object filterToLabel(PackageParser.ActivityIntentInfo filter) {
8475            return filter.activity;
8476        }
8477
8478        protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
8479            PackageParser.Activity activity = (PackageParser.Activity)label;
8480            out.print(prefix); out.print(
8481                    Integer.toHexString(System.identityHashCode(activity)));
8482                    out.print(' ');
8483                    activity.printComponentShortName(out);
8484            if (count > 1) {
8485                out.print(" ("); out.print(count); out.print(" filters)");
8486            }
8487            out.println();
8488        }
8489
8490//        List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) {
8491//            final Iterator<ResolveInfo> i = resolveInfoList.iterator();
8492//            final List<ResolveInfo> retList = Lists.newArrayList();
8493//            while (i.hasNext()) {
8494//                final ResolveInfo resolveInfo = i.next();
8495//                if (isEnabledLP(resolveInfo.activityInfo)) {
8496//                    retList.add(resolveInfo);
8497//                }
8498//            }
8499//            return retList;
8500//        }
8501
8502        // Keys are String (activity class name), values are Activity.
8503        private final ArrayMap<ComponentName, PackageParser.Activity> mActivities
8504                = new ArrayMap<ComponentName, PackageParser.Activity>();
8505        private int mFlags;
8506    }
8507
8508    private final class ServiceIntentResolver
8509            extends IntentResolver<PackageParser.ServiceIntentInfo, ResolveInfo> {
8510        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
8511                boolean defaultOnly, int userId) {
8512            mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
8513            return super.queryIntent(intent, resolvedType, defaultOnly, userId);
8514        }
8515
8516        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
8517                int userId) {
8518            if (!sUserManager.exists(userId)) return null;
8519            mFlags = flags;
8520            return super.queryIntent(intent, resolvedType,
8521                    (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId);
8522        }
8523
8524        public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
8525                int flags, ArrayList<PackageParser.Service> packageServices, int userId) {
8526            if (!sUserManager.exists(userId)) return null;
8527            if (packageServices == null) {
8528                return null;
8529            }
8530            mFlags = flags;
8531            final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0;
8532            final int N = packageServices.size();
8533            ArrayList<PackageParser.ServiceIntentInfo[]> listCut =
8534                new ArrayList<PackageParser.ServiceIntentInfo[]>(N);
8535
8536            ArrayList<PackageParser.ServiceIntentInfo> intentFilters;
8537            for (int i = 0; i < N; ++i) {
8538                intentFilters = packageServices.get(i).intents;
8539                if (intentFilters != null && intentFilters.size() > 0) {
8540                    PackageParser.ServiceIntentInfo[] array =
8541                            new PackageParser.ServiceIntentInfo[intentFilters.size()];
8542                    intentFilters.toArray(array);
8543                    listCut.add(array);
8544                }
8545            }
8546            return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
8547        }
8548
8549        public final void addService(PackageParser.Service s) {
8550            mServices.put(s.getComponentName(), s);
8551            if (DEBUG_SHOW_INFO) {
8552                Log.v(TAG, "  "
8553                        + (s.info.nonLocalizedLabel != null
8554                        ? s.info.nonLocalizedLabel : s.info.name) + ":");
8555                Log.v(TAG, "    Class=" + s.info.name);
8556            }
8557            final int NI = s.intents.size();
8558            int j;
8559            for (j=0; j<NI; j++) {
8560                PackageParser.ServiceIntentInfo intent = s.intents.get(j);
8561                if (DEBUG_SHOW_INFO) {
8562                    Log.v(TAG, "    IntentFilter:");
8563                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
8564                }
8565                if (!intent.debugCheck()) {
8566                    Log.w(TAG, "==> For Service " + s.info.name);
8567                }
8568                addFilter(intent);
8569            }
8570        }
8571
8572        public final void removeService(PackageParser.Service s) {
8573            mServices.remove(s.getComponentName());
8574            if (DEBUG_SHOW_INFO) {
8575                Log.v(TAG, "  " + (s.info.nonLocalizedLabel != null
8576                        ? s.info.nonLocalizedLabel : s.info.name) + ":");
8577                Log.v(TAG, "    Class=" + s.info.name);
8578            }
8579            final int NI = s.intents.size();
8580            int j;
8581            for (j=0; j<NI; j++) {
8582                PackageParser.ServiceIntentInfo intent = s.intents.get(j);
8583                if (DEBUG_SHOW_INFO) {
8584                    Log.v(TAG, "    IntentFilter:");
8585                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
8586                }
8587                removeFilter(intent);
8588            }
8589        }
8590
8591        @Override
8592        protected boolean allowFilterResult(
8593                PackageParser.ServiceIntentInfo filter, List<ResolveInfo> dest) {
8594            ServiceInfo filterSi = filter.service.info;
8595            for (int i=dest.size()-1; i>=0; i--) {
8596                ServiceInfo destAi = dest.get(i).serviceInfo;
8597                if (destAi.name == filterSi.name
8598                        && destAi.packageName == filterSi.packageName) {
8599                    return false;
8600                }
8601            }
8602            return true;
8603        }
8604
8605        @Override
8606        protected PackageParser.ServiceIntentInfo[] newArray(int size) {
8607            return new PackageParser.ServiceIntentInfo[size];
8608        }
8609
8610        @Override
8611        protected boolean isFilterStopped(PackageParser.ServiceIntentInfo filter, int userId) {
8612            if (!sUserManager.exists(userId)) return true;
8613            PackageParser.Package p = filter.service.owner;
8614            if (p != null) {
8615                PackageSetting ps = (PackageSetting)p.mExtras;
8616                if (ps != null) {
8617                    // System apps are never considered stopped for purposes of
8618                    // filtering, because there may be no way for the user to
8619                    // actually re-launch them.
8620                    return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
8621                            && ps.getStopped(userId);
8622                }
8623            }
8624            return false;
8625        }
8626
8627        @Override
8628        protected boolean isPackageForFilter(String packageName,
8629                PackageParser.ServiceIntentInfo info) {
8630            return packageName.equals(info.service.owner.packageName);
8631        }
8632
8633        @Override
8634        protected ResolveInfo newResult(PackageParser.ServiceIntentInfo filter,
8635                int match, int userId) {
8636            if (!sUserManager.exists(userId)) return null;
8637            final PackageParser.ServiceIntentInfo info = (PackageParser.ServiceIntentInfo)filter;
8638            if (!mSettings.isEnabledLPr(info.service.info, mFlags, userId)) {
8639                return null;
8640            }
8641            final PackageParser.Service service = info.service;
8642            if (mSafeMode && (service.info.applicationInfo.flags
8643                    &ApplicationInfo.FLAG_SYSTEM) == 0) {
8644                return null;
8645            }
8646            PackageSetting ps = (PackageSetting) service.owner.mExtras;
8647            if (ps == null) {
8648                return null;
8649            }
8650            ServiceInfo si = PackageParser.generateServiceInfo(service, mFlags,
8651                    ps.readUserState(userId), userId);
8652            if (si == null) {
8653                return null;
8654            }
8655            final ResolveInfo res = new ResolveInfo();
8656            res.serviceInfo = si;
8657            if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
8658                res.filter = filter;
8659            }
8660            res.priority = info.getPriority();
8661            res.preferredOrder = service.owner.mPreferredOrder;
8662            res.match = match;
8663            res.isDefault = info.hasDefault;
8664            res.labelRes = info.labelRes;
8665            res.nonLocalizedLabel = info.nonLocalizedLabel;
8666            res.icon = info.icon;
8667            res.system = res.serviceInfo.applicationInfo.isSystemApp();
8668            return res;
8669        }
8670
8671        @Override
8672        protected void sortResults(List<ResolveInfo> results) {
8673            Collections.sort(results, mResolvePrioritySorter);
8674        }
8675
8676        @Override
8677        protected void dumpFilter(PrintWriter out, String prefix,
8678                PackageParser.ServiceIntentInfo filter) {
8679            out.print(prefix); out.print(
8680                    Integer.toHexString(System.identityHashCode(filter.service)));
8681                    out.print(' ');
8682                    filter.service.printComponentShortName(out);
8683                    out.print(" filter ");
8684                    out.println(Integer.toHexString(System.identityHashCode(filter)));
8685        }
8686
8687        @Override
8688        protected Object filterToLabel(PackageParser.ServiceIntentInfo filter) {
8689            return filter.service;
8690        }
8691
8692        protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
8693            PackageParser.Service service = (PackageParser.Service)label;
8694            out.print(prefix); out.print(
8695                    Integer.toHexString(System.identityHashCode(service)));
8696                    out.print(' ');
8697                    service.printComponentShortName(out);
8698            if (count > 1) {
8699                out.print(" ("); out.print(count); out.print(" filters)");
8700            }
8701            out.println();
8702        }
8703
8704//        List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) {
8705//            final Iterator<ResolveInfo> i = resolveInfoList.iterator();
8706//            final List<ResolveInfo> retList = Lists.newArrayList();
8707//            while (i.hasNext()) {
8708//                final ResolveInfo resolveInfo = (ResolveInfo) i;
8709//                if (isEnabledLP(resolveInfo.serviceInfo)) {
8710//                    retList.add(resolveInfo);
8711//                }
8712//            }
8713//            return retList;
8714//        }
8715
8716        // Keys are String (activity class name), values are Activity.
8717        private final ArrayMap<ComponentName, PackageParser.Service> mServices
8718                = new ArrayMap<ComponentName, PackageParser.Service>();
8719        private int mFlags;
8720    };
8721
8722    private final class ProviderIntentResolver
8723            extends IntentResolver<PackageParser.ProviderIntentInfo, ResolveInfo> {
8724        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
8725                boolean defaultOnly, int userId) {
8726            mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
8727            return super.queryIntent(intent, resolvedType, defaultOnly, userId);
8728        }
8729
8730        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
8731                int userId) {
8732            if (!sUserManager.exists(userId))
8733                return null;
8734            mFlags = flags;
8735            return super.queryIntent(intent, resolvedType,
8736                    (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId);
8737        }
8738
8739        public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
8740                int flags, ArrayList<PackageParser.Provider> packageProviders, int userId) {
8741            if (!sUserManager.exists(userId))
8742                return null;
8743            if (packageProviders == null) {
8744                return null;
8745            }
8746            mFlags = flags;
8747            final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0;
8748            final int N = packageProviders.size();
8749            ArrayList<PackageParser.ProviderIntentInfo[]> listCut =
8750                    new ArrayList<PackageParser.ProviderIntentInfo[]>(N);
8751
8752            ArrayList<PackageParser.ProviderIntentInfo> intentFilters;
8753            for (int i = 0; i < N; ++i) {
8754                intentFilters = packageProviders.get(i).intents;
8755                if (intentFilters != null && intentFilters.size() > 0) {
8756                    PackageParser.ProviderIntentInfo[] array =
8757                            new PackageParser.ProviderIntentInfo[intentFilters.size()];
8758                    intentFilters.toArray(array);
8759                    listCut.add(array);
8760                }
8761            }
8762            return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
8763        }
8764
8765        public final void addProvider(PackageParser.Provider p) {
8766            if (mProviders.containsKey(p.getComponentName())) {
8767                Slog.w(TAG, "Provider " + p.getComponentName() + " already defined; ignoring");
8768                return;
8769            }
8770
8771            mProviders.put(p.getComponentName(), p);
8772            if (DEBUG_SHOW_INFO) {
8773                Log.v(TAG, "  "
8774                        + (p.info.nonLocalizedLabel != null
8775                                ? p.info.nonLocalizedLabel : p.info.name) + ":");
8776                Log.v(TAG, "    Class=" + p.info.name);
8777            }
8778            final int NI = p.intents.size();
8779            int j;
8780            for (j = 0; j < NI; j++) {
8781                PackageParser.ProviderIntentInfo intent = p.intents.get(j);
8782                if (DEBUG_SHOW_INFO) {
8783                    Log.v(TAG, "    IntentFilter:");
8784                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
8785                }
8786                if (!intent.debugCheck()) {
8787                    Log.w(TAG, "==> For Provider " + p.info.name);
8788                }
8789                addFilter(intent);
8790            }
8791        }
8792
8793        public final void removeProvider(PackageParser.Provider p) {
8794            mProviders.remove(p.getComponentName());
8795            if (DEBUG_SHOW_INFO) {
8796                Log.v(TAG, "  " + (p.info.nonLocalizedLabel != null
8797                        ? p.info.nonLocalizedLabel : p.info.name) + ":");
8798                Log.v(TAG, "    Class=" + p.info.name);
8799            }
8800            final int NI = p.intents.size();
8801            int j;
8802            for (j = 0; j < NI; j++) {
8803                PackageParser.ProviderIntentInfo intent = p.intents.get(j);
8804                if (DEBUG_SHOW_INFO) {
8805                    Log.v(TAG, "    IntentFilter:");
8806                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
8807                }
8808                removeFilter(intent);
8809            }
8810        }
8811
8812        @Override
8813        protected boolean allowFilterResult(
8814                PackageParser.ProviderIntentInfo filter, List<ResolveInfo> dest) {
8815            ProviderInfo filterPi = filter.provider.info;
8816            for (int i = dest.size() - 1; i >= 0; i--) {
8817                ProviderInfo destPi = dest.get(i).providerInfo;
8818                if (destPi.name == filterPi.name
8819                        && destPi.packageName == filterPi.packageName) {
8820                    return false;
8821                }
8822            }
8823            return true;
8824        }
8825
8826        @Override
8827        protected PackageParser.ProviderIntentInfo[] newArray(int size) {
8828            return new PackageParser.ProviderIntentInfo[size];
8829        }
8830
8831        @Override
8832        protected boolean isFilterStopped(PackageParser.ProviderIntentInfo filter, int userId) {
8833            if (!sUserManager.exists(userId))
8834                return true;
8835            PackageParser.Package p = filter.provider.owner;
8836            if (p != null) {
8837                PackageSetting ps = (PackageSetting) p.mExtras;
8838                if (ps != null) {
8839                    // System apps are never considered stopped for purposes of
8840                    // filtering, because there may be no way for the user to
8841                    // actually re-launch them.
8842                    return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
8843                            && ps.getStopped(userId);
8844                }
8845            }
8846            return false;
8847        }
8848
8849        @Override
8850        protected boolean isPackageForFilter(String packageName,
8851                PackageParser.ProviderIntentInfo info) {
8852            return packageName.equals(info.provider.owner.packageName);
8853        }
8854
8855        @Override
8856        protected ResolveInfo newResult(PackageParser.ProviderIntentInfo filter,
8857                int match, int userId) {
8858            if (!sUserManager.exists(userId))
8859                return null;
8860            final PackageParser.ProviderIntentInfo info = filter;
8861            if (!mSettings.isEnabledLPr(info.provider.info, mFlags, userId)) {
8862                return null;
8863            }
8864            final PackageParser.Provider provider = info.provider;
8865            if (mSafeMode && (provider.info.applicationInfo.flags
8866                    & ApplicationInfo.FLAG_SYSTEM) == 0) {
8867                return null;
8868            }
8869            PackageSetting ps = (PackageSetting) provider.owner.mExtras;
8870            if (ps == null) {
8871                return null;
8872            }
8873            ProviderInfo pi = PackageParser.generateProviderInfo(provider, mFlags,
8874                    ps.readUserState(userId), userId);
8875            if (pi == null) {
8876                return null;
8877            }
8878            final ResolveInfo res = new ResolveInfo();
8879            res.providerInfo = pi;
8880            if ((mFlags & PackageManager.GET_RESOLVED_FILTER) != 0) {
8881                res.filter = filter;
8882            }
8883            res.priority = info.getPriority();
8884            res.preferredOrder = provider.owner.mPreferredOrder;
8885            res.match = match;
8886            res.isDefault = info.hasDefault;
8887            res.labelRes = info.labelRes;
8888            res.nonLocalizedLabel = info.nonLocalizedLabel;
8889            res.icon = info.icon;
8890            res.system = res.providerInfo.applicationInfo.isSystemApp();
8891            return res;
8892        }
8893
8894        @Override
8895        protected void sortResults(List<ResolveInfo> results) {
8896            Collections.sort(results, mResolvePrioritySorter);
8897        }
8898
8899        @Override
8900        protected void dumpFilter(PrintWriter out, String prefix,
8901                PackageParser.ProviderIntentInfo filter) {
8902            out.print(prefix);
8903            out.print(
8904                    Integer.toHexString(System.identityHashCode(filter.provider)));
8905            out.print(' ');
8906            filter.provider.printComponentShortName(out);
8907            out.print(" filter ");
8908            out.println(Integer.toHexString(System.identityHashCode(filter)));
8909        }
8910
8911        @Override
8912        protected Object filterToLabel(PackageParser.ProviderIntentInfo filter) {
8913            return filter.provider;
8914        }
8915
8916        protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
8917            PackageParser.Provider provider = (PackageParser.Provider)label;
8918            out.print(prefix); out.print(
8919                    Integer.toHexString(System.identityHashCode(provider)));
8920                    out.print(' ');
8921                    provider.printComponentShortName(out);
8922            if (count > 1) {
8923                out.print(" ("); out.print(count); out.print(" filters)");
8924            }
8925            out.println();
8926        }
8927
8928        private final ArrayMap<ComponentName, PackageParser.Provider> mProviders
8929                = new ArrayMap<ComponentName, PackageParser.Provider>();
8930        private int mFlags;
8931    };
8932
8933    private static final Comparator<ResolveInfo> mResolvePrioritySorter =
8934            new Comparator<ResolveInfo>() {
8935        public int compare(ResolveInfo r1, ResolveInfo r2) {
8936            int v1 = r1.priority;
8937            int v2 = r2.priority;
8938            //System.out.println("Comparing: q1=" + q1 + " q2=" + q2);
8939            if (v1 != v2) {
8940                return (v1 > v2) ? -1 : 1;
8941            }
8942            v1 = r1.preferredOrder;
8943            v2 = r2.preferredOrder;
8944            if (v1 != v2) {
8945                return (v1 > v2) ? -1 : 1;
8946            }
8947            if (r1.isDefault != r2.isDefault) {
8948                return r1.isDefault ? -1 : 1;
8949            }
8950            v1 = r1.match;
8951            v2 = r2.match;
8952            //System.out.println("Comparing: m1=" + m1 + " m2=" + m2);
8953            if (v1 != v2) {
8954                return (v1 > v2) ? -1 : 1;
8955            }
8956            if (r1.system != r2.system) {
8957                return r1.system ? -1 : 1;
8958            }
8959            return 0;
8960        }
8961    };
8962
8963    private static final Comparator<ProviderInfo> mProviderInitOrderSorter =
8964            new Comparator<ProviderInfo>() {
8965        public int compare(ProviderInfo p1, ProviderInfo p2) {
8966            final int v1 = p1.initOrder;
8967            final int v2 = p2.initOrder;
8968            return (v1 > v2) ? -1 : ((v1 < v2) ? 1 : 0);
8969        }
8970    };
8971
8972    final void sendPackageBroadcast(final String action, final String pkg,
8973            final Bundle extras, final String targetPkg, final IIntentReceiver finishedReceiver,
8974            final int[] userIds) {
8975        mHandler.post(new Runnable() {
8976            @Override
8977            public void run() {
8978                try {
8979                    final IActivityManager am = ActivityManagerNative.getDefault();
8980                    if (am == null) return;
8981                    final int[] resolvedUserIds;
8982                    if (userIds == null) {
8983                        resolvedUserIds = am.getRunningUserIds();
8984                    } else {
8985                        resolvedUserIds = userIds;
8986                    }
8987                    for (int id : resolvedUserIds) {
8988                        final Intent intent = new Intent(action,
8989                                pkg != null ? Uri.fromParts("package", pkg, null) : null);
8990                        if (extras != null) {
8991                            intent.putExtras(extras);
8992                        }
8993                        if (targetPkg != null) {
8994                            intent.setPackage(targetPkg);
8995                        }
8996                        // Modify the UID when posting to other users
8997                        int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
8998                        if (uid > 0 && UserHandle.getUserId(uid) != id) {
8999                            uid = UserHandle.getUid(id, UserHandle.getAppId(uid));
9000                            intent.putExtra(Intent.EXTRA_UID, uid);
9001                        }
9002                        intent.putExtra(Intent.EXTRA_USER_HANDLE, id);
9003                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
9004                        if (DEBUG_BROADCASTS) {
9005                            RuntimeException here = new RuntimeException("here");
9006                            here.fillInStackTrace();
9007                            Slog.d(TAG, "Sending to user " + id + ": "
9008                                    + intent.toShortString(false, true, false, false)
9009                                    + " " + intent.getExtras(), here);
9010                        }
9011                        am.broadcastIntent(null, intent, null, finishedReceiver,
9012                                0, null, null, null, android.app.AppOpsManager.OP_NONE,
9013                                null, finishedReceiver != null, false, id);
9014                    }
9015                } catch (RemoteException ex) {
9016                }
9017            }
9018        });
9019    }
9020
9021    /**
9022     * Check if the external storage media is available. This is true if there
9023     * is a mounted external storage medium or if the external storage is
9024     * emulated.
9025     */
9026    private boolean isExternalMediaAvailable() {
9027        return mMediaMounted || Environment.isExternalStorageEmulated();
9028    }
9029
9030    @Override
9031    public PackageCleanItem nextPackageToClean(PackageCleanItem lastPackage) {
9032        // writer
9033        synchronized (mPackages) {
9034            if (!isExternalMediaAvailable()) {
9035                // If the external storage is no longer mounted at this point,
9036                // the caller may not have been able to delete all of this
9037                // packages files and can not delete any more.  Bail.
9038                return null;
9039            }
9040            final ArrayList<PackageCleanItem> pkgs = mSettings.mPackagesToBeCleaned;
9041            if (lastPackage != null) {
9042                pkgs.remove(lastPackage);
9043            }
9044            if (pkgs.size() > 0) {
9045                return pkgs.get(0);
9046            }
9047        }
9048        return null;
9049    }
9050
9051    void schedulePackageCleaning(String packageName, int userId, boolean andCode) {
9052        final Message msg = mHandler.obtainMessage(START_CLEANING_PACKAGE,
9053                userId, andCode ? 1 : 0, packageName);
9054        if (mSystemReady) {
9055            msg.sendToTarget();
9056        } else {
9057            if (mPostSystemReadyMessages == null) {
9058                mPostSystemReadyMessages = new ArrayList<>();
9059            }
9060            mPostSystemReadyMessages.add(msg);
9061        }
9062    }
9063
9064    void startCleaningPackages() {
9065        // reader
9066        synchronized (mPackages) {
9067            if (!isExternalMediaAvailable()) {
9068                return;
9069            }
9070            if (mSettings.mPackagesToBeCleaned.isEmpty()) {
9071                return;
9072            }
9073        }
9074        Intent intent = new Intent(PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE);
9075        intent.setComponent(DEFAULT_CONTAINER_COMPONENT);
9076        IActivityManager am = ActivityManagerNative.getDefault();
9077        if (am != null) {
9078            try {
9079                am.startService(null, intent, null, UserHandle.USER_OWNER);
9080            } catch (RemoteException e) {
9081            }
9082        }
9083    }
9084
9085    @Override
9086    public void installPackage(String originPath, IPackageInstallObserver2 observer,
9087            int installFlags, String installerPackageName, VerificationParams verificationParams,
9088            String packageAbiOverride) {
9089        installPackageAsUser(originPath, observer, installFlags, installerPackageName,
9090                verificationParams, packageAbiOverride, UserHandle.getCallingUserId());
9091    }
9092
9093    @Override
9094    public void installPackageAsUser(String originPath, IPackageInstallObserver2 observer,
9095            int installFlags, String installerPackageName, VerificationParams verificationParams,
9096            String packageAbiOverride, int userId) {
9097        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null);
9098
9099        final int callingUid = Binder.getCallingUid();
9100        enforceCrossUserPermission(callingUid, userId, true, true, "installPackageAsUser");
9101
9102        if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
9103            try {
9104                if (observer != null) {
9105                    observer.onPackageInstalled("", INSTALL_FAILED_USER_RESTRICTED, null, null);
9106                }
9107            } catch (RemoteException re) {
9108            }
9109            return;
9110        }
9111
9112        if ((callingUid == Process.SHELL_UID) || (callingUid == Process.ROOT_UID)) {
9113            installFlags |= PackageManager.INSTALL_FROM_ADB;
9114
9115        } else {
9116            // Caller holds INSTALL_PACKAGES permission, so we're less strict
9117            // about installerPackageName.
9118
9119            installFlags &= ~PackageManager.INSTALL_FROM_ADB;
9120            installFlags &= ~PackageManager.INSTALL_ALL_USERS;
9121        }
9122
9123        UserHandle user;
9124        if ((installFlags & PackageManager.INSTALL_ALL_USERS) != 0) {
9125            user = UserHandle.ALL;
9126        } else {
9127            user = new UserHandle(userId);
9128        }
9129
9130        // Only system components can circumvent runtime permissions when installing.
9131        if ((installFlags & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0
9132                && mContext.checkCallingOrSelfPermission(Manifest.permission
9133                .INSTALL_GRANT_RUNTIME_PERMISSIONS) == PackageManager.PERMISSION_DENIED) {
9134            throw new SecurityException("You need the "
9135                    + "android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS permission "
9136                    + "to use the PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS flag");
9137        }
9138
9139        verificationParams.setInstallerUid(callingUid);
9140
9141        final File originFile = new File(originPath);
9142        final OriginInfo origin = OriginInfo.fromUntrustedFile(originFile);
9143
9144        final Message msg = mHandler.obtainMessage(INIT_COPY);
9145        msg.obj = new InstallParams(origin, null, observer, installFlags, installerPackageName,
9146                null, verificationParams, user, packageAbiOverride);
9147        mHandler.sendMessage(msg);
9148    }
9149
9150    void installStage(String packageName, File stagedDir, String stagedCid,
9151            IPackageInstallObserver2 observer, PackageInstaller.SessionParams params,
9152            String installerPackageName, int installerUid, UserHandle user) {
9153        final VerificationParams verifParams = new VerificationParams(null, params.originatingUri,
9154                params.referrerUri, installerUid, null);
9155        verifParams.setInstallerUid(installerUid);
9156
9157        final OriginInfo origin;
9158        if (stagedDir != null) {
9159            origin = OriginInfo.fromStagedFile(stagedDir);
9160        } else {
9161            origin = OriginInfo.fromStagedContainer(stagedCid);
9162        }
9163
9164        final Message msg = mHandler.obtainMessage(INIT_COPY);
9165        msg.obj = new InstallParams(origin, null, observer, params.installFlags,
9166                installerPackageName, params.volumeUuid, verifParams, user, params.abiOverride);
9167        mHandler.sendMessage(msg);
9168    }
9169
9170    private void sendPackageAddedForUser(String packageName, PackageSetting pkgSetting, int userId) {
9171        Bundle extras = new Bundle(1);
9172        extras.putInt(Intent.EXTRA_UID, UserHandle.getUid(userId, pkgSetting.appId));
9173
9174        sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
9175                packageName, extras, null, null, new int[] {userId});
9176        try {
9177            IActivityManager am = ActivityManagerNative.getDefault();
9178            final boolean isSystem =
9179                    isSystemApp(pkgSetting) || isUpdatedSystemApp(pkgSetting);
9180            if (isSystem && am.isUserRunning(userId, false)) {
9181                // The just-installed/enabled app is bundled on the system, so presumed
9182                // to be able to run automatically without needing an explicit launch.
9183                // Send it a BOOT_COMPLETED if it would ordinarily have gotten one.
9184                Intent bcIntent = new Intent(Intent.ACTION_BOOT_COMPLETED)
9185                        .addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES)
9186                        .setPackage(packageName);
9187                am.broadcastIntent(null, bcIntent, null, null, 0, null, null, null,
9188                        android.app.AppOpsManager.OP_NONE, null, false, false, userId);
9189            }
9190        } catch (RemoteException e) {
9191            // shouldn't happen
9192            Slog.w(TAG, "Unable to bootstrap installed package", e);
9193        }
9194    }
9195
9196    @Override
9197    public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden,
9198            int userId) {
9199        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
9200        PackageSetting pkgSetting;
9201        final int uid = Binder.getCallingUid();
9202        enforceCrossUserPermission(uid, userId, true, true,
9203                "setApplicationHiddenSetting for user " + userId);
9204
9205        if (hidden && isPackageDeviceAdmin(packageName, userId)) {
9206            Slog.w(TAG, "Not hiding package " + packageName + ": has active device admin");
9207            return false;
9208        }
9209
9210        long callingId = Binder.clearCallingIdentity();
9211        try {
9212            boolean sendAdded = false;
9213            boolean sendRemoved = false;
9214            // writer
9215            synchronized (mPackages) {
9216                pkgSetting = mSettings.mPackages.get(packageName);
9217                if (pkgSetting == null) {
9218                    return false;
9219                }
9220                if (pkgSetting.getHidden(userId) != hidden) {
9221                    pkgSetting.setHidden(hidden, userId);
9222                    mSettings.writePackageRestrictionsLPr(userId);
9223                    if (hidden) {
9224                        sendRemoved = true;
9225                    } else {
9226                        sendAdded = true;
9227                    }
9228                }
9229            }
9230            if (sendAdded) {
9231                sendPackageAddedForUser(packageName, pkgSetting, userId);
9232                return true;
9233            }
9234            if (sendRemoved) {
9235                killApplication(packageName, UserHandle.getUid(userId, pkgSetting.appId),
9236                        "hiding pkg");
9237                sendApplicationHiddenForUser(packageName, pkgSetting, userId);
9238            }
9239        } finally {
9240            Binder.restoreCallingIdentity(callingId);
9241        }
9242        return false;
9243    }
9244
9245    private void sendApplicationHiddenForUser(String packageName, PackageSetting pkgSetting,
9246            int userId) {
9247        final PackageRemovedInfo info = new PackageRemovedInfo();
9248        info.removedPackage = packageName;
9249        info.removedUsers = new int[] {userId};
9250        info.uid = UserHandle.getUid(userId, pkgSetting.appId);
9251        info.sendBroadcast(false, false, false);
9252    }
9253
9254    /**
9255     * Returns true if application is not found or there was an error. Otherwise it returns
9256     * the hidden state of the package for the given user.
9257     */
9258    @Override
9259    public boolean getApplicationHiddenSettingAsUser(String packageName, int userId) {
9260        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
9261        enforceCrossUserPermission(Binder.getCallingUid(), userId, true,
9262                false, "getApplicationHidden for user " + userId);
9263        PackageSetting pkgSetting;
9264        long callingId = Binder.clearCallingIdentity();
9265        try {
9266            // writer
9267            synchronized (mPackages) {
9268                pkgSetting = mSettings.mPackages.get(packageName);
9269                if (pkgSetting == null) {
9270                    return true;
9271                }
9272                return pkgSetting.getHidden(userId);
9273            }
9274        } finally {
9275            Binder.restoreCallingIdentity(callingId);
9276        }
9277    }
9278
9279    /**
9280     * @hide
9281     */
9282    @Override
9283    public int installExistingPackageAsUser(String packageName, int userId) {
9284        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES,
9285                null);
9286        PackageSetting pkgSetting;
9287        final int uid = Binder.getCallingUid();
9288        enforceCrossUserPermission(uid, userId, true, true, "installExistingPackage for user "
9289                + userId);
9290        if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
9291            return PackageManager.INSTALL_FAILED_USER_RESTRICTED;
9292        }
9293
9294        long callingId = Binder.clearCallingIdentity();
9295        try {
9296            boolean sendAdded = false;
9297
9298            // writer
9299            synchronized (mPackages) {
9300                pkgSetting = mSettings.mPackages.get(packageName);
9301                if (pkgSetting == null) {
9302                    return PackageManager.INSTALL_FAILED_INVALID_URI;
9303                }
9304                if (!pkgSetting.getInstalled(userId)) {
9305                    pkgSetting.setInstalled(true, userId);
9306                    pkgSetting.setHidden(false, userId);
9307                    mSettings.writePackageRestrictionsLPr(userId);
9308                    sendAdded = true;
9309                }
9310            }
9311
9312            if (sendAdded) {
9313                sendPackageAddedForUser(packageName, pkgSetting, userId);
9314            }
9315        } finally {
9316            Binder.restoreCallingIdentity(callingId);
9317        }
9318
9319        return PackageManager.INSTALL_SUCCEEDED;
9320    }
9321
9322    boolean isUserRestricted(int userId, String restrictionKey) {
9323        Bundle restrictions = sUserManager.getUserRestrictions(userId);
9324        if (restrictions.getBoolean(restrictionKey, false)) {
9325            Log.w(TAG, "User is restricted: " + restrictionKey);
9326            return true;
9327        }
9328        return false;
9329    }
9330
9331    @Override
9332    public void verifyPendingInstall(int id, int verificationCode) throws RemoteException {
9333        mContext.enforceCallingOrSelfPermission(
9334                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
9335                "Only package verification agents can verify applications");
9336
9337        final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
9338        final PackageVerificationResponse response = new PackageVerificationResponse(
9339                verificationCode, Binder.getCallingUid());
9340        msg.arg1 = id;
9341        msg.obj = response;
9342        mHandler.sendMessage(msg);
9343    }
9344
9345    @Override
9346    public void extendVerificationTimeout(int id, int verificationCodeAtTimeout,
9347            long millisecondsToDelay) {
9348        mContext.enforceCallingOrSelfPermission(
9349                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
9350                "Only package verification agents can extend verification timeouts");
9351
9352        final PackageVerificationState state = mPendingVerification.get(id);
9353        final PackageVerificationResponse response = new PackageVerificationResponse(
9354                verificationCodeAtTimeout, Binder.getCallingUid());
9355
9356        if (millisecondsToDelay > PackageManager.MAXIMUM_VERIFICATION_TIMEOUT) {
9357            millisecondsToDelay = PackageManager.MAXIMUM_VERIFICATION_TIMEOUT;
9358        }
9359        if (millisecondsToDelay < 0) {
9360            millisecondsToDelay = 0;
9361        }
9362        if ((verificationCodeAtTimeout != PackageManager.VERIFICATION_ALLOW)
9363                && (verificationCodeAtTimeout != PackageManager.VERIFICATION_REJECT)) {
9364            verificationCodeAtTimeout = PackageManager.VERIFICATION_REJECT;
9365        }
9366
9367        if ((state != null) && !state.timeoutExtended()) {
9368            state.extendTimeout();
9369
9370            final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
9371            msg.arg1 = id;
9372            msg.obj = response;
9373            mHandler.sendMessageDelayed(msg, millisecondsToDelay);
9374        }
9375    }
9376
9377    private void broadcastPackageVerified(int verificationId, Uri packageUri,
9378            int verificationCode, UserHandle user) {
9379        final Intent intent = new Intent(Intent.ACTION_PACKAGE_VERIFIED);
9380        intent.setDataAndType(packageUri, PACKAGE_MIME_TYPE);
9381        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
9382        intent.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
9383        intent.putExtra(PackageManager.EXTRA_VERIFICATION_RESULT, verificationCode);
9384
9385        mContext.sendBroadcastAsUser(intent, user,
9386                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT);
9387    }
9388
9389    private ComponentName matchComponentForVerifier(String packageName,
9390            List<ResolveInfo> receivers) {
9391        ActivityInfo targetReceiver = null;
9392
9393        final int NR = receivers.size();
9394        for (int i = 0; i < NR; i++) {
9395            final ResolveInfo info = receivers.get(i);
9396            if (info.activityInfo == null) {
9397                continue;
9398            }
9399
9400            if (packageName.equals(info.activityInfo.packageName)) {
9401                targetReceiver = info.activityInfo;
9402                break;
9403            }
9404        }
9405
9406        if (targetReceiver == null) {
9407            return null;
9408        }
9409
9410        return new ComponentName(targetReceiver.packageName, targetReceiver.name);
9411    }
9412
9413    private List<ComponentName> matchVerifiers(PackageInfoLite pkgInfo,
9414            List<ResolveInfo> receivers, final PackageVerificationState verificationState) {
9415        if (pkgInfo.verifiers.length == 0) {
9416            return null;
9417        }
9418
9419        final int N = pkgInfo.verifiers.length;
9420        final List<ComponentName> sufficientVerifiers = new ArrayList<ComponentName>(N + 1);
9421        for (int i = 0; i < N; i++) {
9422            final VerifierInfo verifierInfo = pkgInfo.verifiers[i];
9423
9424            final ComponentName comp = matchComponentForVerifier(verifierInfo.packageName,
9425                    receivers);
9426            if (comp == null) {
9427                continue;
9428            }
9429
9430            final int verifierUid = getUidForVerifier(verifierInfo);
9431            if (verifierUid == -1) {
9432                continue;
9433            }
9434
9435            if (DEBUG_VERIFY) {
9436                Slog.d(TAG, "Added sufficient verifier " + verifierInfo.packageName
9437                        + " with the correct signature");
9438            }
9439            sufficientVerifiers.add(comp);
9440            verificationState.addSufficientVerifier(verifierUid);
9441        }
9442
9443        return sufficientVerifiers;
9444    }
9445
9446    private int getUidForVerifier(VerifierInfo verifierInfo) {
9447        synchronized (mPackages) {
9448            final PackageParser.Package pkg = mPackages.get(verifierInfo.packageName);
9449            if (pkg == null) {
9450                return -1;
9451            } else if (pkg.mSignatures.length != 1) {
9452                Slog.i(TAG, "Verifier package " + verifierInfo.packageName
9453                        + " has more than one signature; ignoring");
9454                return -1;
9455            }
9456
9457            /*
9458             * If the public key of the package's signature does not match
9459             * our expected public key, then this is a different package and
9460             * we should skip.
9461             */
9462
9463            final byte[] expectedPublicKey;
9464            try {
9465                final Signature verifierSig = pkg.mSignatures[0];
9466                final PublicKey publicKey = verifierSig.getPublicKey();
9467                expectedPublicKey = publicKey.getEncoded();
9468            } catch (CertificateException e) {
9469                return -1;
9470            }
9471
9472            final byte[] actualPublicKey = verifierInfo.publicKey.getEncoded();
9473
9474            if (!Arrays.equals(actualPublicKey, expectedPublicKey)) {
9475                Slog.i(TAG, "Verifier package " + verifierInfo.packageName
9476                        + " does not have the expected public key; ignoring");
9477                return -1;
9478            }
9479
9480            return pkg.applicationInfo.uid;
9481        }
9482    }
9483
9484    @Override
9485    public void finishPackageInstall(int token) {
9486        enforceSystemOrRoot("Only the system is allowed to finish installs");
9487
9488        if (DEBUG_INSTALL) {
9489            Slog.v(TAG, "BM finishing package install for " + token);
9490        }
9491
9492        final Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0);
9493        mHandler.sendMessage(msg);
9494    }
9495
9496    /**
9497     * Get the verification agent timeout.
9498     *
9499     * @return verification timeout in milliseconds
9500     */
9501    private long getVerificationTimeout() {
9502        return android.provider.Settings.Global.getLong(mContext.getContentResolver(),
9503                android.provider.Settings.Global.PACKAGE_VERIFIER_TIMEOUT,
9504                DEFAULT_VERIFICATION_TIMEOUT);
9505    }
9506
9507    /**
9508     * Get the default verification agent response code.
9509     *
9510     * @return default verification response code
9511     */
9512    private int getDefaultVerificationResponse() {
9513        return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
9514                android.provider.Settings.Global.PACKAGE_VERIFIER_DEFAULT_RESPONSE,
9515                DEFAULT_VERIFICATION_RESPONSE);
9516    }
9517
9518    /**
9519     * Check whether or not package verification has been enabled.
9520     *
9521     * @return true if verification should be performed
9522     */
9523    private boolean isVerificationEnabled(int userId, int installFlags) {
9524        if (!DEFAULT_VERIFY_ENABLE) {
9525            return false;
9526        }
9527
9528        boolean ensureVerifyAppsEnabled = isUserRestricted(userId, UserManager.ENSURE_VERIFY_APPS);
9529
9530        // Check if installing from ADB
9531        if ((installFlags & PackageManager.INSTALL_FROM_ADB) != 0) {
9532            // Do not run verification in a test harness environment
9533            if (ActivityManager.isRunningInTestHarness()) {
9534                return false;
9535            }
9536            if (ensureVerifyAppsEnabled) {
9537                return true;
9538            }
9539            // Check if the developer does not want package verification for ADB installs
9540            if (android.provider.Settings.Global.getInt(mContext.getContentResolver(),
9541                    android.provider.Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, 1) == 0) {
9542                return false;
9543            }
9544        }
9545
9546        if (ensureVerifyAppsEnabled) {
9547            return true;
9548        }
9549
9550        return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
9551                android.provider.Settings.Global.PACKAGE_VERIFIER_ENABLE, 1) == 1;
9552    }
9553
9554    @Override
9555    public void verifyIntentFilter(int id, int verificationCode, List<String> failedDomains)
9556            throws RemoteException {
9557        mContext.enforceCallingOrSelfPermission(
9558                Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT,
9559                "Only intentfilter verification agents can verify applications");
9560
9561        final Message msg = mHandler.obtainMessage(INTENT_FILTER_VERIFIED);
9562        final IntentFilterVerificationResponse response = new IntentFilterVerificationResponse(
9563                Binder.getCallingUid(), verificationCode, failedDomains);
9564        msg.arg1 = id;
9565        msg.obj = response;
9566        mHandler.sendMessage(msg);
9567    }
9568
9569    @Override
9570    public int getIntentVerificationStatus(String packageName, int userId) {
9571        synchronized (mPackages) {
9572            return mSettings.getIntentFilterVerificationStatusLPr(packageName, userId);
9573        }
9574    }
9575
9576    @Override
9577    public boolean updateIntentVerificationStatus(String packageName, int status, int userId) {
9578        boolean result = false;
9579        synchronized (mPackages) {
9580            result = mSettings.updateIntentFilterVerificationStatusLPw(packageName, status, userId);
9581        }
9582        if (result) {
9583            scheduleWritePackageRestrictionsLocked(userId);
9584        }
9585        return result;
9586    }
9587
9588    @Override
9589    public List<IntentFilterVerificationInfo> getIntentFilterVerifications(String packageName) {
9590        synchronized (mPackages) {
9591            return mSettings.getIntentFilterVerificationsLPr(packageName);
9592        }
9593    }
9594
9595    @Override
9596    public List<IntentFilter> getAllIntentFilters(String packageName) {
9597        if (TextUtils.isEmpty(packageName)) {
9598            return Collections.<IntentFilter>emptyList();
9599        }
9600        synchronized (mPackages) {
9601            PackageParser.Package pkg = mPackages.get(packageName);
9602            if (pkg == null || pkg.activities == null) {
9603                return Collections.<IntentFilter>emptyList();
9604            }
9605            final int count = pkg.activities.size();
9606            ArrayList<IntentFilter> result = new ArrayList<>();
9607            for (int n=0; n<count; n++) {
9608                PackageParser.Activity activity = pkg.activities.get(n);
9609                if (activity.intents != null || activity.intents.size() > 0) {
9610                    result.addAll(activity.intents);
9611                }
9612            }
9613            return result;
9614        }
9615    }
9616
9617    @Override
9618    public boolean setDefaultBrowserPackageName(String packageName, int userId) {
9619        synchronized (mPackages) {
9620            boolean result = mSettings.setDefaultBrowserPackageNameLPr(packageName, userId);
9621            if (packageName != null) {
9622                result |= updateIntentVerificationStatus(packageName,
9623                        PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS,
9624                        UserHandle.myUserId());
9625            }
9626            return result;
9627        }
9628    }
9629
9630    @Override
9631    public String getDefaultBrowserPackageName(int userId) {
9632        synchronized (mPackages) {
9633            return mSettings.getDefaultBrowserPackageNameLPw(userId);
9634        }
9635    }
9636
9637    /**
9638     * Get the "allow unknown sources" setting.
9639     *
9640     * @return the current "allow unknown sources" setting
9641     */
9642    private int getUnknownSourcesSettings() {
9643        return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
9644                android.provider.Settings.Global.INSTALL_NON_MARKET_APPS,
9645                -1);
9646    }
9647
9648    @Override
9649    public void setInstallerPackageName(String targetPackage, String installerPackageName) {
9650        final int uid = Binder.getCallingUid();
9651        // writer
9652        synchronized (mPackages) {
9653            PackageSetting targetPackageSetting = mSettings.mPackages.get(targetPackage);
9654            if (targetPackageSetting == null) {
9655                throw new IllegalArgumentException("Unknown target package: " + targetPackage);
9656            }
9657
9658            PackageSetting installerPackageSetting;
9659            if (installerPackageName != null) {
9660                installerPackageSetting = mSettings.mPackages.get(installerPackageName);
9661                if (installerPackageSetting == null) {
9662                    throw new IllegalArgumentException("Unknown installer package: "
9663                            + installerPackageName);
9664                }
9665            } else {
9666                installerPackageSetting = null;
9667            }
9668
9669            Signature[] callerSignature;
9670            Object obj = mSettings.getUserIdLPr(uid);
9671            if (obj != null) {
9672                if (obj instanceof SharedUserSetting) {
9673                    callerSignature = ((SharedUserSetting)obj).signatures.mSignatures;
9674                } else if (obj instanceof PackageSetting) {
9675                    callerSignature = ((PackageSetting)obj).signatures.mSignatures;
9676                } else {
9677                    throw new SecurityException("Bad object " + obj + " for uid " + uid);
9678                }
9679            } else {
9680                throw new SecurityException("Unknown calling uid " + uid);
9681            }
9682
9683            // Verify: can't set installerPackageName to a package that is
9684            // not signed with the same cert as the caller.
9685            if (installerPackageSetting != null) {
9686                if (compareSignatures(callerSignature,
9687                        installerPackageSetting.signatures.mSignatures)
9688                        != PackageManager.SIGNATURE_MATCH) {
9689                    throw new SecurityException(
9690                            "Caller does not have same cert as new installer package "
9691                            + installerPackageName);
9692                }
9693            }
9694
9695            // Verify: if target already has an installer package, it must
9696            // be signed with the same cert as the caller.
9697            if (targetPackageSetting.installerPackageName != null) {
9698                PackageSetting setting = mSettings.mPackages.get(
9699                        targetPackageSetting.installerPackageName);
9700                // If the currently set package isn't valid, then it's always
9701                // okay to change it.
9702                if (setting != null) {
9703                    if (compareSignatures(callerSignature,
9704                            setting.signatures.mSignatures)
9705                            != PackageManager.SIGNATURE_MATCH) {
9706                        throw new SecurityException(
9707                                "Caller does not have same cert as old installer package "
9708                                + targetPackageSetting.installerPackageName);
9709                    }
9710                }
9711            }
9712
9713            // Okay!
9714            targetPackageSetting.installerPackageName = installerPackageName;
9715            scheduleWriteSettingsLocked();
9716        }
9717    }
9718
9719    private void processPendingInstall(final InstallArgs args, final int currentStatus) {
9720        // Queue up an async operation since the package installation may take a little while.
9721        mHandler.post(new Runnable() {
9722            public void run() {
9723                mHandler.removeCallbacks(this);
9724                 // Result object to be returned
9725                PackageInstalledInfo res = new PackageInstalledInfo();
9726                res.returnCode = currentStatus;
9727                res.uid = -1;
9728                res.pkg = null;
9729                res.removedInfo = new PackageRemovedInfo();
9730                if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
9731                    args.doPreInstall(res.returnCode);
9732                    synchronized (mInstallLock) {
9733                        installPackageLI(args, res);
9734                    }
9735                    args.doPostInstall(res.returnCode, res.uid);
9736                }
9737
9738                // A restore should be performed at this point if (a) the install
9739                // succeeded, (b) the operation is not an update, and (c) the new
9740                // package has not opted out of backup participation.
9741                final boolean update = res.removedInfo.removedPackage != null;
9742                final int flags = (res.pkg == null) ? 0 : res.pkg.applicationInfo.flags;
9743                boolean doRestore = !update
9744                        && ((flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0);
9745
9746                // Set up the post-install work request bookkeeping.  This will be used
9747                // and cleaned up by the post-install event handling regardless of whether
9748                // there's a restore pass performed.  Token values are >= 1.
9749                int token;
9750                if (mNextInstallToken < 0) mNextInstallToken = 1;
9751                token = mNextInstallToken++;
9752
9753                PostInstallData data = new PostInstallData(args, res);
9754                mRunningInstalls.put(token, data);
9755                if (DEBUG_INSTALL) Log.v(TAG, "+ starting restore round-trip " + token);
9756
9757                if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && doRestore) {
9758                    // Pass responsibility to the Backup Manager.  It will perform a
9759                    // restore if appropriate, then pass responsibility back to the
9760                    // Package Manager to run the post-install observer callbacks
9761                    // and broadcasts.
9762                    IBackupManager bm = IBackupManager.Stub.asInterface(
9763                            ServiceManager.getService(Context.BACKUP_SERVICE));
9764                    if (bm != null) {
9765                        if (DEBUG_INSTALL) Log.v(TAG, "token " + token
9766                                + " to BM for possible restore");
9767                        try {
9768                            if (bm.isBackupServiceActive(UserHandle.USER_OWNER)) {
9769                                bm.restoreAtInstall(res.pkg.applicationInfo.packageName, token);
9770                            } else {
9771                                doRestore = false;
9772                            }
9773                        } catch (RemoteException e) {
9774                            // can't happen; the backup manager is local
9775                        } catch (Exception e) {
9776                            Slog.e(TAG, "Exception trying to enqueue restore", e);
9777                            doRestore = false;
9778                        }
9779                    } else {
9780                        Slog.e(TAG, "Backup Manager not found!");
9781                        doRestore = false;
9782                    }
9783                }
9784
9785                if (!doRestore) {
9786                    // No restore possible, or the Backup Manager was mysteriously not
9787                    // available -- just fire the post-install work request directly.
9788                    if (DEBUG_INSTALL) Log.v(TAG, "No restore - queue post-install for " + token);
9789                    Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0);
9790                    mHandler.sendMessage(msg);
9791                }
9792            }
9793        });
9794    }
9795
9796    private abstract class HandlerParams {
9797        private static final int MAX_RETRIES = 4;
9798
9799        /**
9800         * Number of times startCopy() has been attempted and had a non-fatal
9801         * error.
9802         */
9803        private int mRetries = 0;
9804
9805        /** User handle for the user requesting the information or installation. */
9806        private final UserHandle mUser;
9807
9808        HandlerParams(UserHandle user) {
9809            mUser = user;
9810        }
9811
9812        UserHandle getUser() {
9813            return mUser;
9814        }
9815
9816        final boolean startCopy() {
9817            boolean res;
9818            try {
9819                if (DEBUG_INSTALL) Slog.i(TAG, "startCopy " + mUser + ": " + this);
9820
9821                if (++mRetries > MAX_RETRIES) {
9822                    Slog.w(TAG, "Failed to invoke remote methods on default container service. Giving up");
9823                    mHandler.sendEmptyMessage(MCS_GIVE_UP);
9824                    handleServiceError();
9825                    return false;
9826                } else {
9827                    handleStartCopy();
9828                    res = true;
9829                }
9830            } catch (RemoteException e) {
9831                if (DEBUG_INSTALL) Slog.i(TAG, "Posting install MCS_RECONNECT");
9832                mHandler.sendEmptyMessage(MCS_RECONNECT);
9833                res = false;
9834            }
9835            handleReturnCode();
9836            return res;
9837        }
9838
9839        final void serviceError() {
9840            if (DEBUG_INSTALL) Slog.i(TAG, "serviceError");
9841            handleServiceError();
9842            handleReturnCode();
9843        }
9844
9845        abstract void handleStartCopy() throws RemoteException;
9846        abstract void handleServiceError();
9847        abstract void handleReturnCode();
9848    }
9849
9850    class MeasureParams extends HandlerParams {
9851        private final PackageStats mStats;
9852        private boolean mSuccess;
9853
9854        private final IPackageStatsObserver mObserver;
9855
9856        public MeasureParams(PackageStats stats, IPackageStatsObserver observer) {
9857            super(new UserHandle(stats.userHandle));
9858            mObserver = observer;
9859            mStats = stats;
9860        }
9861
9862        @Override
9863        public String toString() {
9864            return "MeasureParams{"
9865                + Integer.toHexString(System.identityHashCode(this))
9866                + " " + mStats.packageName + "}";
9867        }
9868
9869        @Override
9870        void handleStartCopy() throws RemoteException {
9871            synchronized (mInstallLock) {
9872                mSuccess = getPackageSizeInfoLI(mStats.packageName, mStats.userHandle, mStats);
9873            }
9874
9875            if (mSuccess) {
9876                final boolean mounted;
9877                if (Environment.isExternalStorageEmulated()) {
9878                    mounted = true;
9879                } else {
9880                    final String status = Environment.getExternalStorageState();
9881                    mounted = (Environment.MEDIA_MOUNTED.equals(status)
9882                            || Environment.MEDIA_MOUNTED_READ_ONLY.equals(status));
9883                }
9884
9885                if (mounted) {
9886                    final UserEnvironment userEnv = new UserEnvironment(mStats.userHandle);
9887
9888                    mStats.externalCacheSize = calculateDirectorySize(mContainerService,
9889                            userEnv.buildExternalStorageAppCacheDirs(mStats.packageName));
9890
9891                    mStats.externalDataSize = calculateDirectorySize(mContainerService,
9892                            userEnv.buildExternalStorageAppDataDirs(mStats.packageName));
9893
9894                    // Always subtract cache size, since it's a subdirectory
9895                    mStats.externalDataSize -= mStats.externalCacheSize;
9896
9897                    mStats.externalMediaSize = calculateDirectorySize(mContainerService,
9898                            userEnv.buildExternalStorageAppMediaDirs(mStats.packageName));
9899
9900                    mStats.externalObbSize = calculateDirectorySize(mContainerService,
9901                            userEnv.buildExternalStorageAppObbDirs(mStats.packageName));
9902                }
9903            }
9904        }
9905
9906        @Override
9907        void handleReturnCode() {
9908            if (mObserver != null) {
9909                try {
9910                    mObserver.onGetStatsCompleted(mStats, mSuccess);
9911                } catch (RemoteException e) {
9912                    Slog.i(TAG, "Observer no longer exists.");
9913                }
9914            }
9915        }
9916
9917        @Override
9918        void handleServiceError() {
9919            Slog.e(TAG, "Could not measure application " + mStats.packageName
9920                            + " external storage");
9921        }
9922    }
9923
9924    private static long calculateDirectorySize(IMediaContainerService mcs, File[] paths)
9925            throws RemoteException {
9926        long result = 0;
9927        for (File path : paths) {
9928            result += mcs.calculateDirectorySize(path.getAbsolutePath());
9929        }
9930        return result;
9931    }
9932
9933    private static void clearDirectory(IMediaContainerService mcs, File[] paths) {
9934        for (File path : paths) {
9935            try {
9936                mcs.clearDirectory(path.getAbsolutePath());
9937            } catch (RemoteException e) {
9938            }
9939        }
9940    }
9941
9942    static class OriginInfo {
9943        /**
9944         * Location where install is coming from, before it has been
9945         * copied/renamed into place. This could be a single monolithic APK
9946         * file, or a cluster directory. This location may be untrusted.
9947         */
9948        final File file;
9949        final String cid;
9950
9951        /**
9952         * Flag indicating that {@link #file} or {@link #cid} has already been
9953         * staged, meaning downstream users don't need to defensively copy the
9954         * contents.
9955         */
9956        final boolean staged;
9957
9958        /**
9959         * Flag indicating that {@link #file} or {@link #cid} is an already
9960         * installed app that is being moved.
9961         */
9962        final boolean existing;
9963
9964        final String resolvedPath;
9965        final File resolvedFile;
9966
9967        static OriginInfo fromNothing() {
9968            return new OriginInfo(null, null, false, false);
9969        }
9970
9971        static OriginInfo fromUntrustedFile(File file) {
9972            return new OriginInfo(file, null, false, false);
9973        }
9974
9975        static OriginInfo fromExistingFile(File file) {
9976            return new OriginInfo(file, null, false, true);
9977        }
9978
9979        static OriginInfo fromStagedFile(File file) {
9980            return new OriginInfo(file, null, true, false);
9981        }
9982
9983        static OriginInfo fromStagedContainer(String cid) {
9984            return new OriginInfo(null, cid, true, false);
9985        }
9986
9987        private OriginInfo(File file, String cid, boolean staged, boolean existing) {
9988            this.file = file;
9989            this.cid = cid;
9990            this.staged = staged;
9991            this.existing = existing;
9992
9993            if (cid != null) {
9994                resolvedPath = PackageHelper.getSdDir(cid);
9995                resolvedFile = new File(resolvedPath);
9996            } else if (file != null) {
9997                resolvedPath = file.getAbsolutePath();
9998                resolvedFile = file;
9999            } else {
10000                resolvedPath = null;
10001                resolvedFile = null;
10002            }
10003        }
10004    }
10005
10006    class MoveInfo {
10007        final int moveId;
10008        final String fromUuid;
10009        final String toUuid;
10010        final String packageName;
10011        final String dataAppName;
10012        final int appId;
10013        final String seinfo;
10014
10015        public MoveInfo(int moveId, String fromUuid, String toUuid, String packageName,
10016                String dataAppName, int appId, String seinfo) {
10017            this.moveId = moveId;
10018            this.fromUuid = fromUuid;
10019            this.toUuid = toUuid;
10020            this.packageName = packageName;
10021            this.dataAppName = dataAppName;
10022            this.appId = appId;
10023            this.seinfo = seinfo;
10024        }
10025    }
10026
10027    class InstallParams extends HandlerParams {
10028        final OriginInfo origin;
10029        final MoveInfo move;
10030        final IPackageInstallObserver2 observer;
10031        int installFlags;
10032        final String installerPackageName;
10033        final String volumeUuid;
10034        final VerificationParams verificationParams;
10035        private InstallArgs mArgs;
10036        private int mRet;
10037        final String packageAbiOverride;
10038
10039        InstallParams(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
10040                int installFlags, String installerPackageName, String volumeUuid,
10041                VerificationParams verificationParams, UserHandle user, String packageAbiOverride) {
10042            super(user);
10043            this.origin = origin;
10044            this.move = move;
10045            this.observer = observer;
10046            this.installFlags = installFlags;
10047            this.installerPackageName = installerPackageName;
10048            this.volumeUuid = volumeUuid;
10049            this.verificationParams = verificationParams;
10050            this.packageAbiOverride = packageAbiOverride;
10051        }
10052
10053        @Override
10054        public String toString() {
10055            return "InstallParams{" + Integer.toHexString(System.identityHashCode(this))
10056                    + " file=" + origin.file + " cid=" + origin.cid + "}";
10057        }
10058
10059        public ManifestDigest getManifestDigest() {
10060            if (verificationParams == null) {
10061                return null;
10062            }
10063            return verificationParams.getManifestDigest();
10064        }
10065
10066        private int installLocationPolicy(PackageInfoLite pkgLite) {
10067            String packageName = pkgLite.packageName;
10068            int installLocation = pkgLite.installLocation;
10069            boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
10070            // reader
10071            synchronized (mPackages) {
10072                PackageParser.Package pkg = mPackages.get(packageName);
10073                if (pkg != null) {
10074                    if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
10075                        // Check for downgrading.
10076                        if ((installFlags & PackageManager.INSTALL_ALLOW_DOWNGRADE) == 0) {
10077                            try {
10078                                checkDowngrade(pkg, pkgLite);
10079                            } catch (PackageManagerException e) {
10080                                Slog.w(TAG, "Downgrade detected: " + e.getMessage());
10081                                return PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE;
10082                            }
10083                        }
10084                        // Check for updated system application.
10085                        if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10086                            if (onSd) {
10087                                Slog.w(TAG, "Cannot install update to system app on sdcard");
10088                                return PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION;
10089                            }
10090                            return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
10091                        } else {
10092                            if (onSd) {
10093                                // Install flag overrides everything.
10094                                return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
10095                            }
10096                            // If current upgrade specifies particular preference
10097                            if (installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) {
10098                                // Application explicitly specified internal.
10099                                return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
10100                            } else if (installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) {
10101                                // App explictly prefers external. Let policy decide
10102                            } else {
10103                                // Prefer previous location
10104                                if (isExternal(pkg)) {
10105                                    return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
10106                                }
10107                                return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
10108                            }
10109                        }
10110                    } else {
10111                        // Invalid install. Return error code
10112                        return PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS;
10113                    }
10114                }
10115            }
10116            // All the special cases have been taken care of.
10117            // Return result based on recommended install location.
10118            if (onSd) {
10119                return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
10120            }
10121            return pkgLite.recommendedInstallLocation;
10122        }
10123
10124        /*
10125         * Invoke remote method to get package information and install
10126         * location values. Override install location based on default
10127         * policy if needed and then create install arguments based
10128         * on the install location.
10129         */
10130        public void handleStartCopy() throws RemoteException {
10131            int ret = PackageManager.INSTALL_SUCCEEDED;
10132
10133            // If we're already staged, we've firmly committed to an install location
10134            if (origin.staged) {
10135                if (origin.file != null) {
10136                    installFlags |= PackageManager.INSTALL_INTERNAL;
10137                    installFlags &= ~PackageManager.INSTALL_EXTERNAL;
10138                } else if (origin.cid != null) {
10139                    installFlags |= PackageManager.INSTALL_EXTERNAL;
10140                    installFlags &= ~PackageManager.INSTALL_INTERNAL;
10141                } else {
10142                    throw new IllegalStateException("Invalid stage location");
10143                }
10144            }
10145
10146            final boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
10147            final boolean onInt = (installFlags & PackageManager.INSTALL_INTERNAL) != 0;
10148
10149            PackageInfoLite pkgLite = null;
10150
10151            if (onInt && onSd) {
10152                // Check if both bits are set.
10153                Slog.w(TAG, "Conflicting flags specified for installing on both internal and external");
10154                ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
10155            } else {
10156                pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, installFlags,
10157                        packageAbiOverride);
10158
10159                /*
10160                 * If we have too little free space, try to free cache
10161                 * before giving up.
10162                 */
10163                if (!origin.staged && pkgLite.recommendedInstallLocation
10164                        == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
10165                    // TODO: focus freeing disk space on the target device
10166                    final StorageManager storage = StorageManager.from(mContext);
10167                    final long lowThreshold = storage.getStorageLowBytes(
10168                            Environment.getDataDirectory());
10169
10170                    final long sizeBytes = mContainerService.calculateInstalledSize(
10171                            origin.resolvedPath, isForwardLocked(), packageAbiOverride);
10172
10173                    if (mInstaller.freeCache(null, sizeBytes + lowThreshold) >= 0) {
10174                        pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath,
10175                                installFlags, packageAbiOverride);
10176                    }
10177
10178                    /*
10179                     * The cache free must have deleted the file we
10180                     * downloaded to install.
10181                     *
10182                     * TODO: fix the "freeCache" call to not delete
10183                     *       the file we care about.
10184                     */
10185                    if (pkgLite.recommendedInstallLocation
10186                            == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
10187                        pkgLite.recommendedInstallLocation
10188                            = PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE;
10189                    }
10190                }
10191            }
10192
10193            if (ret == PackageManager.INSTALL_SUCCEEDED) {
10194                int loc = pkgLite.recommendedInstallLocation;
10195                if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION) {
10196                    ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
10197                } else if (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS) {
10198                    ret = PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
10199                } else if (loc == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
10200                    ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
10201                } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_APK) {
10202                    ret = PackageManager.INSTALL_FAILED_INVALID_APK;
10203                } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
10204                    ret = PackageManager.INSTALL_FAILED_INVALID_URI;
10205                } else if (loc == PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE) {
10206                    ret = PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE;
10207                } else {
10208                    // Override with defaults if needed.
10209                    loc = installLocationPolicy(pkgLite);
10210                    if (loc == PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE) {
10211                        ret = PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
10212                    } else if (!onSd && !onInt) {
10213                        // Override install location with flags
10214                        if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) {
10215                            // Set the flag to install on external media.
10216                            installFlags |= PackageManager.INSTALL_EXTERNAL;
10217                            installFlags &= ~PackageManager.INSTALL_INTERNAL;
10218                        } else {
10219                            // Make sure the flag for installing on external
10220                            // media is unset
10221                            installFlags |= PackageManager.INSTALL_INTERNAL;
10222                            installFlags &= ~PackageManager.INSTALL_EXTERNAL;
10223                        }
10224                    }
10225                }
10226            }
10227
10228            final InstallArgs args = createInstallArgs(this);
10229            mArgs = args;
10230
10231            if (ret == PackageManager.INSTALL_SUCCEEDED) {
10232                 /*
10233                 * ADB installs appear as UserHandle.USER_ALL, and can only be performed by
10234                 * UserHandle.USER_OWNER, so use the package verifier for UserHandle.USER_OWNER.
10235                 */
10236                int userIdentifier = getUser().getIdentifier();
10237                if (userIdentifier == UserHandle.USER_ALL
10238                        && ((installFlags & PackageManager.INSTALL_FROM_ADB) != 0)) {
10239                    userIdentifier = UserHandle.USER_OWNER;
10240                }
10241
10242                /*
10243                 * Determine if we have any installed package verifiers. If we
10244                 * do, then we'll defer to them to verify the packages.
10245                 */
10246                final int requiredUid = mRequiredVerifierPackage == null ? -1
10247                        : getPackageUid(mRequiredVerifierPackage, userIdentifier);
10248                if (!origin.existing && requiredUid != -1
10249                        && isVerificationEnabled(userIdentifier, installFlags)) {
10250                    final Intent verification = new Intent(
10251                            Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
10252                    verification.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10253                    verification.setDataAndType(Uri.fromFile(new File(origin.resolvedPath)),
10254                            PACKAGE_MIME_TYPE);
10255                    verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
10256
10257                    final List<ResolveInfo> receivers = queryIntentReceivers(verification,
10258                            PACKAGE_MIME_TYPE, PackageManager.GET_DISABLED_COMPONENTS,
10259                            0 /* TODO: Which userId? */);
10260
10261                    if (DEBUG_VERIFY) {
10262                        Slog.d(TAG, "Found " + receivers.size() + " verifiers for intent "
10263                                + verification.toString() + " with " + pkgLite.verifiers.length
10264                                + " optional verifiers");
10265                    }
10266
10267                    final int verificationId = mPendingVerificationToken++;
10268
10269                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
10270
10271                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_PACKAGE,
10272                            installerPackageName);
10273
10274                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALL_FLAGS,
10275                            installFlags);
10276
10277                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_PACKAGE_NAME,
10278                            pkgLite.packageName);
10279
10280                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_VERSION_CODE,
10281                            pkgLite.versionCode);
10282
10283                    if (verificationParams != null) {
10284                        if (verificationParams.getVerificationURI() != null) {
10285                           verification.putExtra(PackageManager.EXTRA_VERIFICATION_URI,
10286                                 verificationParams.getVerificationURI());
10287                        }
10288                        if (verificationParams.getOriginatingURI() != null) {
10289                            verification.putExtra(Intent.EXTRA_ORIGINATING_URI,
10290                                  verificationParams.getOriginatingURI());
10291                        }
10292                        if (verificationParams.getReferrer() != null) {
10293                            verification.putExtra(Intent.EXTRA_REFERRER,
10294                                  verificationParams.getReferrer());
10295                        }
10296                        if (verificationParams.getOriginatingUid() >= 0) {
10297                            verification.putExtra(Intent.EXTRA_ORIGINATING_UID,
10298                                  verificationParams.getOriginatingUid());
10299                        }
10300                        if (verificationParams.getInstallerUid() >= 0) {
10301                            verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_UID,
10302                                  verificationParams.getInstallerUid());
10303                        }
10304                    }
10305
10306                    final PackageVerificationState verificationState = new PackageVerificationState(
10307                            requiredUid, args);
10308
10309                    mPendingVerification.append(verificationId, verificationState);
10310
10311                    final List<ComponentName> sufficientVerifiers = matchVerifiers(pkgLite,
10312                            receivers, verificationState);
10313
10314                    /*
10315                     * If any sufficient verifiers were listed in the package
10316                     * manifest, attempt to ask them.
10317                     */
10318                    if (sufficientVerifiers != null) {
10319                        final int N = sufficientVerifiers.size();
10320                        if (N == 0) {
10321                            Slog.i(TAG, "Additional verifiers required, but none installed.");
10322                            ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
10323                        } else {
10324                            for (int i = 0; i < N; i++) {
10325                                final ComponentName verifierComponent = sufficientVerifiers.get(i);
10326
10327                                final Intent sufficientIntent = new Intent(verification);
10328                                sufficientIntent.setComponent(verifierComponent);
10329
10330                                mContext.sendBroadcastAsUser(sufficientIntent, getUser());
10331                            }
10332                        }
10333                    }
10334
10335                    final ComponentName requiredVerifierComponent = matchComponentForVerifier(
10336                            mRequiredVerifierPackage, receivers);
10337                    if (ret == PackageManager.INSTALL_SUCCEEDED
10338                            && mRequiredVerifierPackage != null) {
10339                        /*
10340                         * Send the intent to the required verification agent,
10341                         * but only start the verification timeout after the
10342                         * target BroadcastReceivers have run.
10343                         */
10344                        verification.setComponent(requiredVerifierComponent);
10345                        mContext.sendOrderedBroadcastAsUser(verification, getUser(),
10346                                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
10347                                new BroadcastReceiver() {
10348                                    @Override
10349                                    public void onReceive(Context context, Intent intent) {
10350                                        final Message msg = mHandler
10351                                                .obtainMessage(CHECK_PENDING_VERIFICATION);
10352                                        msg.arg1 = verificationId;
10353                                        mHandler.sendMessageDelayed(msg, getVerificationTimeout());
10354                                    }
10355                                }, null, 0, null, null);
10356
10357                        /*
10358                         * We don't want the copy to proceed until verification
10359                         * succeeds, so null out this field.
10360                         */
10361                        mArgs = null;
10362                    }
10363                } else {
10364                    /*
10365                     * No package verification is enabled, so immediately start
10366                     * the remote call to initiate copy using temporary file.
10367                     */
10368                    ret = args.copyApk(mContainerService, true);
10369                }
10370            }
10371
10372            mRet = ret;
10373        }
10374
10375        @Override
10376        void handleReturnCode() {
10377            // If mArgs is null, then MCS couldn't be reached. When it
10378            // reconnects, it will try again to install. At that point, this
10379            // will succeed.
10380            if (mArgs != null) {
10381                processPendingInstall(mArgs, mRet);
10382            }
10383        }
10384
10385        @Override
10386        void handleServiceError() {
10387            mArgs = createInstallArgs(this);
10388            mRet = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
10389        }
10390
10391        public boolean isForwardLocked() {
10392            return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
10393        }
10394    }
10395
10396    /**
10397     * Used during creation of InstallArgs
10398     *
10399     * @param installFlags package installation flags
10400     * @return true if should be installed on external storage
10401     */
10402    private static boolean installOnExternalAsec(int installFlags) {
10403        if ((installFlags & PackageManager.INSTALL_INTERNAL) != 0) {
10404            return false;
10405        }
10406        if ((installFlags & PackageManager.INSTALL_EXTERNAL) != 0) {
10407            return true;
10408        }
10409        return false;
10410    }
10411
10412    /**
10413     * Used during creation of InstallArgs
10414     *
10415     * @param installFlags package installation flags
10416     * @return true if should be installed as forward locked
10417     */
10418    private static boolean installForwardLocked(int installFlags) {
10419        return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
10420    }
10421
10422    private InstallArgs createInstallArgs(InstallParams params) {
10423        if (params.move != null) {
10424            return new MoveInstallArgs(params);
10425        } else if (installOnExternalAsec(params.installFlags) || params.isForwardLocked()) {
10426            return new AsecInstallArgs(params);
10427        } else {
10428            return new FileInstallArgs(params);
10429        }
10430    }
10431
10432    /**
10433     * Create args that describe an existing installed package. Typically used
10434     * when cleaning up old installs, or used as a move source.
10435     */
10436    private InstallArgs createInstallArgsForExisting(int installFlags, String codePath,
10437            String resourcePath, String[] instructionSets) {
10438        final boolean isInAsec;
10439        if (installOnExternalAsec(installFlags)) {
10440            /* Apps on SD card are always in ASEC containers. */
10441            isInAsec = true;
10442        } else if (installForwardLocked(installFlags)
10443                && !codePath.startsWith(mDrmAppPrivateInstallDir.getAbsolutePath())) {
10444            /*
10445             * Forward-locked apps are only in ASEC containers if they're the
10446             * new style
10447             */
10448            isInAsec = true;
10449        } else {
10450            isInAsec = false;
10451        }
10452
10453        if (isInAsec) {
10454            return new AsecInstallArgs(codePath, instructionSets,
10455                    installOnExternalAsec(installFlags), installForwardLocked(installFlags));
10456        } else {
10457            return new FileInstallArgs(codePath, resourcePath, instructionSets);
10458        }
10459    }
10460
10461    static abstract class InstallArgs {
10462        /** @see InstallParams#origin */
10463        final OriginInfo origin;
10464        /** @see InstallParams#move */
10465        final MoveInfo move;
10466
10467        final IPackageInstallObserver2 observer;
10468        // Always refers to PackageManager flags only
10469        final int installFlags;
10470        final String installerPackageName;
10471        final String volumeUuid;
10472        final ManifestDigest manifestDigest;
10473        final UserHandle user;
10474        final String abiOverride;
10475
10476        // The list of instruction sets supported by this app. This is currently
10477        // only used during the rmdex() phase to clean up resources. We can get rid of this
10478        // if we move dex files under the common app path.
10479        /* nullable */ String[] instructionSets;
10480
10481        InstallArgs(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
10482                int installFlags, String installerPackageName, String volumeUuid,
10483                ManifestDigest manifestDigest, UserHandle user, String[] instructionSets,
10484                String abiOverride) {
10485            this.origin = origin;
10486            this.move = move;
10487            this.installFlags = installFlags;
10488            this.observer = observer;
10489            this.installerPackageName = installerPackageName;
10490            this.volumeUuid = volumeUuid;
10491            this.manifestDigest = manifestDigest;
10492            this.user = user;
10493            this.instructionSets = instructionSets;
10494            this.abiOverride = abiOverride;
10495        }
10496
10497        abstract int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException;
10498        abstract int doPreInstall(int status);
10499
10500        /**
10501         * Rename package into final resting place. All paths on the given
10502         * scanned package should be updated to reflect the rename.
10503         */
10504        abstract boolean doRename(int status, PackageParser.Package pkg, String oldCodePath);
10505        abstract int doPostInstall(int status, int uid);
10506
10507        /** @see PackageSettingBase#codePathString */
10508        abstract String getCodePath();
10509        /** @see PackageSettingBase#resourcePathString */
10510        abstract String getResourcePath();
10511
10512        // Need installer lock especially for dex file removal.
10513        abstract void cleanUpResourcesLI();
10514        abstract boolean doPostDeleteLI(boolean delete);
10515
10516        /**
10517         * Called before the source arguments are copied. This is used mostly
10518         * for MoveParams when it needs to read the source file to put it in the
10519         * destination.
10520         */
10521        int doPreCopy() {
10522            return PackageManager.INSTALL_SUCCEEDED;
10523        }
10524
10525        /**
10526         * Called after the source arguments are copied. This is used mostly for
10527         * MoveParams when it needs to read the source file to put it in the
10528         * destination.
10529         *
10530         * @return
10531         */
10532        int doPostCopy(int uid) {
10533            return PackageManager.INSTALL_SUCCEEDED;
10534        }
10535
10536        protected boolean isFwdLocked() {
10537            return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
10538        }
10539
10540        protected boolean isExternalAsec() {
10541            return (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
10542        }
10543
10544        UserHandle getUser() {
10545            return user;
10546        }
10547    }
10548
10549    private void removeDexFiles(List<String> allCodePaths, String[] instructionSets) {
10550        if (!allCodePaths.isEmpty()) {
10551            if (instructionSets == null) {
10552                throw new IllegalStateException("instructionSet == null");
10553            }
10554            String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
10555            for (String codePath : allCodePaths) {
10556                for (String dexCodeInstructionSet : dexCodeInstructionSets) {
10557                    int retCode = mInstaller.rmdex(codePath, dexCodeInstructionSet);
10558                    if (retCode < 0) {
10559                        Slog.w(TAG, "Couldn't remove dex file for package: "
10560                                + " at location " + codePath + ", retcode=" + retCode);
10561                        // we don't consider this to be a failure of the core package deletion
10562                    }
10563                }
10564            }
10565        }
10566    }
10567
10568    /**
10569     * Logic to handle installation of non-ASEC applications, including copying
10570     * and renaming logic.
10571     */
10572    class FileInstallArgs extends InstallArgs {
10573        private File codeFile;
10574        private File resourceFile;
10575
10576        // Example topology:
10577        // /data/app/com.example/base.apk
10578        // /data/app/com.example/split_foo.apk
10579        // /data/app/com.example/lib/arm/libfoo.so
10580        // /data/app/com.example/lib/arm64/libfoo.so
10581        // /data/app/com.example/dalvik/arm/base.apk@classes.dex
10582
10583        /** New install */
10584        FileInstallArgs(InstallParams params) {
10585            super(params.origin, params.move, params.observer, params.installFlags,
10586                    params.installerPackageName, params.volumeUuid, params.getManifestDigest(),
10587                    params.getUser(), null /* instruction sets */, params.packageAbiOverride);
10588            if (isFwdLocked()) {
10589                throw new IllegalArgumentException("Forward locking only supported in ASEC");
10590            }
10591        }
10592
10593        /** Existing install */
10594        FileInstallArgs(String codePath, String resourcePath, String[] instructionSets) {
10595            super(OriginInfo.fromNothing(), null, null, 0, null, null, null, null, instructionSets,
10596                    null);
10597            this.codeFile = (codePath != null) ? new File(codePath) : null;
10598            this.resourceFile = (resourcePath != null) ? new File(resourcePath) : null;
10599        }
10600
10601        int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
10602            if (origin.staged) {
10603                if (DEBUG_INSTALL) Slog.d(TAG, origin.file + " already staged; skipping copy");
10604                codeFile = origin.file;
10605                resourceFile = origin.file;
10606                return PackageManager.INSTALL_SUCCEEDED;
10607            }
10608
10609            try {
10610                final File tempDir = mInstallerService.allocateStageDirLegacy(volumeUuid);
10611                codeFile = tempDir;
10612                resourceFile = tempDir;
10613            } catch (IOException e) {
10614                Slog.w(TAG, "Failed to create copy file: " + e);
10615                return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
10616            }
10617
10618            final IParcelFileDescriptorFactory target = new IParcelFileDescriptorFactory.Stub() {
10619                @Override
10620                public ParcelFileDescriptor open(String name, int mode) throws RemoteException {
10621                    if (!FileUtils.isValidExtFilename(name)) {
10622                        throw new IllegalArgumentException("Invalid filename: " + name);
10623                    }
10624                    try {
10625                        final File file = new File(codeFile, name);
10626                        final FileDescriptor fd = Os.open(file.getAbsolutePath(),
10627                                O_RDWR | O_CREAT, 0644);
10628                        Os.chmod(file.getAbsolutePath(), 0644);
10629                        return new ParcelFileDescriptor(fd);
10630                    } catch (ErrnoException e) {
10631                        throw new RemoteException("Failed to open: " + e.getMessage());
10632                    }
10633                }
10634            };
10635
10636            int ret = PackageManager.INSTALL_SUCCEEDED;
10637            ret = imcs.copyPackage(origin.file.getAbsolutePath(), target);
10638            if (ret != PackageManager.INSTALL_SUCCEEDED) {
10639                Slog.e(TAG, "Failed to copy package");
10640                return ret;
10641            }
10642
10643            final File libraryRoot = new File(codeFile, LIB_DIR_NAME);
10644            NativeLibraryHelper.Handle handle = null;
10645            try {
10646                handle = NativeLibraryHelper.Handle.create(codeFile);
10647                ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot,
10648                        abiOverride);
10649            } catch (IOException e) {
10650                Slog.e(TAG, "Copying native libraries failed", e);
10651                ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
10652            } finally {
10653                IoUtils.closeQuietly(handle);
10654            }
10655
10656            return ret;
10657        }
10658
10659        int doPreInstall(int status) {
10660            if (status != PackageManager.INSTALL_SUCCEEDED) {
10661                cleanUp();
10662            }
10663            return status;
10664        }
10665
10666        boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
10667            if (status != PackageManager.INSTALL_SUCCEEDED) {
10668                cleanUp();
10669                return false;
10670            }
10671
10672            final File targetDir = codeFile.getParentFile();
10673            final File beforeCodeFile = codeFile;
10674            final File afterCodeFile = getNextCodePath(targetDir, pkg.packageName);
10675
10676            if (DEBUG_INSTALL) Slog.d(TAG, "Renaming " + beforeCodeFile + " to " + afterCodeFile);
10677            try {
10678                Os.rename(beforeCodeFile.getAbsolutePath(), afterCodeFile.getAbsolutePath());
10679            } catch (ErrnoException e) {
10680                Slog.w(TAG, "Failed to rename", e);
10681                return false;
10682            }
10683
10684            if (!SELinux.restoreconRecursive(afterCodeFile)) {
10685                Slog.w(TAG, "Failed to restorecon");
10686                return false;
10687            }
10688
10689            // Reflect the rename internally
10690            codeFile = afterCodeFile;
10691            resourceFile = afterCodeFile;
10692
10693            // Reflect the rename in scanned details
10694            pkg.codePath = afterCodeFile.getAbsolutePath();
10695            pkg.baseCodePath = FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile,
10696                    pkg.baseCodePath);
10697            pkg.splitCodePaths = FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile,
10698                    pkg.splitCodePaths);
10699
10700            // Reflect the rename in app info
10701            pkg.applicationInfo.volumeUuid = pkg.volumeUuid;
10702            pkg.applicationInfo.setCodePath(pkg.codePath);
10703            pkg.applicationInfo.setBaseCodePath(pkg.baseCodePath);
10704            pkg.applicationInfo.setSplitCodePaths(pkg.splitCodePaths);
10705            pkg.applicationInfo.setResourcePath(pkg.codePath);
10706            pkg.applicationInfo.setBaseResourcePath(pkg.baseCodePath);
10707            pkg.applicationInfo.setSplitResourcePaths(pkg.splitCodePaths);
10708
10709            return true;
10710        }
10711
10712        int doPostInstall(int status, int uid) {
10713            if (status != PackageManager.INSTALL_SUCCEEDED) {
10714                cleanUp();
10715            }
10716            return status;
10717        }
10718
10719        @Override
10720        String getCodePath() {
10721            return (codeFile != null) ? codeFile.getAbsolutePath() : null;
10722        }
10723
10724        @Override
10725        String getResourcePath() {
10726            return (resourceFile != null) ? resourceFile.getAbsolutePath() : null;
10727        }
10728
10729        private boolean cleanUp() {
10730            if (codeFile == null || !codeFile.exists()) {
10731                return false;
10732            }
10733
10734            if (codeFile.isDirectory()) {
10735                mInstaller.rmPackageDir(codeFile.getAbsolutePath());
10736            } else {
10737                codeFile.delete();
10738            }
10739
10740            if (resourceFile != null && !FileUtils.contains(codeFile, resourceFile)) {
10741                resourceFile.delete();
10742            }
10743
10744            return true;
10745        }
10746
10747        void cleanUpResourcesLI() {
10748            // Try enumerating all code paths before deleting
10749            List<String> allCodePaths = Collections.EMPTY_LIST;
10750            if (codeFile != null && codeFile.exists()) {
10751                try {
10752                    final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0);
10753                    allCodePaths = pkg.getAllCodePaths();
10754                } catch (PackageParserException e) {
10755                    // Ignored; we tried our best
10756                }
10757            }
10758
10759            cleanUp();
10760            removeDexFiles(allCodePaths, instructionSets);
10761        }
10762
10763        boolean doPostDeleteLI(boolean delete) {
10764            // XXX err, shouldn't we respect the delete flag?
10765            cleanUpResourcesLI();
10766            return true;
10767        }
10768    }
10769
10770    private boolean isAsecExternal(String cid) {
10771        final String asecPath = PackageHelper.getSdFilesystem(cid);
10772        return !asecPath.startsWith(mAsecInternalPath);
10773    }
10774
10775    private static void maybeThrowExceptionForMultiArchCopy(String message, int copyRet) throws
10776            PackageManagerException {
10777        if (copyRet < 0) {
10778            if (copyRet != PackageManager.NO_NATIVE_LIBRARIES &&
10779                    copyRet != PackageManager.INSTALL_FAILED_NO_MATCHING_ABIS) {
10780                throw new PackageManagerException(copyRet, message);
10781            }
10782        }
10783    }
10784
10785    /**
10786     * Extract the MountService "container ID" from the full code path of an
10787     * .apk.
10788     */
10789    static String cidFromCodePath(String fullCodePath) {
10790        int eidx = fullCodePath.lastIndexOf("/");
10791        String subStr1 = fullCodePath.substring(0, eidx);
10792        int sidx = subStr1.lastIndexOf("/");
10793        return subStr1.substring(sidx+1, eidx);
10794    }
10795
10796    /**
10797     * Logic to handle installation of ASEC applications, including copying and
10798     * renaming logic.
10799     */
10800    class AsecInstallArgs extends InstallArgs {
10801        static final String RES_FILE_NAME = "pkg.apk";
10802        static final String PUBLIC_RES_FILE_NAME = "res.zip";
10803
10804        String cid;
10805        String packagePath;
10806        String resourcePath;
10807
10808        /** New install */
10809        AsecInstallArgs(InstallParams params) {
10810            super(params.origin, params.move, params.observer, params.installFlags,
10811                    params.installerPackageName, params.volumeUuid, params.getManifestDigest(),
10812                    params.getUser(), null /* instruction sets */, params.packageAbiOverride);
10813        }
10814
10815        /** Existing install */
10816        AsecInstallArgs(String fullCodePath, String[] instructionSets,
10817                        boolean isExternal, boolean isForwardLocked) {
10818            super(OriginInfo.fromNothing(), null, null, (isExternal ? INSTALL_EXTERNAL : 0)
10819                    | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null, null,
10820                    instructionSets, null);
10821            // Hackily pretend we're still looking at a full code path
10822            if (!fullCodePath.endsWith(RES_FILE_NAME)) {
10823                fullCodePath = new File(fullCodePath, RES_FILE_NAME).getAbsolutePath();
10824            }
10825
10826            // Extract cid from fullCodePath
10827            int eidx = fullCodePath.lastIndexOf("/");
10828            String subStr1 = fullCodePath.substring(0, eidx);
10829            int sidx = subStr1.lastIndexOf("/");
10830            cid = subStr1.substring(sidx+1, eidx);
10831            setMountPath(subStr1);
10832        }
10833
10834        AsecInstallArgs(String cid, String[] instructionSets, boolean isForwardLocked) {
10835            super(OriginInfo.fromNothing(), null, null, (isAsecExternal(cid) ? INSTALL_EXTERNAL : 0)
10836                    | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null, null,
10837                    instructionSets, null);
10838            this.cid = cid;
10839            setMountPath(PackageHelper.getSdDir(cid));
10840        }
10841
10842        void createCopyFile() {
10843            cid = mInstallerService.allocateExternalStageCidLegacy();
10844        }
10845
10846        int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
10847            if (origin.staged) {
10848                if (DEBUG_INSTALL) Slog.d(TAG, origin.cid + " already staged; skipping copy");
10849                cid = origin.cid;
10850                setMountPath(PackageHelper.getSdDir(cid));
10851                return PackageManager.INSTALL_SUCCEEDED;
10852            }
10853
10854            if (temp) {
10855                createCopyFile();
10856            } else {
10857                /*
10858                 * Pre-emptively destroy the container since it's destroyed if
10859                 * copying fails due to it existing anyway.
10860                 */
10861                PackageHelper.destroySdDir(cid);
10862            }
10863
10864            final String newMountPath = imcs.copyPackageToContainer(
10865                    origin.file.getAbsolutePath(), cid, getEncryptKey(), isExternalAsec(),
10866                    isFwdLocked(), deriveAbiOverride(abiOverride, null /* settings */));
10867
10868            if (newMountPath != null) {
10869                setMountPath(newMountPath);
10870                return PackageManager.INSTALL_SUCCEEDED;
10871            } else {
10872                return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
10873            }
10874        }
10875
10876        @Override
10877        String getCodePath() {
10878            return packagePath;
10879        }
10880
10881        @Override
10882        String getResourcePath() {
10883            return resourcePath;
10884        }
10885
10886        int doPreInstall(int status) {
10887            if (status != PackageManager.INSTALL_SUCCEEDED) {
10888                // Destroy container
10889                PackageHelper.destroySdDir(cid);
10890            } else {
10891                boolean mounted = PackageHelper.isContainerMounted(cid);
10892                if (!mounted) {
10893                    String newMountPath = PackageHelper.mountSdDir(cid, getEncryptKey(),
10894                            Process.SYSTEM_UID);
10895                    if (newMountPath != null) {
10896                        setMountPath(newMountPath);
10897                    } else {
10898                        return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
10899                    }
10900                }
10901            }
10902            return status;
10903        }
10904
10905        boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
10906            String newCacheId = getNextCodePath(oldCodePath, pkg.packageName, "/" + RES_FILE_NAME);
10907            String newMountPath = null;
10908            if (PackageHelper.isContainerMounted(cid)) {
10909                // Unmount the container
10910                if (!PackageHelper.unMountSdDir(cid)) {
10911                    Slog.i(TAG, "Failed to unmount " + cid + " before renaming");
10912                    return false;
10913                }
10914            }
10915            if (!PackageHelper.renameSdDir(cid, newCacheId)) {
10916                Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId +
10917                        " which might be stale. Will try to clean up.");
10918                // Clean up the stale container and proceed to recreate.
10919                if (!PackageHelper.destroySdDir(newCacheId)) {
10920                    Slog.e(TAG, "Very strange. Cannot clean up stale container " + newCacheId);
10921                    return false;
10922                }
10923                // Successfully cleaned up stale container. Try to rename again.
10924                if (!PackageHelper.renameSdDir(cid, newCacheId)) {
10925                    Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId
10926                            + " inspite of cleaning it up.");
10927                    return false;
10928                }
10929            }
10930            if (!PackageHelper.isContainerMounted(newCacheId)) {
10931                Slog.w(TAG, "Mounting container " + newCacheId);
10932                newMountPath = PackageHelper.mountSdDir(newCacheId,
10933                        getEncryptKey(), Process.SYSTEM_UID);
10934            } else {
10935                newMountPath = PackageHelper.getSdDir(newCacheId);
10936            }
10937            if (newMountPath == null) {
10938                Slog.w(TAG, "Failed to get cache path for  " + newCacheId);
10939                return false;
10940            }
10941            Log.i(TAG, "Succesfully renamed " + cid +
10942                    " to " + newCacheId +
10943                    " at new path: " + newMountPath);
10944            cid = newCacheId;
10945
10946            final File beforeCodeFile = new File(packagePath);
10947            setMountPath(newMountPath);
10948            final File afterCodeFile = new File(packagePath);
10949
10950            // Reflect the rename in scanned details
10951            pkg.codePath = afterCodeFile.getAbsolutePath();
10952            pkg.baseCodePath = FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile,
10953                    pkg.baseCodePath);
10954            pkg.splitCodePaths = FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile,
10955                    pkg.splitCodePaths);
10956
10957            // Reflect the rename in app info
10958            pkg.applicationInfo.volumeUuid = pkg.volumeUuid;
10959            pkg.applicationInfo.setCodePath(pkg.codePath);
10960            pkg.applicationInfo.setBaseCodePath(pkg.baseCodePath);
10961            pkg.applicationInfo.setSplitCodePaths(pkg.splitCodePaths);
10962            pkg.applicationInfo.setResourcePath(pkg.codePath);
10963            pkg.applicationInfo.setBaseResourcePath(pkg.baseCodePath);
10964            pkg.applicationInfo.setSplitResourcePaths(pkg.splitCodePaths);
10965
10966            return true;
10967        }
10968
10969        private void setMountPath(String mountPath) {
10970            final File mountFile = new File(mountPath);
10971
10972            final File monolithicFile = new File(mountFile, RES_FILE_NAME);
10973            if (monolithicFile.exists()) {
10974                packagePath = monolithicFile.getAbsolutePath();
10975                if (isFwdLocked()) {
10976                    resourcePath = new File(mountFile, PUBLIC_RES_FILE_NAME).getAbsolutePath();
10977                } else {
10978                    resourcePath = packagePath;
10979                }
10980            } else {
10981                packagePath = mountFile.getAbsolutePath();
10982                resourcePath = packagePath;
10983            }
10984        }
10985
10986        int doPostInstall(int status, int uid) {
10987            if (status != PackageManager.INSTALL_SUCCEEDED) {
10988                cleanUp();
10989            } else {
10990                final int groupOwner;
10991                final String protectedFile;
10992                if (isFwdLocked()) {
10993                    groupOwner = UserHandle.getSharedAppGid(uid);
10994                    protectedFile = RES_FILE_NAME;
10995                } else {
10996                    groupOwner = -1;
10997                    protectedFile = null;
10998                }
10999
11000                if (uid < Process.FIRST_APPLICATION_UID
11001                        || !PackageHelper.fixSdPermissions(cid, groupOwner, protectedFile)) {
11002                    Slog.e(TAG, "Failed to finalize " + cid);
11003                    PackageHelper.destroySdDir(cid);
11004                    return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
11005                }
11006
11007                boolean mounted = PackageHelper.isContainerMounted(cid);
11008                if (!mounted) {
11009                    PackageHelper.mountSdDir(cid, getEncryptKey(), Process.myUid());
11010                }
11011            }
11012            return status;
11013        }
11014
11015        private void cleanUp() {
11016            if (DEBUG_SD_INSTALL) Slog.i(TAG, "cleanUp");
11017
11018            // Destroy secure container
11019            PackageHelper.destroySdDir(cid);
11020        }
11021
11022        private List<String> getAllCodePaths() {
11023            final File codeFile = new File(getCodePath());
11024            if (codeFile != null && codeFile.exists()) {
11025                try {
11026                    final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0);
11027                    return pkg.getAllCodePaths();
11028                } catch (PackageParserException e) {
11029                    // Ignored; we tried our best
11030                }
11031            }
11032            return Collections.EMPTY_LIST;
11033        }
11034
11035        void cleanUpResourcesLI() {
11036            // Enumerate all code paths before deleting
11037            cleanUpResourcesLI(getAllCodePaths());
11038        }
11039
11040        private void cleanUpResourcesLI(List<String> allCodePaths) {
11041            cleanUp();
11042            removeDexFiles(allCodePaths, instructionSets);
11043        }
11044
11045        String getPackageName() {
11046            return getAsecPackageName(cid);
11047        }
11048
11049        boolean doPostDeleteLI(boolean delete) {
11050            if (DEBUG_SD_INSTALL) Slog.i(TAG, "doPostDeleteLI() del=" + delete);
11051            final List<String> allCodePaths = getAllCodePaths();
11052            boolean mounted = PackageHelper.isContainerMounted(cid);
11053            if (mounted) {
11054                // Unmount first
11055                if (PackageHelper.unMountSdDir(cid)) {
11056                    mounted = false;
11057                }
11058            }
11059            if (!mounted && delete) {
11060                cleanUpResourcesLI(allCodePaths);
11061            }
11062            return !mounted;
11063        }
11064
11065        @Override
11066        int doPreCopy() {
11067            if (isFwdLocked()) {
11068                if (!PackageHelper.fixSdPermissions(cid,
11069                        getPackageUid(DEFAULT_CONTAINER_PACKAGE, 0), RES_FILE_NAME)) {
11070                    return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
11071                }
11072            }
11073
11074            return PackageManager.INSTALL_SUCCEEDED;
11075        }
11076
11077        @Override
11078        int doPostCopy(int uid) {
11079            if (isFwdLocked()) {
11080                if (uid < Process.FIRST_APPLICATION_UID
11081                        || !PackageHelper.fixSdPermissions(cid, UserHandle.getSharedAppGid(uid),
11082                                RES_FILE_NAME)) {
11083                    Slog.e(TAG, "Failed to finalize " + cid);
11084                    PackageHelper.destroySdDir(cid);
11085                    return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
11086                }
11087            }
11088
11089            return PackageManager.INSTALL_SUCCEEDED;
11090        }
11091    }
11092
11093    /**
11094     * Logic to handle movement of existing installed applications.
11095     */
11096    class MoveInstallArgs extends InstallArgs {
11097        private File codeFile;
11098        private File resourceFile;
11099
11100        /** New install */
11101        MoveInstallArgs(InstallParams params) {
11102            super(params.origin, params.move, params.observer, params.installFlags,
11103                    params.installerPackageName, params.volumeUuid, params.getManifestDigest(),
11104                    params.getUser(), null /* instruction sets */, params.packageAbiOverride);
11105        }
11106
11107        int copyApk(IMediaContainerService imcs, boolean temp) {
11108            if (DEBUG_INSTALL) Slog.d(TAG, "Moving " + move.packageName + " from "
11109                    + move.fromUuid + " to " + move.toUuid);
11110            synchronized (mInstaller) {
11111                if (mInstaller.moveCompleteApp(move.fromUuid, move.toUuid, move.packageName,
11112                        move.dataAppName, move.appId, move.seinfo) != 0) {
11113                    return PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
11114                }
11115            }
11116
11117            codeFile = new File(Environment.getDataAppDirectory(move.toUuid), move.dataAppName);
11118            resourceFile = codeFile;
11119            if (DEBUG_INSTALL) Slog.d(TAG, "codeFile after move is " + codeFile);
11120
11121            return PackageManager.INSTALL_SUCCEEDED;
11122        }
11123
11124        int doPreInstall(int status) {
11125            if (status != PackageManager.INSTALL_SUCCEEDED) {
11126                cleanUp();
11127            }
11128            return status;
11129        }
11130
11131        boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
11132            if (status != PackageManager.INSTALL_SUCCEEDED) {
11133                cleanUp();
11134                return false;
11135            }
11136
11137            // Reflect the move in app info
11138            pkg.applicationInfo.volumeUuid = pkg.volumeUuid;
11139            pkg.applicationInfo.setCodePath(pkg.codePath);
11140            pkg.applicationInfo.setBaseCodePath(pkg.baseCodePath);
11141            pkg.applicationInfo.setSplitCodePaths(pkg.splitCodePaths);
11142            pkg.applicationInfo.setResourcePath(pkg.codePath);
11143            pkg.applicationInfo.setBaseResourcePath(pkg.baseCodePath);
11144            pkg.applicationInfo.setSplitResourcePaths(pkg.splitCodePaths);
11145
11146            return true;
11147        }
11148
11149        int doPostInstall(int status, int uid) {
11150            if (status != PackageManager.INSTALL_SUCCEEDED) {
11151                cleanUp();
11152            }
11153            return status;
11154        }
11155
11156        @Override
11157        String getCodePath() {
11158            return (codeFile != null) ? codeFile.getAbsolutePath() : null;
11159        }
11160
11161        @Override
11162        String getResourcePath() {
11163            return (resourceFile != null) ? resourceFile.getAbsolutePath() : null;
11164        }
11165
11166        private boolean cleanUp() {
11167            if (codeFile == null || !codeFile.exists()) {
11168                return false;
11169            }
11170
11171            if (codeFile.isDirectory()) {
11172                mInstaller.rmPackageDir(codeFile.getAbsolutePath());
11173            } else {
11174                codeFile.delete();
11175            }
11176
11177            if (resourceFile != null && !FileUtils.contains(codeFile, resourceFile)) {
11178                resourceFile.delete();
11179            }
11180
11181            return true;
11182        }
11183
11184        void cleanUpResourcesLI() {
11185            cleanUp();
11186        }
11187
11188        boolean doPostDeleteLI(boolean delete) {
11189            // XXX err, shouldn't we respect the delete flag?
11190            cleanUpResourcesLI();
11191            return true;
11192        }
11193    }
11194
11195    static String getAsecPackageName(String packageCid) {
11196        int idx = packageCid.lastIndexOf("-");
11197        if (idx == -1) {
11198            return packageCid;
11199        }
11200        return packageCid.substring(0, idx);
11201    }
11202
11203    // Utility method used to create code paths based on package name and available index.
11204    private static String getNextCodePath(String oldCodePath, String prefix, String suffix) {
11205        String idxStr = "";
11206        int idx = 1;
11207        // Fall back to default value of idx=1 if prefix is not
11208        // part of oldCodePath
11209        if (oldCodePath != null) {
11210            String subStr = oldCodePath;
11211            // Drop the suffix right away
11212            if (suffix != null && subStr.endsWith(suffix)) {
11213                subStr = subStr.substring(0, subStr.length() - suffix.length());
11214            }
11215            // If oldCodePath already contains prefix find out the
11216            // ending index to either increment or decrement.
11217            int sidx = subStr.lastIndexOf(prefix);
11218            if (sidx != -1) {
11219                subStr = subStr.substring(sidx + prefix.length());
11220                if (subStr != null) {
11221                    if (subStr.startsWith(INSTALL_PACKAGE_SUFFIX)) {
11222                        subStr = subStr.substring(INSTALL_PACKAGE_SUFFIX.length());
11223                    }
11224                    try {
11225                        idx = Integer.parseInt(subStr);
11226                        if (idx <= 1) {
11227                            idx++;
11228                        } else {
11229                            idx--;
11230                        }
11231                    } catch(NumberFormatException e) {
11232                    }
11233                }
11234            }
11235        }
11236        idxStr = INSTALL_PACKAGE_SUFFIX + Integer.toString(idx);
11237        return prefix + idxStr;
11238    }
11239
11240    private File getNextCodePath(File targetDir, String packageName) {
11241        int suffix = 1;
11242        File result;
11243        do {
11244            result = new File(targetDir, packageName + "-" + suffix);
11245            suffix++;
11246        } while (result.exists());
11247        return result;
11248    }
11249
11250    // Utility method that returns the relative package path with respect
11251    // to the installation directory. Like say for /data/data/com.test-1.apk
11252    // string com.test-1 is returned.
11253    static String deriveCodePathName(String codePath) {
11254        if (codePath == null) {
11255            return null;
11256        }
11257        final File codeFile = new File(codePath);
11258        final String name = codeFile.getName();
11259        if (codeFile.isDirectory()) {
11260            return name;
11261        } else if (name.endsWith(".apk") || name.endsWith(".tmp")) {
11262            final int lastDot = name.lastIndexOf('.');
11263            return name.substring(0, lastDot);
11264        } else {
11265            Slog.w(TAG, "Odd, " + codePath + " doesn't look like an APK");
11266            return null;
11267        }
11268    }
11269
11270    class PackageInstalledInfo {
11271        String name;
11272        int uid;
11273        // The set of users that originally had this package installed.
11274        int[] origUsers;
11275        // The set of users that now have this package installed.
11276        int[] newUsers;
11277        PackageParser.Package pkg;
11278        int returnCode;
11279        String returnMsg;
11280        PackageRemovedInfo removedInfo;
11281
11282        public void setError(int code, String msg) {
11283            returnCode = code;
11284            returnMsg = msg;
11285            Slog.w(TAG, msg);
11286        }
11287
11288        public void setError(String msg, PackageParserException e) {
11289            returnCode = e.error;
11290            returnMsg = ExceptionUtils.getCompleteMessage(msg, e);
11291            Slog.w(TAG, msg, e);
11292        }
11293
11294        public void setError(String msg, PackageManagerException e) {
11295            returnCode = e.error;
11296            returnMsg = ExceptionUtils.getCompleteMessage(msg, e);
11297            Slog.w(TAG, msg, e);
11298        }
11299
11300        // In some error cases we want to convey more info back to the observer
11301        String origPackage;
11302        String origPermission;
11303    }
11304
11305    /*
11306     * Install a non-existing package.
11307     */
11308    private void installNewPackageLI(PackageParser.Package pkg, int parseFlags, int scanFlags,
11309            UserHandle user, String installerPackageName, String volumeUuid,
11310            PackageInstalledInfo res) {
11311        // Remember this for later, in case we need to rollback this install
11312        String pkgName = pkg.packageName;
11313
11314        if (DEBUG_INSTALL) Slog.d(TAG, "installNewPackageLI: " + pkg);
11315        final boolean dataDirExists = PackageManager.getDataDirForUser(volumeUuid, pkgName,
11316                UserHandle.USER_OWNER).exists();
11317        synchronized(mPackages) {
11318            if (mSettings.mRenamedPackages.containsKey(pkgName)) {
11319                // A package with the same name is already installed, though
11320                // it has been renamed to an older name.  The package we
11321                // are trying to install should be installed as an update to
11322                // the existing one, but that has not been requested, so bail.
11323                res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName
11324                        + " without first uninstalling package running as "
11325                        + mSettings.mRenamedPackages.get(pkgName));
11326                return;
11327            }
11328            if (mPackages.containsKey(pkgName)) {
11329                // Don't allow installation over an existing package with the same name.
11330                res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName
11331                        + " without first uninstalling.");
11332                return;
11333            }
11334        }
11335
11336        try {
11337            PackageParser.Package newPackage = scanPackageLI(pkg, parseFlags, scanFlags,
11338                    System.currentTimeMillis(), user);
11339
11340            updateSettingsLI(newPackage, installerPackageName, volumeUuid, null, null, res, user);
11341            // delete the partially installed application. the data directory will have to be
11342            // restored if it was already existing
11343            if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
11344                // remove package from internal structures.  Note that we want deletePackageX to
11345                // delete the package data and cache directories that it created in
11346                // scanPackageLocked, unless those directories existed before we even tried to
11347                // install.
11348                deletePackageLI(pkgName, UserHandle.ALL, false, null, null,
11349                        dataDirExists ? PackageManager.DELETE_KEEP_DATA : 0,
11350                                res.removedInfo, true);
11351            }
11352
11353        } catch (PackageManagerException e) {
11354            res.setError("Package couldn't be installed in " + pkg.codePath, e);
11355        }
11356    }
11357
11358    private boolean shouldCheckUpgradeKeySetLP(PackageSetting oldPs, int scanFlags) {
11359        // Can't rotate keys during boot or if sharedUser.
11360        if (oldPs == null || (scanFlags&SCAN_INITIAL) != 0 || oldPs.sharedUser != null
11361                || !oldPs.keySetData.isUsingUpgradeKeySets()) {
11362            return false;
11363        }
11364        // app is using upgradeKeySets; make sure all are valid
11365        KeySetManagerService ksms = mSettings.mKeySetManagerService;
11366        long[] upgradeKeySets = oldPs.keySetData.getUpgradeKeySets();
11367        for (int i = 0; i < upgradeKeySets.length; i++) {
11368            if (!ksms.isIdValidKeySetId(upgradeKeySets[i])) {
11369                Slog.wtf(TAG, "Package "
11370                         + (oldPs.name != null ? oldPs.name : "<null>")
11371                         + " contains upgrade-key-set reference to unknown key-set: "
11372                         + upgradeKeySets[i]
11373                         + " reverting to signatures check.");
11374                return false;
11375            }
11376        }
11377        return true;
11378    }
11379
11380    private boolean checkUpgradeKeySetLP(PackageSetting oldPS, PackageParser.Package newPkg) {
11381        // Upgrade keysets are being used.  Determine if new package has a superset of the
11382        // required keys.
11383        long[] upgradeKeySets = oldPS.keySetData.getUpgradeKeySets();
11384        KeySetManagerService ksms = mSettings.mKeySetManagerService;
11385        for (int i = 0; i < upgradeKeySets.length; i++) {
11386            Set<PublicKey> upgradeSet = ksms.getPublicKeysFromKeySetLPr(upgradeKeySets[i]);
11387            if (upgradeSet != null && newPkg.mSigningKeys.containsAll(upgradeSet)) {
11388                return true;
11389            }
11390        }
11391        return false;
11392    }
11393
11394    private void replacePackageLI(PackageParser.Package pkg, int parseFlags, int scanFlags,
11395            UserHandle user, String installerPackageName, String volumeUuid,
11396            PackageInstalledInfo res) {
11397        final PackageParser.Package oldPackage;
11398        final String pkgName = pkg.packageName;
11399        final int[] allUsers;
11400        final boolean[] perUserInstalled;
11401        final boolean weFroze;
11402
11403        // First find the old package info and check signatures
11404        synchronized(mPackages) {
11405            oldPackage = mPackages.get(pkgName);
11406            if (DEBUG_INSTALL) Slog.d(TAG, "replacePackageLI: new=" + pkg + ", old=" + oldPackage);
11407            final PackageSetting ps = mSettings.mPackages.get(pkgName);
11408            if (shouldCheckUpgradeKeySetLP(ps, scanFlags)) {
11409                if(!checkUpgradeKeySetLP(ps, pkg)) {
11410                    res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
11411                            "New package not signed by keys specified by upgrade-keysets: "
11412                            + pkgName);
11413                    return;
11414                }
11415            } else {
11416                // default to original signature matching
11417                if (compareSignatures(oldPackage.mSignatures, pkg.mSignatures)
11418                    != PackageManager.SIGNATURE_MATCH) {
11419                    res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
11420                            "New package has a different signature: " + pkgName);
11421                    return;
11422                }
11423            }
11424
11425            // In case of rollback, remember per-user/profile install state
11426            allUsers = sUserManager.getUserIds();
11427            perUserInstalled = new boolean[allUsers.length];
11428            for (int i = 0; i < allUsers.length; i++) {
11429                perUserInstalled[i] = ps != null ? ps.getInstalled(allUsers[i]) : false;
11430            }
11431
11432            // Mark the app as frozen to prevent launching during the upgrade
11433            // process, and then kill all running instances
11434            if (!ps.frozen) {
11435                ps.frozen = true;
11436                weFroze = true;
11437            } else {
11438                weFroze = false;
11439            }
11440        }
11441
11442        // Now that we're guarded by frozen state, kill app during upgrade
11443        killApplication(pkgName, oldPackage.applicationInfo.uid, "replace pkg");
11444
11445        try {
11446            boolean sysPkg = (isSystemApp(oldPackage));
11447            if (sysPkg) {
11448                replaceSystemPackageLI(oldPackage, pkg, parseFlags, scanFlags,
11449                        user, allUsers, perUserInstalled, installerPackageName, volumeUuid, res);
11450            } else {
11451                replaceNonSystemPackageLI(oldPackage, pkg, parseFlags, scanFlags,
11452                        user, allUsers, perUserInstalled, installerPackageName, volumeUuid, res);
11453            }
11454        } finally {
11455            // Regardless of success or failure of upgrade steps above, always
11456            // unfreeze the package if we froze it
11457            if (weFroze) {
11458                unfreezePackage(pkgName);
11459            }
11460        }
11461    }
11462
11463    private void replaceNonSystemPackageLI(PackageParser.Package deletedPackage,
11464            PackageParser.Package pkg, int parseFlags, int scanFlags, UserHandle user,
11465            int[] allUsers, boolean[] perUserInstalled, String installerPackageName,
11466            String volumeUuid, PackageInstalledInfo res) {
11467        String pkgName = deletedPackage.packageName;
11468        boolean deletedPkg = true;
11469        boolean updatedSettings = false;
11470
11471        if (DEBUG_INSTALL) Slog.d(TAG, "replaceNonSystemPackageLI: new=" + pkg + ", old="
11472                + deletedPackage);
11473        long origUpdateTime;
11474        if (pkg.mExtras != null) {
11475            origUpdateTime = ((PackageSetting)pkg.mExtras).lastUpdateTime;
11476        } else {
11477            origUpdateTime = 0;
11478        }
11479
11480        // First delete the existing package while retaining the data directory
11481        if (!deletePackageLI(pkgName, null, true, null, null, PackageManager.DELETE_KEEP_DATA,
11482                res.removedInfo, true)) {
11483            // If the existing package wasn't successfully deleted
11484            res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE, "replaceNonSystemPackageLI");
11485            deletedPkg = false;
11486        } else {
11487            // Successfully deleted the old package; proceed with replace.
11488
11489            // If deleted package lived in a container, give users a chance to
11490            // relinquish resources before killing.
11491            if (deletedPackage.isForwardLocked() || isExternal(deletedPackage)) {
11492                if (DEBUG_INSTALL) {
11493                    Slog.i(TAG, "upgrading pkg " + deletedPackage + " is ASEC-hosted -> UNAVAILABLE");
11494                }
11495                final int[] uidArray = new int[] { deletedPackage.applicationInfo.uid };
11496                final ArrayList<String> pkgList = new ArrayList<String>(1);
11497                pkgList.add(deletedPackage.applicationInfo.packageName);
11498                sendResourcesChangedBroadcast(false, true, pkgList, uidArray, null);
11499            }
11500
11501            deleteCodeCacheDirsLI(pkg.volumeUuid, pkgName);
11502            try {
11503                final PackageParser.Package newPackage = scanPackageLI(pkg, parseFlags,
11504                        scanFlags | SCAN_UPDATE_TIME, System.currentTimeMillis(), user);
11505                updateSettingsLI(newPackage, installerPackageName, volumeUuid, allUsers,
11506                        perUserInstalled, res, user);
11507                updatedSettings = true;
11508            } catch (PackageManagerException e) {
11509                res.setError("Package couldn't be installed in " + pkg.codePath, e);
11510            }
11511        }
11512
11513        if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
11514            // remove package from internal structures.  Note that we want deletePackageX to
11515            // delete the package data and cache directories that it created in
11516            // scanPackageLocked, unless those directories existed before we even tried to
11517            // install.
11518            if(updatedSettings) {
11519                if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, rolling pack: " + pkgName);
11520                deletePackageLI(
11521                        pkgName, null, true, allUsers, perUserInstalled,
11522                        PackageManager.DELETE_KEEP_DATA,
11523                                res.removedInfo, true);
11524            }
11525            // Since we failed to install the new package we need to restore the old
11526            // package that we deleted.
11527            if (deletedPkg) {
11528                if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, reinstalling: " + deletedPackage);
11529                File restoreFile = new File(deletedPackage.codePath);
11530                // Parse old package
11531                boolean oldExternal = isExternal(deletedPackage);
11532                int oldParseFlags  = mDefParseFlags | PackageParser.PARSE_CHATTY |
11533                        (deletedPackage.isForwardLocked() ? PackageParser.PARSE_FORWARD_LOCK : 0) |
11534                        (oldExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0);
11535                int oldScanFlags = SCAN_UPDATE_SIGNATURE | SCAN_UPDATE_TIME;
11536                try {
11537                    scanPackageLI(restoreFile, oldParseFlags, oldScanFlags, origUpdateTime, null);
11538                } catch (PackageManagerException e) {
11539                    Slog.e(TAG, "Failed to restore package : " + pkgName + " after failed upgrade: "
11540                            + e.getMessage());
11541                    return;
11542                }
11543                // Restore of old package succeeded. Update permissions.
11544                // writer
11545                synchronized (mPackages) {
11546                    updatePermissionsLPw(deletedPackage.packageName, deletedPackage,
11547                            UPDATE_PERMISSIONS_ALL);
11548                    // can downgrade to reader
11549                    mSettings.writeLPr();
11550                }
11551                Slog.i(TAG, "Successfully restored package : " + pkgName + " after failed upgrade");
11552            }
11553        }
11554    }
11555
11556    private void replaceSystemPackageLI(PackageParser.Package deletedPackage,
11557            PackageParser.Package pkg, int parseFlags, int scanFlags, UserHandle user,
11558            int[] allUsers, boolean[] perUserInstalled, String installerPackageName,
11559            String volumeUuid, PackageInstalledInfo res) {
11560        if (DEBUG_INSTALL) Slog.d(TAG, "replaceSystemPackageLI: new=" + pkg
11561                + ", old=" + deletedPackage);
11562        boolean disabledSystem = false;
11563        boolean updatedSettings = false;
11564        parseFlags |= PackageParser.PARSE_IS_SYSTEM;
11565        if ((deletedPackage.applicationInfo.privateFlags&ApplicationInfo.PRIVATE_FLAG_PRIVILEGED)
11566                != 0) {
11567            parseFlags |= PackageParser.PARSE_IS_PRIVILEGED;
11568        }
11569        String packageName = deletedPackage.packageName;
11570        if (packageName == null) {
11571            res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE,
11572                    "Attempt to delete null packageName.");
11573            return;
11574        }
11575        PackageParser.Package oldPkg;
11576        PackageSetting oldPkgSetting;
11577        // reader
11578        synchronized (mPackages) {
11579            oldPkg = mPackages.get(packageName);
11580            oldPkgSetting = mSettings.mPackages.get(packageName);
11581            if((oldPkg == null) || (oldPkg.applicationInfo == null) ||
11582                    (oldPkgSetting == null)) {
11583                res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE,
11584                        "Couldn't find package:" + packageName + " information");
11585                return;
11586            }
11587        }
11588
11589        res.removedInfo.uid = oldPkg.applicationInfo.uid;
11590        res.removedInfo.removedPackage = packageName;
11591        // Remove existing system package
11592        removePackageLI(oldPkgSetting, true);
11593        // writer
11594        synchronized (mPackages) {
11595            disabledSystem = mSettings.disableSystemPackageLPw(packageName);
11596            if (!disabledSystem && deletedPackage != null) {
11597                // We didn't need to disable the .apk as a current system package,
11598                // which means we are replacing another update that is already
11599                // installed.  We need to make sure to delete the older one's .apk.
11600                res.removedInfo.args = createInstallArgsForExisting(0,
11601                        deletedPackage.applicationInfo.getCodePath(),
11602                        deletedPackage.applicationInfo.getResourcePath(),
11603                        getAppDexInstructionSets(deletedPackage.applicationInfo));
11604            } else {
11605                res.removedInfo.args = null;
11606            }
11607        }
11608
11609        // Successfully disabled the old package. Now proceed with re-installation
11610        deleteCodeCacheDirsLI(pkg.volumeUuid, packageName);
11611
11612        res.returnCode = PackageManager.INSTALL_SUCCEEDED;
11613        pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
11614
11615        PackageParser.Package newPackage = null;
11616        try {
11617            newPackage = scanPackageLI(pkg, parseFlags, scanFlags, 0, user);
11618            if (newPackage.mExtras != null) {
11619                final PackageSetting newPkgSetting = (PackageSetting) newPackage.mExtras;
11620                newPkgSetting.firstInstallTime = oldPkgSetting.firstInstallTime;
11621                newPkgSetting.lastUpdateTime = System.currentTimeMillis();
11622
11623                // is the update attempting to change shared user? that isn't going to work...
11624                if (oldPkgSetting.sharedUser != newPkgSetting.sharedUser) {
11625                    res.setError(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
11626                            "Forbidding shared user change from " + oldPkgSetting.sharedUser
11627                            + " to " + newPkgSetting.sharedUser);
11628                    updatedSettings = true;
11629                }
11630            }
11631
11632            if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
11633                updateSettingsLI(newPackage, installerPackageName, volumeUuid, allUsers,
11634                        perUserInstalled, res, user);
11635                updatedSettings = true;
11636            }
11637
11638        } catch (PackageManagerException e) {
11639            res.setError("Package couldn't be installed in " + pkg.codePath, e);
11640        }
11641
11642        if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
11643            // Re installation failed. Restore old information
11644            // Remove new pkg information
11645            if (newPackage != null) {
11646                removeInstalledPackageLI(newPackage, true);
11647            }
11648            // Add back the old system package
11649            try {
11650                scanPackageLI(oldPkg, parseFlags, SCAN_UPDATE_SIGNATURE, 0, user);
11651            } catch (PackageManagerException e) {
11652                Slog.e(TAG, "Failed to restore original package: " + e.getMessage());
11653            }
11654            // Restore the old system information in Settings
11655            synchronized (mPackages) {
11656                if (disabledSystem) {
11657                    mSettings.enableSystemPackageLPw(packageName);
11658                }
11659                if (updatedSettings) {
11660                    mSettings.setInstallerPackageName(packageName,
11661                            oldPkgSetting.installerPackageName);
11662                }
11663                mSettings.writeLPr();
11664            }
11665        }
11666    }
11667
11668    private void updateSettingsLI(PackageParser.Package newPackage, String installerPackageName,
11669            String volumeUuid, int[] allUsers, boolean[] perUserInstalled, PackageInstalledInfo res,
11670            UserHandle user) {
11671        String pkgName = newPackage.packageName;
11672        synchronized (mPackages) {
11673            //write settings. the installStatus will be incomplete at this stage.
11674            //note that the new package setting would have already been
11675            //added to mPackages. It hasn't been persisted yet.
11676            mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_INCOMPLETE);
11677            mSettings.writeLPr();
11678        }
11679
11680        if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + newPackage.codePath);
11681
11682        synchronized (mPackages) {
11683            updatePermissionsLPw(newPackage.packageName, newPackage,
11684                    UPDATE_PERMISSIONS_REPLACE_PKG | (newPackage.permissions.size() > 0
11685                            ? UPDATE_PERMISSIONS_ALL : 0));
11686            // For system-bundled packages, we assume that installing an upgraded version
11687            // of the package implies that the user actually wants to run that new code,
11688            // so we enable the package.
11689            PackageSetting ps = mSettings.mPackages.get(pkgName);
11690            if (ps != null) {
11691                if (isSystemApp(newPackage)) {
11692                    // NB: implicit assumption that system package upgrades apply to all users
11693                    if (DEBUG_INSTALL) {
11694                        Slog.d(TAG, "Implicitly enabling system package on upgrade: " + pkgName);
11695                    }
11696                    if (res.origUsers != null) {
11697                        for (int userHandle : res.origUsers) {
11698                            ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT,
11699                                    userHandle, installerPackageName);
11700                        }
11701                    }
11702                    // Also convey the prior install/uninstall state
11703                    if (allUsers != null && perUserInstalled != null) {
11704                        for (int i = 0; i < allUsers.length; i++) {
11705                            if (DEBUG_INSTALL) {
11706                                Slog.d(TAG, "    user " + allUsers[i]
11707                                        + " => " + perUserInstalled[i]);
11708                            }
11709                            ps.setInstalled(perUserInstalled[i], allUsers[i]);
11710                        }
11711                        // these install state changes will be persisted in the
11712                        // upcoming call to mSettings.writeLPr().
11713                    }
11714                }
11715                // It's implied that when a user requests installation, they want the app to be
11716                // installed and enabled.
11717                int userId = user.getIdentifier();
11718                if (userId != UserHandle.USER_ALL) {
11719                    ps.setInstalled(true, userId);
11720                    ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, userId, installerPackageName);
11721                }
11722            }
11723            res.name = pkgName;
11724            res.uid = newPackage.applicationInfo.uid;
11725            res.pkg = newPackage;
11726            mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_COMPLETE);
11727            mSettings.setInstallerPackageName(pkgName, installerPackageName);
11728            res.returnCode = PackageManager.INSTALL_SUCCEEDED;
11729            //to update install status
11730            mSettings.writeLPr();
11731        }
11732    }
11733
11734    private void installPackageLI(InstallArgs args, PackageInstalledInfo res) {
11735        final int installFlags = args.installFlags;
11736        final String installerPackageName = args.installerPackageName;
11737        final String volumeUuid = args.volumeUuid;
11738        final File tmpPackageFile = new File(args.getCodePath());
11739        final boolean forwardLocked = ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0);
11740        final boolean onExternal = (((installFlags & PackageManager.INSTALL_EXTERNAL) != 0)
11741                || (args.volumeUuid != null));
11742        boolean replace = false;
11743        int scanFlags = SCAN_NEW_INSTALL | SCAN_UPDATE_SIGNATURE;
11744        if (args.move != null) {
11745            // moving a complete application; perfom an initial scan on the new install location
11746            scanFlags |= SCAN_INITIAL;
11747        }
11748        // Result object to be returned
11749        res.returnCode = PackageManager.INSTALL_SUCCEEDED;
11750
11751        if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile);
11752        // Retrieve PackageSettings and parse package
11753        final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY
11754                | (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0)
11755                | (onExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0);
11756        PackageParser pp = new PackageParser();
11757        pp.setSeparateProcesses(mSeparateProcesses);
11758        pp.setDisplayMetrics(mMetrics);
11759
11760        final PackageParser.Package pkg;
11761        try {
11762            pkg = pp.parsePackage(tmpPackageFile, parseFlags);
11763        } catch (PackageParserException e) {
11764            res.setError("Failed parse during installPackageLI", e);
11765            return;
11766        }
11767
11768        // Mark that we have an install time CPU ABI override.
11769        pkg.cpuAbiOverride = args.abiOverride;
11770
11771        String pkgName = res.name = pkg.packageName;
11772        if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_TEST_ONLY) != 0) {
11773            if ((installFlags & PackageManager.INSTALL_ALLOW_TEST) == 0) {
11774                res.setError(INSTALL_FAILED_TEST_ONLY, "installPackageLI");
11775                return;
11776            }
11777        }
11778
11779        try {
11780            pp.collectCertificates(pkg, parseFlags);
11781            pp.collectManifestDigest(pkg);
11782        } catch (PackageParserException e) {
11783            res.setError("Failed collect during installPackageLI", e);
11784            return;
11785        }
11786
11787        /* If the installer passed in a manifest digest, compare it now. */
11788        if (args.manifestDigest != null) {
11789            if (DEBUG_INSTALL) {
11790                final String parsedManifest = pkg.manifestDigest == null ? "null"
11791                        : pkg.manifestDigest.toString();
11792                Slog.d(TAG, "Comparing manifests: " + args.manifestDigest.toString() + " vs. "
11793                        + parsedManifest);
11794            }
11795
11796            if (!args.manifestDigest.equals(pkg.manifestDigest)) {
11797                res.setError(INSTALL_FAILED_PACKAGE_CHANGED, "Manifest digest changed");
11798                return;
11799            }
11800        } else if (DEBUG_INSTALL) {
11801            final String parsedManifest = pkg.manifestDigest == null
11802                    ? "null" : pkg.manifestDigest.toString();
11803            Slog.d(TAG, "manifestDigest was not present, but parser got: " + parsedManifest);
11804        }
11805
11806        // Get rid of all references to package scan path via parser.
11807        pp = null;
11808        String oldCodePath = null;
11809        boolean systemApp = false;
11810        synchronized (mPackages) {
11811            // Check if installing already existing package
11812            if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
11813                String oldName = mSettings.mRenamedPackages.get(pkgName);
11814                if (pkg.mOriginalPackages != null
11815                        && pkg.mOriginalPackages.contains(oldName)
11816                        && mPackages.containsKey(oldName)) {
11817                    // This package is derived from an original package,
11818                    // and this device has been updating from that original
11819                    // name.  We must continue using the original name, so
11820                    // rename the new package here.
11821                    pkg.setPackageName(oldName);
11822                    pkgName = pkg.packageName;
11823                    replace = true;
11824                    if (DEBUG_INSTALL) Slog.d(TAG, "Replacing existing renamed package: oldName="
11825                            + oldName + " pkgName=" + pkgName);
11826                } else if (mPackages.containsKey(pkgName)) {
11827                    // This package, under its official name, already exists
11828                    // on the device; we should replace it.
11829                    replace = true;
11830                    if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing pacakge: " + pkgName);
11831                }
11832
11833                // Prevent apps opting out from runtime permissions
11834                if (replace) {
11835                    PackageParser.Package oldPackage = mPackages.get(pkgName);
11836                    final int oldTargetSdk = oldPackage.applicationInfo.targetSdkVersion;
11837                    final int newTargetSdk = pkg.applicationInfo.targetSdkVersion;
11838                    if (oldTargetSdk > Build.VERSION_CODES.LOLLIPOP_MR1
11839                            && newTargetSdk <= Build.VERSION_CODES.LOLLIPOP_MR1) {
11840                        res.setError(PackageManager.INSTALL_FAILED_PERMISSION_MODEL_DOWNGRADE,
11841                                "Package " + pkg.packageName + " new target SDK " + newTargetSdk
11842                                        + " doesn't support runtime permissions but the old"
11843                                        + " target SDK " + oldTargetSdk + " does.");
11844                        return;
11845                    }
11846                }
11847            }
11848
11849            PackageSetting ps = mSettings.mPackages.get(pkgName);
11850            if (ps != null) {
11851                if (DEBUG_INSTALL) Slog.d(TAG, "Existing package: " + ps);
11852
11853                // Quick sanity check that we're signed correctly if updating;
11854                // we'll check this again later when scanning, but we want to
11855                // bail early here before tripping over redefined permissions.
11856                if (shouldCheckUpgradeKeySetLP(ps, scanFlags)) {
11857                    if (!checkUpgradeKeySetLP(ps, pkg)) {
11858                        res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
11859                                + pkg.packageName + " upgrade keys do not match the "
11860                                + "previously installed version");
11861                        return;
11862                    }
11863                } else {
11864                    try {
11865                        verifySignaturesLP(ps, pkg);
11866                    } catch (PackageManagerException e) {
11867                        res.setError(e.error, e.getMessage());
11868                        return;
11869                    }
11870                }
11871
11872                oldCodePath = mSettings.mPackages.get(pkgName).codePathString;
11873                if (ps.pkg != null && ps.pkg.applicationInfo != null) {
11874                    systemApp = (ps.pkg.applicationInfo.flags &
11875                            ApplicationInfo.FLAG_SYSTEM) != 0;
11876                }
11877                res.origUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
11878            }
11879
11880            // Check whether the newly-scanned package wants to define an already-defined perm
11881            int N = pkg.permissions.size();
11882            for (int i = N-1; i >= 0; i--) {
11883                PackageParser.Permission perm = pkg.permissions.get(i);
11884                BasePermission bp = mSettings.mPermissions.get(perm.info.name);
11885                if (bp != null) {
11886                    // If the defining package is signed with our cert, it's okay.  This
11887                    // also includes the "updating the same package" case, of course.
11888                    // "updating same package" could also involve key-rotation.
11889                    final boolean sigsOk;
11890                    if (bp.sourcePackage.equals(pkg.packageName)
11891                            && (bp.packageSetting instanceof PackageSetting)
11892                            && (shouldCheckUpgradeKeySetLP((PackageSetting) bp.packageSetting,
11893                                    scanFlags))) {
11894                        sigsOk = checkUpgradeKeySetLP((PackageSetting) bp.packageSetting, pkg);
11895                    } else {
11896                        sigsOk = compareSignatures(bp.packageSetting.signatures.mSignatures,
11897                                pkg.mSignatures) == PackageManager.SIGNATURE_MATCH;
11898                    }
11899                    if (!sigsOk) {
11900                        // If the owning package is the system itself, we log but allow
11901                        // install to proceed; we fail the install on all other permission
11902                        // redefinitions.
11903                        if (!bp.sourcePackage.equals("android")) {
11904                            res.setError(INSTALL_FAILED_DUPLICATE_PERMISSION, "Package "
11905                                    + pkg.packageName + " attempting to redeclare permission "
11906                                    + perm.info.name + " already owned by " + bp.sourcePackage);
11907                            res.origPermission = perm.info.name;
11908                            res.origPackage = bp.sourcePackage;
11909                            return;
11910                        } else {
11911                            Slog.w(TAG, "Package " + pkg.packageName
11912                                    + " attempting to redeclare system permission "
11913                                    + perm.info.name + "; ignoring new declaration");
11914                            pkg.permissions.remove(i);
11915                        }
11916                    }
11917                }
11918            }
11919
11920        }
11921
11922        if (systemApp && onExternal) {
11923            // Disable updates to system apps on sdcard
11924            res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
11925                    "Cannot install updates to system apps on sdcard");
11926            return;
11927        }
11928
11929        if (args.move != null) {
11930            // We did an in-place move, so dex is ready to roll
11931            scanFlags |= SCAN_NO_DEX;
11932            scanFlags |= SCAN_MOVE;
11933        } else if (!forwardLocked && !pkg.applicationInfo.isExternalAsec()) {
11934            // Enable SCAN_NO_DEX flag to skip dexopt at a later stage
11935            scanFlags |= SCAN_NO_DEX;
11936
11937            try {
11938                derivePackageAbi(pkg, new File(pkg.codePath), args.abiOverride,
11939                        true /* extract libs */);
11940            } catch (PackageManagerException pme) {
11941                Slog.e(TAG, "Error deriving application ABI", pme);
11942                res.setError(INSTALL_FAILED_INTERNAL_ERROR, "Error deriving application ABI");
11943                return;
11944            }
11945
11946            // Run dexopt before old package gets removed, to minimize time when app is unavailable
11947            int result = mPackageDexOptimizer
11948                    .performDexOpt(pkg, null /* instruction sets */, false /* forceDex */,
11949                            false /* defer */, false /* inclDependencies */);
11950            if (result == PackageDexOptimizer.DEX_OPT_FAILED) {
11951                res.setError(INSTALL_FAILED_DEXOPT, "Dexopt failed for " + pkg.codePath);
11952                return;
11953            }
11954        }
11955
11956        if (!args.doRename(res.returnCode, pkg, oldCodePath)) {
11957            res.setError(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename");
11958            return;
11959        }
11960
11961        startIntentFilterVerifications(args.user.getIdentifier(), replace, pkg);
11962
11963        if (replace) {
11964            replacePackageLI(pkg, parseFlags, scanFlags, args.user,
11965                    installerPackageName, volumeUuid, res);
11966        } else {
11967            installNewPackageLI(pkg, parseFlags, scanFlags | SCAN_DELETE_DATA_ON_FAILURES,
11968                    args.user, installerPackageName, volumeUuid, res);
11969        }
11970        synchronized (mPackages) {
11971            final PackageSetting ps = mSettings.mPackages.get(pkgName);
11972            if (ps != null) {
11973                res.newUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
11974            }
11975        }
11976    }
11977
11978    private void startIntentFilterVerifications(int userId, boolean replacing,
11979            PackageParser.Package pkg) {
11980        if (mIntentFilterVerifierComponent == null) {
11981            Slog.w(TAG, "No IntentFilter verification will not be done as "
11982                    + "there is no IntentFilterVerifier available!");
11983            return;
11984        }
11985
11986        final int verifierUid = getPackageUid(
11987                mIntentFilterVerifierComponent.getPackageName(),
11988                (userId == UserHandle.USER_ALL) ? UserHandle.USER_OWNER : userId);
11989
11990        mHandler.removeMessages(START_INTENT_FILTER_VERIFICATIONS);
11991        final Message msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS);
11992        msg.obj = new IFVerificationParams(pkg, replacing, userId, verifierUid);
11993        mHandler.sendMessage(msg);
11994    }
11995
11996    private void verifyIntentFiltersIfNeeded(int userId, int verifierUid, boolean replacing,
11997            PackageParser.Package pkg) {
11998        int size = pkg.activities.size();
11999        if (size == 0) {
12000            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
12001                    "No activity, so no need to verify any IntentFilter!");
12002            return;
12003        }
12004
12005        final boolean hasDomainURLs = hasDomainURLs(pkg);
12006        if (!hasDomainURLs) {
12007            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
12008                    "No domain URLs, so no need to verify any IntentFilter!");
12009            return;
12010        }
12011
12012        if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Checking for userId:" + userId
12013                + " if any IntentFilter from the " + size
12014                + " Activities needs verification ...");
12015
12016        int count = 0;
12017        final String packageName = pkg.packageName;
12018
12019        synchronized (mPackages) {
12020            // If this is a new install and we see that we've already run verification for this
12021            // package, we have nothing to do: it means the state was restored from backup.
12022            if (!replacing) {
12023                IntentFilterVerificationInfo ivi =
12024                        mSettings.getIntentFilterVerificationLPr(packageName);
12025                if (ivi != null) {
12026                    if (DEBUG_DOMAIN_VERIFICATION) {
12027                        Slog.i(TAG, "Package " + packageName+ " already verified: status="
12028                                + ivi.getStatusString());
12029                    }
12030                    return;
12031                }
12032            }
12033
12034            // If any filters need to be verified, then all need to be.
12035            boolean needToVerify = false;
12036            for (PackageParser.Activity a : pkg.activities) {
12037                for (ActivityIntentInfo filter : a.intents) {
12038                    if (filter.needsVerification() && needsNetworkVerificationLPr(filter)) {
12039                        if (DEBUG_DOMAIN_VERIFICATION) {
12040                            Slog.d(TAG, "Intent filter needs verification, so processing all filters");
12041                        }
12042                        needToVerify = true;
12043                        break;
12044                    }
12045                }
12046            }
12047
12048            if (needToVerify) {
12049                final int verificationId = mIntentFilterVerificationToken++;
12050                for (PackageParser.Activity a : pkg.activities) {
12051                    for (ActivityIntentInfo filter : a.intents) {
12052                        if (filter.hasOnlyWebDataURI() && needsNetworkVerificationLPr(filter)) {
12053                            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
12054                                    "Verification needed for IntentFilter:" + filter.toString());
12055                            mIntentFilterVerifier.addOneIntentFilterVerification(
12056                                    verifierUid, userId, verificationId, filter, packageName);
12057                            count++;
12058                        }
12059                    }
12060                }
12061            }
12062        }
12063
12064        if (count > 0) {
12065            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Starting " + count
12066                    + " IntentFilter verification" + (count > 1 ? "s" : "")
12067                    +  " for userId:" + userId);
12068            mIntentFilterVerifier.startVerifications(userId);
12069        } else {
12070            if (DEBUG_DOMAIN_VERIFICATION) {
12071                Slog.d(TAG, "No filters or not all autoVerify for " + packageName);
12072            }
12073        }
12074    }
12075
12076    private boolean needsNetworkVerificationLPr(ActivityIntentInfo filter) {
12077        final ComponentName cn  = filter.activity.getComponentName();
12078        final String packageName = cn.getPackageName();
12079
12080        IntentFilterVerificationInfo ivi = mSettings.getIntentFilterVerificationLPr(
12081                packageName);
12082        if (ivi == null) {
12083            return true;
12084        }
12085        int status = ivi.getStatus();
12086        switch (status) {
12087            case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED:
12088            case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK:
12089                return true;
12090
12091            default:
12092                // Nothing to do
12093                return false;
12094        }
12095    }
12096
12097    private static boolean isMultiArch(PackageSetting ps) {
12098        return (ps.pkgFlags & ApplicationInfo.FLAG_MULTIARCH) != 0;
12099    }
12100
12101    private static boolean isMultiArch(ApplicationInfo info) {
12102        return (info.flags & ApplicationInfo.FLAG_MULTIARCH) != 0;
12103    }
12104
12105    private static boolean isExternal(PackageParser.Package pkg) {
12106        return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
12107    }
12108
12109    private static boolean isExternal(PackageSetting ps) {
12110        return (ps.pkgFlags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
12111    }
12112
12113    private static boolean isExternal(ApplicationInfo info) {
12114        return (info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
12115    }
12116
12117    private static boolean isSystemApp(PackageParser.Package pkg) {
12118        return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
12119    }
12120
12121    private static boolean isPrivilegedApp(PackageParser.Package pkg) {
12122        return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0;
12123    }
12124
12125    private static boolean hasDomainURLs(PackageParser.Package pkg) {
12126        return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) != 0;
12127    }
12128
12129    private static boolean isSystemApp(PackageSetting ps) {
12130        return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0;
12131    }
12132
12133    private static boolean isUpdatedSystemApp(PackageSetting ps) {
12134        return (ps.pkgFlags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
12135    }
12136
12137    private int packageFlagsToInstallFlags(PackageSetting ps) {
12138        int installFlags = 0;
12139        if (isExternal(ps) && TextUtils.isEmpty(ps.volumeUuid)) {
12140            // This existing package was an external ASEC install when we have
12141            // the external flag without a UUID
12142            installFlags |= PackageManager.INSTALL_EXTERNAL;
12143        }
12144        if (ps.isForwardLocked()) {
12145            installFlags |= PackageManager.INSTALL_FORWARD_LOCK;
12146        }
12147        return installFlags;
12148    }
12149
12150    private void deleteTempPackageFiles() {
12151        final FilenameFilter filter = new FilenameFilter() {
12152            public boolean accept(File dir, String name) {
12153                return name.startsWith("vmdl") && name.endsWith(".tmp");
12154            }
12155        };
12156        for (File file : mDrmAppPrivateInstallDir.listFiles(filter)) {
12157            file.delete();
12158        }
12159    }
12160
12161    @Override
12162    public void deletePackageAsUser(String packageName, IPackageDeleteObserver observer, int userId,
12163            int flags) {
12164        deletePackage(packageName, new LegacyPackageDeleteObserver(observer).getBinder(), userId,
12165                flags);
12166    }
12167
12168    @Override
12169    public void deletePackage(final String packageName,
12170            final IPackageDeleteObserver2 observer, final int userId, final int flags) {
12171        mContext.enforceCallingOrSelfPermission(
12172                android.Manifest.permission.DELETE_PACKAGES, null);
12173        final int uid = Binder.getCallingUid();
12174        if (UserHandle.getUserId(uid) != userId) {
12175            mContext.enforceCallingPermission(
12176                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
12177                    "deletePackage for user " + userId);
12178        }
12179        if (isUserRestricted(userId, UserManager.DISALLOW_UNINSTALL_APPS)) {
12180            try {
12181                observer.onPackageDeleted(packageName,
12182                        PackageManager.DELETE_FAILED_USER_RESTRICTED, null);
12183            } catch (RemoteException re) {
12184            }
12185            return;
12186        }
12187
12188        boolean uninstallBlocked = false;
12189        if ((flags & PackageManager.DELETE_ALL_USERS) != 0) {
12190            int[] users = sUserManager.getUserIds();
12191            for (int i = 0; i < users.length; ++i) {
12192                if (getBlockUninstallForUser(packageName, users[i])) {
12193                    uninstallBlocked = true;
12194                    break;
12195                }
12196            }
12197        } else {
12198            uninstallBlocked = getBlockUninstallForUser(packageName, userId);
12199        }
12200        if (uninstallBlocked) {
12201            try {
12202                observer.onPackageDeleted(packageName, PackageManager.DELETE_FAILED_OWNER_BLOCKED,
12203                        null);
12204            } catch (RemoteException re) {
12205            }
12206            return;
12207        }
12208
12209        if (DEBUG_REMOVE) {
12210            Slog.d(TAG, "deletePackageAsUser: pkg=" + packageName + " user=" + userId);
12211        }
12212        // Queue up an async operation since the package deletion may take a little while.
12213        mHandler.post(new Runnable() {
12214            public void run() {
12215                mHandler.removeCallbacks(this);
12216                final int returnCode = deletePackageX(packageName, userId, flags);
12217                if (observer != null) {
12218                    try {
12219                        observer.onPackageDeleted(packageName, returnCode, null);
12220                    } catch (RemoteException e) {
12221                        Log.i(TAG, "Observer no longer exists.");
12222                    } //end catch
12223                } //end if
12224            } //end run
12225        });
12226    }
12227
12228    private boolean isPackageDeviceAdmin(String packageName, int userId) {
12229        IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
12230                ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
12231        try {
12232            if (dpm != null) {
12233                if (dpm.isDeviceOwner(packageName)) {
12234                    return true;
12235                }
12236                int[] users;
12237                if (userId == UserHandle.USER_ALL) {
12238                    users = sUserManager.getUserIds();
12239                } else {
12240                    users = new int[]{userId};
12241                }
12242                for (int i = 0; i < users.length; ++i) {
12243                    if (dpm.packageHasActiveAdmins(packageName, users[i])) {
12244                        return true;
12245                    }
12246                }
12247            }
12248        } catch (RemoteException e) {
12249        }
12250        return false;
12251    }
12252
12253    /**
12254     *  This method is an internal method that could be get invoked either
12255     *  to delete an installed package or to clean up a failed installation.
12256     *  After deleting an installed package, a broadcast is sent to notify any
12257     *  listeners that the package has been installed. For cleaning up a failed
12258     *  installation, the broadcast is not necessary since the package's
12259     *  installation wouldn't have sent the initial broadcast either
12260     *  The key steps in deleting a package are
12261     *  deleting the package information in internal structures like mPackages,
12262     *  deleting the packages base directories through installd
12263     *  updating mSettings to reflect current status
12264     *  persisting settings for later use
12265     *  sending a broadcast if necessary
12266     */
12267    private int deletePackageX(String packageName, int userId, int flags) {
12268        final PackageRemovedInfo info = new PackageRemovedInfo();
12269        final boolean res;
12270
12271        final UserHandle removeForUser = (flags & PackageManager.DELETE_ALL_USERS) != 0
12272                ? UserHandle.ALL : new UserHandle(userId);
12273
12274        if (isPackageDeviceAdmin(packageName, removeForUser.getIdentifier())) {
12275            Slog.w(TAG, "Not removing package " + packageName + ": has active device admin");
12276            return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER;
12277        }
12278
12279        boolean removedForAllUsers = false;
12280        boolean systemUpdate = false;
12281
12282        // for the uninstall-updates case and restricted profiles, remember the per-
12283        // userhandle installed state
12284        int[] allUsers;
12285        boolean[] perUserInstalled;
12286        synchronized (mPackages) {
12287            PackageSetting ps = mSettings.mPackages.get(packageName);
12288            allUsers = sUserManager.getUserIds();
12289            perUserInstalled = new boolean[allUsers.length];
12290            for (int i = 0; i < allUsers.length; i++) {
12291                perUserInstalled[i] = ps != null ? ps.getInstalled(allUsers[i]) : false;
12292            }
12293        }
12294
12295        synchronized (mInstallLock) {
12296            if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageX: pkg=" + packageName + " user=" + userId);
12297            res = deletePackageLI(packageName, removeForUser,
12298                    true, allUsers, perUserInstalled,
12299                    flags | REMOVE_CHATTY, info, true);
12300            systemUpdate = info.isRemovedPackageSystemUpdate;
12301            if (res && !systemUpdate && mPackages.get(packageName) == null) {
12302                removedForAllUsers = true;
12303            }
12304            if (DEBUG_REMOVE) Slog.d(TAG, "delete res: systemUpdate=" + systemUpdate
12305                    + " removedForAllUsers=" + removedForAllUsers);
12306        }
12307
12308        if (res) {
12309            info.sendBroadcast(true, systemUpdate, removedForAllUsers);
12310
12311            // If the removed package was a system update, the old system package
12312            // was re-enabled; we need to broadcast this information
12313            if (systemUpdate) {
12314                Bundle extras = new Bundle(1);
12315                extras.putInt(Intent.EXTRA_UID, info.removedAppId >= 0
12316                        ? info.removedAppId : info.uid);
12317                extras.putBoolean(Intent.EXTRA_REPLACING, true);
12318
12319                sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
12320                        extras, null, null, null);
12321                sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, packageName,
12322                        extras, null, null, null);
12323                sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, null,
12324                        null, packageName, null, null);
12325            }
12326        }
12327        // Force a gc here.
12328        Runtime.getRuntime().gc();
12329        // Delete the resources here after sending the broadcast to let
12330        // other processes clean up before deleting resources.
12331        if (info.args != null) {
12332            synchronized (mInstallLock) {
12333                info.args.doPostDeleteLI(true);
12334            }
12335        }
12336
12337        return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR;
12338    }
12339
12340    class PackageRemovedInfo {
12341        String removedPackage;
12342        int uid = -1;
12343        int removedAppId = -1;
12344        int[] removedUsers = null;
12345        boolean isRemovedPackageSystemUpdate = false;
12346        // Clean up resources deleted packages.
12347        InstallArgs args = null;
12348
12349        void sendBroadcast(boolean fullRemove, boolean replacing, boolean removedForAllUsers) {
12350            Bundle extras = new Bundle(1);
12351            extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid);
12352            extras.putBoolean(Intent.EXTRA_DATA_REMOVED, fullRemove);
12353            if (replacing) {
12354                extras.putBoolean(Intent.EXTRA_REPLACING, true);
12355            }
12356            extras.putBoolean(Intent.EXTRA_REMOVED_FOR_ALL_USERS, removedForAllUsers);
12357            if (removedPackage != null) {
12358                sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED, removedPackage,
12359                        extras, null, null, removedUsers);
12360                if (fullRemove && !replacing) {
12361                    sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED, removedPackage,
12362                            extras, null, null, removedUsers);
12363                }
12364            }
12365            if (removedAppId >= 0) {
12366                sendPackageBroadcast(Intent.ACTION_UID_REMOVED, null, extras, null, null,
12367                        removedUsers);
12368            }
12369        }
12370    }
12371
12372    /*
12373     * This method deletes the package from internal data structures. If the DONT_DELETE_DATA
12374     * flag is not set, the data directory is removed as well.
12375     * make sure this flag is set for partially installed apps. If not its meaningless to
12376     * delete a partially installed application.
12377     */
12378    private void removePackageDataLI(PackageSetting ps,
12379            int[] allUserHandles, boolean[] perUserInstalled,
12380            PackageRemovedInfo outInfo, int flags, boolean writeSettings) {
12381        String packageName = ps.name;
12382        if (DEBUG_REMOVE) Slog.d(TAG, "removePackageDataLI: " + ps);
12383        removePackageLI(ps, (flags&REMOVE_CHATTY) != 0);
12384        // Retrieve object to delete permissions for shared user later on
12385        final PackageSetting deletedPs;
12386        // reader
12387        synchronized (mPackages) {
12388            deletedPs = mSettings.mPackages.get(packageName);
12389            if (outInfo != null) {
12390                outInfo.removedPackage = packageName;
12391                outInfo.removedUsers = deletedPs != null
12392                        ? deletedPs.queryInstalledUsers(sUserManager.getUserIds(), true)
12393                        : null;
12394            }
12395        }
12396        if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) {
12397            removeDataDirsLI(ps.volumeUuid, packageName);
12398            schedulePackageCleaning(packageName, UserHandle.USER_ALL, true);
12399        }
12400        // writer
12401        synchronized (mPackages) {
12402            if (deletedPs != null) {
12403                if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) {
12404                    clearIntentFilterVerificationsLPw(deletedPs.name, UserHandle.USER_ALL);
12405                    clearDefaultBrowserIfNeeded(packageName);
12406                    if (outInfo != null) {
12407                        mSettings.mKeySetManagerService.removeAppKeySetDataLPw(packageName);
12408                        outInfo.removedAppId = mSettings.removePackageLPw(packageName);
12409                    }
12410                    updatePermissionsLPw(deletedPs.name, null, 0);
12411                    if (deletedPs.sharedUser != null) {
12412                        // Remove permissions associated with package. Since runtime
12413                        // permissions are per user we have to kill the removed package
12414                        // or packages running under the shared user of the removed
12415                        // package if revoking the permissions requested only by the removed
12416                        // package is successful and this causes a change in gids.
12417                        for (int userId : UserManagerService.getInstance().getUserIds()) {
12418                            final int userIdToKill = mSettings.updateSharedUserPermsLPw(deletedPs,
12419                                    userId);
12420                            if (userIdToKill == UserHandle.USER_ALL
12421                                    || userIdToKill >= UserHandle.USER_OWNER) {
12422                                // If gids changed for this user, kill all affected packages.
12423                                mHandler.post(new Runnable() {
12424                                    @Override
12425                                    public void run() {
12426                                        // This has to happen with no lock held.
12427                                        killSettingPackagesForUser(deletedPs, userIdToKill,
12428                                                KILL_APP_REASON_GIDS_CHANGED);
12429                                    }
12430                                });
12431                            break;
12432                            }
12433                        }
12434                    }
12435                    clearPackagePreferredActivitiesLPw(deletedPs.name, UserHandle.USER_ALL);
12436                }
12437                // make sure to preserve per-user disabled state if this removal was just
12438                // a downgrade of a system app to the factory package
12439                if (allUserHandles != null && perUserInstalled != null) {
12440                    if (DEBUG_REMOVE) {
12441                        Slog.d(TAG, "Propagating install state across downgrade");
12442                    }
12443                    for (int i = 0; i < allUserHandles.length; i++) {
12444                        if (DEBUG_REMOVE) {
12445                            Slog.d(TAG, "    user " + allUserHandles[i]
12446                                    + " => " + perUserInstalled[i]);
12447                        }
12448                        ps.setInstalled(perUserInstalled[i], allUserHandles[i]);
12449                    }
12450                }
12451            }
12452            // can downgrade to reader
12453            if (writeSettings) {
12454                // Save settings now
12455                mSettings.writeLPr();
12456            }
12457        }
12458        if (outInfo != null) {
12459            // A user ID was deleted here. Go through all users and remove it
12460            // from KeyStore.
12461            removeKeystoreDataIfNeeded(UserHandle.USER_ALL, outInfo.removedAppId);
12462        }
12463    }
12464
12465    static boolean locationIsPrivileged(File path) {
12466        try {
12467            final String privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app")
12468                    .getCanonicalPath();
12469            return path.getCanonicalPath().startsWith(privilegedAppDir);
12470        } catch (IOException e) {
12471            Slog.e(TAG, "Unable to access code path " + path);
12472        }
12473        return false;
12474    }
12475
12476    /*
12477     * Tries to delete system package.
12478     */
12479    private boolean deleteSystemPackageLI(PackageSetting newPs,
12480            int[] allUserHandles, boolean[] perUserInstalled,
12481            int flags, PackageRemovedInfo outInfo, boolean writeSettings) {
12482        final boolean applyUserRestrictions
12483                = (allUserHandles != null) && (perUserInstalled != null);
12484        PackageSetting disabledPs = null;
12485        // Confirm if the system package has been updated
12486        // An updated system app can be deleted. This will also have to restore
12487        // the system pkg from system partition
12488        // reader
12489        synchronized (mPackages) {
12490            disabledPs = mSettings.getDisabledSystemPkgLPr(newPs.name);
12491        }
12492        if (DEBUG_REMOVE) Slog.d(TAG, "deleteSystemPackageLI: newPs=" + newPs
12493                + " disabledPs=" + disabledPs);
12494        if (disabledPs == null) {
12495            Slog.w(TAG, "Attempt to delete unknown system package "+ newPs.name);
12496            return false;
12497        } else if (DEBUG_REMOVE) {
12498            Slog.d(TAG, "Deleting system pkg from data partition");
12499        }
12500        if (DEBUG_REMOVE) {
12501            if (applyUserRestrictions) {
12502                Slog.d(TAG, "Remembering install states:");
12503                for (int i = 0; i < allUserHandles.length; i++) {
12504                    Slog.d(TAG, "   u=" + allUserHandles[i] + " inst=" + perUserInstalled[i]);
12505                }
12506            }
12507        }
12508        // Delete the updated package
12509        outInfo.isRemovedPackageSystemUpdate = true;
12510        if (disabledPs.versionCode < newPs.versionCode) {
12511            // Delete data for downgrades
12512            flags &= ~PackageManager.DELETE_KEEP_DATA;
12513        } else {
12514            // Preserve data by setting flag
12515            flags |= PackageManager.DELETE_KEEP_DATA;
12516        }
12517        boolean ret = deleteInstalledPackageLI(newPs, true, flags,
12518                allUserHandles, perUserInstalled, outInfo, writeSettings);
12519        if (!ret) {
12520            return false;
12521        }
12522        // writer
12523        synchronized (mPackages) {
12524            // Reinstate the old system package
12525            mSettings.enableSystemPackageLPw(newPs.name);
12526            // Remove any native libraries from the upgraded package.
12527            NativeLibraryHelper.removeNativeBinariesLI(newPs.legacyNativeLibraryPathString);
12528        }
12529        // Install the system package
12530        if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs);
12531        int parseFlags = PackageParser.PARSE_MUST_BE_APK | PackageParser.PARSE_IS_SYSTEM;
12532        if (locationIsPrivileged(disabledPs.codePath)) {
12533            parseFlags |= PackageParser.PARSE_IS_PRIVILEGED;
12534        }
12535
12536        final PackageParser.Package newPkg;
12537        try {
12538            newPkg = scanPackageLI(disabledPs.codePath, parseFlags, SCAN_NO_PATHS, 0, null);
12539        } catch (PackageManagerException e) {
12540            Slog.w(TAG, "Failed to restore system package:" + newPs.name + ": " + e.getMessage());
12541            return false;
12542        }
12543
12544        // writer
12545        synchronized (mPackages) {
12546            PackageSetting ps = mSettings.mPackages.get(newPkg.packageName);
12547            updatePermissionsLPw(newPkg.packageName, newPkg,
12548                    UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG);
12549            if (applyUserRestrictions) {
12550                if (DEBUG_REMOVE) {
12551                    Slog.d(TAG, "Propagating install state across reinstall");
12552                }
12553                for (int i = 0; i < allUserHandles.length; i++) {
12554                    if (DEBUG_REMOVE) {
12555                        Slog.d(TAG, "    user " + allUserHandles[i]
12556                                + " => " + perUserInstalled[i]);
12557                    }
12558                    ps.setInstalled(perUserInstalled[i], allUserHandles[i]);
12559                }
12560                // Regardless of writeSettings we need to ensure that this restriction
12561                // state propagation is persisted
12562                mSettings.writeAllUsersPackageRestrictionsLPr();
12563            }
12564            // can downgrade to reader here
12565            if (writeSettings) {
12566                mSettings.writeLPr();
12567            }
12568        }
12569        return true;
12570    }
12571
12572    private boolean deleteInstalledPackageLI(PackageSetting ps,
12573            boolean deleteCodeAndResources, int flags,
12574            int[] allUserHandles, boolean[] perUserInstalled,
12575            PackageRemovedInfo outInfo, boolean writeSettings) {
12576        if (outInfo != null) {
12577            outInfo.uid = ps.appId;
12578        }
12579
12580        // Delete package data from internal structures and also remove data if flag is set
12581        removePackageDataLI(ps, allUserHandles, perUserInstalled, outInfo, flags, writeSettings);
12582
12583        // Delete application code and resources
12584        if (deleteCodeAndResources && (outInfo != null)) {
12585            outInfo.args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
12586                    ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
12587            if (DEBUG_SD_INSTALL) Slog.i(TAG, "args=" + outInfo.args);
12588        }
12589        return true;
12590    }
12591
12592    @Override
12593    public boolean setBlockUninstallForUser(String packageName, boolean blockUninstall,
12594            int userId) {
12595        mContext.enforceCallingOrSelfPermission(
12596                android.Manifest.permission.DELETE_PACKAGES, null);
12597        synchronized (mPackages) {
12598            PackageSetting ps = mSettings.mPackages.get(packageName);
12599            if (ps == null) {
12600                Log.i(TAG, "Package doesn't exist in set block uninstall " + packageName);
12601                return false;
12602            }
12603            if (!ps.getInstalled(userId)) {
12604                // Can't block uninstall for an app that is not installed or enabled.
12605                Log.i(TAG, "Package not installed in set block uninstall " + packageName);
12606                return false;
12607            }
12608            ps.setBlockUninstall(blockUninstall, userId);
12609            mSettings.writePackageRestrictionsLPr(userId);
12610        }
12611        return true;
12612    }
12613
12614    @Override
12615    public boolean getBlockUninstallForUser(String packageName, int userId) {
12616        synchronized (mPackages) {
12617            PackageSetting ps = mSettings.mPackages.get(packageName);
12618            if (ps == null) {
12619                Log.i(TAG, "Package doesn't exist in get block uninstall " + packageName);
12620                return false;
12621            }
12622            return ps.getBlockUninstall(userId);
12623        }
12624    }
12625
12626    /*
12627     * This method handles package deletion in general
12628     */
12629    private boolean deletePackageLI(String packageName, UserHandle user,
12630            boolean deleteCodeAndResources, int[] allUserHandles, boolean[] perUserInstalled,
12631            int flags, PackageRemovedInfo outInfo,
12632            boolean writeSettings) {
12633        if (packageName == null) {
12634            Slog.w(TAG, "Attempt to delete null packageName.");
12635            return false;
12636        }
12637        if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: " + packageName + " user " + user);
12638        PackageSetting ps;
12639        boolean dataOnly = false;
12640        int removeUser = -1;
12641        int appId = -1;
12642        synchronized (mPackages) {
12643            ps = mSettings.mPackages.get(packageName);
12644            if (ps == null) {
12645                Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
12646                return false;
12647            }
12648            if ((!isSystemApp(ps) || (flags&PackageManager.DELETE_SYSTEM_APP) != 0) && user != null
12649                    && user.getIdentifier() != UserHandle.USER_ALL) {
12650                // The caller is asking that the package only be deleted for a single
12651                // user.  To do this, we just mark its uninstalled state and delete
12652                // its data.  If this is a system app, we only allow this to happen if
12653                // they have set the special DELETE_SYSTEM_APP which requests different
12654                // semantics than normal for uninstalling system apps.
12655                if (DEBUG_REMOVE) Slog.d(TAG, "Only deleting for single user");
12656                ps.setUserState(user.getIdentifier(),
12657                        COMPONENT_ENABLED_STATE_DEFAULT,
12658                        false, //installed
12659                        true,  //stopped
12660                        true,  //notLaunched
12661                        false, //hidden
12662                        null, null, null,
12663                        false, // blockUninstall
12664                        INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED);
12665                if (!isSystemApp(ps)) {
12666                    if (ps.isAnyInstalled(sUserManager.getUserIds())) {
12667                        // Other user still have this package installed, so all
12668                        // we need to do is clear this user's data and save that
12669                        // it is uninstalled.
12670                        if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users");
12671                        removeUser = user.getIdentifier();
12672                        appId = ps.appId;
12673                        scheduleWritePackageRestrictionsLocked(removeUser);
12674                    } else {
12675                        // We need to set it back to 'installed' so the uninstall
12676                        // broadcasts will be sent correctly.
12677                        if (DEBUG_REMOVE) Slog.d(TAG, "Not installed by other users, full delete");
12678                        ps.setInstalled(true, user.getIdentifier());
12679                    }
12680                } else {
12681                    // This is a system app, so we assume that the
12682                    // other users still have this package installed, so all
12683                    // we need to do is clear this user's data and save that
12684                    // it is uninstalled.
12685                    if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app");
12686                    removeUser = user.getIdentifier();
12687                    appId = ps.appId;
12688                    scheduleWritePackageRestrictionsLocked(removeUser);
12689                }
12690            }
12691        }
12692
12693        if (removeUser >= 0) {
12694            // From above, we determined that we are deleting this only
12695            // for a single user.  Continue the work here.
12696            if (DEBUG_REMOVE) Slog.d(TAG, "Updating install state for user: " + removeUser);
12697            if (outInfo != null) {
12698                outInfo.removedPackage = packageName;
12699                outInfo.removedAppId = appId;
12700                outInfo.removedUsers = new int[] {removeUser};
12701            }
12702            mInstaller.clearUserData(ps.volumeUuid, packageName, removeUser);
12703            removeKeystoreDataIfNeeded(removeUser, appId);
12704            schedulePackageCleaning(packageName, removeUser, false);
12705            synchronized (mPackages) {
12706                if (clearPackagePreferredActivitiesLPw(packageName, removeUser)) {
12707                    scheduleWritePackageRestrictionsLocked(removeUser);
12708                }
12709                revokeRuntimePermissionsAndClearAllFlagsLocked(ps.getPermissionsState(),
12710                        removeUser);
12711            }
12712            return true;
12713        }
12714
12715        if (dataOnly) {
12716            // Delete application data first
12717            if (DEBUG_REMOVE) Slog.d(TAG, "Removing package data only");
12718            removePackageDataLI(ps, null, null, outInfo, flags, writeSettings);
12719            return true;
12720        }
12721
12722        boolean ret = false;
12723        if (isSystemApp(ps)) {
12724            if (DEBUG_REMOVE) Slog.d(TAG, "Removing system package:" + ps.name);
12725            // When an updated system application is deleted we delete the existing resources as well and
12726            // fall back to existing code in system partition
12727            ret = deleteSystemPackageLI(ps, allUserHandles, perUserInstalled,
12728                    flags, outInfo, writeSettings);
12729        } else {
12730            if (DEBUG_REMOVE) Slog.d(TAG, "Removing non-system package:" + ps.name);
12731            // Kill application pre-emptively especially for apps on sd.
12732            killApplication(packageName, ps.appId, "uninstall pkg");
12733            ret = deleteInstalledPackageLI(ps, deleteCodeAndResources, flags,
12734                    allUserHandles, perUserInstalled,
12735                    outInfo, writeSettings);
12736        }
12737
12738        return ret;
12739    }
12740
12741    private final class ClearStorageConnection implements ServiceConnection {
12742        IMediaContainerService mContainerService;
12743
12744        @Override
12745        public void onServiceConnected(ComponentName name, IBinder service) {
12746            synchronized (this) {
12747                mContainerService = IMediaContainerService.Stub.asInterface(service);
12748                notifyAll();
12749            }
12750        }
12751
12752        @Override
12753        public void onServiceDisconnected(ComponentName name) {
12754        }
12755    }
12756
12757    private void clearExternalStorageDataSync(String packageName, int userId, boolean allData) {
12758        final boolean mounted;
12759        if (Environment.isExternalStorageEmulated()) {
12760            mounted = true;
12761        } else {
12762            final String status = Environment.getExternalStorageState();
12763
12764            mounted = status.equals(Environment.MEDIA_MOUNTED)
12765                    || status.equals(Environment.MEDIA_MOUNTED_READ_ONLY);
12766        }
12767
12768        if (!mounted) {
12769            return;
12770        }
12771
12772        final Intent containerIntent = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
12773        int[] users;
12774        if (userId == UserHandle.USER_ALL) {
12775            users = sUserManager.getUserIds();
12776        } else {
12777            users = new int[] { userId };
12778        }
12779        final ClearStorageConnection conn = new ClearStorageConnection();
12780        if (mContext.bindServiceAsUser(
12781                containerIntent, conn, Context.BIND_AUTO_CREATE, UserHandle.OWNER)) {
12782            try {
12783                for (int curUser : users) {
12784                    long timeout = SystemClock.uptimeMillis() + 5000;
12785                    synchronized (conn) {
12786                        long now = SystemClock.uptimeMillis();
12787                        while (conn.mContainerService == null && now < timeout) {
12788                            try {
12789                                conn.wait(timeout - now);
12790                            } catch (InterruptedException e) {
12791                            }
12792                        }
12793                    }
12794                    if (conn.mContainerService == null) {
12795                        return;
12796                    }
12797
12798                    final UserEnvironment userEnv = new UserEnvironment(curUser);
12799                    clearDirectory(conn.mContainerService,
12800                            userEnv.buildExternalStorageAppCacheDirs(packageName));
12801                    if (allData) {
12802                        clearDirectory(conn.mContainerService,
12803                                userEnv.buildExternalStorageAppDataDirs(packageName));
12804                        clearDirectory(conn.mContainerService,
12805                                userEnv.buildExternalStorageAppMediaDirs(packageName));
12806                    }
12807                }
12808            } finally {
12809                mContext.unbindService(conn);
12810            }
12811        }
12812    }
12813
12814    @Override
12815    public void clearApplicationUserData(final String packageName,
12816            final IPackageDataObserver observer, final int userId) {
12817        mContext.enforceCallingOrSelfPermission(
12818                android.Manifest.permission.CLEAR_APP_USER_DATA, null);
12819        enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, "clear application data");
12820        // Queue up an async operation since the package deletion may take a little while.
12821        mHandler.post(new Runnable() {
12822            public void run() {
12823                mHandler.removeCallbacks(this);
12824                final boolean succeeded;
12825                synchronized (mInstallLock) {
12826                    succeeded = clearApplicationUserDataLI(packageName, userId);
12827                }
12828                clearExternalStorageDataSync(packageName, userId, true);
12829                if (succeeded) {
12830                    // invoke DeviceStorageMonitor's update method to clear any notifications
12831                    DeviceStorageMonitorInternal
12832                            dsm = LocalServices.getService(DeviceStorageMonitorInternal.class);
12833                    if (dsm != null) {
12834                        dsm.checkMemory();
12835                    }
12836                }
12837                if(observer != null) {
12838                    try {
12839                        observer.onRemoveCompleted(packageName, succeeded);
12840                    } catch (RemoteException e) {
12841                        Log.i(TAG, "Observer no longer exists.");
12842                    }
12843                } //end if observer
12844            } //end run
12845        });
12846    }
12847
12848    private boolean clearApplicationUserDataLI(String packageName, int userId) {
12849        if (packageName == null) {
12850            Slog.w(TAG, "Attempt to delete null packageName.");
12851            return false;
12852        }
12853
12854        // Try finding details about the requested package
12855        PackageParser.Package pkg;
12856        synchronized (mPackages) {
12857            pkg = mPackages.get(packageName);
12858            if (pkg == null) {
12859                final PackageSetting ps = mSettings.mPackages.get(packageName);
12860                if (ps != null) {
12861                    pkg = ps.pkg;
12862                }
12863            }
12864
12865            if (pkg == null) {
12866                Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
12867                return false;
12868            }
12869
12870            PackageSetting ps = (PackageSetting) pkg.mExtras;
12871            PermissionsState permissionsState = ps.getPermissionsState();
12872            revokeRuntimePermissionsAndClearUserSetFlagsLocked(permissionsState, userId);
12873        }
12874
12875        // Always delete data directories for package, even if we found no other
12876        // record of app. This helps users recover from UID mismatches without
12877        // resorting to a full data wipe.
12878        int retCode = mInstaller.clearUserData(pkg.volumeUuid, packageName, userId);
12879        if (retCode < 0) {
12880            Slog.w(TAG, "Couldn't remove cache files for package: " + packageName);
12881            return false;
12882        }
12883
12884        final int appId = pkg.applicationInfo.uid;
12885        removeKeystoreDataIfNeeded(userId, appId);
12886
12887        // Create a native library symlink only if we have native libraries
12888        // and if the native libraries are 32 bit libraries. We do not provide
12889        // this symlink for 64 bit libraries.
12890        if (pkg.applicationInfo.primaryCpuAbi != null &&
12891                !VMRuntime.is64BitAbi(pkg.applicationInfo.primaryCpuAbi)) {
12892            final String nativeLibPath = pkg.applicationInfo.nativeLibraryDir;
12893            if (mInstaller.linkNativeLibraryDirectory(pkg.volumeUuid, pkg.packageName,
12894                    nativeLibPath, userId) < 0) {
12895                Slog.w(TAG, "Failed linking native library dir");
12896                return false;
12897            }
12898        }
12899
12900        return true;
12901    }
12902
12903
12904    /**
12905     * Revokes granted runtime permissions and clears resettable flags
12906     * which are flags that can be set by a user interaction.
12907     *
12908     * @param permissionsState The permission state to reset.
12909     * @param userId The device user for which to do a reset.
12910     */
12911    private void revokeRuntimePermissionsAndClearUserSetFlagsLocked(
12912            PermissionsState permissionsState, int userId) {
12913        final int userSetFlags = PackageManager.FLAG_PERMISSION_USER_SET
12914                | PackageManager.FLAG_PERMISSION_USER_FIXED
12915                | PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE;
12916
12917        revokeRuntimePermissionsAndClearFlagsLocked(permissionsState, userId, userSetFlags);
12918    }
12919
12920    /**
12921     * Revokes granted runtime permissions and clears all flags.
12922     *
12923     * @param permissionsState The permission state to reset.
12924     * @param userId The device user for which to do a reset.
12925     */
12926    private void revokeRuntimePermissionsAndClearAllFlagsLocked(
12927            PermissionsState permissionsState, int userId) {
12928        revokeRuntimePermissionsAndClearFlagsLocked(permissionsState, userId,
12929                PackageManager.MASK_PERMISSION_FLAGS);
12930    }
12931
12932    /**
12933     * Revokes granted runtime permissions and clears certain flags.
12934     *
12935     * @param permissionsState The permission state to reset.
12936     * @param userId The device user for which to do a reset.
12937     * @param flags The flags that is going to be reset.
12938     */
12939    private void revokeRuntimePermissionsAndClearFlagsLocked(
12940            PermissionsState permissionsState, int userId, int flags) {
12941        boolean needsWrite = false;
12942
12943        for (PermissionState state : permissionsState.getRuntimePermissionStates(userId)) {
12944            BasePermission bp = mSettings.mPermissions.get(state.getName());
12945            if (bp != null) {
12946                permissionsState.revokeRuntimePermission(bp, userId);
12947                permissionsState.updatePermissionFlags(bp, userId, flags, 0);
12948                needsWrite = true;
12949            }
12950        }
12951
12952        // Ensure default permissions are never cleared.
12953        mDefaultPermissionPolicy.grantDefaultPermissions(userId);
12954
12955        if (needsWrite) {
12956            mSettings.writeRuntimePermissionsForUserLPr(userId, true);
12957        }
12958    }
12959
12960    /**
12961     * Remove entries from the keystore daemon. Will only remove it if the
12962     * {@code appId} is valid.
12963     */
12964    private static void removeKeystoreDataIfNeeded(int userId, int appId) {
12965        if (appId < 0) {
12966            return;
12967        }
12968
12969        final KeyStore keyStore = KeyStore.getInstance();
12970        if (keyStore != null) {
12971            if (userId == UserHandle.USER_ALL) {
12972                for (final int individual : sUserManager.getUserIds()) {
12973                    keyStore.clearUid(UserHandle.getUid(individual, appId));
12974                }
12975            } else {
12976                keyStore.clearUid(UserHandle.getUid(userId, appId));
12977            }
12978        } else {
12979            Slog.w(TAG, "Could not contact keystore to clear entries for app id " + appId);
12980        }
12981    }
12982
12983    @Override
12984    public void deleteApplicationCacheFiles(final String packageName,
12985            final IPackageDataObserver observer) {
12986        mContext.enforceCallingOrSelfPermission(
12987                android.Manifest.permission.DELETE_CACHE_FILES, null);
12988        // Queue up an async operation since the package deletion may take a little while.
12989        final int userId = UserHandle.getCallingUserId();
12990        mHandler.post(new Runnable() {
12991            public void run() {
12992                mHandler.removeCallbacks(this);
12993                final boolean succeded;
12994                synchronized (mInstallLock) {
12995                    succeded = deleteApplicationCacheFilesLI(packageName, userId);
12996                }
12997                clearExternalStorageDataSync(packageName, userId, false);
12998                if (observer != null) {
12999                    try {
13000                        observer.onRemoveCompleted(packageName, succeded);
13001                    } catch (RemoteException e) {
13002                        Log.i(TAG, "Observer no longer exists.");
13003                    }
13004                } //end if observer
13005            } //end run
13006        });
13007    }
13008
13009    private boolean deleteApplicationCacheFilesLI(String packageName, int userId) {
13010        if (packageName == null) {
13011            Slog.w(TAG, "Attempt to delete null packageName.");
13012            return false;
13013        }
13014        PackageParser.Package p;
13015        synchronized (mPackages) {
13016            p = mPackages.get(packageName);
13017        }
13018        if (p == null) {
13019            Slog.w(TAG, "Package named '" + packageName +"' doesn't exist.");
13020            return false;
13021        }
13022        final ApplicationInfo applicationInfo = p.applicationInfo;
13023        if (applicationInfo == null) {
13024            Slog.w(TAG, "Package " + packageName + " has no applicationInfo.");
13025            return false;
13026        }
13027        int retCode = mInstaller.deleteCacheFiles(p.volumeUuid, packageName, userId);
13028        if (retCode < 0) {
13029            Slog.w(TAG, "Couldn't remove cache files for package: "
13030                       + packageName + " u" + userId);
13031            return false;
13032        }
13033        return true;
13034    }
13035
13036    @Override
13037    public void getPackageSizeInfo(final String packageName, int userHandle,
13038            final IPackageStatsObserver observer) {
13039        mContext.enforceCallingOrSelfPermission(
13040                android.Manifest.permission.GET_PACKAGE_SIZE, null);
13041        if (packageName == null) {
13042            throw new IllegalArgumentException("Attempt to get size of null packageName");
13043        }
13044
13045        PackageStats stats = new PackageStats(packageName, userHandle);
13046
13047        /*
13048         * Queue up an async operation since the package measurement may take a
13049         * little while.
13050         */
13051        Message msg = mHandler.obtainMessage(INIT_COPY);
13052        msg.obj = new MeasureParams(stats, observer);
13053        mHandler.sendMessage(msg);
13054    }
13055
13056    private boolean getPackageSizeInfoLI(String packageName, int userHandle,
13057            PackageStats pStats) {
13058        if (packageName == null) {
13059            Slog.w(TAG, "Attempt to get size of null packageName.");
13060            return false;
13061        }
13062        PackageParser.Package p;
13063        boolean dataOnly = false;
13064        String libDirRoot = null;
13065        String asecPath = null;
13066        PackageSetting ps = null;
13067        synchronized (mPackages) {
13068            p = mPackages.get(packageName);
13069            ps = mSettings.mPackages.get(packageName);
13070            if(p == null) {
13071                dataOnly = true;
13072                if((ps == null) || (ps.pkg == null)) {
13073                    Slog.w(TAG, "Package named '" + packageName +"' doesn't exist.");
13074                    return false;
13075                }
13076                p = ps.pkg;
13077            }
13078            if (ps != null) {
13079                libDirRoot = ps.legacyNativeLibraryPathString;
13080            }
13081            if (p != null && (isExternal(p) || p.isForwardLocked())) {
13082                String secureContainerId = cidFromCodePath(p.applicationInfo.getBaseCodePath());
13083                if (secureContainerId != null) {
13084                    asecPath = PackageHelper.getSdFilesystem(secureContainerId);
13085                }
13086            }
13087        }
13088        String publicSrcDir = null;
13089        if(!dataOnly) {
13090            final ApplicationInfo applicationInfo = p.applicationInfo;
13091            if (applicationInfo == null) {
13092                Slog.w(TAG, "Package " + packageName + " has no applicationInfo.");
13093                return false;
13094            }
13095            if (p.isForwardLocked()) {
13096                publicSrcDir = applicationInfo.getBaseResourcePath();
13097            }
13098        }
13099        // TODO: extend to measure size of split APKs
13100        // TODO(multiArch): Extend getSizeInfo to look at the full subdirectory tree,
13101        // not just the first level.
13102        // TODO(multiArch): Extend getSizeInfo to look at *all* instruction sets, not
13103        // just the primary.
13104        String[] dexCodeInstructionSets = getDexCodeInstructionSets(getAppDexInstructionSets(ps));
13105        int res = mInstaller.getSizeInfo(p.volumeUuid, packageName, userHandle, p.baseCodePath,
13106                libDirRoot, publicSrcDir, asecPath, dexCodeInstructionSets, pStats);
13107        if (res < 0) {
13108            return false;
13109        }
13110
13111        // Fix-up for forward-locked applications in ASEC containers.
13112        if (!isExternal(p)) {
13113            pStats.codeSize += pStats.externalCodeSize;
13114            pStats.externalCodeSize = 0L;
13115        }
13116
13117        return true;
13118    }
13119
13120
13121    @Override
13122    public void addPackageToPreferred(String packageName) {
13123        Slog.w(TAG, "addPackageToPreferred: this is now a no-op");
13124    }
13125
13126    @Override
13127    public void removePackageFromPreferred(String packageName) {
13128        Slog.w(TAG, "removePackageFromPreferred: this is now a no-op");
13129    }
13130
13131    @Override
13132    public List<PackageInfo> getPreferredPackages(int flags) {
13133        return new ArrayList<PackageInfo>();
13134    }
13135
13136    private int getUidTargetSdkVersionLockedLPr(int uid) {
13137        Object obj = mSettings.getUserIdLPr(uid);
13138        if (obj instanceof SharedUserSetting) {
13139            final SharedUserSetting sus = (SharedUserSetting) obj;
13140            int vers = Build.VERSION_CODES.CUR_DEVELOPMENT;
13141            final Iterator<PackageSetting> it = sus.packages.iterator();
13142            while (it.hasNext()) {
13143                final PackageSetting ps = it.next();
13144                if (ps.pkg != null) {
13145                    int v = ps.pkg.applicationInfo.targetSdkVersion;
13146                    if (v < vers) vers = v;
13147                }
13148            }
13149            return vers;
13150        } else if (obj instanceof PackageSetting) {
13151            final PackageSetting ps = (PackageSetting) obj;
13152            if (ps.pkg != null) {
13153                return ps.pkg.applicationInfo.targetSdkVersion;
13154            }
13155        }
13156        return Build.VERSION_CODES.CUR_DEVELOPMENT;
13157    }
13158
13159    @Override
13160    public void addPreferredActivity(IntentFilter filter, int match,
13161            ComponentName[] set, ComponentName activity, int userId) {
13162        addPreferredActivityInternal(filter, match, set, activity, true, userId,
13163                "Adding preferred");
13164    }
13165
13166    private void addPreferredActivityInternal(IntentFilter filter, int match,
13167            ComponentName[] set, ComponentName activity, boolean always, int userId,
13168            String opname) {
13169        // writer
13170        int callingUid = Binder.getCallingUid();
13171        enforceCrossUserPermission(callingUid, userId, true, false, "add preferred activity");
13172        if (filter.countActions() == 0) {
13173            Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
13174            return;
13175        }
13176        synchronized (mPackages) {
13177            if (mContext.checkCallingOrSelfPermission(
13178                    android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
13179                    != PackageManager.PERMISSION_GRANTED) {
13180                if (getUidTargetSdkVersionLockedLPr(callingUid)
13181                        < Build.VERSION_CODES.FROYO) {
13182                    Slog.w(TAG, "Ignoring addPreferredActivity() from uid "
13183                            + callingUid);
13184                    return;
13185                }
13186                mContext.enforceCallingOrSelfPermission(
13187                        android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
13188            }
13189
13190            PreferredIntentResolver pir = mSettings.editPreferredActivitiesLPw(userId);
13191            Slog.i(TAG, opname + " activity " + activity.flattenToShortString() + " for user "
13192                    + userId + ":");
13193            filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
13194            pir.addFilter(new PreferredActivity(filter, match, set, activity, always));
13195            scheduleWritePackageRestrictionsLocked(userId);
13196        }
13197    }
13198
13199    @Override
13200    public void replacePreferredActivity(IntentFilter filter, int match,
13201            ComponentName[] set, ComponentName activity, int userId) {
13202        if (filter.countActions() != 1) {
13203            throw new IllegalArgumentException(
13204                    "replacePreferredActivity expects filter to have only 1 action.");
13205        }
13206        if (filter.countDataAuthorities() != 0
13207                || filter.countDataPaths() != 0
13208                || filter.countDataSchemes() > 1
13209                || filter.countDataTypes() != 0) {
13210            throw new IllegalArgumentException(
13211                    "replacePreferredActivity expects filter to have no data authorities, " +
13212                    "paths, or types; and at most one scheme.");
13213        }
13214
13215        final int callingUid = Binder.getCallingUid();
13216        enforceCrossUserPermission(callingUid, userId, true, false, "replace preferred activity");
13217        synchronized (mPackages) {
13218            if (mContext.checkCallingOrSelfPermission(
13219                    android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
13220                    != PackageManager.PERMISSION_GRANTED) {
13221                if (getUidTargetSdkVersionLockedLPr(callingUid)
13222                        < Build.VERSION_CODES.FROYO) {
13223                    Slog.w(TAG, "Ignoring replacePreferredActivity() from uid "
13224                            + Binder.getCallingUid());
13225                    return;
13226                }
13227                mContext.enforceCallingOrSelfPermission(
13228                        android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
13229            }
13230
13231            PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
13232            if (pir != null) {
13233                // Get all of the existing entries that exactly match this filter.
13234                ArrayList<PreferredActivity> existing = pir.findFilters(filter);
13235                if (existing != null && existing.size() == 1) {
13236                    PreferredActivity cur = existing.get(0);
13237                    if (DEBUG_PREFERRED) {
13238                        Slog.i(TAG, "Checking replace of preferred:");
13239                        filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
13240                        if (!cur.mPref.mAlways) {
13241                            Slog.i(TAG, "  -- CUR; not mAlways!");
13242                        } else {
13243                            Slog.i(TAG, "  -- CUR: mMatch=" + cur.mPref.mMatch);
13244                            Slog.i(TAG, "  -- CUR: mSet="
13245                                    + Arrays.toString(cur.mPref.mSetComponents));
13246                            Slog.i(TAG, "  -- CUR: mComponent=" + cur.mPref.mShortComponent);
13247                            Slog.i(TAG, "  -- NEW: mMatch="
13248                                    + (match&IntentFilter.MATCH_CATEGORY_MASK));
13249                            Slog.i(TAG, "  -- CUR: mSet=" + Arrays.toString(set));
13250                            Slog.i(TAG, "  -- CUR: mComponent=" + activity.flattenToShortString());
13251                        }
13252                    }
13253                    if (cur.mPref.mAlways && cur.mPref.mComponent.equals(activity)
13254                            && cur.mPref.mMatch == (match&IntentFilter.MATCH_CATEGORY_MASK)
13255                            && cur.mPref.sameSet(set)) {
13256                        // Setting the preferred activity to what it happens to be already
13257                        if (DEBUG_PREFERRED) {
13258                            Slog.i(TAG, "Replacing with same preferred activity "
13259                                    + cur.mPref.mShortComponent + " for user "
13260                                    + userId + ":");
13261                            filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
13262                        }
13263                        return;
13264                    }
13265                }
13266
13267                if (existing != null) {
13268                    if (DEBUG_PREFERRED) {
13269                        Slog.i(TAG, existing.size() + " existing preferred matches for:");
13270                        filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
13271                    }
13272                    for (int i = 0; i < existing.size(); i++) {
13273                        PreferredActivity pa = existing.get(i);
13274                        if (DEBUG_PREFERRED) {
13275                            Slog.i(TAG, "Removing existing preferred activity "
13276                                    + pa.mPref.mComponent + ":");
13277                            pa.dump(new LogPrinter(Log.INFO, TAG), "  ");
13278                        }
13279                        pir.removeFilter(pa);
13280                    }
13281                }
13282            }
13283            addPreferredActivityInternal(filter, match, set, activity, true, userId,
13284                    "Replacing preferred");
13285        }
13286    }
13287
13288    @Override
13289    public void clearPackagePreferredActivities(String packageName) {
13290        final int uid = Binder.getCallingUid();
13291        // writer
13292        synchronized (mPackages) {
13293            PackageParser.Package pkg = mPackages.get(packageName);
13294            if (pkg == null || pkg.applicationInfo.uid != uid) {
13295                if (mContext.checkCallingOrSelfPermission(
13296                        android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
13297                        != PackageManager.PERMISSION_GRANTED) {
13298                    if (getUidTargetSdkVersionLockedLPr(Binder.getCallingUid())
13299                            < Build.VERSION_CODES.FROYO) {
13300                        Slog.w(TAG, "Ignoring clearPackagePreferredActivities() from uid "
13301                                + Binder.getCallingUid());
13302                        return;
13303                    }
13304                    mContext.enforceCallingOrSelfPermission(
13305                            android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
13306                }
13307            }
13308
13309            int user = UserHandle.getCallingUserId();
13310            if (clearPackagePreferredActivitiesLPw(packageName, user)) {
13311                scheduleWritePackageRestrictionsLocked(user);
13312            }
13313        }
13314    }
13315
13316    /** This method takes a specific user id as well as UserHandle.USER_ALL. */
13317    boolean clearPackagePreferredActivitiesLPw(String packageName, int userId) {
13318        ArrayList<PreferredActivity> removed = null;
13319        boolean changed = false;
13320        for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
13321            final int thisUserId = mSettings.mPreferredActivities.keyAt(i);
13322            PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
13323            if (userId != UserHandle.USER_ALL && userId != thisUserId) {
13324                continue;
13325            }
13326            Iterator<PreferredActivity> it = pir.filterIterator();
13327            while (it.hasNext()) {
13328                PreferredActivity pa = it.next();
13329                // Mark entry for removal only if it matches the package name
13330                // and the entry is of type "always".
13331                if (packageName == null ||
13332                        (pa.mPref.mComponent.getPackageName().equals(packageName)
13333                                && pa.mPref.mAlways)) {
13334                    if (removed == null) {
13335                        removed = new ArrayList<PreferredActivity>();
13336                    }
13337                    removed.add(pa);
13338                }
13339            }
13340            if (removed != null) {
13341                for (int j=0; j<removed.size(); j++) {
13342                    PreferredActivity pa = removed.get(j);
13343                    pir.removeFilter(pa);
13344                }
13345                changed = true;
13346            }
13347        }
13348        return changed;
13349    }
13350
13351    /** This method takes a specific user id as well as UserHandle.USER_ALL. */
13352    void clearIntentFilterVerificationsLPw(String packageName, int userId) {
13353        if (userId == UserHandle.USER_ALL) {
13354            if (mSettings.removeIntentFilterVerificationLPw(packageName,
13355                    sUserManager.getUserIds())) {
13356                for (int oneUserId : sUserManager.getUserIds()) {
13357                    scheduleWritePackageRestrictionsLocked(oneUserId);
13358                }
13359            }
13360        } else {
13361            if (mSettings.removeIntentFilterVerificationLPw(packageName, userId)) {
13362                scheduleWritePackageRestrictionsLocked(userId);
13363            }
13364        }
13365    }
13366
13367
13368    void clearDefaultBrowserIfNeeded(String packageName) {
13369        for (int oneUserId : sUserManager.getUserIds()) {
13370            String defaultBrowserPackageName = getDefaultBrowserPackageName(oneUserId);
13371            if (TextUtils.isEmpty(defaultBrowserPackageName)) continue;
13372            if (packageName.equals(defaultBrowserPackageName)) {
13373                setDefaultBrowserPackageName(null, oneUserId);
13374            }
13375        }
13376    }
13377
13378    @Override
13379    public void resetPreferredActivities(int userId) {
13380        /* TODO: Actually use userId. Why is it being passed in? */
13381        mContext.enforceCallingOrSelfPermission(
13382                android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
13383        // writer
13384        synchronized (mPackages) {
13385            int user = UserHandle.getCallingUserId();
13386            clearPackagePreferredActivitiesLPw(null, user);
13387            mSettings.readDefaultPreferredAppsLPw(this, user);
13388            scheduleWritePackageRestrictionsLocked(user);
13389        }
13390    }
13391
13392    @Override
13393    public int getPreferredActivities(List<IntentFilter> outFilters,
13394            List<ComponentName> outActivities, String packageName) {
13395
13396        int num = 0;
13397        final int userId = UserHandle.getCallingUserId();
13398        // reader
13399        synchronized (mPackages) {
13400            PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
13401            if (pir != null) {
13402                final Iterator<PreferredActivity> it = pir.filterIterator();
13403                while (it.hasNext()) {
13404                    final PreferredActivity pa = it.next();
13405                    if (packageName == null
13406                            || (pa.mPref.mComponent.getPackageName().equals(packageName)
13407                                    && pa.mPref.mAlways)) {
13408                        if (outFilters != null) {
13409                            outFilters.add(new IntentFilter(pa));
13410                        }
13411                        if (outActivities != null) {
13412                            outActivities.add(pa.mPref.mComponent);
13413                        }
13414                    }
13415                }
13416            }
13417        }
13418
13419        return num;
13420    }
13421
13422    @Override
13423    public void addPersistentPreferredActivity(IntentFilter filter, ComponentName activity,
13424            int userId) {
13425        int callingUid = Binder.getCallingUid();
13426        if (callingUid != Process.SYSTEM_UID) {
13427            throw new SecurityException(
13428                    "addPersistentPreferredActivity can only be run by the system");
13429        }
13430        if (filter.countActions() == 0) {
13431            Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
13432            return;
13433        }
13434        synchronized (mPackages) {
13435            Slog.i(TAG, "Adding persistent preferred activity " + activity + " for user " + userId +
13436                    " :");
13437            filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
13438            mSettings.editPersistentPreferredActivitiesLPw(userId).addFilter(
13439                    new PersistentPreferredActivity(filter, activity));
13440            scheduleWritePackageRestrictionsLocked(userId);
13441        }
13442    }
13443
13444    @Override
13445    public void clearPackagePersistentPreferredActivities(String packageName, int userId) {
13446        int callingUid = Binder.getCallingUid();
13447        if (callingUid != Process.SYSTEM_UID) {
13448            throw new SecurityException(
13449                    "clearPackagePersistentPreferredActivities can only be run by the system");
13450        }
13451        ArrayList<PersistentPreferredActivity> removed = null;
13452        boolean changed = false;
13453        synchronized (mPackages) {
13454            for (int i=0; i<mSettings.mPersistentPreferredActivities.size(); i++) {
13455                final int thisUserId = mSettings.mPersistentPreferredActivities.keyAt(i);
13456                PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
13457                        .valueAt(i);
13458                if (userId != thisUserId) {
13459                    continue;
13460                }
13461                Iterator<PersistentPreferredActivity> it = ppir.filterIterator();
13462                while (it.hasNext()) {
13463                    PersistentPreferredActivity ppa = it.next();
13464                    // Mark entry for removal only if it matches the package name.
13465                    if (ppa.mComponent.getPackageName().equals(packageName)) {
13466                        if (removed == null) {
13467                            removed = new ArrayList<PersistentPreferredActivity>();
13468                        }
13469                        removed.add(ppa);
13470                    }
13471                }
13472                if (removed != null) {
13473                    for (int j=0; j<removed.size(); j++) {
13474                        PersistentPreferredActivity ppa = removed.get(j);
13475                        ppir.removeFilter(ppa);
13476                    }
13477                    changed = true;
13478                }
13479            }
13480
13481            if (changed) {
13482                scheduleWritePackageRestrictionsLocked(userId);
13483            }
13484        }
13485    }
13486
13487    /**
13488     * Common machinery for picking apart a restored XML blob and passing
13489     * it to a caller-supplied functor to be applied to the running system.
13490     */
13491    private void restoreFromXml(XmlPullParser parser, int userId,
13492            String expectedStartTag, BlobXmlRestorer functor)
13493            throws IOException, XmlPullParserException {
13494        int type;
13495        while ((type = parser.next()) != XmlPullParser.START_TAG
13496                && type != XmlPullParser.END_DOCUMENT) {
13497        }
13498        if (type != XmlPullParser.START_TAG) {
13499            // oops didn't find a start tag?!
13500            if (DEBUG_BACKUP) {
13501                Slog.e(TAG, "Didn't find start tag during restore");
13502            }
13503            return;
13504        }
13505
13506        // this is supposed to be TAG_PREFERRED_BACKUP
13507        if (!expectedStartTag.equals(parser.getName())) {
13508            if (DEBUG_BACKUP) {
13509                Slog.e(TAG, "Found unexpected tag " + parser.getName());
13510            }
13511            return;
13512        }
13513
13514        // skip interfering stuff, then we're aligned with the backing implementation
13515        while ((type = parser.next()) == XmlPullParser.TEXT) { }
13516        functor.apply(parser, userId);
13517    }
13518
13519    private interface BlobXmlRestorer {
13520        public void apply(XmlPullParser parser, int userId) throws IOException, XmlPullParserException;
13521    }
13522
13523    /**
13524     * Non-Binder method, support for the backup/restore mechanism: write the
13525     * full set of preferred activities in its canonical XML format.  Returns the
13526     * XML output as a byte array, or null if there is none.
13527     */
13528    @Override
13529    public byte[] getPreferredActivityBackup(int userId) {
13530        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
13531            throw new SecurityException("Only the system may call getPreferredActivityBackup()");
13532        }
13533
13534        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
13535        try {
13536            final XmlSerializer serializer = new FastXmlSerializer();
13537            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
13538            serializer.startDocument(null, true);
13539            serializer.startTag(null, TAG_PREFERRED_BACKUP);
13540
13541            synchronized (mPackages) {
13542                mSettings.writePreferredActivitiesLPr(serializer, userId, true);
13543            }
13544
13545            serializer.endTag(null, TAG_PREFERRED_BACKUP);
13546            serializer.endDocument();
13547            serializer.flush();
13548        } catch (Exception e) {
13549            if (DEBUG_BACKUP) {
13550                Slog.e(TAG, "Unable to write preferred activities for backup", e);
13551            }
13552            return null;
13553        }
13554
13555        return dataStream.toByteArray();
13556    }
13557
13558    @Override
13559    public void restorePreferredActivities(byte[] backup, int userId) {
13560        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
13561            throw new SecurityException("Only the system may call restorePreferredActivities()");
13562        }
13563
13564        try {
13565            final XmlPullParser parser = Xml.newPullParser();
13566            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
13567            restoreFromXml(parser, userId, TAG_PREFERRED_BACKUP,
13568                    new BlobXmlRestorer() {
13569                        @Override
13570                        public void apply(XmlPullParser parser, int userId)
13571                                throws XmlPullParserException, IOException {
13572                            synchronized (mPackages) {
13573                                mSettings.readPreferredActivitiesLPw(parser, userId);
13574                            }
13575                        }
13576                    } );
13577        } catch (Exception e) {
13578            if (DEBUG_BACKUP) {
13579                Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
13580            }
13581        }
13582    }
13583
13584    /**
13585     * Non-Binder method, support for the backup/restore mechanism: write the
13586     * default browser (etc) settings in its canonical XML format.  Returns the default
13587     * browser XML representation as a byte array, or null if there is none.
13588     */
13589    @Override
13590    public byte[] getDefaultAppsBackup(int userId) {
13591        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
13592            throw new SecurityException("Only the system may call getDefaultAppsBackup()");
13593        }
13594
13595        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
13596        try {
13597            final XmlSerializer serializer = new FastXmlSerializer();
13598            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
13599            serializer.startDocument(null, true);
13600            serializer.startTag(null, TAG_DEFAULT_APPS);
13601
13602            synchronized (mPackages) {
13603                mSettings.writeDefaultAppsLPr(serializer, userId);
13604            }
13605
13606            serializer.endTag(null, TAG_DEFAULT_APPS);
13607            serializer.endDocument();
13608            serializer.flush();
13609        } catch (Exception e) {
13610            if (DEBUG_BACKUP) {
13611                Slog.e(TAG, "Unable to write default apps for backup", e);
13612            }
13613            return null;
13614        }
13615
13616        return dataStream.toByteArray();
13617    }
13618
13619    @Override
13620    public void restoreDefaultApps(byte[] backup, int userId) {
13621        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
13622            throw new SecurityException("Only the system may call restoreDefaultApps()");
13623        }
13624
13625        try {
13626            final XmlPullParser parser = Xml.newPullParser();
13627            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
13628            restoreFromXml(parser, userId, TAG_DEFAULT_APPS,
13629                    new BlobXmlRestorer() {
13630                        @Override
13631                        public void apply(XmlPullParser parser, int userId)
13632                                throws XmlPullParserException, IOException {
13633                            synchronized (mPackages) {
13634                                mSettings.readDefaultAppsLPw(parser, userId);
13635                            }
13636                        }
13637                    } );
13638        } catch (Exception e) {
13639            if (DEBUG_BACKUP) {
13640                Slog.e(TAG, "Exception restoring default apps: " + e.getMessage());
13641            }
13642        }
13643    }
13644
13645    @Override
13646    public byte[] getIntentFilterVerificationBackup(int userId) {
13647        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
13648            throw new SecurityException("Only the system may call getIntentFilterVerificationBackup()");
13649        }
13650
13651        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
13652        try {
13653            final XmlSerializer serializer = new FastXmlSerializer();
13654            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
13655            serializer.startDocument(null, true);
13656            serializer.startTag(null, TAG_INTENT_FILTER_VERIFICATION);
13657
13658            synchronized (mPackages) {
13659                mSettings.writeAllDomainVerificationsLPr(serializer, userId);
13660            }
13661
13662            serializer.endTag(null, TAG_INTENT_FILTER_VERIFICATION);
13663            serializer.endDocument();
13664            serializer.flush();
13665        } catch (Exception e) {
13666            if (DEBUG_BACKUP) {
13667                Slog.e(TAG, "Unable to write default apps for backup", e);
13668            }
13669            return null;
13670        }
13671
13672        return dataStream.toByteArray();
13673    }
13674
13675    @Override
13676    public void restoreIntentFilterVerification(byte[] backup, int userId) {
13677        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
13678            throw new SecurityException("Only the system may call restorePreferredActivities()");
13679        }
13680
13681        try {
13682            final XmlPullParser parser = Xml.newPullParser();
13683            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
13684            restoreFromXml(parser, userId, TAG_INTENT_FILTER_VERIFICATION,
13685                    new BlobXmlRestorer() {
13686                        @Override
13687                        public void apply(XmlPullParser parser, int userId)
13688                                throws XmlPullParserException, IOException {
13689                            synchronized (mPackages) {
13690                                mSettings.readAllDomainVerificationsLPr(parser, userId);
13691                                mSettings.writeLPr();
13692                            }
13693                        }
13694                    } );
13695        } catch (Exception e) {
13696            if (DEBUG_BACKUP) {
13697                Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
13698            }
13699        }
13700    }
13701
13702    @Override
13703    public void addCrossProfileIntentFilter(IntentFilter intentFilter, String ownerPackage,
13704            int sourceUserId, int targetUserId, int flags) {
13705        mContext.enforceCallingOrSelfPermission(
13706                        android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
13707        int callingUid = Binder.getCallingUid();
13708        enforceOwnerRights(ownerPackage, callingUid);
13709        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
13710        if (intentFilter.countActions() == 0) {
13711            Slog.w(TAG, "Cannot set a crossProfile intent filter with no filter actions");
13712            return;
13713        }
13714        synchronized (mPackages) {
13715            CrossProfileIntentFilter newFilter = new CrossProfileIntentFilter(intentFilter,
13716                    ownerPackage, targetUserId, flags);
13717            CrossProfileIntentResolver resolver =
13718                    mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
13719            ArrayList<CrossProfileIntentFilter> existing = resolver.findFilters(intentFilter);
13720            // We have all those whose filter is equal. Now checking if the rest is equal as well.
13721            if (existing != null) {
13722                int size = existing.size();
13723                for (int i = 0; i < size; i++) {
13724                    if (newFilter.equalsIgnoreFilter(existing.get(i))) {
13725                        return;
13726                    }
13727                }
13728            }
13729            resolver.addFilter(newFilter);
13730            scheduleWritePackageRestrictionsLocked(sourceUserId);
13731        }
13732    }
13733
13734    @Override
13735    public void clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage) {
13736        mContext.enforceCallingOrSelfPermission(
13737                        android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
13738        int callingUid = Binder.getCallingUid();
13739        enforceOwnerRights(ownerPackage, callingUid);
13740        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
13741        synchronized (mPackages) {
13742            CrossProfileIntentResolver resolver =
13743                    mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
13744            ArraySet<CrossProfileIntentFilter> set =
13745                    new ArraySet<CrossProfileIntentFilter>(resolver.filterSet());
13746            for (CrossProfileIntentFilter filter : set) {
13747                if (filter.getOwnerPackage().equals(ownerPackage)) {
13748                    resolver.removeFilter(filter);
13749                }
13750            }
13751            scheduleWritePackageRestrictionsLocked(sourceUserId);
13752        }
13753    }
13754
13755    // Enforcing that callingUid is owning pkg on userId
13756    private void enforceOwnerRights(String pkg, int callingUid) {
13757        // The system owns everything.
13758        if (UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) {
13759            return;
13760        }
13761        int callingUserId = UserHandle.getUserId(callingUid);
13762        PackageInfo pi = getPackageInfo(pkg, 0, callingUserId);
13763        if (pi == null) {
13764            throw new IllegalArgumentException("Unknown package " + pkg + " on user "
13765                    + callingUserId);
13766        }
13767        if (!UserHandle.isSameApp(pi.applicationInfo.uid, callingUid)) {
13768            throw new SecurityException("Calling uid " + callingUid
13769                    + " does not own package " + pkg);
13770        }
13771    }
13772
13773    @Override
13774    public ComponentName getHomeActivities(List<ResolveInfo> allHomeCandidates) {
13775        Intent intent = new Intent(Intent.ACTION_MAIN);
13776        intent.addCategory(Intent.CATEGORY_HOME);
13777
13778        final int callingUserId = UserHandle.getCallingUserId();
13779        List<ResolveInfo> list = queryIntentActivities(intent, null,
13780                PackageManager.GET_META_DATA, callingUserId);
13781        ResolveInfo preferred = findPreferredActivity(intent, null, 0, list, 0,
13782                true, false, false, callingUserId);
13783
13784        allHomeCandidates.clear();
13785        if (list != null) {
13786            for (ResolveInfo ri : list) {
13787                allHomeCandidates.add(ri);
13788            }
13789        }
13790        return (preferred == null || preferred.activityInfo == null)
13791                ? null
13792                : new ComponentName(preferred.activityInfo.packageName,
13793                        preferred.activityInfo.name);
13794    }
13795
13796    @Override
13797    public void setApplicationEnabledSetting(String appPackageName,
13798            int newState, int flags, int userId, String callingPackage) {
13799        if (!sUserManager.exists(userId)) return;
13800        if (callingPackage == null) {
13801            callingPackage = Integer.toString(Binder.getCallingUid());
13802        }
13803        setEnabledSetting(appPackageName, null, newState, flags, userId, callingPackage);
13804    }
13805
13806    @Override
13807    public void setComponentEnabledSetting(ComponentName componentName,
13808            int newState, int flags, int userId) {
13809        if (!sUserManager.exists(userId)) return;
13810        setEnabledSetting(componentName.getPackageName(),
13811                componentName.getClassName(), newState, flags, userId, null);
13812    }
13813
13814    private void setEnabledSetting(final String packageName, String className, int newState,
13815            final int flags, int userId, String callingPackage) {
13816        if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT
13817              || newState == COMPONENT_ENABLED_STATE_ENABLED
13818              || newState == COMPONENT_ENABLED_STATE_DISABLED
13819              || newState == COMPONENT_ENABLED_STATE_DISABLED_USER
13820              || newState == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED)) {
13821            throw new IllegalArgumentException("Invalid new component state: "
13822                    + newState);
13823        }
13824        PackageSetting pkgSetting;
13825        final int uid = Binder.getCallingUid();
13826        final int permission = mContext.checkCallingOrSelfPermission(
13827                android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
13828        enforceCrossUserPermission(uid, userId, false, true, "set enabled");
13829        final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
13830        boolean sendNow = false;
13831        boolean isApp = (className == null);
13832        String componentName = isApp ? packageName : className;
13833        int packageUid = -1;
13834        ArrayList<String> components;
13835
13836        // writer
13837        synchronized (mPackages) {
13838            pkgSetting = mSettings.mPackages.get(packageName);
13839            if (pkgSetting == null) {
13840                if (className == null) {
13841                    throw new IllegalArgumentException(
13842                            "Unknown package: " + packageName);
13843                }
13844                throw new IllegalArgumentException(
13845                        "Unknown component: " + packageName
13846                        + "/" + className);
13847            }
13848            // Allow root and verify that userId is not being specified by a different user
13849            if (!allowedByPermission && !UserHandle.isSameApp(uid, pkgSetting.appId)) {
13850                throw new SecurityException(
13851                        "Permission Denial: attempt to change component state from pid="
13852                        + Binder.getCallingPid()
13853                        + ", uid=" + uid + ", package uid=" + pkgSetting.appId);
13854            }
13855            if (className == null) {
13856                // We're dealing with an application/package level state change
13857                if (pkgSetting.getEnabled(userId) == newState) {
13858                    // Nothing to do
13859                    return;
13860                }
13861                if (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
13862                    || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {
13863                    // Don't care about who enables an app.
13864                    callingPackage = null;
13865                }
13866                pkgSetting.setEnabled(newState, userId, callingPackage);
13867                // pkgSetting.pkg.mSetEnabled = newState;
13868            } else {
13869                // We're dealing with a component level state change
13870                // First, verify that this is a valid class name.
13871                PackageParser.Package pkg = pkgSetting.pkg;
13872                if (pkg == null || !pkg.hasComponentClassName(className)) {
13873                    if (pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.JELLY_BEAN) {
13874                        throw new IllegalArgumentException("Component class " + className
13875                                + " does not exist in " + packageName);
13876                    } else {
13877                        Slog.w(TAG, "Failed setComponentEnabledSetting: component class "
13878                                + className + " does not exist in " + packageName);
13879                    }
13880                }
13881                switch (newState) {
13882                case COMPONENT_ENABLED_STATE_ENABLED:
13883                    if (!pkgSetting.enableComponentLPw(className, userId)) {
13884                        return;
13885                    }
13886                    break;
13887                case COMPONENT_ENABLED_STATE_DISABLED:
13888                    if (!pkgSetting.disableComponentLPw(className, userId)) {
13889                        return;
13890                    }
13891                    break;
13892                case COMPONENT_ENABLED_STATE_DEFAULT:
13893                    if (!pkgSetting.restoreComponentLPw(className, userId)) {
13894                        return;
13895                    }
13896                    break;
13897                default:
13898                    Slog.e(TAG, "Invalid new component state: " + newState);
13899                    return;
13900                }
13901            }
13902            scheduleWritePackageRestrictionsLocked(userId);
13903            components = mPendingBroadcasts.get(userId, packageName);
13904            final boolean newPackage = components == null;
13905            if (newPackage) {
13906                components = new ArrayList<String>();
13907            }
13908            if (!components.contains(componentName)) {
13909                components.add(componentName);
13910            }
13911            if ((flags&PackageManager.DONT_KILL_APP) == 0) {
13912                sendNow = true;
13913                // Purge entry from pending broadcast list if another one exists already
13914                // since we are sending one right away.
13915                mPendingBroadcasts.remove(userId, packageName);
13916            } else {
13917                if (newPackage) {
13918                    mPendingBroadcasts.put(userId, packageName, components);
13919                }
13920                if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) {
13921                    // Schedule a message
13922                    mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, BROADCAST_DELAY);
13923                }
13924            }
13925        }
13926
13927        long callingId = Binder.clearCallingIdentity();
13928        try {
13929            if (sendNow) {
13930                packageUid = UserHandle.getUid(userId, pkgSetting.appId);
13931                sendPackageChangedBroadcast(packageName,
13932                        (flags&PackageManager.DONT_KILL_APP) != 0, components, packageUid);
13933            }
13934        } finally {
13935            Binder.restoreCallingIdentity(callingId);
13936        }
13937    }
13938
13939    private void sendPackageChangedBroadcast(String packageName,
13940            boolean killFlag, ArrayList<String> componentNames, int packageUid) {
13941        if (DEBUG_INSTALL)
13942            Log.v(TAG, "Sending package changed: package=" + packageName + " components="
13943                    + componentNames);
13944        Bundle extras = new Bundle(4);
13945        extras.putString(Intent.EXTRA_CHANGED_COMPONENT_NAME, componentNames.get(0));
13946        String nameList[] = new String[componentNames.size()];
13947        componentNames.toArray(nameList);
13948        extras.putStringArray(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST, nameList);
13949        extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, killFlag);
13950        extras.putInt(Intent.EXTRA_UID, packageUid);
13951        sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED,  packageName, extras, null, null,
13952                new int[] {UserHandle.getUserId(packageUid)});
13953    }
13954
13955    @Override
13956    public void setPackageStoppedState(String packageName, boolean stopped, int userId) {
13957        if (!sUserManager.exists(userId)) return;
13958        final int uid = Binder.getCallingUid();
13959        final int permission = mContext.checkCallingOrSelfPermission(
13960                android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
13961        final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
13962        enforceCrossUserPermission(uid, userId, true, true, "stop package");
13963        // writer
13964        synchronized (mPackages) {
13965            if (mSettings.setPackageStoppedStateLPw(this, packageName, stopped,
13966                    allowedByPermission, uid, userId)) {
13967                scheduleWritePackageRestrictionsLocked(userId);
13968            }
13969        }
13970    }
13971
13972    @Override
13973    public String getInstallerPackageName(String packageName) {
13974        // reader
13975        synchronized (mPackages) {
13976            return mSettings.getInstallerPackageNameLPr(packageName);
13977        }
13978    }
13979
13980    @Override
13981    public int getApplicationEnabledSetting(String packageName, int userId) {
13982        if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
13983        int uid = Binder.getCallingUid();
13984        enforceCrossUserPermission(uid, userId, false, false, "get enabled");
13985        // reader
13986        synchronized (mPackages) {
13987            return mSettings.getApplicationEnabledSettingLPr(packageName, userId);
13988        }
13989    }
13990
13991    @Override
13992    public int getComponentEnabledSetting(ComponentName componentName, int userId) {
13993        if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
13994        int uid = Binder.getCallingUid();
13995        enforceCrossUserPermission(uid, userId, false, false, "get component enabled");
13996        // reader
13997        synchronized (mPackages) {
13998            return mSettings.getComponentEnabledSettingLPr(componentName, userId);
13999        }
14000    }
14001
14002    @Override
14003    public void enterSafeMode() {
14004        enforceSystemOrRoot("Only the system can request entering safe mode");
14005
14006        if (!mSystemReady) {
14007            mSafeMode = true;
14008        }
14009    }
14010
14011    @Override
14012    public void systemReady() {
14013        mSystemReady = true;
14014
14015        // Read the compatibilty setting when the system is ready.
14016        boolean compatibilityModeEnabled = android.provider.Settings.Global.getInt(
14017                mContext.getContentResolver(),
14018                android.provider.Settings.Global.COMPATIBILITY_MODE, 1) == 1;
14019        PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled);
14020        if (DEBUG_SETTINGS) {
14021            Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled);
14022        }
14023
14024        synchronized (mPackages) {
14025            // Verify that all of the preferred activity components actually
14026            // exist.  It is possible for applications to be updated and at
14027            // that point remove a previously declared activity component that
14028            // had been set as a preferred activity.  We try to clean this up
14029            // the next time we encounter that preferred activity, but it is
14030            // possible for the user flow to never be able to return to that
14031            // situation so here we do a sanity check to make sure we haven't
14032            // left any junk around.
14033            ArrayList<PreferredActivity> removed = new ArrayList<PreferredActivity>();
14034            for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
14035                PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
14036                removed.clear();
14037                for (PreferredActivity pa : pir.filterSet()) {
14038                    if (mActivities.mActivities.get(pa.mPref.mComponent) == null) {
14039                        removed.add(pa);
14040                    }
14041                }
14042                if (removed.size() > 0) {
14043                    for (int r=0; r<removed.size(); r++) {
14044                        PreferredActivity pa = removed.get(r);
14045                        Slog.w(TAG, "Removing dangling preferred activity: "
14046                                + pa.mPref.mComponent);
14047                        pir.removeFilter(pa);
14048                    }
14049                    mSettings.writePackageRestrictionsLPr(
14050                            mSettings.mPreferredActivities.keyAt(i));
14051                }
14052            }
14053        }
14054        sUserManager.systemReady();
14055
14056        // If we upgraded grant all default permissions before kicking off.
14057        if (isFirstBoot() || (CLEAR_RUNTIME_PERMISSIONS_ON_UPGRADE && mIsUpgrade)) {
14058            updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL);
14059            for (int userId : UserManagerService.getInstance().getUserIds()) {
14060                mDefaultPermissionPolicy.grantDefaultPermissions(userId);
14061            }
14062        }
14063
14064        // Kick off any messages waiting for system ready
14065        if (mPostSystemReadyMessages != null) {
14066            for (Message msg : mPostSystemReadyMessages) {
14067                msg.sendToTarget();
14068            }
14069            mPostSystemReadyMessages = null;
14070        }
14071
14072        // Watch for external volumes that come and go over time
14073        final StorageManager storage = mContext.getSystemService(StorageManager.class);
14074        storage.registerListener(mStorageListener);
14075
14076        mInstallerService.systemReady();
14077        mPackageDexOptimizer.systemReady();
14078    }
14079
14080    @Override
14081    public boolean isSafeMode() {
14082        return mSafeMode;
14083    }
14084
14085    @Override
14086    public boolean hasSystemUidErrors() {
14087        return mHasSystemUidErrors;
14088    }
14089
14090    static String arrayToString(int[] array) {
14091        StringBuffer buf = new StringBuffer(128);
14092        buf.append('[');
14093        if (array != null) {
14094            for (int i=0; i<array.length; i++) {
14095                if (i > 0) buf.append(", ");
14096                buf.append(array[i]);
14097            }
14098        }
14099        buf.append(']');
14100        return buf.toString();
14101    }
14102
14103    static class DumpState {
14104        public static final int DUMP_LIBS = 1 << 0;
14105        public static final int DUMP_FEATURES = 1 << 1;
14106        public static final int DUMP_RESOLVERS = 1 << 2;
14107        public static final int DUMP_PERMISSIONS = 1 << 3;
14108        public static final int DUMP_PACKAGES = 1 << 4;
14109        public static final int DUMP_SHARED_USERS = 1 << 5;
14110        public static final int DUMP_MESSAGES = 1 << 6;
14111        public static final int DUMP_PROVIDERS = 1 << 7;
14112        public static final int DUMP_VERIFIERS = 1 << 8;
14113        public static final int DUMP_PREFERRED = 1 << 9;
14114        public static final int DUMP_PREFERRED_XML = 1 << 10;
14115        public static final int DUMP_KEYSETS = 1 << 11;
14116        public static final int DUMP_VERSION = 1 << 12;
14117        public static final int DUMP_INSTALLS = 1 << 13;
14118        public static final int DUMP_INTENT_FILTER_VERIFIERS = 1 << 14;
14119        public static final int DUMP_DOMAIN_PREFERRED = 1 << 15;
14120
14121        public static final int OPTION_SHOW_FILTERS = 1 << 0;
14122
14123        private int mTypes;
14124
14125        private int mOptions;
14126
14127        private boolean mTitlePrinted;
14128
14129        private SharedUserSetting mSharedUser;
14130
14131        public boolean isDumping(int type) {
14132            if (mTypes == 0 && type != DUMP_PREFERRED_XML) {
14133                return true;
14134            }
14135
14136            return (mTypes & type) != 0;
14137        }
14138
14139        public void setDump(int type) {
14140            mTypes |= type;
14141        }
14142
14143        public boolean isOptionEnabled(int option) {
14144            return (mOptions & option) != 0;
14145        }
14146
14147        public void setOptionEnabled(int option) {
14148            mOptions |= option;
14149        }
14150
14151        public boolean onTitlePrinted() {
14152            final boolean printed = mTitlePrinted;
14153            mTitlePrinted = true;
14154            return printed;
14155        }
14156
14157        public boolean getTitlePrinted() {
14158            return mTitlePrinted;
14159        }
14160
14161        public void setTitlePrinted(boolean enabled) {
14162            mTitlePrinted = enabled;
14163        }
14164
14165        public SharedUserSetting getSharedUser() {
14166            return mSharedUser;
14167        }
14168
14169        public void setSharedUser(SharedUserSetting user) {
14170            mSharedUser = user;
14171        }
14172    }
14173
14174    @Override
14175    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
14176        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
14177                != PackageManager.PERMISSION_GRANTED) {
14178            pw.println("Permission Denial: can't dump ActivityManager from from pid="
14179                    + Binder.getCallingPid()
14180                    + ", uid=" + Binder.getCallingUid()
14181                    + " without permission "
14182                    + android.Manifest.permission.DUMP);
14183            return;
14184        }
14185
14186        DumpState dumpState = new DumpState();
14187        boolean fullPreferred = false;
14188        boolean checkin = false;
14189
14190        String packageName = null;
14191
14192        int opti = 0;
14193        while (opti < args.length) {
14194            String opt = args[opti];
14195            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
14196                break;
14197            }
14198            opti++;
14199
14200            if ("-a".equals(opt)) {
14201                // Right now we only know how to print all.
14202            } else if ("-h".equals(opt)) {
14203                pw.println("Package manager dump options:");
14204                pw.println("  [-h] [-f] [--checkin] [cmd] ...");
14205                pw.println("    --checkin: dump for a checkin");
14206                pw.println("    -f: print details of intent filters");
14207                pw.println("    -h: print this help");
14208                pw.println("  cmd may be one of:");
14209                pw.println("    l[ibraries]: list known shared libraries");
14210                pw.println("    f[ibraries]: list device features");
14211                pw.println("    k[eysets]: print known keysets");
14212                pw.println("    r[esolvers]: dump intent resolvers");
14213                pw.println("    perm[issions]: dump permissions");
14214                pw.println("    pref[erred]: print preferred package settings");
14215                pw.println("    preferred-xml [--full]: print preferred package settings as xml");
14216                pw.println("    prov[iders]: dump content providers");
14217                pw.println("    p[ackages]: dump installed packages");
14218                pw.println("    s[hared-users]: dump shared user IDs");
14219                pw.println("    m[essages]: print collected runtime messages");
14220                pw.println("    v[erifiers]: print package verifier info");
14221                pw.println("    version: print database version info");
14222                pw.println("    write: write current settings now");
14223                pw.println("    <package.name>: info about given package");
14224                pw.println("    installs: details about install sessions");
14225                pw.println("    d[omain-preferred-apps]: print domains preferred apps");
14226                pw.println("    i[ntent-filter-verifiers]|ifv: print intent filter verifier info");
14227                return;
14228            } else if ("--checkin".equals(opt)) {
14229                checkin = true;
14230            } else if ("-f".equals(opt)) {
14231                dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
14232            } else {
14233                pw.println("Unknown argument: " + opt + "; use -h for help");
14234            }
14235        }
14236
14237        // Is the caller requesting to dump a particular piece of data?
14238        if (opti < args.length) {
14239            String cmd = args[opti];
14240            opti++;
14241            // Is this a package name?
14242            if ("android".equals(cmd) || cmd.contains(".")) {
14243                packageName = cmd;
14244                // When dumping a single package, we always dump all of its
14245                // filter information since the amount of data will be reasonable.
14246                dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
14247            } else if ("l".equals(cmd) || "libraries".equals(cmd)) {
14248                dumpState.setDump(DumpState.DUMP_LIBS);
14249            } else if ("f".equals(cmd) || "features".equals(cmd)) {
14250                dumpState.setDump(DumpState.DUMP_FEATURES);
14251            } else if ("r".equals(cmd) || "resolvers".equals(cmd)) {
14252                dumpState.setDump(DumpState.DUMP_RESOLVERS);
14253            } else if ("perm".equals(cmd) || "permissions".equals(cmd)) {
14254                dumpState.setDump(DumpState.DUMP_PERMISSIONS);
14255            } else if ("pref".equals(cmd) || "preferred".equals(cmd)) {
14256                dumpState.setDump(DumpState.DUMP_PREFERRED);
14257            } else if ("preferred-xml".equals(cmd)) {
14258                dumpState.setDump(DumpState.DUMP_PREFERRED_XML);
14259                if (opti < args.length && "--full".equals(args[opti])) {
14260                    fullPreferred = true;
14261                    opti++;
14262                }
14263            } else if ("d".equals(cmd) || "domain-preferred-apps".equals(cmd)) {
14264                dumpState.setDump(DumpState.DUMP_DOMAIN_PREFERRED);
14265            } else if ("p".equals(cmd) || "packages".equals(cmd)) {
14266                dumpState.setDump(DumpState.DUMP_PACKAGES);
14267            } else if ("s".equals(cmd) || "shared-users".equals(cmd)) {
14268                dumpState.setDump(DumpState.DUMP_SHARED_USERS);
14269            } else if ("prov".equals(cmd) || "providers".equals(cmd)) {
14270                dumpState.setDump(DumpState.DUMP_PROVIDERS);
14271            } else if ("m".equals(cmd) || "messages".equals(cmd)) {
14272                dumpState.setDump(DumpState.DUMP_MESSAGES);
14273            } else if ("v".equals(cmd) || "verifiers".equals(cmd)) {
14274                dumpState.setDump(DumpState.DUMP_VERIFIERS);
14275            } else if ("i".equals(cmd) || "ifv".equals(cmd)
14276                    || "intent-filter-verifiers".equals(cmd)) {
14277                dumpState.setDump(DumpState.DUMP_INTENT_FILTER_VERIFIERS);
14278            } else if ("version".equals(cmd)) {
14279                dumpState.setDump(DumpState.DUMP_VERSION);
14280            } else if ("k".equals(cmd) || "keysets".equals(cmd)) {
14281                dumpState.setDump(DumpState.DUMP_KEYSETS);
14282            } else if ("installs".equals(cmd)) {
14283                dumpState.setDump(DumpState.DUMP_INSTALLS);
14284            } else if ("write".equals(cmd)) {
14285                synchronized (mPackages) {
14286                    mSettings.writeLPr();
14287                    pw.println("Settings written.");
14288                    return;
14289                }
14290            }
14291        }
14292
14293        if (checkin) {
14294            pw.println("vers,1");
14295        }
14296
14297        // reader
14298        synchronized (mPackages) {
14299            if (dumpState.isDumping(DumpState.DUMP_VERSION) && packageName == null) {
14300                if (!checkin) {
14301                    if (dumpState.onTitlePrinted())
14302                        pw.println();
14303                    pw.println("Database versions:");
14304                    pw.print("  SDK Version:");
14305                    pw.print(" internal=");
14306                    pw.print(mSettings.mInternalSdkPlatform);
14307                    pw.print(" external=");
14308                    pw.println(mSettings.mExternalSdkPlatform);
14309                    pw.print("  DB Version:");
14310                    pw.print(" internal=");
14311                    pw.print(mSettings.mInternalDatabaseVersion);
14312                    pw.print(" external=");
14313                    pw.println(mSettings.mExternalDatabaseVersion);
14314                }
14315            }
14316
14317            if (dumpState.isDumping(DumpState.DUMP_VERIFIERS) && packageName == null) {
14318                if (!checkin) {
14319                    if (dumpState.onTitlePrinted())
14320                        pw.println();
14321                    pw.println("Verifiers:");
14322                    pw.print("  Required: ");
14323                    pw.print(mRequiredVerifierPackage);
14324                    pw.print(" (uid=");
14325                    pw.print(getPackageUid(mRequiredVerifierPackage, 0));
14326                    pw.println(")");
14327                } else if (mRequiredVerifierPackage != null) {
14328                    pw.print("vrfy,"); pw.print(mRequiredVerifierPackage);
14329                    pw.print(","); pw.println(getPackageUid(mRequiredVerifierPackage, 0));
14330                }
14331            }
14332
14333            if (dumpState.isDumping(DumpState.DUMP_INTENT_FILTER_VERIFIERS) &&
14334                    packageName == null) {
14335                if (mIntentFilterVerifierComponent != null) {
14336                    String verifierPackageName = mIntentFilterVerifierComponent.getPackageName();
14337                    if (!checkin) {
14338                        if (dumpState.onTitlePrinted())
14339                            pw.println();
14340                        pw.println("Intent Filter Verifier:");
14341                        pw.print("  Using: ");
14342                        pw.print(verifierPackageName);
14343                        pw.print(" (uid=");
14344                        pw.print(getPackageUid(verifierPackageName, 0));
14345                        pw.println(")");
14346                    } else if (verifierPackageName != null) {
14347                        pw.print("ifv,"); pw.print(verifierPackageName);
14348                        pw.print(","); pw.println(getPackageUid(verifierPackageName, 0));
14349                    }
14350                } else {
14351                    pw.println();
14352                    pw.println("No Intent Filter Verifier available!");
14353                }
14354            }
14355
14356            if (dumpState.isDumping(DumpState.DUMP_LIBS) && packageName == null) {
14357                boolean printedHeader = false;
14358                final Iterator<String> it = mSharedLibraries.keySet().iterator();
14359                while (it.hasNext()) {
14360                    String name = it.next();
14361                    SharedLibraryEntry ent = mSharedLibraries.get(name);
14362                    if (!checkin) {
14363                        if (!printedHeader) {
14364                            if (dumpState.onTitlePrinted())
14365                                pw.println();
14366                            pw.println("Libraries:");
14367                            printedHeader = true;
14368                        }
14369                        pw.print("  ");
14370                    } else {
14371                        pw.print("lib,");
14372                    }
14373                    pw.print(name);
14374                    if (!checkin) {
14375                        pw.print(" -> ");
14376                    }
14377                    if (ent.path != null) {
14378                        if (!checkin) {
14379                            pw.print("(jar) ");
14380                            pw.print(ent.path);
14381                        } else {
14382                            pw.print(",jar,");
14383                            pw.print(ent.path);
14384                        }
14385                    } else {
14386                        if (!checkin) {
14387                            pw.print("(apk) ");
14388                            pw.print(ent.apk);
14389                        } else {
14390                            pw.print(",apk,");
14391                            pw.print(ent.apk);
14392                        }
14393                    }
14394                    pw.println();
14395                }
14396            }
14397
14398            if (dumpState.isDumping(DumpState.DUMP_FEATURES) && packageName == null) {
14399                if (dumpState.onTitlePrinted())
14400                    pw.println();
14401                if (!checkin) {
14402                    pw.println("Features:");
14403                }
14404                Iterator<String> it = mAvailableFeatures.keySet().iterator();
14405                while (it.hasNext()) {
14406                    String name = it.next();
14407                    if (!checkin) {
14408                        pw.print("  ");
14409                    } else {
14410                        pw.print("feat,");
14411                    }
14412                    pw.println(name);
14413                }
14414            }
14415
14416            if (!checkin && dumpState.isDumping(DumpState.DUMP_RESOLVERS)) {
14417                if (mActivities.dump(pw, dumpState.getTitlePrinted() ? "\nActivity Resolver Table:"
14418                        : "Activity Resolver Table:", "  ", packageName,
14419                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
14420                    dumpState.setTitlePrinted(true);
14421                }
14422                if (mReceivers.dump(pw, dumpState.getTitlePrinted() ? "\nReceiver Resolver Table:"
14423                        : "Receiver Resolver Table:", "  ", packageName,
14424                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
14425                    dumpState.setTitlePrinted(true);
14426                }
14427                if (mServices.dump(pw, dumpState.getTitlePrinted() ? "\nService Resolver Table:"
14428                        : "Service Resolver Table:", "  ", packageName,
14429                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
14430                    dumpState.setTitlePrinted(true);
14431                }
14432                if (mProviders.dump(pw, dumpState.getTitlePrinted() ? "\nProvider Resolver Table:"
14433                        : "Provider Resolver Table:", "  ", packageName,
14434                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
14435                    dumpState.setTitlePrinted(true);
14436                }
14437            }
14438
14439            if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED)) {
14440                for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
14441                    PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
14442                    int user = mSettings.mPreferredActivities.keyAt(i);
14443                    if (pir.dump(pw,
14444                            dumpState.getTitlePrinted()
14445                                ? "\nPreferred Activities User " + user + ":"
14446                                : "Preferred Activities User " + user + ":", "  ",
14447                            packageName, true, false)) {
14448                        dumpState.setTitlePrinted(true);
14449                    }
14450                }
14451            }
14452
14453            if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED_XML)) {
14454                pw.flush();
14455                FileOutputStream fout = new FileOutputStream(fd);
14456                BufferedOutputStream str = new BufferedOutputStream(fout);
14457                XmlSerializer serializer = new FastXmlSerializer();
14458                try {
14459                    serializer.setOutput(str, StandardCharsets.UTF_8.name());
14460                    serializer.startDocument(null, true);
14461                    serializer.setFeature(
14462                            "http://xmlpull.org/v1/doc/features.html#indent-output", true);
14463                    mSettings.writePreferredActivitiesLPr(serializer, 0, fullPreferred);
14464                    serializer.endDocument();
14465                    serializer.flush();
14466                } catch (IllegalArgumentException e) {
14467                    pw.println("Failed writing: " + e);
14468                } catch (IllegalStateException e) {
14469                    pw.println("Failed writing: " + e);
14470                } catch (IOException e) {
14471                    pw.println("Failed writing: " + e);
14472                }
14473            }
14474
14475            if (!checkin
14476                    && dumpState.isDumping(DumpState.DUMP_DOMAIN_PREFERRED)
14477                    && packageName == null) {
14478                pw.println();
14479                int count = mSettings.mPackages.size();
14480                if (count == 0) {
14481                    pw.println("No domain preferred apps!");
14482                    pw.println();
14483                } else {
14484                    final String prefix = "  ";
14485                    Collection<PackageSetting> allPackageSettings = mSettings.mPackages.values();
14486                    if (allPackageSettings.size() == 0) {
14487                        pw.println("No domain preferred apps!");
14488                        pw.println();
14489                    } else {
14490                        pw.println("Domain preferred apps status:");
14491                        pw.println();
14492                        count = 0;
14493                        for (PackageSetting ps : allPackageSettings) {
14494                            IntentFilterVerificationInfo ivi = ps.getIntentFilterVerificationInfo();
14495                            if (ivi == null || ivi.getPackageName() == null) continue;
14496                            pw.println(prefix + "Package Name: " + ivi.getPackageName());
14497                            pw.println(prefix + "Domains: " + ivi.getDomainsString());
14498                            pw.println(prefix + "Status: " + ivi.getStatusString());
14499                            pw.println();
14500                            count++;
14501                        }
14502                        if (count == 0) {
14503                            pw.println(prefix + "No domain preferred app status!");
14504                            pw.println();
14505                        }
14506                        for (int userId : sUserManager.getUserIds()) {
14507                            pw.println("Domain preferred apps for User " + userId + ":");
14508                            pw.println();
14509                            count = 0;
14510                            for (PackageSetting ps : allPackageSettings) {
14511                                IntentFilterVerificationInfo ivi = ps.getIntentFilterVerificationInfo();
14512                                if (ivi == null || ivi.getPackageName() == null) {
14513                                    continue;
14514                                }
14515                                final int status = ps.getDomainVerificationStatusForUser(userId);
14516                                if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) {
14517                                    continue;
14518                                }
14519                                pw.println(prefix + "Package Name: " + ivi.getPackageName());
14520                                pw.println(prefix + "Domains: " + ivi.getDomainsString());
14521                                String statusStr = IntentFilterVerificationInfo.
14522                                        getStatusStringFromValue(status);
14523                                pw.println(prefix + "Status: " + statusStr);
14524                                pw.println();
14525                                count++;
14526                            }
14527                            if (count == 0) {
14528                                pw.println(prefix + "No domain preferred apps!");
14529                                pw.println();
14530                            }
14531                        }
14532                    }
14533                }
14534            }
14535
14536            if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) {
14537                mSettings.dumpPermissionsLPr(pw, packageName, dumpState);
14538                if (packageName == null) {
14539                    for (int iperm=0; iperm<mAppOpPermissionPackages.size(); iperm++) {
14540                        if (iperm == 0) {
14541                            if (dumpState.onTitlePrinted())
14542                                pw.println();
14543                            pw.println("AppOp Permissions:");
14544                        }
14545                        pw.print("  AppOp Permission ");
14546                        pw.print(mAppOpPermissionPackages.keyAt(iperm));
14547                        pw.println(":");
14548                        ArraySet<String> pkgs = mAppOpPermissionPackages.valueAt(iperm);
14549                        for (int ipkg=0; ipkg<pkgs.size(); ipkg++) {
14550                            pw.print("    "); pw.println(pkgs.valueAt(ipkg));
14551                        }
14552                    }
14553                }
14554            }
14555
14556            if (!checkin && dumpState.isDumping(DumpState.DUMP_PROVIDERS)) {
14557                boolean printedSomething = false;
14558                for (PackageParser.Provider p : mProviders.mProviders.values()) {
14559                    if (packageName != null && !packageName.equals(p.info.packageName)) {
14560                        continue;
14561                    }
14562                    if (!printedSomething) {
14563                        if (dumpState.onTitlePrinted())
14564                            pw.println();
14565                        pw.println("Registered ContentProviders:");
14566                        printedSomething = true;
14567                    }
14568                    pw.print("  "); p.printComponentShortName(pw); pw.println(":");
14569                    pw.print("    "); pw.println(p.toString());
14570                }
14571                printedSomething = false;
14572                for (Map.Entry<String, PackageParser.Provider> entry :
14573                        mProvidersByAuthority.entrySet()) {
14574                    PackageParser.Provider p = entry.getValue();
14575                    if (packageName != null && !packageName.equals(p.info.packageName)) {
14576                        continue;
14577                    }
14578                    if (!printedSomething) {
14579                        if (dumpState.onTitlePrinted())
14580                            pw.println();
14581                        pw.println("ContentProvider Authorities:");
14582                        printedSomething = true;
14583                    }
14584                    pw.print("  ["); pw.print(entry.getKey()); pw.println("]:");
14585                    pw.print("    "); pw.println(p.toString());
14586                    if (p.info != null && p.info.applicationInfo != null) {
14587                        final String appInfo = p.info.applicationInfo.toString();
14588                        pw.print("      applicationInfo="); pw.println(appInfo);
14589                    }
14590                }
14591            }
14592
14593            if (!checkin && dumpState.isDumping(DumpState.DUMP_KEYSETS)) {
14594                mSettings.mKeySetManagerService.dumpLPr(pw, packageName, dumpState);
14595            }
14596
14597            if (dumpState.isDumping(DumpState.DUMP_PACKAGES)) {
14598                mSettings.dumpPackagesLPr(pw, packageName, dumpState, checkin);
14599            }
14600
14601            if (dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) {
14602                mSettings.dumpSharedUsersLPr(pw, packageName, dumpState, checkin);
14603            }
14604
14605            if (!checkin && dumpState.isDumping(DumpState.DUMP_INSTALLS) && packageName == null) {
14606                // XXX should handle packageName != null by dumping only install data that
14607                // the given package is involved with.
14608                if (dumpState.onTitlePrinted()) pw.println();
14609                mInstallerService.dump(new IndentingPrintWriter(pw, "  ", 120));
14610            }
14611
14612            if (!checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES) && packageName == null) {
14613                if (dumpState.onTitlePrinted()) pw.println();
14614                mSettings.dumpReadMessagesLPr(pw, dumpState);
14615
14616                pw.println();
14617                pw.println("Package warning messages:");
14618                BufferedReader in = null;
14619                String line = null;
14620                try {
14621                    in = new BufferedReader(new FileReader(getSettingsProblemFile()));
14622                    while ((line = in.readLine()) != null) {
14623                        if (line.contains("ignored: updated version")) continue;
14624                        pw.println(line);
14625                    }
14626                } catch (IOException ignored) {
14627                } finally {
14628                    IoUtils.closeQuietly(in);
14629                }
14630            }
14631
14632            if (checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES)) {
14633                BufferedReader in = null;
14634                String line = null;
14635                try {
14636                    in = new BufferedReader(new FileReader(getSettingsProblemFile()));
14637                    while ((line = in.readLine()) != null) {
14638                        if (line.contains("ignored: updated version")) continue;
14639                        pw.print("msg,");
14640                        pw.println(line);
14641                    }
14642                } catch (IOException ignored) {
14643                } finally {
14644                    IoUtils.closeQuietly(in);
14645                }
14646            }
14647        }
14648    }
14649
14650    // ------- apps on sdcard specific code -------
14651    static final boolean DEBUG_SD_INSTALL = false;
14652
14653    private static final String SD_ENCRYPTION_KEYSTORE_NAME = "AppsOnSD";
14654
14655    private static final String SD_ENCRYPTION_ALGORITHM = "AES";
14656
14657    private boolean mMediaMounted = false;
14658
14659    static String getEncryptKey() {
14660        try {
14661            String sdEncKey = SystemKeyStore.getInstance().retrieveKeyHexString(
14662                    SD_ENCRYPTION_KEYSTORE_NAME);
14663            if (sdEncKey == null) {
14664                sdEncKey = SystemKeyStore.getInstance().generateNewKeyHexString(128,
14665                        SD_ENCRYPTION_ALGORITHM, SD_ENCRYPTION_KEYSTORE_NAME);
14666                if (sdEncKey == null) {
14667                    Slog.e(TAG, "Failed to create encryption keys");
14668                    return null;
14669                }
14670            }
14671            return sdEncKey;
14672        } catch (NoSuchAlgorithmException nsae) {
14673            Slog.e(TAG, "Failed to create encryption keys with exception: " + nsae);
14674            return null;
14675        } catch (IOException ioe) {
14676            Slog.e(TAG, "Failed to retrieve encryption keys with exception: " + ioe);
14677            return null;
14678        }
14679    }
14680
14681    /*
14682     * Update media status on PackageManager.
14683     */
14684    @Override
14685    public void updateExternalMediaStatus(final boolean mediaStatus, final boolean reportStatus) {
14686        int callingUid = Binder.getCallingUid();
14687        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
14688            throw new SecurityException("Media status can only be updated by the system");
14689        }
14690        // reader; this apparently protects mMediaMounted, but should probably
14691        // be a different lock in that case.
14692        synchronized (mPackages) {
14693            Log.i(TAG, "Updating external media status from "
14694                    + (mMediaMounted ? "mounted" : "unmounted") + " to "
14695                    + (mediaStatus ? "mounted" : "unmounted"));
14696            if (DEBUG_SD_INSTALL)
14697                Log.i(TAG, "updateExternalMediaStatus:: mediaStatus=" + mediaStatus
14698                        + ", mMediaMounted=" + mMediaMounted);
14699            if (mediaStatus == mMediaMounted) {
14700                final Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1
14701                        : 0, -1);
14702                mHandler.sendMessage(msg);
14703                return;
14704            }
14705            mMediaMounted = mediaStatus;
14706        }
14707        // Queue up an async operation since the package installation may take a
14708        // little while.
14709        mHandler.post(new Runnable() {
14710            public void run() {
14711                updateExternalMediaStatusInner(mediaStatus, reportStatus, true);
14712            }
14713        });
14714    }
14715
14716    /**
14717     * Called by MountService when the initial ASECs to scan are available.
14718     * Should block until all the ASEC containers are finished being scanned.
14719     */
14720    public void scanAvailableAsecs() {
14721        updateExternalMediaStatusInner(true, false, false);
14722        if (mShouldRestoreconData) {
14723            SELinuxMMAC.setRestoreconDone();
14724            mShouldRestoreconData = false;
14725        }
14726    }
14727
14728    /*
14729     * Collect information of applications on external media, map them against
14730     * existing containers and update information based on current mount status.
14731     * Please note that we always have to report status if reportStatus has been
14732     * set to true especially when unloading packages.
14733     */
14734    private void updateExternalMediaStatusInner(boolean isMounted, boolean reportStatus,
14735            boolean externalStorage) {
14736        ArrayMap<AsecInstallArgs, String> processCids = new ArrayMap<>();
14737        int[] uidArr = EmptyArray.INT;
14738
14739        final String[] list = PackageHelper.getSecureContainerList();
14740        if (ArrayUtils.isEmpty(list)) {
14741            Log.i(TAG, "No secure containers found");
14742        } else {
14743            // Process list of secure containers and categorize them
14744            // as active or stale based on their package internal state.
14745
14746            // reader
14747            synchronized (mPackages) {
14748                for (String cid : list) {
14749                    // Leave stages untouched for now; installer service owns them
14750                    if (PackageInstallerService.isStageName(cid)) continue;
14751
14752                    if (DEBUG_SD_INSTALL)
14753                        Log.i(TAG, "Processing container " + cid);
14754                    String pkgName = getAsecPackageName(cid);
14755                    if (pkgName == null) {
14756                        Slog.i(TAG, "Found stale container " + cid + " with no package name");
14757                        continue;
14758                    }
14759                    if (DEBUG_SD_INSTALL)
14760                        Log.i(TAG, "Looking for pkg : " + pkgName);
14761
14762                    final PackageSetting ps = mSettings.mPackages.get(pkgName);
14763                    if (ps == null) {
14764                        Slog.i(TAG, "Found stale container " + cid + " with no matching settings");
14765                        continue;
14766                    }
14767
14768                    /*
14769                     * Skip packages that are not external if we're unmounting
14770                     * external storage.
14771                     */
14772                    if (externalStorage && !isMounted && !isExternal(ps)) {
14773                        continue;
14774                    }
14775
14776                    final AsecInstallArgs args = new AsecInstallArgs(cid,
14777                            getAppDexInstructionSets(ps), ps.isForwardLocked());
14778                    // The package status is changed only if the code path
14779                    // matches between settings and the container id.
14780                    if (ps.codePathString != null
14781                            && ps.codePathString.startsWith(args.getCodePath())) {
14782                        if (DEBUG_SD_INSTALL) {
14783                            Log.i(TAG, "Container : " + cid + " corresponds to pkg : " + pkgName
14784                                    + " at code path: " + ps.codePathString);
14785                        }
14786
14787                        // We do have a valid package installed on sdcard
14788                        processCids.put(args, ps.codePathString);
14789                        final int uid = ps.appId;
14790                        if (uid != -1) {
14791                            uidArr = ArrayUtils.appendInt(uidArr, uid);
14792                        }
14793                    } else {
14794                        Slog.i(TAG, "Found stale container " + cid + ": expected codePath="
14795                                + ps.codePathString);
14796                    }
14797                }
14798            }
14799
14800            Arrays.sort(uidArr);
14801        }
14802
14803        // Process packages with valid entries.
14804        if (isMounted) {
14805            if (DEBUG_SD_INSTALL)
14806                Log.i(TAG, "Loading packages");
14807            loadMediaPackages(processCids, uidArr);
14808            startCleaningPackages();
14809            mInstallerService.onSecureContainersAvailable();
14810        } else {
14811            if (DEBUG_SD_INSTALL)
14812                Log.i(TAG, "Unloading packages");
14813            unloadMediaPackages(processCids, uidArr, reportStatus);
14814        }
14815    }
14816
14817    private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
14818            ArrayList<ApplicationInfo> infos, IIntentReceiver finishedReceiver) {
14819        final int size = infos.size();
14820        final String[] packageNames = new String[size];
14821        final int[] packageUids = new int[size];
14822        for (int i = 0; i < size; i++) {
14823            final ApplicationInfo info = infos.get(i);
14824            packageNames[i] = info.packageName;
14825            packageUids[i] = info.uid;
14826        }
14827        sendResourcesChangedBroadcast(mediaStatus, replacing, packageNames, packageUids,
14828                finishedReceiver);
14829    }
14830
14831    private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
14832            ArrayList<String> pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
14833        sendResourcesChangedBroadcast(mediaStatus, replacing,
14834                pkgList.toArray(new String[pkgList.size()]), uidArr, finishedReceiver);
14835    }
14836
14837    private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
14838            String[] pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
14839        int size = pkgList.length;
14840        if (size > 0) {
14841            // Send broadcasts here
14842            Bundle extras = new Bundle();
14843            extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
14844            if (uidArr != null) {
14845                extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidArr);
14846            }
14847            if (replacing) {
14848                extras.putBoolean(Intent.EXTRA_REPLACING, replacing);
14849            }
14850            String action = mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE
14851                    : Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE;
14852            sendPackageBroadcast(action, null, extras, null, finishedReceiver, null);
14853        }
14854    }
14855
14856   /*
14857     * Look at potentially valid container ids from processCids If package
14858     * information doesn't match the one on record or package scanning fails,
14859     * the cid is added to list of removeCids. We currently don't delete stale
14860     * containers.
14861     */
14862    private void loadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int[] uidArr) {
14863        ArrayList<String> pkgList = new ArrayList<String>();
14864        Set<AsecInstallArgs> keys = processCids.keySet();
14865
14866        for (AsecInstallArgs args : keys) {
14867            String codePath = processCids.get(args);
14868            if (DEBUG_SD_INSTALL)
14869                Log.i(TAG, "Loading container : " + args.cid);
14870            int retCode = PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
14871            try {
14872                // Make sure there are no container errors first.
14873                if (args.doPreInstall(PackageManager.INSTALL_SUCCEEDED) != PackageManager.INSTALL_SUCCEEDED) {
14874                    Slog.e(TAG, "Failed to mount cid : " + args.cid
14875                            + " when installing from sdcard");
14876                    continue;
14877                }
14878                // Check code path here.
14879                if (codePath == null || !codePath.startsWith(args.getCodePath())) {
14880                    Slog.e(TAG, "Container " + args.cid + " cachepath " + args.getCodePath()
14881                            + " does not match one in settings " + codePath);
14882                    continue;
14883                }
14884                // Parse package
14885                int parseFlags = mDefParseFlags;
14886                if (args.isExternalAsec()) {
14887                    parseFlags |= PackageParser.PARSE_EXTERNAL_STORAGE;
14888                }
14889                if (args.isFwdLocked()) {
14890                    parseFlags |= PackageParser.PARSE_FORWARD_LOCK;
14891                }
14892
14893                synchronized (mInstallLock) {
14894                    PackageParser.Package pkg = null;
14895                    try {
14896                        pkg = scanPackageLI(new File(codePath), parseFlags, 0, 0, null);
14897                    } catch (PackageManagerException e) {
14898                        Slog.w(TAG, "Failed to scan " + codePath + ": " + e.getMessage());
14899                    }
14900                    // Scan the package
14901                    if (pkg != null) {
14902                        /*
14903                         * TODO why is the lock being held? doPostInstall is
14904                         * called in other places without the lock. This needs
14905                         * to be straightened out.
14906                         */
14907                        // writer
14908                        synchronized (mPackages) {
14909                            retCode = PackageManager.INSTALL_SUCCEEDED;
14910                            pkgList.add(pkg.packageName);
14911                            // Post process args
14912                            args.doPostInstall(PackageManager.INSTALL_SUCCEEDED,
14913                                    pkg.applicationInfo.uid);
14914                        }
14915                    } else {
14916                        Slog.i(TAG, "Failed to install pkg from  " + codePath + " from sdcard");
14917                    }
14918                }
14919
14920            } finally {
14921                if (retCode != PackageManager.INSTALL_SUCCEEDED) {
14922                    Log.w(TAG, "Container " + args.cid + " is stale, retCode=" + retCode);
14923                }
14924            }
14925        }
14926        // writer
14927        synchronized (mPackages) {
14928            // If the platform SDK has changed since the last time we booted,
14929            // we need to re-grant app permission to catch any new ones that
14930            // appear. This is really a hack, and means that apps can in some
14931            // cases get permissions that the user didn't initially explicitly
14932            // allow... it would be nice to have some better way to handle
14933            // this situation.
14934            final boolean regrantPermissions = mSettings.mExternalSdkPlatform != mSdkVersion;
14935            if (regrantPermissions)
14936                Slog.i(TAG, "Platform changed from " + mSettings.mExternalSdkPlatform + " to "
14937                        + mSdkVersion + "; regranting permissions for external storage");
14938            mSettings.mExternalSdkPlatform = mSdkVersion;
14939
14940            // Make sure group IDs have been assigned, and any permission
14941            // changes in other apps are accounted for
14942            updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL
14943                    | (regrantPermissions
14944                            ? (UPDATE_PERMISSIONS_REPLACE_PKG|UPDATE_PERMISSIONS_REPLACE_ALL)
14945                            : 0));
14946
14947            mSettings.updateExternalDatabaseVersion();
14948
14949            // can downgrade to reader
14950            // Persist settings
14951            mSettings.writeLPr();
14952        }
14953        // Send a broadcast to let everyone know we are done processing
14954        if (pkgList.size() > 0) {
14955            sendResourcesChangedBroadcast(true, false, pkgList, uidArr, null);
14956        }
14957    }
14958
14959   /*
14960     * Utility method to unload a list of specified containers
14961     */
14962    private void unloadAllContainers(Set<AsecInstallArgs> cidArgs) {
14963        // Just unmount all valid containers.
14964        for (AsecInstallArgs arg : cidArgs) {
14965            synchronized (mInstallLock) {
14966                arg.doPostDeleteLI(false);
14967           }
14968       }
14969   }
14970
14971    /*
14972     * Unload packages mounted on external media. This involves deleting package
14973     * data from internal structures, sending broadcasts about diabled packages,
14974     * gc'ing to free up references, unmounting all secure containers
14975     * corresponding to packages on external media, and posting a
14976     * UPDATED_MEDIA_STATUS message if status has been requested. Please note
14977     * that we always have to post this message if status has been requested no
14978     * matter what.
14979     */
14980    private void unloadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int uidArr[],
14981            final boolean reportStatus) {
14982        if (DEBUG_SD_INSTALL)
14983            Log.i(TAG, "unloading media packages");
14984        ArrayList<String> pkgList = new ArrayList<String>();
14985        ArrayList<AsecInstallArgs> failedList = new ArrayList<AsecInstallArgs>();
14986        final Set<AsecInstallArgs> keys = processCids.keySet();
14987        for (AsecInstallArgs args : keys) {
14988            String pkgName = args.getPackageName();
14989            if (DEBUG_SD_INSTALL)
14990                Log.i(TAG, "Trying to unload pkg : " + pkgName);
14991            // Delete package internally
14992            PackageRemovedInfo outInfo = new PackageRemovedInfo();
14993            synchronized (mInstallLock) {
14994                boolean res = deletePackageLI(pkgName, null, false, null, null,
14995                        PackageManager.DELETE_KEEP_DATA, outInfo, false);
14996                if (res) {
14997                    pkgList.add(pkgName);
14998                } else {
14999                    Slog.e(TAG, "Failed to delete pkg from sdcard : " + pkgName);
15000                    failedList.add(args);
15001                }
15002            }
15003        }
15004
15005        // reader
15006        synchronized (mPackages) {
15007            // We didn't update the settings after removing each package;
15008            // write them now for all packages.
15009            mSettings.writeLPr();
15010        }
15011
15012        // We have to absolutely send UPDATED_MEDIA_STATUS only
15013        // after confirming that all the receivers processed the ordered
15014        // broadcast when packages get disabled, force a gc to clean things up.
15015        // and unload all the containers.
15016        if (pkgList.size() > 0) {
15017            sendResourcesChangedBroadcast(false, false, pkgList, uidArr,
15018                    new IIntentReceiver.Stub() {
15019                public void performReceive(Intent intent, int resultCode, String data,
15020                        Bundle extras, boolean ordered, boolean sticky,
15021                        int sendingUser) throws RemoteException {
15022                    Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS,
15023                            reportStatus ? 1 : 0, 1, keys);
15024                    mHandler.sendMessage(msg);
15025                }
15026            });
15027        } else {
15028            Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1 : 0, -1,
15029                    keys);
15030            mHandler.sendMessage(msg);
15031        }
15032    }
15033
15034    private void loadPrivatePackages(VolumeInfo vol) {
15035        final ArrayList<ApplicationInfo> loaded = new ArrayList<>();
15036        final int parseFlags = mDefParseFlags | PackageParser.PARSE_EXTERNAL_STORAGE;
15037        synchronized (mInstallLock) {
15038        synchronized (mPackages) {
15039            final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(vol.fsUuid);
15040            for (PackageSetting ps : packages) {
15041                final PackageParser.Package pkg;
15042                try {
15043                    pkg = scanPackageLI(ps.codePath, parseFlags, SCAN_INITIAL, 0L, null);
15044                    loaded.add(pkg.applicationInfo);
15045                } catch (PackageManagerException e) {
15046                    Slog.w(TAG, "Failed to scan " + ps.codePath + ": " + e.getMessage());
15047                }
15048            }
15049
15050            // TODO: regrant any permissions that changed based since original install
15051
15052            mSettings.writeLPr();
15053        }
15054        }
15055
15056        if (DEBUG_INSTALL) Slog.d(TAG, "Loaded packages " + loaded);
15057        sendResourcesChangedBroadcast(true, false, loaded, null);
15058    }
15059
15060    private void unloadPrivatePackages(VolumeInfo vol) {
15061        final ArrayList<ApplicationInfo> unloaded = new ArrayList<>();
15062        synchronized (mInstallLock) {
15063        synchronized (mPackages) {
15064            final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(vol.fsUuid);
15065            for (PackageSetting ps : packages) {
15066                if (ps.pkg == null) continue;
15067
15068                final ApplicationInfo info = ps.pkg.applicationInfo;
15069                final PackageRemovedInfo outInfo = new PackageRemovedInfo();
15070                if (deletePackageLI(ps.name, null, false, null, null,
15071                        PackageManager.DELETE_KEEP_DATA, outInfo, false)) {
15072                    unloaded.add(info);
15073                } else {
15074                    Slog.w(TAG, "Failed to unload " + ps.codePath);
15075                }
15076            }
15077
15078            mSettings.writeLPr();
15079        }
15080        }
15081
15082        if (DEBUG_INSTALL) Slog.d(TAG, "Unloaded packages " + unloaded);
15083        sendResourcesChangedBroadcast(false, false, unloaded, null);
15084    }
15085
15086    private void unfreezePackage(String packageName) {
15087        synchronized (mPackages) {
15088            final PackageSetting ps = mSettings.mPackages.get(packageName);
15089            if (ps != null) {
15090                ps.frozen = false;
15091            }
15092        }
15093    }
15094
15095    @Override
15096    public int movePackage(final String packageName, final String volumeUuid) {
15097        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
15098
15099        final int moveId = mNextMoveId.getAndIncrement();
15100        try {
15101            movePackageInternal(packageName, volumeUuid, moveId);
15102        } catch (PackageManagerException e) {
15103            Slog.w(TAG, "Failed to move " + packageName, e);
15104            mMoveCallbacks.notifyStatusChanged(moveId,
15105                    PackageManager.MOVE_FAILED_INTERNAL_ERROR);
15106        }
15107        return moveId;
15108    }
15109
15110    private void movePackageInternal(final String packageName, final String volumeUuid,
15111            final int moveId) throws PackageManagerException {
15112        final UserHandle user = new UserHandle(UserHandle.getCallingUserId());
15113        final StorageManager storage = mContext.getSystemService(StorageManager.class);
15114        final PackageManager pm = mContext.getPackageManager();
15115
15116        final boolean currentAsec;
15117        final String currentVolumeUuid;
15118        final File codeFile;
15119        final String installerPackageName;
15120        final String packageAbiOverride;
15121        final int appId;
15122        final String seinfo;
15123        final String label;
15124
15125        // reader
15126        synchronized (mPackages) {
15127            final PackageParser.Package pkg = mPackages.get(packageName);
15128            final PackageSetting ps = mSettings.mPackages.get(packageName);
15129            if (pkg == null || ps == null) {
15130                throw new PackageManagerException(MOVE_FAILED_DOESNT_EXIST, "Missing package");
15131            }
15132
15133            if (pkg.applicationInfo.isSystemApp()) {
15134                throw new PackageManagerException(MOVE_FAILED_SYSTEM_PACKAGE,
15135                        "Cannot move system application");
15136            }
15137
15138            if (Objects.equals(ps.volumeUuid, volumeUuid)) {
15139                throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
15140                        "Package already moved to " + volumeUuid);
15141            }
15142
15143            final File probe = new File(pkg.codePath);
15144            final File probeOat = new File(probe, "oat");
15145            if (!probe.isDirectory() || !probeOat.isDirectory()) {
15146                throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
15147                        "Move only supported for modern cluster style installs");
15148            }
15149
15150            if (ps.frozen) {
15151                throw new PackageManagerException(MOVE_FAILED_OPERATION_PENDING,
15152                        "Failed to move already frozen package");
15153            }
15154            ps.frozen = true;
15155
15156            currentAsec = pkg.applicationInfo.isForwardLocked()
15157                    || pkg.applicationInfo.isExternalAsec();
15158            currentVolumeUuid = ps.volumeUuid;
15159            codeFile = new File(pkg.codePath);
15160            installerPackageName = ps.installerPackageName;
15161            packageAbiOverride = ps.cpuAbiOverrideString;
15162            appId = UserHandle.getAppId(pkg.applicationInfo.uid);
15163            seinfo = pkg.applicationInfo.seinfo;
15164            label = String.valueOf(pm.getApplicationLabel(pkg.applicationInfo));
15165        }
15166
15167        // Now that we're guarded by frozen state, kill app during move
15168        killApplication(packageName, appId, "move pkg");
15169
15170        final Bundle extras = new Bundle();
15171        extras.putString(Intent.EXTRA_PACKAGE_NAME, packageName);
15172        extras.putString(Intent.EXTRA_TITLE, label);
15173        mMoveCallbacks.notifyCreated(moveId, extras);
15174
15175        int installFlags;
15176        final boolean moveCompleteApp;
15177        final File measurePath;
15178
15179        if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, volumeUuid)) {
15180            installFlags = INSTALL_INTERNAL;
15181            moveCompleteApp = !currentAsec;
15182            measurePath = Environment.getDataAppDirectory(volumeUuid);
15183        } else if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, volumeUuid)) {
15184            installFlags = INSTALL_EXTERNAL;
15185            moveCompleteApp = false;
15186            measurePath = storage.getPrimaryPhysicalVolume().getPath();
15187        } else {
15188            final VolumeInfo volume = storage.findVolumeByUuid(volumeUuid);
15189            if (volume == null || volume.getType() != VolumeInfo.TYPE_PRIVATE
15190                    || !volume.isMountedWritable()) {
15191                unfreezePackage(packageName);
15192                throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
15193                        "Move location not mounted private volume");
15194            }
15195
15196            Preconditions.checkState(!currentAsec);
15197
15198            installFlags = INSTALL_INTERNAL;
15199            moveCompleteApp = true;
15200            measurePath = Environment.getDataAppDirectory(volumeUuid);
15201        }
15202
15203        final PackageStats stats = new PackageStats(null, -1);
15204        synchronized (mInstaller) {
15205            if (!getPackageSizeInfoLI(packageName, -1, stats)) {
15206                unfreezePackage(packageName);
15207                throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
15208                        "Failed to measure package size");
15209            }
15210        }
15211
15212        if (DEBUG_INSTALL) Slog.d(TAG, "Measured code size " + stats.codeSize + ", data size "
15213                + stats.dataSize);
15214
15215        final long startFreeBytes = measurePath.getFreeSpace();
15216        final long sizeBytes;
15217        if (moveCompleteApp) {
15218            sizeBytes = stats.codeSize + stats.dataSize;
15219        } else {
15220            sizeBytes = stats.codeSize;
15221        }
15222
15223        if (sizeBytes > storage.getStorageBytesUntilLow(measurePath)) {
15224            unfreezePackage(packageName);
15225            throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
15226                    "Not enough free space to move");
15227        }
15228
15229        mMoveCallbacks.notifyStatusChanged(moveId, 10);
15230
15231        final CountDownLatch installedLatch = new CountDownLatch(1);
15232        final IPackageInstallObserver2 installObserver = new IPackageInstallObserver2.Stub() {
15233            @Override
15234            public void onUserActionRequired(Intent intent) throws RemoteException {
15235                throw new IllegalStateException();
15236            }
15237
15238            @Override
15239            public void onPackageInstalled(String basePackageName, int returnCode, String msg,
15240                    Bundle extras) throws RemoteException {
15241                if (DEBUG_INSTALL) Slog.d(TAG, "Install result for move: "
15242                        + PackageManager.installStatusToString(returnCode, msg));
15243
15244                installedLatch.countDown();
15245
15246                // Regardless of success or failure of the move operation,
15247                // always unfreeze the package
15248                unfreezePackage(packageName);
15249
15250                final int status = PackageManager.installStatusToPublicStatus(returnCode);
15251                switch (status) {
15252                    case PackageInstaller.STATUS_SUCCESS:
15253                        mMoveCallbacks.notifyStatusChanged(moveId,
15254                                PackageManager.MOVE_SUCCEEDED);
15255                        break;
15256                    case PackageInstaller.STATUS_FAILURE_STORAGE:
15257                        mMoveCallbacks.notifyStatusChanged(moveId,
15258                                PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE);
15259                        break;
15260                    default:
15261                        mMoveCallbacks.notifyStatusChanged(moveId,
15262                                PackageManager.MOVE_FAILED_INTERNAL_ERROR);
15263                        break;
15264                }
15265            }
15266        };
15267
15268        final MoveInfo move;
15269        if (moveCompleteApp) {
15270            // Kick off a thread to report progress estimates
15271            new Thread() {
15272                @Override
15273                public void run() {
15274                    while (true) {
15275                        try {
15276                            if (installedLatch.await(1, TimeUnit.SECONDS)) {
15277                                break;
15278                            }
15279                        } catch (InterruptedException ignored) {
15280                        }
15281
15282                        final long deltaFreeBytes = startFreeBytes - measurePath.getFreeSpace();
15283                        final int progress = 10 + (int) MathUtils.constrain(
15284                                ((deltaFreeBytes * 80) / sizeBytes), 0, 80);
15285                        mMoveCallbacks.notifyStatusChanged(moveId, progress);
15286                    }
15287                }
15288            }.start();
15289
15290            final String dataAppName = codeFile.getName();
15291            move = new MoveInfo(moveId, currentVolumeUuid, volumeUuid, packageName,
15292                    dataAppName, appId, seinfo);
15293        } else {
15294            move = null;
15295        }
15296
15297        installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
15298
15299        final Message msg = mHandler.obtainMessage(INIT_COPY);
15300        final OriginInfo origin = OriginInfo.fromExistingFile(codeFile);
15301        msg.obj = new InstallParams(origin, move, installObserver, installFlags,
15302                installerPackageName, volumeUuid, null, user, packageAbiOverride);
15303        mHandler.sendMessage(msg);
15304    }
15305
15306    @Override
15307    public int movePrimaryStorage(String volumeUuid) throws RemoteException {
15308        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
15309
15310        final int realMoveId = mNextMoveId.getAndIncrement();
15311        final Bundle extras = new Bundle();
15312        extras.putString(VolumeRecord.EXTRA_FS_UUID, volumeUuid);
15313        mMoveCallbacks.notifyCreated(realMoveId, extras);
15314
15315        final IPackageMoveObserver callback = new IPackageMoveObserver.Stub() {
15316            @Override
15317            public void onCreated(int moveId, Bundle extras) {
15318                // Ignored
15319            }
15320
15321            @Override
15322            public void onStatusChanged(int moveId, int status, long estMillis) {
15323                mMoveCallbacks.notifyStatusChanged(realMoveId, status, estMillis);
15324            }
15325        };
15326
15327        final StorageManager storage = mContext.getSystemService(StorageManager.class);
15328        storage.setPrimaryStorageUuid(volumeUuid, callback);
15329        return realMoveId;
15330    }
15331
15332    @Override
15333    public int getMoveStatus(int moveId) {
15334        mContext.enforceCallingOrSelfPermission(
15335                android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
15336        return mMoveCallbacks.mLastStatus.get(moveId);
15337    }
15338
15339    @Override
15340    public void registerMoveCallback(IPackageMoveObserver callback) {
15341        mContext.enforceCallingOrSelfPermission(
15342                android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
15343        mMoveCallbacks.register(callback);
15344    }
15345
15346    @Override
15347    public void unregisterMoveCallback(IPackageMoveObserver callback) {
15348        mContext.enforceCallingOrSelfPermission(
15349                android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
15350        mMoveCallbacks.unregister(callback);
15351    }
15352
15353    @Override
15354    public boolean setInstallLocation(int loc) {
15355        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS,
15356                null);
15357        if (getInstallLocation() == loc) {
15358            return true;
15359        }
15360        if (loc == PackageHelper.APP_INSTALL_AUTO || loc == PackageHelper.APP_INSTALL_INTERNAL
15361                || loc == PackageHelper.APP_INSTALL_EXTERNAL) {
15362            android.provider.Settings.Global.putInt(mContext.getContentResolver(),
15363                    android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, loc);
15364            return true;
15365        }
15366        return false;
15367   }
15368
15369    @Override
15370    public int getInstallLocation() {
15371        return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
15372                android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION,
15373                PackageHelper.APP_INSTALL_AUTO);
15374    }
15375
15376    /** Called by UserManagerService */
15377    void cleanUpUserLILPw(UserManagerService userManager, int userHandle) {
15378        mDirtyUsers.remove(userHandle);
15379        mSettings.removeUserLPw(userHandle);
15380        mPendingBroadcasts.remove(userHandle);
15381        if (mInstaller != null) {
15382            // Technically, we shouldn't be doing this with the package lock
15383            // held.  However, this is very rare, and there is already so much
15384            // other disk I/O going on, that we'll let it slide for now.
15385            final StorageManager storage = StorageManager.from(mContext);
15386            final List<VolumeInfo> vols = storage.getVolumes();
15387            for (VolumeInfo vol : vols) {
15388                if (vol.getType() == VolumeInfo.TYPE_PRIVATE && vol.isMountedWritable()) {
15389                    final String volumeUuid = vol.getFsUuid();
15390                    if (DEBUG_INSTALL) Slog.d(TAG, "Removing user data on volume " + volumeUuid);
15391                    mInstaller.removeUserDataDirs(volumeUuid, userHandle);
15392                }
15393            }
15394        }
15395        mUserNeedsBadging.delete(userHandle);
15396        removeUnusedPackagesLILPw(userManager, userHandle);
15397    }
15398
15399    /**
15400     * We're removing userHandle and would like to remove any downloaded packages
15401     * that are no longer in use by any other user.
15402     * @param userHandle the user being removed
15403     */
15404    private void removeUnusedPackagesLILPw(UserManagerService userManager, final int userHandle) {
15405        final boolean DEBUG_CLEAN_APKS = false;
15406        int [] users = userManager.getUserIdsLPr();
15407        Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
15408        while (psit.hasNext()) {
15409            PackageSetting ps = psit.next();
15410            if (ps.pkg == null) {
15411                continue;
15412            }
15413            final String packageName = ps.pkg.packageName;
15414            // Skip over if system app
15415            if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) {
15416                continue;
15417            }
15418            if (DEBUG_CLEAN_APKS) {
15419                Slog.i(TAG, "Checking package " + packageName);
15420            }
15421            boolean keep = false;
15422            for (int i = 0; i < users.length; i++) {
15423                if (users[i] != userHandle && ps.getInstalled(users[i])) {
15424                    keep = true;
15425                    if (DEBUG_CLEAN_APKS) {
15426                        Slog.i(TAG, "  Keeping package " + packageName + " for user "
15427                                + users[i]);
15428                    }
15429                    break;
15430                }
15431            }
15432            if (!keep) {
15433                if (DEBUG_CLEAN_APKS) {
15434                    Slog.i(TAG, "  Removing package " + packageName);
15435                }
15436                mHandler.post(new Runnable() {
15437                    public void run() {
15438                        deletePackageX(packageName, userHandle, 0);
15439                    } //end run
15440                });
15441            }
15442        }
15443    }
15444
15445    /** Called by UserManagerService */
15446    void createNewUserLILPw(int userHandle, File path) {
15447        if (mInstaller != null) {
15448            mInstaller.createUserConfig(userHandle);
15449            mSettings.createNewUserLILPw(this, mInstaller, userHandle, path);
15450        }
15451    }
15452
15453    void newUserCreatedLILPw(final int userHandle) {
15454        // We cannot grant the default permissions with a lock held as
15455        // we query providers from other components for default handlers
15456        // such as enabled IMEs, etc.
15457        mHandler.post(new Runnable() {
15458            @Override
15459            public void run() {
15460                mDefaultPermissionPolicy.grantDefaultPermissions(userHandle);
15461            }
15462        });
15463    }
15464
15465    @Override
15466    public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException {
15467        mContext.enforceCallingOrSelfPermission(
15468                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
15469                "Only package verification agents can read the verifier device identity");
15470
15471        synchronized (mPackages) {
15472            return mSettings.getVerifierDeviceIdentityLPw();
15473        }
15474    }
15475
15476    @Override
15477    public void setPermissionEnforced(String permission, boolean enforced) {
15478        mContext.enforceCallingOrSelfPermission(GRANT_REVOKE_PERMISSIONS, null);
15479        if (READ_EXTERNAL_STORAGE.equals(permission)) {
15480            synchronized (mPackages) {
15481                if (mSettings.mReadExternalStorageEnforced == null
15482                        || mSettings.mReadExternalStorageEnforced != enforced) {
15483                    mSettings.mReadExternalStorageEnforced = enforced;
15484                    mSettings.writeLPr();
15485                }
15486            }
15487            // kill any non-foreground processes so we restart them and
15488            // grant/revoke the GID.
15489            final IActivityManager am = ActivityManagerNative.getDefault();
15490            if (am != null) {
15491                final long token = Binder.clearCallingIdentity();
15492                try {
15493                    am.killProcessesBelowForeground("setPermissionEnforcement");
15494                } catch (RemoteException e) {
15495                } finally {
15496                    Binder.restoreCallingIdentity(token);
15497                }
15498            }
15499        } else {
15500            throw new IllegalArgumentException("No selective enforcement for " + permission);
15501        }
15502    }
15503
15504    @Override
15505    @Deprecated
15506    public boolean isPermissionEnforced(String permission) {
15507        return true;
15508    }
15509
15510    @Override
15511    public boolean isStorageLow() {
15512        final long token = Binder.clearCallingIdentity();
15513        try {
15514            final DeviceStorageMonitorInternal
15515                    dsm = LocalServices.getService(DeviceStorageMonitorInternal.class);
15516            if (dsm != null) {
15517                return dsm.isMemoryLow();
15518            } else {
15519                return false;
15520            }
15521        } finally {
15522            Binder.restoreCallingIdentity(token);
15523        }
15524    }
15525
15526    @Override
15527    public IPackageInstaller getPackageInstaller() {
15528        return mInstallerService;
15529    }
15530
15531    private boolean userNeedsBadging(int userId) {
15532        int index = mUserNeedsBadging.indexOfKey(userId);
15533        if (index < 0) {
15534            final UserInfo userInfo;
15535            final long token = Binder.clearCallingIdentity();
15536            try {
15537                userInfo = sUserManager.getUserInfo(userId);
15538            } finally {
15539                Binder.restoreCallingIdentity(token);
15540            }
15541            final boolean b;
15542            if (userInfo != null && userInfo.isManagedProfile()) {
15543                b = true;
15544            } else {
15545                b = false;
15546            }
15547            mUserNeedsBadging.put(userId, b);
15548            return b;
15549        }
15550        return mUserNeedsBadging.valueAt(index);
15551    }
15552
15553    @Override
15554    public KeySet getKeySetByAlias(String packageName, String alias) {
15555        if (packageName == null || alias == null) {
15556            return null;
15557        }
15558        synchronized(mPackages) {
15559            final PackageParser.Package pkg = mPackages.get(packageName);
15560            if (pkg == null) {
15561                Slog.w(TAG, "KeySet requested for unknown package:" + packageName);
15562                throw new IllegalArgumentException("Unknown package: " + packageName);
15563            }
15564            KeySetManagerService ksms = mSettings.mKeySetManagerService;
15565            return new KeySet(ksms.getKeySetByAliasAndPackageNameLPr(packageName, alias));
15566        }
15567    }
15568
15569    @Override
15570    public KeySet getSigningKeySet(String packageName) {
15571        if (packageName == null) {
15572            return null;
15573        }
15574        synchronized(mPackages) {
15575            final PackageParser.Package pkg = mPackages.get(packageName);
15576            if (pkg == null) {
15577                Slog.w(TAG, "KeySet requested for unknown package:" + packageName);
15578                throw new IllegalArgumentException("Unknown package: " + packageName);
15579            }
15580            if (pkg.applicationInfo.uid != Binder.getCallingUid()
15581                    && Process.SYSTEM_UID != Binder.getCallingUid()) {
15582                throw new SecurityException("May not access signing KeySet of other apps.");
15583            }
15584            KeySetManagerService ksms = mSettings.mKeySetManagerService;
15585            return new KeySet(ksms.getSigningKeySetByPackageNameLPr(packageName));
15586        }
15587    }
15588
15589    @Override
15590    public boolean isPackageSignedByKeySet(String packageName, KeySet ks) {
15591        if (packageName == null || ks == null) {
15592            return false;
15593        }
15594        synchronized(mPackages) {
15595            final PackageParser.Package pkg = mPackages.get(packageName);
15596            if (pkg == null) {
15597                Slog.w(TAG, "KeySet requested for unknown package:" + packageName);
15598                throw new IllegalArgumentException("Unknown package: " + packageName);
15599            }
15600            IBinder ksh = ks.getToken();
15601            if (ksh instanceof KeySetHandle) {
15602                KeySetManagerService ksms = mSettings.mKeySetManagerService;
15603                return ksms.packageIsSignedByLPr(packageName, (KeySetHandle) ksh);
15604            }
15605            return false;
15606        }
15607    }
15608
15609    @Override
15610    public boolean isPackageSignedByKeySetExactly(String packageName, KeySet ks) {
15611        if (packageName == null || ks == null) {
15612            return false;
15613        }
15614        synchronized(mPackages) {
15615            final PackageParser.Package pkg = mPackages.get(packageName);
15616            if (pkg == null) {
15617                Slog.w(TAG, "KeySet requested for unknown package:" + packageName);
15618                throw new IllegalArgumentException("Unknown package: " + packageName);
15619            }
15620            IBinder ksh = ks.getToken();
15621            if (ksh instanceof KeySetHandle) {
15622                KeySetManagerService ksms = mSettings.mKeySetManagerService;
15623                return ksms.packageIsSignedByExactlyLPr(packageName, (KeySetHandle) ksh);
15624            }
15625            return false;
15626        }
15627    }
15628
15629    public void getUsageStatsIfNoPackageUsageInfo() {
15630        if (!mPackageUsage.isHistoricalPackageUsageAvailable()) {
15631            UsageStatsManager usm = (UsageStatsManager) mContext.getSystemService(Context.USAGE_STATS_SERVICE);
15632            if (usm == null) {
15633                throw new IllegalStateException("UsageStatsManager must be initialized");
15634            }
15635            long now = System.currentTimeMillis();
15636            Map<String, UsageStats> stats = usm.queryAndAggregateUsageStats(now - mDexOptLRUThresholdInMills, now);
15637            for (Map.Entry<String, UsageStats> entry : stats.entrySet()) {
15638                String packageName = entry.getKey();
15639                PackageParser.Package pkg = mPackages.get(packageName);
15640                if (pkg == null) {
15641                    continue;
15642                }
15643                UsageStats usage = entry.getValue();
15644                pkg.mLastPackageUsageTimeInMills = usage.getLastTimeUsed();
15645                mPackageUsage.mIsHistoricalPackageUsageAvailable = true;
15646            }
15647        }
15648    }
15649
15650    /**
15651     * Check and throw if the given before/after packages would be considered a
15652     * downgrade.
15653     */
15654    private static void checkDowngrade(PackageParser.Package before, PackageInfoLite after)
15655            throws PackageManagerException {
15656        if (after.versionCode < before.mVersionCode) {
15657            throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
15658                    "Update version code " + after.versionCode + " is older than current "
15659                    + before.mVersionCode);
15660        } else if (after.versionCode == before.mVersionCode) {
15661            if (after.baseRevisionCode < before.baseRevisionCode) {
15662                throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
15663                        "Update base revision code " + after.baseRevisionCode
15664                        + " is older than current " + before.baseRevisionCode);
15665            }
15666
15667            if (!ArrayUtils.isEmpty(after.splitNames)) {
15668                for (int i = 0; i < after.splitNames.length; i++) {
15669                    final String splitName = after.splitNames[i];
15670                    final int j = ArrayUtils.indexOf(before.splitNames, splitName);
15671                    if (j != -1) {
15672                        if (after.splitRevisionCodes[i] < before.splitRevisionCodes[j]) {
15673                            throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
15674                                    "Update split " + splitName + " revision code "
15675                                    + after.splitRevisionCodes[i] + " is older than current "
15676                                    + before.splitRevisionCodes[j]);
15677                        }
15678                    }
15679                }
15680            }
15681        }
15682    }
15683
15684    private static class MoveCallbacks extends Handler {
15685        private static final int MSG_CREATED = 1;
15686        private static final int MSG_STATUS_CHANGED = 2;
15687
15688        private final RemoteCallbackList<IPackageMoveObserver>
15689                mCallbacks = new RemoteCallbackList<>();
15690
15691        private final SparseIntArray mLastStatus = new SparseIntArray();
15692
15693        public MoveCallbacks(Looper looper) {
15694            super(looper);
15695        }
15696
15697        public void register(IPackageMoveObserver callback) {
15698            mCallbacks.register(callback);
15699        }
15700
15701        public void unregister(IPackageMoveObserver callback) {
15702            mCallbacks.unregister(callback);
15703        }
15704
15705        @Override
15706        public void handleMessage(Message msg) {
15707            final SomeArgs args = (SomeArgs) msg.obj;
15708            final int n = mCallbacks.beginBroadcast();
15709            for (int i = 0; i < n; i++) {
15710                final IPackageMoveObserver callback = mCallbacks.getBroadcastItem(i);
15711                try {
15712                    invokeCallback(callback, msg.what, args);
15713                } catch (RemoteException ignored) {
15714                }
15715            }
15716            mCallbacks.finishBroadcast();
15717            args.recycle();
15718        }
15719
15720        private void invokeCallback(IPackageMoveObserver callback, int what, SomeArgs args)
15721                throws RemoteException {
15722            switch (what) {
15723                case MSG_CREATED: {
15724                    callback.onCreated(args.argi1, (Bundle) args.arg2);
15725                    break;
15726                }
15727                case MSG_STATUS_CHANGED: {
15728                    callback.onStatusChanged(args.argi1, args.argi2, (long) args.arg3);
15729                    break;
15730                }
15731            }
15732        }
15733
15734        private void notifyCreated(int moveId, Bundle extras) {
15735            Slog.v(TAG, "Move " + moveId + " created " + extras.toString());
15736
15737            final SomeArgs args = SomeArgs.obtain();
15738            args.argi1 = moveId;
15739            args.arg2 = extras;
15740            obtainMessage(MSG_CREATED, args).sendToTarget();
15741        }
15742
15743        private void notifyStatusChanged(int moveId, int status) {
15744            notifyStatusChanged(moveId, status, -1);
15745        }
15746
15747        private void notifyStatusChanged(int moveId, int status, long estMillis) {
15748            Slog.v(TAG, "Move " + moveId + " status " + status);
15749
15750            final SomeArgs args = SomeArgs.obtain();
15751            args.argi1 = moveId;
15752            args.argi2 = status;
15753            args.arg3 = estMillis;
15754            obtainMessage(MSG_STATUS_CHANGED, args).sendToTarget();
15755
15756            synchronized (mLastStatus) {
15757                mLastStatus.put(moveId, status);
15758            }
15759        }
15760    }
15761
15762    private final class OnPermissionChangeListeners extends Handler {
15763        private static final int MSG_ON_PERMISSIONS_CHANGED = 1;
15764
15765        private final RemoteCallbackList<IOnPermissionsChangeListener> mPermissionListeners =
15766                new RemoteCallbackList<>();
15767
15768        public OnPermissionChangeListeners(Looper looper) {
15769            super(looper);
15770        }
15771
15772        @Override
15773        public void handleMessage(Message msg) {
15774            switch (msg.what) {
15775                case MSG_ON_PERMISSIONS_CHANGED: {
15776                    final int uid = msg.arg1;
15777                    handleOnPermissionsChanged(uid);
15778                } break;
15779            }
15780        }
15781
15782        public void addListenerLocked(IOnPermissionsChangeListener listener) {
15783            mPermissionListeners.register(listener);
15784
15785        }
15786
15787        public void removeListenerLocked(IOnPermissionsChangeListener listener) {
15788            mPermissionListeners.unregister(listener);
15789        }
15790
15791        public void onPermissionsChanged(int uid) {
15792            if (mPermissionListeners.getRegisteredCallbackCount() > 0) {
15793                obtainMessage(MSG_ON_PERMISSIONS_CHANGED, uid, 0).sendToTarget();
15794            }
15795        }
15796
15797        private void handleOnPermissionsChanged(int uid) {
15798            final int count = mPermissionListeners.beginBroadcast();
15799            try {
15800                for (int i = 0; i < count; i++) {
15801                    IOnPermissionsChangeListener callback = mPermissionListeners
15802                            .getBroadcastItem(i);
15803                    try {
15804                        callback.onPermissionsChanged(uid);
15805                    } catch (RemoteException e) {
15806                        Log.e(TAG, "Permission listener is dead", e);
15807                    }
15808                }
15809            } finally {
15810                mPermissionListeners.finishBroadcast();
15811            }
15812        }
15813    }
15814
15815    private class PackageManagerInternalImpl extends PackageManagerInternal {
15816        @Override
15817        public void setLocationPackagesProvider(PackagesProvider provider) {
15818            synchronized (mPackages) {
15819                mDefaultPermissionPolicy.setLocationPackagesProviderLPw(provider);
15820            }
15821        }
15822
15823        @Override
15824        public void setImePackagesProvider(PackagesProvider provider) {
15825            synchronized (mPackages) {
15826                mDefaultPermissionPolicy.setImePackagesProviderLPr(provider);
15827            }
15828        }
15829
15830        @Override
15831        public void setVoiceInteractionPackagesProvider(PackagesProvider provider) {
15832            synchronized (mPackages) {
15833                mDefaultPermissionPolicy.setVoiceInteractionPackagesProviderLPw(provider);
15834            }
15835        }
15836    }
15837
15838    @Override
15839    public void grantDefaultPermissions(final int userId) {
15840        enforceSystemOrPhoneCaller("grantDefaultPermissions");
15841        long token = Binder.clearCallingIdentity();
15842        try {
15843            // We cannot grant the default permissions with a lock held as
15844            // we query providers from other components for default handlers
15845            // such as enabled IMEs, etc.
15846            mHandler.post(new Runnable() {
15847                @Override
15848                public void run() {
15849                    mDefaultPermissionPolicy.grantDefaultPermissions(userId);
15850                }
15851            });
15852        } finally {
15853            Binder.restoreCallingIdentity(token);
15854        }
15855    }
15856
15857    @Override
15858    public void setCarrierAppPackagesProvider(final IPackagesProvider provider) {
15859        enforceSystemOrPhoneCaller("setCarrierAppPackagesProvider");
15860        long token = Binder.clearCallingIdentity();
15861        try {
15862            PackageManagerInternal.PackagesProvider wrapper =
15863                    new PackageManagerInternal.PackagesProvider() {
15864                @Override
15865                public String[] getPackages(int userId) {
15866                    try {
15867                        return provider.getPackages(userId);
15868                    } catch (RemoteException e) {
15869                        return null;
15870                    }
15871                }
15872            };
15873            synchronized (mPackages) {
15874                mDefaultPermissionPolicy.setCarrierAppPackagesProviderLPw(wrapper);
15875            }
15876        } finally {
15877            Binder.restoreCallingIdentity(token);
15878        }
15879    }
15880
15881    private static void enforceSystemOrPhoneCaller(String tag) {
15882        int callingUid = Binder.getCallingUid();
15883        if (callingUid != Process.PHONE_UID && callingUid != Process.SYSTEM_UID) {
15884            throw new SecurityException(
15885                    "Cannot call " + tag + " from UID " + callingUid);
15886        }
15887    }
15888}
15889