PackageManagerService.java revision 019d2304998f3ed77c0a608df6cf4bea1138f8dc
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.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
22import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
23import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED;
24import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER;
25import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
26import static android.content.pm.PackageManager.INSTALL_EXTERNAL;
27import static android.content.pm.PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
28import static android.content.pm.PackageManager.INSTALL_FAILED_CONFLICTING_PROVIDER;
29import static android.content.pm.PackageManager.INSTALL_FAILED_DEXOPT;
30import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE;
31import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION;
32import static android.content.pm.PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
33import static android.content.pm.PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
34import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_APK;
35import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
36import static android.content.pm.PackageManager.INSTALL_FAILED_MISSING_SHARED_LIBRARY;
37import static android.content.pm.PackageManager.INSTALL_FAILED_PACKAGE_CHANGED;
38import static android.content.pm.PackageManager.INSTALL_FAILED_REPLACE_COULDNT_DELETE;
39import static android.content.pm.PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE;
40import static android.content.pm.PackageManager.INSTALL_FAILED_TEST_ONLY;
41import static android.content.pm.PackageManager.INSTALL_FAILED_UID_CHANGED;
42import static android.content.pm.PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE;
43import static android.content.pm.PackageManager.INSTALL_FAILED_USER_RESTRICTED;
44import static android.content.pm.PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
45import static android.content.pm.PackageManager.INSTALL_FORWARD_LOCK;
46import static android.content.pm.PackageManager.INSTALL_INTERNAL;
47import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
48import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
49import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK;
50import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER;
51import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
52import static android.content.pm.PackageManager.MATCH_ALL;
53import static android.content.pm.PackageManager.MOVE_FAILED_DOESNT_EXIST;
54import static android.content.pm.PackageManager.MOVE_FAILED_INTERNAL_ERROR;
55import static android.content.pm.PackageManager.MOVE_FAILED_OPERATION_PENDING;
56import static android.content.pm.PackageManager.MOVE_FAILED_SYSTEM_PACKAGE;
57import static android.content.pm.PackageParser.isApkFile;
58import static android.os.Process.PACKAGE_INFO_GID;
59import static android.os.Process.SYSTEM_UID;
60import static android.system.OsConstants.O_CREAT;
61import static android.system.OsConstants.O_RDWR;
62import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE;
63import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_USER_OWNER;
64import static com.android.internal.content.NativeLibraryHelper.LIB64_DIR_NAME;
65import static com.android.internal.content.NativeLibraryHelper.LIB_DIR_NAME;
66import static com.android.internal.util.ArrayUtils.appendInt;
67import static com.android.server.pm.InstructionSets.getAppDexInstructionSets;
68import static com.android.server.pm.InstructionSets.getDexCodeInstructionSet;
69import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets;
70import static com.android.server.pm.InstructionSets.getPreferredInstructionSet;
71import static com.android.server.pm.InstructionSets.getPrimaryInstructionSet;
72
73import android.Manifest;
74import android.app.ActivityManager;
75import android.app.ActivityManagerNative;
76import android.app.AppGlobals;
77import android.app.IActivityManager;
78import android.app.admin.IDevicePolicyManager;
79import android.app.backup.IBackupManager;
80import android.app.usage.UsageStats;
81import android.app.usage.UsageStatsManager;
82import android.content.BroadcastReceiver;
83import android.content.ComponentName;
84import android.content.Context;
85import android.content.IIntentReceiver;
86import android.content.Intent;
87import android.content.IntentFilter;
88import android.content.IntentSender;
89import android.content.IntentSender.SendIntentException;
90import android.content.ServiceConnection;
91import android.content.pm.ActivityInfo;
92import android.content.pm.ApplicationInfo;
93import android.content.pm.FeatureInfo;
94import android.content.pm.IPackageDataObserver;
95import android.content.pm.IPackageDeleteObserver;
96import android.content.pm.IPackageDeleteObserver2;
97import android.content.pm.IPackageInstallObserver2;
98import android.content.pm.IPackageInstaller;
99import android.content.pm.IPackageManager;
100import android.content.pm.IPackageMoveObserver;
101import android.content.pm.IPackageStatsObserver;
102import android.content.pm.InstrumentationInfo;
103import android.content.pm.IntentFilterVerificationInfo;
104import android.content.pm.KeySet;
105import android.content.pm.ManifestDigest;
106import android.content.pm.PackageCleanItem;
107import android.content.pm.PackageInfo;
108import android.content.pm.PackageInfoLite;
109import android.content.pm.PackageInstaller;
110import android.content.pm.PackageManager;
111import android.content.pm.PackageManager.LegacyPackageDeleteObserver;
112import android.content.pm.PackageParser;
113import android.content.pm.PackageParser.ActivityIntentInfo;
114import android.content.pm.PackageParser.PackageLite;
115import android.content.pm.PackageParser.PackageParserException;
116import android.content.pm.PackageStats;
117import android.content.pm.PackageUserState;
118import android.content.pm.ParceledListSlice;
119import android.content.pm.PermissionGroupInfo;
120import android.content.pm.PermissionInfo;
121import android.content.pm.ProviderInfo;
122import android.content.pm.ResolveInfo;
123import android.content.pm.ServiceInfo;
124import android.content.pm.Signature;
125import android.content.pm.UserInfo;
126import android.content.pm.VerificationParams;
127import android.content.pm.VerifierDeviceIdentity;
128import android.content.pm.VerifierInfo;
129import android.content.res.Resources;
130import android.hardware.display.DisplayManager;
131import android.net.Uri;
132import android.os.Binder;
133import android.os.Build;
134import android.os.Bundle;
135import android.os.Debug;
136import android.os.Environment;
137import android.os.Environment.UserEnvironment;
138import android.os.FileUtils;
139import android.os.Handler;
140import android.os.IBinder;
141import android.os.Looper;
142import android.os.Message;
143import android.os.Parcel;
144import android.os.ParcelFileDescriptor;
145import android.os.Process;
146import android.os.RemoteCallbackList;
147import android.os.RemoteException;
148import android.os.SELinux;
149import android.os.ServiceManager;
150import android.os.SystemClock;
151import android.os.SystemProperties;
152import android.os.UserHandle;
153import android.os.UserManager;
154import android.os.storage.IMountService;
155import android.os.storage.StorageEventListener;
156import android.os.storage.StorageManager;
157import android.os.storage.VolumeInfo;
158import android.os.storage.VolumeRecord;
159import android.security.KeyStore;
160import android.security.SystemKeyStore;
161import android.system.ErrnoException;
162import android.system.Os;
163import android.system.StructStat;
164import android.text.TextUtils;
165import android.text.format.DateUtils;
166import android.util.ArrayMap;
167import android.util.ArraySet;
168import android.util.AtomicFile;
169import android.util.DisplayMetrics;
170import android.util.EventLog;
171import android.util.ExceptionUtils;
172import android.util.Log;
173import android.util.LogPrinter;
174import android.util.MathUtils;
175import android.util.PrintStreamPrinter;
176import android.util.Slog;
177import android.util.SparseArray;
178import android.util.SparseBooleanArray;
179import android.util.SparseIntArray;
180import android.util.Xml;
181import android.view.Display;
182
183import dalvik.system.DexFile;
184import dalvik.system.VMRuntime;
185
186import libcore.io.IoUtils;
187import libcore.util.EmptyArray;
188
189import com.android.internal.R;
190import com.android.internal.app.IMediaContainerService;
191import com.android.internal.app.ResolverActivity;
192import com.android.internal.content.NativeLibraryHelper;
193import com.android.internal.content.PackageHelper;
194import com.android.internal.os.IParcelFileDescriptorFactory;
195import com.android.internal.os.SomeArgs;
196import com.android.internal.util.ArrayUtils;
197import com.android.internal.util.FastPrintWriter;
198import com.android.internal.util.FastXmlSerializer;
199import com.android.internal.util.IndentingPrintWriter;
200import com.android.internal.util.Preconditions;
201import com.android.server.EventLogTags;
202import com.android.server.FgThread;
203import com.android.server.IntentResolver;
204import com.android.server.LocalServices;
205import com.android.server.ServiceThread;
206import com.android.server.SystemConfig;
207import com.android.server.Watchdog;
208import com.android.server.pm.Settings.DatabaseVersion;
209import com.android.server.storage.DeviceStorageMonitorInternal;
210
211import org.xmlpull.v1.XmlPullParser;
212import org.xmlpull.v1.XmlSerializer;
213
214import java.io.BufferedInputStream;
215import java.io.BufferedOutputStream;
216import java.io.BufferedReader;
217import java.io.ByteArrayInputStream;
218import java.io.ByteArrayOutputStream;
219import java.io.File;
220import java.io.FileDescriptor;
221import java.io.FileNotFoundException;
222import java.io.FileOutputStream;
223import java.io.FileReader;
224import java.io.FilenameFilter;
225import java.io.IOException;
226import java.io.InputStream;
227import java.io.PrintWriter;
228import java.nio.charset.StandardCharsets;
229import java.security.NoSuchAlgorithmException;
230import java.security.PublicKey;
231import java.security.cert.CertificateEncodingException;
232import java.security.cert.CertificateException;
233import java.text.SimpleDateFormat;
234import java.util.ArrayList;
235import java.util.Arrays;
236import java.util.Collection;
237import java.util.Collections;
238import java.util.Comparator;
239import java.util.Date;
240import java.util.Iterator;
241import java.util.List;
242import java.util.Map;
243import java.util.Objects;
244import java.util.Set;
245import java.util.concurrent.CountDownLatch;
246import java.util.concurrent.TimeUnit;
247import java.util.concurrent.atomic.AtomicBoolean;
248import java.util.concurrent.atomic.AtomicInteger;
249import java.util.concurrent.atomic.AtomicLong;
250
251/**
252 * Keep track of all those .apks everywhere.
253 *
254 * This is very central to the platform's security; please run the unit
255 * tests whenever making modifications here:
256 *
257mmm frameworks/base/tests/AndroidTests
258adb install -r -f out/target/product/passion/data/app/AndroidTests.apk
259adb shell am instrument -w -e class com.android.unit_tests.PackageManagerTests com.android.unit_tests/android.test.InstrumentationTestRunner
260 *
261 * {@hide}
262 */
263public class PackageManagerService extends IPackageManager.Stub {
264    static final String TAG = "PackageManager";
265    static final boolean DEBUG_SETTINGS = false;
266    static final boolean DEBUG_PREFERRED = false;
267    static final boolean DEBUG_UPGRADE = false;
268    private static final boolean DEBUG_BACKUP = true;
269    private static final boolean DEBUG_INSTALL = false;
270    private static final boolean DEBUG_REMOVE = false;
271    private static final boolean DEBUG_BROADCASTS = false;
272    private static final boolean DEBUG_SHOW_INFO = false;
273    private static final boolean DEBUG_PACKAGE_INFO = false;
274    private static final boolean DEBUG_INTENT_MATCHING = false;
275    private static final boolean DEBUG_PACKAGE_SCANNING = false;
276    private static final boolean DEBUG_VERIFY = false;
277    private static final boolean DEBUG_DEXOPT = false;
278    private static final boolean DEBUG_ABI_SELECTION = false;
279
280    private static final int RADIO_UID = Process.PHONE_UID;
281    private static final int LOG_UID = Process.LOG_UID;
282    private static final int NFC_UID = Process.NFC_UID;
283    private static final int BLUETOOTH_UID = Process.BLUETOOTH_UID;
284    private static final int SHELL_UID = Process.SHELL_UID;
285
286    // Cap the size of permission trees that 3rd party apps can define
287    private static final int MAX_PERMISSION_TREE_FOOTPRINT = 32768;     // characters of text
288
289    // Suffix used during package installation when copying/moving
290    // package apks to install directory.
291    private static final String INSTALL_PACKAGE_SUFFIX = "-";
292
293    static final int SCAN_NO_DEX = 1<<1;
294    static final int SCAN_FORCE_DEX = 1<<2;
295    static final int SCAN_UPDATE_SIGNATURE = 1<<3;
296    static final int SCAN_NEW_INSTALL = 1<<4;
297    static final int SCAN_NO_PATHS = 1<<5;
298    static final int SCAN_UPDATE_TIME = 1<<6;
299    static final int SCAN_DEFER_DEX = 1<<7;
300    static final int SCAN_BOOTING = 1<<8;
301    static final int SCAN_TRUSTED_OVERLAY = 1<<9;
302    static final int SCAN_DELETE_DATA_ON_FAILURES = 1<<10;
303    static final int SCAN_REQUIRE_KNOWN = 1<<12;
304
305    static final int REMOVE_CHATTY = 1<<16;
306
307    /**
308     * Timeout (in milliseconds) after which the watchdog should declare that
309     * our handler thread is wedged.  The usual default for such things is one
310     * minute but we sometimes do very lengthy I/O operations on this thread,
311     * such as installing multi-gigabyte applications, so ours needs to be longer.
312     */
313    private static final long WATCHDOG_TIMEOUT = 1000*60*10;     // ten minutes
314
315    /**
316     * Wall-clock timeout (in milliseconds) after which we *require* that an fstrim
317     * be run on this device.  We use the value in the Settings.Global.MANDATORY_FSTRIM_INTERVAL
318     * settings entry if available, otherwise we use the hardcoded default.  If it's been
319     * more than this long since the last fstrim, we force one during the boot sequence.
320     *
321     * This backstops other fstrim scheduling:  if the device is alive at midnight+idle,
322     * one gets run at the next available charging+idle time.  This final mandatory
323     * no-fstrim check kicks in only of the other scheduling criteria is never met.
324     */
325    private static final long DEFAULT_MANDATORY_FSTRIM_INTERVAL = 3 * DateUtils.DAY_IN_MILLIS;
326
327    /**
328     * Whether verification is enabled by default.
329     */
330    private static final boolean DEFAULT_VERIFY_ENABLE = true;
331
332    /**
333     * The default maximum time to wait for the verification agent to return in
334     * milliseconds.
335     */
336    private static final long DEFAULT_VERIFICATION_TIMEOUT = 10 * 1000;
337
338    /**
339     * The default response for package verification timeout.
340     *
341     * This can be either PackageManager.VERIFICATION_ALLOW or
342     * PackageManager.VERIFICATION_REJECT.
343     */
344    private static final int DEFAULT_VERIFICATION_RESPONSE = PackageManager.VERIFICATION_ALLOW;
345
346    static final String DEFAULT_CONTAINER_PACKAGE = "com.android.defcontainer";
347
348    static final ComponentName DEFAULT_CONTAINER_COMPONENT = new ComponentName(
349            DEFAULT_CONTAINER_PACKAGE,
350            "com.android.defcontainer.DefaultContainerService");
351
352    private static final String KILL_APP_REASON_GIDS_CHANGED =
353            "permission grant or revoke changed gids";
354
355    private static final String KILL_APP_REASON_PERMISSIONS_REVOKED =
356            "permissions revoked";
357
358    private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive";
359
360    private static final String VENDOR_OVERLAY_DIR = "/vendor/overlay";
361
362    /** Permission grant: not grant the permission. */
363    private static final int GRANT_DENIED = 1;
364
365    /** Permission grant: grant the permission as an install permission. */
366    private static final int GRANT_INSTALL = 2;
367
368    /** Permission grant: grant the permission as a runtime one. */
369    private static final int GRANT_RUNTIME = 3;
370
371    /** Permission grant: grant as runtime a permission that was granted as an install time one. */
372    private static final int GRANT_UPGRADE = 4;
373
374    final ServiceThread mHandlerThread;
375
376    final PackageHandler mHandler;
377
378    /**
379     * Messages for {@link #mHandler} that need to wait for system ready before
380     * being dispatched.
381     */
382    private ArrayList<Message> mPostSystemReadyMessages;
383
384    final int mSdkVersion = Build.VERSION.SDK_INT;
385
386    final Context mContext;
387    final boolean mFactoryTest;
388    final boolean mOnlyCore;
389    final boolean mLazyDexOpt;
390    final long mDexOptLRUThresholdInMills;
391    final DisplayMetrics mMetrics;
392    final int mDefParseFlags;
393    final String[] mSeparateProcesses;
394    final boolean mIsUpgrade;
395
396    // This is where all application persistent data goes.
397    final File mAppDataDir;
398
399    // This is where all application persistent data goes for secondary users.
400    final File mUserAppDataDir;
401
402    /** The location for ASEC container files on internal storage. */
403    final String mAsecInternalPath;
404
405    // Used for privilege escalation. MUST NOT BE CALLED WITH mPackages
406    // LOCK HELD.  Can be called with mInstallLock held.
407    final Installer mInstaller;
408
409    /** Directory where installed third-party apps stored */
410    final File mAppInstallDir;
411
412    /**
413     * Directory to which applications installed internally have their
414     * 32 bit native libraries copied.
415     */
416    private File mAppLib32InstallDir;
417
418    // Directory containing the private parts (e.g. code and non-resource assets) of forward-locked
419    // apps.
420    final File mDrmAppPrivateInstallDir;
421
422    // ----------------------------------------------------------------
423
424    // Lock for state used when installing and doing other long running
425    // operations.  Methods that must be called with this lock held have
426    // the suffix "LI".
427    final Object mInstallLock = new Object();
428
429    // ----------------------------------------------------------------
430
431    // Keys are String (package name), values are Package.  This also serves
432    // as the lock for the global state.  Methods that must be called with
433    // this lock held have the prefix "LP".
434    final ArrayMap<String, PackageParser.Package> mPackages =
435            new ArrayMap<String, PackageParser.Package>();
436
437    // Tracks available target package names -> overlay package paths.
438    final ArrayMap<String, ArrayMap<String, PackageParser.Package>> mOverlays =
439        new ArrayMap<String, ArrayMap<String, PackageParser.Package>>();
440
441    final Settings mSettings;
442    boolean mRestoredSettings;
443
444    // System configuration read by SystemConfig.
445    final int[] mGlobalGids;
446    final SparseArray<ArraySet<String>> mSystemPermissions;
447    final ArrayMap<String, FeatureInfo> mAvailableFeatures;
448
449    // If mac_permissions.xml was found for seinfo labeling.
450    boolean mFoundPolicyFile;
451
452    // If a recursive restorecon of /data/data/<pkg> is needed.
453    private boolean mShouldRestoreconData = SELinuxMMAC.shouldRestorecon();
454
455    public static final class SharedLibraryEntry {
456        public final String path;
457        public final String apk;
458
459        SharedLibraryEntry(String _path, String _apk) {
460            path = _path;
461            apk = _apk;
462        }
463    }
464
465    // Currently known shared libraries.
466    final ArrayMap<String, SharedLibraryEntry> mSharedLibraries =
467            new ArrayMap<String, SharedLibraryEntry>();
468
469    // All available activities, for your resolving pleasure.
470    final ActivityIntentResolver mActivities =
471            new ActivityIntentResolver();
472
473    // All available receivers, for your resolving pleasure.
474    final ActivityIntentResolver mReceivers =
475            new ActivityIntentResolver();
476
477    // All available services, for your resolving pleasure.
478    final ServiceIntentResolver mServices = new ServiceIntentResolver();
479
480    // All available providers, for your resolving pleasure.
481    final ProviderIntentResolver mProviders = new ProviderIntentResolver();
482
483    // Mapping from provider base names (first directory in content URI codePath)
484    // to the provider information.
485    final ArrayMap<String, PackageParser.Provider> mProvidersByAuthority =
486            new ArrayMap<String, PackageParser.Provider>();
487
488    // Mapping from instrumentation class names to info about them.
489    final ArrayMap<ComponentName, PackageParser.Instrumentation> mInstrumentation =
490            new ArrayMap<ComponentName, PackageParser.Instrumentation>();
491
492    // Mapping from permission names to info about them.
493    final ArrayMap<String, PackageParser.PermissionGroup> mPermissionGroups =
494            new ArrayMap<String, PackageParser.PermissionGroup>();
495
496    // Packages whose data we have transfered into another package, thus
497    // should no longer exist.
498    final ArraySet<String> mTransferedPackages = new ArraySet<String>();
499
500    // Broadcast actions that are only available to the system.
501    final ArraySet<String> mProtectedBroadcasts = new ArraySet<String>();
502
503    /** List of packages waiting for verification. */
504    final SparseArray<PackageVerificationState> mPendingVerification
505            = new SparseArray<PackageVerificationState>();
506
507    /** Set of packages associated with each app op permission. */
508    final ArrayMap<String, ArraySet<String>> mAppOpPermissionPackages = new ArrayMap<>();
509
510    final PackageInstallerService mInstallerService;
511
512    private final PackageDexOptimizer mPackageDexOptimizer;
513
514    private AtomicInteger mNextMoveId = new AtomicInteger();
515    private final MoveCallbacks mMoveCallbacks;
516
517    // Cache of users who need badging.
518    SparseBooleanArray mUserNeedsBadging = new SparseBooleanArray();
519
520    /** Token for keys in mPendingVerification. */
521    private int mPendingVerificationToken = 0;
522
523    volatile boolean mSystemReady;
524    volatile boolean mSafeMode;
525    volatile boolean mHasSystemUidErrors;
526
527    ApplicationInfo mAndroidApplication;
528    final ActivityInfo mResolveActivity = new ActivityInfo();
529    final ResolveInfo mResolveInfo = new ResolveInfo();
530    ComponentName mResolveComponentName;
531    PackageParser.Package mPlatformPackage;
532    ComponentName mCustomResolverComponentName;
533
534    boolean mResolverReplaced = false;
535
536    private final ComponentName mIntentFilterVerifierComponent;
537    private int mIntentFilterVerificationToken = 0;
538
539    final SparseArray<IntentFilterVerificationState> mIntentFilterVerificationStates
540            = new SparseArray<IntentFilterVerificationState>();
541
542    private interface IntentFilterVerifier<T extends IntentFilter> {
543        boolean addOneIntentFilterVerification(int verifierId, int userId, int verificationId,
544                                               T filter, String packageName);
545        void startVerifications(int userId);
546        void receiveVerificationResponse(int verificationId);
547    }
548
549    private class IntentVerifierProxy implements IntentFilterVerifier<ActivityIntentInfo> {
550        private Context mContext;
551        private ComponentName mIntentFilterVerifierComponent;
552        private ArrayList<Integer> mCurrentIntentFilterVerifications = new ArrayList<Integer>();
553
554        public IntentVerifierProxy(Context context, ComponentName verifierComponent) {
555            mContext = context;
556            mIntentFilterVerifierComponent = verifierComponent;
557        }
558
559        private String getDefaultScheme() {
560            // TODO: replace SCHEME_HTTP with SCHEME_HTTPS
561            return IntentFilter.SCHEME_HTTP;
562        }
563
564        @Override
565        public void startVerifications(int userId) {
566            // Launch verifications requests
567            int count = mCurrentIntentFilterVerifications.size();
568            for (int n=0; n<count; n++) {
569                int verificationId = mCurrentIntentFilterVerifications.get(n);
570                final IntentFilterVerificationState ivs =
571                        mIntentFilterVerificationStates.get(verificationId);
572
573                String packageName = ivs.getPackageName();
574
575                ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters();
576                final int filterCount = filters.size();
577                ArraySet<String> domainsSet = new ArraySet<>();
578                for (int m=0; m<filterCount; m++) {
579                    PackageParser.ActivityIntentInfo filter = filters.get(m);
580                    domainsSet.addAll(filter.getHostsList());
581                }
582                ArrayList<String> domainsList = new ArrayList<>(domainsSet);
583                synchronized (mPackages) {
584                    if (mSettings.createIntentFilterVerificationIfNeededLPw(
585                            packageName, domainsList) != null) {
586                        scheduleWriteSettingsLocked();
587                    }
588                }
589                sendVerificationRequest(userId, verificationId, ivs);
590            }
591            mCurrentIntentFilterVerifications.clear();
592        }
593
594        private void sendVerificationRequest(int userId, int verificationId,
595                IntentFilterVerificationState ivs) {
596
597            Intent verificationIntent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION);
598            verificationIntent.putExtra(
599                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_ID,
600                    verificationId);
601            verificationIntent.putExtra(
602                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_URI_SCHEME,
603                    getDefaultScheme());
604            verificationIntent.putExtra(
605                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_HOSTS,
606                    ivs.getHostsString());
607            verificationIntent.putExtra(
608                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_PACKAGE_NAME,
609                    ivs.getPackageName());
610            verificationIntent.setComponent(mIntentFilterVerifierComponent);
611            verificationIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
612
613            UserHandle user = new UserHandle(userId);
614            mContext.sendBroadcastAsUser(verificationIntent, user);
615            Slog.d(TAG, "Sending IntenFilter verification broadcast");
616        }
617
618        public void receiveVerificationResponse(int verificationId) {
619            IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId);
620
621            final boolean verified = ivs.isVerified();
622
623            ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters();
624            final int count = filters.size();
625            for (int n=0; n<count; n++) {
626                PackageParser.ActivityIntentInfo filter = filters.get(n);
627                filter.setVerified(verified);
628
629                Slog.d(TAG, "IntentFilter " + filter.toString() + " verified with result:"
630                        + verified + " and hosts:" + ivs.getHostsString());
631            }
632
633            mIntentFilterVerificationStates.remove(verificationId);
634
635            final String packageName = ivs.getPackageName();
636            IntentFilterVerificationInfo ivi = null;
637
638            synchronized (mPackages) {
639                ivi = mSettings.getIntentFilterVerificationLPr(packageName);
640            }
641            if (ivi == null) {
642                Slog.w(TAG, "IntentFilterVerificationInfo not found for verificationId:"
643                        + verificationId + " packageName:" + packageName);
644                return;
645            }
646            Slog.d(TAG, "Updating IntentFilterVerificationInfo for verificationId:"
647                    + verificationId);
648
649            synchronized (mPackages) {
650                if (verified) {
651                    ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS);
652                } else {
653                    ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK);
654                }
655                scheduleWriteSettingsLocked();
656
657                final int userId = ivs.getUserId();
658                if (userId != UserHandle.USER_ALL) {
659                    final int userStatus =
660                            mSettings.getIntentFilterVerificationStatusLPr(packageName, userId);
661
662                    int updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
663                    boolean needUpdate = false;
664
665                    // We cannot override the STATUS_ALWAYS / STATUS_NEVER states if they have
666                    // already been set by the User thru the Disambiguation dialog
667                    switch (userStatus) {
668                        case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED:
669                            if (verified) {
670                                updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
671                            } else {
672                                updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK;
673                            }
674                            needUpdate = true;
675                            break;
676
677                        case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK:
678                            if (verified) {
679                                updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
680                                needUpdate = true;
681                            }
682                            break;
683
684                        default:
685                            // Nothing to do
686                    }
687
688                    if (needUpdate) {
689                        mSettings.updateIntentFilterVerificationStatusLPw(
690                                packageName, updatedStatus, userId);
691                        scheduleWritePackageRestrictionsLocked(userId);
692                    }
693                }
694            }
695        }
696
697        @Override
698        public boolean addOneIntentFilterVerification(int verifierId, int userId, int verificationId,
699                    ActivityIntentInfo filter, String packageName) {
700            if (!(filter.hasDataScheme(IntentFilter.SCHEME_HTTP) ||
701                    filter.hasDataScheme(IntentFilter.SCHEME_HTTPS))) {
702                Slog.d(TAG, "IntentFilter does not contain HTTP nor HTTPS data scheme");
703                return false;
704            }
705            IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId);
706            if (ivs == null) {
707                ivs = createDomainVerificationState(verifierId, userId, verificationId,
708                        packageName);
709            }
710            if (!hasValidDomains(filter)) {
711                return false;
712            }
713            ivs.addFilter(filter);
714            return true;
715        }
716
717        private IntentFilterVerificationState createDomainVerificationState(int verifierId,
718                int userId, int verificationId, String packageName) {
719            IntentFilterVerificationState ivs = new IntentFilterVerificationState(
720                    verifierId, userId, packageName);
721            ivs.setPendingState();
722            synchronized (mPackages) {
723                mIntentFilterVerificationStates.append(verificationId, ivs);
724                mCurrentIntentFilterVerifications.add(verificationId);
725            }
726            return ivs;
727        }
728    }
729
730    private static boolean hasValidDomains(ActivityIntentInfo filter) {
731        return hasValidDomains(filter, true);
732    }
733
734    private static boolean hasValidDomains(ActivityIntentInfo filter, boolean logging) {
735        boolean hasHTTPorHTTPS = filter.hasDataScheme(IntentFilter.SCHEME_HTTP) ||
736                filter.hasDataScheme(IntentFilter.SCHEME_HTTPS);
737        if (!hasHTTPorHTTPS) {
738            if (logging) {
739                Slog.d(TAG, "IntentFilter does not contain any HTTP or HTTPS data scheme");
740            }
741            return false;
742        }
743        return true;
744    }
745
746    private IntentFilterVerifier mIntentFilterVerifier;
747
748    // Set of pending broadcasts for aggregating enable/disable of components.
749    static class PendingPackageBroadcasts {
750        // for each user id, a map of <package name -> components within that package>
751        final SparseArray<ArrayMap<String, ArrayList<String>>> mUidMap;
752
753        public PendingPackageBroadcasts() {
754            mUidMap = new SparseArray<ArrayMap<String, ArrayList<String>>>(2);
755        }
756
757        public ArrayList<String> get(int userId, String packageName) {
758            ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId);
759            return packages.get(packageName);
760        }
761
762        public void put(int userId, String packageName, ArrayList<String> components) {
763            ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId);
764            packages.put(packageName, components);
765        }
766
767        public void remove(int userId, String packageName) {
768            ArrayMap<String, ArrayList<String>> packages = mUidMap.get(userId);
769            if (packages != null) {
770                packages.remove(packageName);
771            }
772        }
773
774        public void remove(int userId) {
775            mUidMap.remove(userId);
776        }
777
778        public int userIdCount() {
779            return mUidMap.size();
780        }
781
782        public int userIdAt(int n) {
783            return mUidMap.keyAt(n);
784        }
785
786        public ArrayMap<String, ArrayList<String>> packagesForUserId(int userId) {
787            return mUidMap.get(userId);
788        }
789
790        public int size() {
791            // total number of pending broadcast entries across all userIds
792            int num = 0;
793            for (int i = 0; i< mUidMap.size(); i++) {
794                num += mUidMap.valueAt(i).size();
795            }
796            return num;
797        }
798
799        public void clear() {
800            mUidMap.clear();
801        }
802
803        private ArrayMap<String, ArrayList<String>> getOrAllocate(int userId) {
804            ArrayMap<String, ArrayList<String>> map = mUidMap.get(userId);
805            if (map == null) {
806                map = new ArrayMap<String, ArrayList<String>>();
807                mUidMap.put(userId, map);
808            }
809            return map;
810        }
811    }
812    final PendingPackageBroadcasts mPendingBroadcasts = new PendingPackageBroadcasts();
813
814    // Service Connection to remote media container service to copy
815    // package uri's from external media onto secure containers
816    // or internal storage.
817    private IMediaContainerService mContainerService = null;
818
819    static final int SEND_PENDING_BROADCAST = 1;
820    static final int MCS_BOUND = 3;
821    static final int END_COPY = 4;
822    static final int INIT_COPY = 5;
823    static final int MCS_UNBIND = 6;
824    static final int START_CLEANING_PACKAGE = 7;
825    static final int FIND_INSTALL_LOC = 8;
826    static final int POST_INSTALL = 9;
827    static final int MCS_RECONNECT = 10;
828    static final int MCS_GIVE_UP = 11;
829    static final int UPDATED_MEDIA_STATUS = 12;
830    static final int WRITE_SETTINGS = 13;
831    static final int WRITE_PACKAGE_RESTRICTIONS = 14;
832    static final int PACKAGE_VERIFIED = 15;
833    static final int CHECK_PENDING_VERIFICATION = 16;
834    static final int START_INTENT_FILTER_VERIFICATIONS = 17;
835    static final int INTENT_FILTER_VERIFIED = 18;
836
837    static final int WRITE_SETTINGS_DELAY = 10*1000;  // 10 seconds
838
839    // Delay time in millisecs
840    static final int BROADCAST_DELAY = 10 * 1000;
841
842    static UserManagerService sUserManager;
843
844    // Stores a list of users whose package restrictions file needs to be updated
845    private ArraySet<Integer> mDirtyUsers = new ArraySet<Integer>();
846
847    final private DefaultContainerConnection mDefContainerConn =
848            new DefaultContainerConnection();
849    class DefaultContainerConnection implements ServiceConnection {
850        public void onServiceConnected(ComponentName name, IBinder service) {
851            if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceConnected");
852            IMediaContainerService imcs =
853                IMediaContainerService.Stub.asInterface(service);
854            mHandler.sendMessage(mHandler.obtainMessage(MCS_BOUND, imcs));
855        }
856
857        public void onServiceDisconnected(ComponentName name) {
858            if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceDisconnected");
859        }
860    };
861
862    // Recordkeeping of restore-after-install operations that are currently in flight
863    // between the Package Manager and the Backup Manager
864    class PostInstallData {
865        public InstallArgs args;
866        public PackageInstalledInfo res;
867
868        PostInstallData(InstallArgs _a, PackageInstalledInfo _r) {
869            args = _a;
870            res = _r;
871        }
872    };
873    final SparseArray<PostInstallData> mRunningInstalls = new SparseArray<PostInstallData>();
874    int mNextInstallToken = 1;  // nonzero; will be wrapped back to 1 when ++ overflows
875
876    // backup/restore of preferred activity state
877    private static final String TAG_PREFERRED_BACKUP = "pa";
878
879    private final String mRequiredVerifierPackage;
880
881    private final PackageUsage mPackageUsage = new PackageUsage();
882
883    private class PackageUsage {
884        private static final int WRITE_INTERVAL
885            = (DEBUG_DEXOPT) ? 0 : 30*60*1000; // 30m in ms
886
887        private final Object mFileLock = new Object();
888        private final AtomicLong mLastWritten = new AtomicLong(0);
889        private final AtomicBoolean mBackgroundWriteRunning = new AtomicBoolean(false);
890
891        private boolean mIsHistoricalPackageUsageAvailable = true;
892
893        boolean isHistoricalPackageUsageAvailable() {
894            return mIsHistoricalPackageUsageAvailable;
895        }
896
897        void write(boolean force) {
898            if (force) {
899                writeInternal();
900                return;
901            }
902            if (SystemClock.elapsedRealtime() - mLastWritten.get() < WRITE_INTERVAL
903                && !DEBUG_DEXOPT) {
904                return;
905            }
906            if (mBackgroundWriteRunning.compareAndSet(false, true)) {
907                new Thread("PackageUsage_DiskWriter") {
908                    @Override
909                    public void run() {
910                        try {
911                            writeInternal();
912                        } finally {
913                            mBackgroundWriteRunning.set(false);
914                        }
915                    }
916                }.start();
917            }
918        }
919
920        private void writeInternal() {
921            synchronized (mPackages) {
922                synchronized (mFileLock) {
923                    AtomicFile file = getFile();
924                    FileOutputStream f = null;
925                    try {
926                        f = file.startWrite();
927                        BufferedOutputStream out = new BufferedOutputStream(f);
928                        FileUtils.setPermissions(file.getBaseFile().getPath(), 0640, SYSTEM_UID, PACKAGE_INFO_GID);
929                        StringBuilder sb = new StringBuilder();
930                        for (PackageParser.Package pkg : mPackages.values()) {
931                            if (pkg.mLastPackageUsageTimeInMills == 0) {
932                                continue;
933                            }
934                            sb.setLength(0);
935                            sb.append(pkg.packageName);
936                            sb.append(' ');
937                            sb.append((long)pkg.mLastPackageUsageTimeInMills);
938                            sb.append('\n');
939                            out.write(sb.toString().getBytes(StandardCharsets.US_ASCII));
940                        }
941                        out.flush();
942                        file.finishWrite(f);
943                    } catch (IOException e) {
944                        if (f != null) {
945                            file.failWrite(f);
946                        }
947                        Log.e(TAG, "Failed to write package usage times", e);
948                    }
949                }
950            }
951            mLastWritten.set(SystemClock.elapsedRealtime());
952        }
953
954        void readLP() {
955            synchronized (mFileLock) {
956                AtomicFile file = getFile();
957                BufferedInputStream in = null;
958                try {
959                    in = new BufferedInputStream(file.openRead());
960                    StringBuffer sb = new StringBuffer();
961                    while (true) {
962                        String packageName = readToken(in, sb, ' ');
963                        if (packageName == null) {
964                            break;
965                        }
966                        String timeInMillisString = readToken(in, sb, '\n');
967                        if (timeInMillisString == null) {
968                            throw new IOException("Failed to find last usage time for package "
969                                                  + packageName);
970                        }
971                        PackageParser.Package pkg = mPackages.get(packageName);
972                        if (pkg == null) {
973                            continue;
974                        }
975                        long timeInMillis;
976                        try {
977                            timeInMillis = Long.parseLong(timeInMillisString.toString());
978                        } catch (NumberFormatException e) {
979                            throw new IOException("Failed to parse " + timeInMillisString
980                                                  + " as a long.", e);
981                        }
982                        pkg.mLastPackageUsageTimeInMills = timeInMillis;
983                    }
984                } catch (FileNotFoundException expected) {
985                    mIsHistoricalPackageUsageAvailable = false;
986                } catch (IOException e) {
987                    Log.w(TAG, "Failed to read package usage times", e);
988                } finally {
989                    IoUtils.closeQuietly(in);
990                }
991            }
992            mLastWritten.set(SystemClock.elapsedRealtime());
993        }
994
995        private String readToken(InputStream in, StringBuffer sb, char endOfToken)
996                throws IOException {
997            sb.setLength(0);
998            while (true) {
999                int ch = in.read();
1000                if (ch == -1) {
1001                    if (sb.length() == 0) {
1002                        return null;
1003                    }
1004                    throw new IOException("Unexpected EOF");
1005                }
1006                if (ch == endOfToken) {
1007                    return sb.toString();
1008                }
1009                sb.append((char)ch);
1010            }
1011        }
1012
1013        private AtomicFile getFile() {
1014            File dataDir = Environment.getDataDirectory();
1015            File systemDir = new File(dataDir, "system");
1016            File fname = new File(systemDir, "package-usage.list");
1017            return new AtomicFile(fname);
1018        }
1019    }
1020
1021    class PackageHandler extends Handler {
1022        private boolean mBound = false;
1023        final ArrayList<HandlerParams> mPendingInstalls =
1024            new ArrayList<HandlerParams>();
1025
1026        private boolean connectToService() {
1027            if (DEBUG_SD_INSTALL) Log.i(TAG, "Trying to bind to" +
1028                    " DefaultContainerService");
1029            Intent service = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
1030            Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1031            if (mContext.bindServiceAsUser(service, mDefContainerConn,
1032                    Context.BIND_AUTO_CREATE, UserHandle.OWNER)) {
1033                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1034                mBound = true;
1035                return true;
1036            }
1037            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1038            return false;
1039        }
1040
1041        private void disconnectService() {
1042            mContainerService = null;
1043            mBound = false;
1044            Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1045            mContext.unbindService(mDefContainerConn);
1046            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1047        }
1048
1049        PackageHandler(Looper looper) {
1050            super(looper);
1051        }
1052
1053        public void handleMessage(Message msg) {
1054            try {
1055                doHandleMessage(msg);
1056            } finally {
1057                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1058            }
1059        }
1060
1061        void doHandleMessage(Message msg) {
1062            switch (msg.what) {
1063                case INIT_COPY: {
1064                    HandlerParams params = (HandlerParams) msg.obj;
1065                    int idx = mPendingInstalls.size();
1066                    if (DEBUG_INSTALL) Slog.i(TAG, "init_copy idx=" + idx + ": " + params);
1067                    // If a bind was already initiated we dont really
1068                    // need to do anything. The pending install
1069                    // will be processed later on.
1070                    if (!mBound) {
1071                        // If this is the only one pending we might
1072                        // have to bind to the service again.
1073                        if (!connectToService()) {
1074                            Slog.e(TAG, "Failed to bind to media container service");
1075                            params.serviceError();
1076                            return;
1077                        } else {
1078                            // Once we bind to the service, the first
1079                            // pending request will be processed.
1080                            mPendingInstalls.add(idx, params);
1081                        }
1082                    } else {
1083                        mPendingInstalls.add(idx, params);
1084                        // Already bound to the service. Just make
1085                        // sure we trigger off processing the first request.
1086                        if (idx == 0) {
1087                            mHandler.sendEmptyMessage(MCS_BOUND);
1088                        }
1089                    }
1090                    break;
1091                }
1092                case MCS_BOUND: {
1093                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_bound");
1094                    if (msg.obj != null) {
1095                        mContainerService = (IMediaContainerService) msg.obj;
1096                    }
1097                    if (mContainerService == null) {
1098                        // Something seriously wrong. Bail out
1099                        Slog.e(TAG, "Cannot bind to media container service");
1100                        for (HandlerParams params : mPendingInstalls) {
1101                            // Indicate service bind error
1102                            params.serviceError();
1103                        }
1104                        mPendingInstalls.clear();
1105                    } else if (mPendingInstalls.size() > 0) {
1106                        HandlerParams params = mPendingInstalls.get(0);
1107                        if (params != null) {
1108                            if (params.startCopy()) {
1109                                // We are done...  look for more work or to
1110                                // go idle.
1111                                if (DEBUG_SD_INSTALL) Log.i(TAG,
1112                                        "Checking for more work or unbind...");
1113                                // Delete pending install
1114                                if (mPendingInstalls.size() > 0) {
1115                                    mPendingInstalls.remove(0);
1116                                }
1117                                if (mPendingInstalls.size() == 0) {
1118                                    if (mBound) {
1119                                        if (DEBUG_SD_INSTALL) Log.i(TAG,
1120                                                "Posting delayed MCS_UNBIND");
1121                                        removeMessages(MCS_UNBIND);
1122                                        Message ubmsg = obtainMessage(MCS_UNBIND);
1123                                        // Unbind after a little delay, to avoid
1124                                        // continual thrashing.
1125                                        sendMessageDelayed(ubmsg, 10000);
1126                                    }
1127                                } else {
1128                                    // There are more pending requests in queue.
1129                                    // Just post MCS_BOUND message to trigger processing
1130                                    // of next pending install.
1131                                    if (DEBUG_SD_INSTALL) Log.i(TAG,
1132                                            "Posting MCS_BOUND for next work");
1133                                    mHandler.sendEmptyMessage(MCS_BOUND);
1134                                }
1135                            }
1136                        }
1137                    } else {
1138                        // Should never happen ideally.
1139                        Slog.w(TAG, "Empty queue");
1140                    }
1141                    break;
1142                }
1143                case MCS_RECONNECT: {
1144                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_reconnect");
1145                    if (mPendingInstalls.size() > 0) {
1146                        if (mBound) {
1147                            disconnectService();
1148                        }
1149                        if (!connectToService()) {
1150                            Slog.e(TAG, "Failed to bind to media container service");
1151                            for (HandlerParams params : mPendingInstalls) {
1152                                // Indicate service bind error
1153                                params.serviceError();
1154                            }
1155                            mPendingInstalls.clear();
1156                        }
1157                    }
1158                    break;
1159                }
1160                case MCS_UNBIND: {
1161                    // If there is no actual work left, then time to unbind.
1162                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_unbind");
1163
1164                    if (mPendingInstalls.size() == 0 && mPendingVerification.size() == 0) {
1165                        if (mBound) {
1166                            if (DEBUG_INSTALL) Slog.i(TAG, "calling disconnectService()");
1167
1168                            disconnectService();
1169                        }
1170                    } else if (mPendingInstalls.size() > 0) {
1171                        // There are more pending requests in queue.
1172                        // Just post MCS_BOUND message to trigger processing
1173                        // of next pending install.
1174                        mHandler.sendEmptyMessage(MCS_BOUND);
1175                    }
1176
1177                    break;
1178                }
1179                case MCS_GIVE_UP: {
1180                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_giveup too many retries");
1181                    mPendingInstalls.remove(0);
1182                    break;
1183                }
1184                case SEND_PENDING_BROADCAST: {
1185                    String packages[];
1186                    ArrayList<String> components[];
1187                    int size = 0;
1188                    int uids[];
1189                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1190                    synchronized (mPackages) {
1191                        if (mPendingBroadcasts == null) {
1192                            return;
1193                        }
1194                        size = mPendingBroadcasts.size();
1195                        if (size <= 0) {
1196                            // Nothing to be done. Just return
1197                            return;
1198                        }
1199                        packages = new String[size];
1200                        components = new ArrayList[size];
1201                        uids = new int[size];
1202                        int i = 0;  // filling out the above arrays
1203
1204                        for (int n = 0; n < mPendingBroadcasts.userIdCount(); n++) {
1205                            int packageUserId = mPendingBroadcasts.userIdAt(n);
1206                            Iterator<Map.Entry<String, ArrayList<String>>> it
1207                                    = mPendingBroadcasts.packagesForUserId(packageUserId)
1208                                            .entrySet().iterator();
1209                            while (it.hasNext() && i < size) {
1210                                Map.Entry<String, ArrayList<String>> ent = it.next();
1211                                packages[i] = ent.getKey();
1212                                components[i] = ent.getValue();
1213                                PackageSetting ps = mSettings.mPackages.get(ent.getKey());
1214                                uids[i] = (ps != null)
1215                                        ? UserHandle.getUid(packageUserId, ps.appId)
1216                                        : -1;
1217                                i++;
1218                            }
1219                        }
1220                        size = i;
1221                        mPendingBroadcasts.clear();
1222                    }
1223                    // Send broadcasts
1224                    for (int i = 0; i < size; i++) {
1225                        sendPackageChangedBroadcast(packages[i], true, components[i], uids[i]);
1226                    }
1227                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1228                    break;
1229                }
1230                case START_CLEANING_PACKAGE: {
1231                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1232                    final String packageName = (String)msg.obj;
1233                    final int userId = msg.arg1;
1234                    final boolean andCode = msg.arg2 != 0;
1235                    synchronized (mPackages) {
1236                        if (userId == UserHandle.USER_ALL) {
1237                            int[] users = sUserManager.getUserIds();
1238                            for (int user : users) {
1239                                mSettings.addPackageToCleanLPw(
1240                                        new PackageCleanItem(user, packageName, andCode));
1241                            }
1242                        } else {
1243                            mSettings.addPackageToCleanLPw(
1244                                    new PackageCleanItem(userId, packageName, andCode));
1245                        }
1246                    }
1247                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1248                    startCleaningPackages();
1249                } break;
1250                case POST_INSTALL: {
1251                    if (DEBUG_INSTALL) Log.v(TAG, "Handling post-install for " + msg.arg1);
1252                    PostInstallData data = mRunningInstalls.get(msg.arg1);
1253                    mRunningInstalls.delete(msg.arg1);
1254                    boolean deleteOld = false;
1255
1256                    if (data != null) {
1257                        InstallArgs args = data.args;
1258                        PackageInstalledInfo res = data.res;
1259
1260                        if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
1261                            res.removedInfo.sendBroadcast(false, true, false);
1262                            Bundle extras = new Bundle(1);
1263                            extras.putInt(Intent.EXTRA_UID, res.uid);
1264
1265                            // Now that we successfully installed the package, grant runtime
1266                            // permissions if requested before broadcasting the install.
1267                            if ((args.installFlags
1268                                    & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0) {
1269                                grantRequestedRuntimePermissions(res.pkg,
1270                                        args.user.getIdentifier());
1271                            }
1272
1273                            // Determine the set of users who are adding this
1274                            // package for the first time vs. those who are seeing
1275                            // an update.
1276                            int[] firstUsers;
1277                            int[] updateUsers = new int[0];
1278                            if (res.origUsers == null || res.origUsers.length == 0) {
1279                                firstUsers = res.newUsers;
1280                            } else {
1281                                firstUsers = new int[0];
1282                                for (int i=0; i<res.newUsers.length; i++) {
1283                                    int user = res.newUsers[i];
1284                                    boolean isNew = true;
1285                                    for (int j=0; j<res.origUsers.length; j++) {
1286                                        if (res.origUsers[j] == user) {
1287                                            isNew = false;
1288                                            break;
1289                                        }
1290                                    }
1291                                    if (isNew) {
1292                                        int[] newFirst = new int[firstUsers.length+1];
1293                                        System.arraycopy(firstUsers, 0, newFirst, 0,
1294                                                firstUsers.length);
1295                                        newFirst[firstUsers.length] = user;
1296                                        firstUsers = newFirst;
1297                                    } else {
1298                                        int[] newUpdate = new int[updateUsers.length+1];
1299                                        System.arraycopy(updateUsers, 0, newUpdate, 0,
1300                                                updateUsers.length);
1301                                        newUpdate[updateUsers.length] = user;
1302                                        updateUsers = newUpdate;
1303                                    }
1304                                }
1305                            }
1306                            sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
1307                                    res.pkg.applicationInfo.packageName,
1308                                    extras, null, null, firstUsers);
1309                            final boolean update = res.removedInfo.removedPackage != null;
1310                            if (update) {
1311                                extras.putBoolean(Intent.EXTRA_REPLACING, true);
1312                            }
1313                            sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
1314                                    res.pkg.applicationInfo.packageName,
1315                                    extras, null, null, updateUsers);
1316                            if (update) {
1317                                sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
1318                                        res.pkg.applicationInfo.packageName,
1319                                        extras, null, null, updateUsers);
1320                                sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
1321                                        null, null,
1322                                        res.pkg.applicationInfo.packageName, null, updateUsers);
1323
1324                                // treat asec-hosted packages like removable media on upgrade
1325                                if (res.pkg.isForwardLocked() || isExternal(res.pkg)) {
1326                                    if (DEBUG_INSTALL) {
1327                                        Slog.i(TAG, "upgrading pkg " + res.pkg
1328                                                + " is ASEC-hosted -> AVAILABLE");
1329                                    }
1330                                    int[] uidArray = new int[] { res.pkg.applicationInfo.uid };
1331                                    ArrayList<String> pkgList = new ArrayList<String>(1);
1332                                    pkgList.add(res.pkg.applicationInfo.packageName);
1333                                    sendResourcesChangedBroadcast(true, true,
1334                                            pkgList,uidArray, null);
1335                                }
1336                            }
1337                            if (res.removedInfo.args != null) {
1338                                // Remove the replaced package's older resources safely now
1339                                deleteOld = true;
1340                            }
1341
1342                            // Log current value of "unknown sources" setting
1343                            EventLog.writeEvent(EventLogTags.UNKNOWN_SOURCES_ENABLED,
1344                                getUnknownSourcesSettings());
1345                        }
1346                        // Force a gc to clear up things
1347                        Runtime.getRuntime().gc();
1348                        // We delete after a gc for applications  on sdcard.
1349                        if (deleteOld) {
1350                            synchronized (mInstallLock) {
1351                                res.removedInfo.args.doPostDeleteLI(true);
1352                            }
1353                        }
1354                        if (args.observer != null) {
1355                            try {
1356                                Bundle extras = extrasForInstallResult(res);
1357                                args.observer.onPackageInstalled(res.name, res.returnCode,
1358                                        res.returnMsg, extras);
1359                            } catch (RemoteException e) {
1360                                Slog.i(TAG, "Observer no longer exists.");
1361                            }
1362                        }
1363                    } else {
1364                        Slog.e(TAG, "Bogus post-install token " + msg.arg1);
1365                    }
1366                } break;
1367                case UPDATED_MEDIA_STATUS: {
1368                    if (DEBUG_SD_INSTALL) Log.i(TAG, "Got message UPDATED_MEDIA_STATUS");
1369                    boolean reportStatus = msg.arg1 == 1;
1370                    boolean doGc = msg.arg2 == 1;
1371                    if (DEBUG_SD_INSTALL) Log.i(TAG, "reportStatus=" + reportStatus + ", doGc = " + doGc);
1372                    if (doGc) {
1373                        // Force a gc to clear up stale containers.
1374                        Runtime.getRuntime().gc();
1375                    }
1376                    if (msg.obj != null) {
1377                        @SuppressWarnings("unchecked")
1378                        Set<AsecInstallArgs> args = (Set<AsecInstallArgs>) msg.obj;
1379                        if (DEBUG_SD_INSTALL) Log.i(TAG, "Unloading all containers");
1380                        // Unload containers
1381                        unloadAllContainers(args);
1382                    }
1383                    if (reportStatus) {
1384                        try {
1385                            if (DEBUG_SD_INSTALL) Log.i(TAG, "Invoking MountService call back");
1386                            PackageHelper.getMountService().finishMediaUpdate();
1387                        } catch (RemoteException e) {
1388                            Log.e(TAG, "MountService not running?");
1389                        }
1390                    }
1391                } break;
1392                case WRITE_SETTINGS: {
1393                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1394                    synchronized (mPackages) {
1395                        removeMessages(WRITE_SETTINGS);
1396                        removeMessages(WRITE_PACKAGE_RESTRICTIONS);
1397                        mSettings.writeLPr();
1398                        mDirtyUsers.clear();
1399                    }
1400                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1401                } break;
1402                case WRITE_PACKAGE_RESTRICTIONS: {
1403                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1404                    synchronized (mPackages) {
1405                        removeMessages(WRITE_PACKAGE_RESTRICTIONS);
1406                        for (int userId : mDirtyUsers) {
1407                            mSettings.writePackageRestrictionsLPr(userId);
1408                        }
1409                        mDirtyUsers.clear();
1410                    }
1411                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1412                } break;
1413                case CHECK_PENDING_VERIFICATION: {
1414                    final int verificationId = msg.arg1;
1415                    final PackageVerificationState state = mPendingVerification.get(verificationId);
1416
1417                    if ((state != null) && !state.timeoutExtended()) {
1418                        final InstallArgs args = state.getInstallArgs();
1419                        final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
1420
1421                        Slog.i(TAG, "Verification timed out for " + originUri);
1422                        mPendingVerification.remove(verificationId);
1423
1424                        int ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
1425
1426                        if (getDefaultVerificationResponse() == PackageManager.VERIFICATION_ALLOW) {
1427                            Slog.i(TAG, "Continuing with installation of " + originUri);
1428                            state.setVerifierResponse(Binder.getCallingUid(),
1429                                    PackageManager.VERIFICATION_ALLOW_WITHOUT_SUFFICIENT);
1430                            broadcastPackageVerified(verificationId, originUri,
1431                                    PackageManager.VERIFICATION_ALLOW,
1432                                    state.getInstallArgs().getUser());
1433                            try {
1434                                ret = args.copyApk(mContainerService, true);
1435                            } catch (RemoteException e) {
1436                                Slog.e(TAG, "Could not contact the ContainerService");
1437                            }
1438                        } else {
1439                            broadcastPackageVerified(verificationId, originUri,
1440                                    PackageManager.VERIFICATION_REJECT,
1441                                    state.getInstallArgs().getUser());
1442                        }
1443
1444                        processPendingInstall(args, ret);
1445                        mHandler.sendEmptyMessage(MCS_UNBIND);
1446                    }
1447                    break;
1448                }
1449                case PACKAGE_VERIFIED: {
1450                    final int verificationId = msg.arg1;
1451
1452                    final PackageVerificationState state = mPendingVerification.get(verificationId);
1453                    if (state == null) {
1454                        Slog.w(TAG, "Invalid verification token " + verificationId + " received");
1455                        break;
1456                    }
1457
1458                    final PackageVerificationResponse response = (PackageVerificationResponse) msg.obj;
1459
1460                    state.setVerifierResponse(response.callerUid, response.code);
1461
1462                    if (state.isVerificationComplete()) {
1463                        mPendingVerification.remove(verificationId);
1464
1465                        final InstallArgs args = state.getInstallArgs();
1466                        final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
1467
1468                        int ret;
1469                        if (state.isInstallAllowed()) {
1470                            ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
1471                            broadcastPackageVerified(verificationId, originUri,
1472                                    response.code, state.getInstallArgs().getUser());
1473                            try {
1474                                ret = args.copyApk(mContainerService, true);
1475                            } catch (RemoteException e) {
1476                                Slog.e(TAG, "Could not contact the ContainerService");
1477                            }
1478                        } else {
1479                            ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
1480                        }
1481
1482                        processPendingInstall(args, ret);
1483
1484                        mHandler.sendEmptyMessage(MCS_UNBIND);
1485                    }
1486
1487                    break;
1488                }
1489                case START_INTENT_FILTER_VERIFICATIONS: {
1490                    int userId = msg.arg1;
1491                    int verifierUid = msg.arg2;
1492                    PackageParser.Package pkg = (PackageParser.Package)msg.obj;
1493
1494                    verifyIntentFiltersIfNeeded(userId, verifierUid, pkg);
1495                    break;
1496                }
1497                case INTENT_FILTER_VERIFIED: {
1498                    final int verificationId = msg.arg1;
1499
1500                    final IntentFilterVerificationState state = mIntentFilterVerificationStates.get(
1501                            verificationId);
1502                    if (state == null) {
1503                        Slog.w(TAG, "Invalid IntentFilter verification token "
1504                                + verificationId + " received");
1505                        break;
1506                    }
1507
1508                    final int userId = state.getUserId();
1509
1510                    Slog.d(TAG, "Processing IntentFilter verification with token:"
1511                            + verificationId + " and userId:" + userId);
1512
1513                    final IntentFilterVerificationResponse response =
1514                            (IntentFilterVerificationResponse) msg.obj;
1515
1516                    state.setVerifierResponse(response.callerUid, response.code);
1517
1518                    Slog.d(TAG, "IntentFilter verification with token:" + verificationId
1519                            + " and userId:" + userId
1520                            + " is settings verifier response with response code:"
1521                            + response.code);
1522
1523                    if (response.code == PackageManager.INTENT_FILTER_VERIFICATION_FAILURE) {
1524                        Slog.d(TAG, "Domains failing verification: "
1525                                + response.getFailedDomainsString());
1526                    }
1527
1528                    if (state.isVerificationComplete()) {
1529                        mIntentFilterVerifier.receiveVerificationResponse(verificationId);
1530                    } else {
1531                        Slog.d(TAG, "IntentFilter verification with token:" + verificationId
1532                                + " was not said to be complete");
1533                    }
1534
1535                    break;
1536                }
1537            }
1538        }
1539    }
1540
1541    private StorageEventListener mStorageListener = new StorageEventListener() {
1542        @Override
1543        public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState) {
1544            if (vol.type == VolumeInfo.TYPE_PRIVATE) {
1545                if (vol.state == VolumeInfo.STATE_MOUNTED) {
1546                    // TODO: ensure that private directories exist for all active users
1547                    // TODO: remove user data whose serial number doesn't match
1548                    loadPrivatePackages(vol);
1549                } else if (vol.state == VolumeInfo.STATE_EJECTING) {
1550                    unloadPrivatePackages(vol);
1551                }
1552            }
1553
1554            if (vol.type == VolumeInfo.TYPE_PUBLIC && vol.isPrimary()) {
1555                if (vol.state == VolumeInfo.STATE_MOUNTED) {
1556                    updateExternalMediaStatus(true, false);
1557                } else if (vol.state == VolumeInfo.STATE_EJECTING) {
1558                    updateExternalMediaStatus(false, false);
1559                }
1560            }
1561        }
1562
1563        @Override
1564        public void onVolumeForgotten(String fsUuid) {
1565            // TODO: remove all packages hosted on this uuid
1566        }
1567    };
1568
1569    private void grantRequestedRuntimePermissions(PackageParser.Package pkg, int userId) {
1570        if (userId >= UserHandle.USER_OWNER) {
1571            grantRequestedRuntimePermissionsForUser(pkg, userId);
1572        } else if (userId == UserHandle.USER_ALL) {
1573            for (int someUserId : UserManagerService.getInstance().getUserIds()) {
1574                grantRequestedRuntimePermissionsForUser(pkg, someUserId);
1575            }
1576        }
1577    }
1578
1579    private void grantRequestedRuntimePermissionsForUser(PackageParser.Package pkg, int userId) {
1580        SettingBase sb = (SettingBase) pkg.mExtras;
1581        if (sb == null) {
1582            return;
1583        }
1584
1585        PermissionsState permissionsState = sb.getPermissionsState();
1586
1587        for (String permission : pkg.requestedPermissions) {
1588            BasePermission bp = mSettings.mPermissions.get(permission);
1589            if (bp != null && bp.isRuntime()) {
1590                permissionsState.grantRuntimePermission(bp, userId);
1591            }
1592        }
1593    }
1594
1595    Bundle extrasForInstallResult(PackageInstalledInfo res) {
1596        Bundle extras = null;
1597        switch (res.returnCode) {
1598            case PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION: {
1599                extras = new Bundle();
1600                extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PERMISSION,
1601                        res.origPermission);
1602                extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PACKAGE,
1603                        res.origPackage);
1604                break;
1605            }
1606            case PackageManager.INSTALL_SUCCEEDED: {
1607                extras = new Bundle();
1608                extras.putBoolean(Intent.EXTRA_REPLACING,
1609                        res.removedInfo != null && res.removedInfo.removedPackage != null);
1610                break;
1611            }
1612        }
1613        return extras;
1614    }
1615
1616    void scheduleWriteSettingsLocked() {
1617        if (!mHandler.hasMessages(WRITE_SETTINGS)) {
1618            mHandler.sendEmptyMessageDelayed(WRITE_SETTINGS, WRITE_SETTINGS_DELAY);
1619        }
1620    }
1621
1622    void scheduleWritePackageRestrictionsLocked(int userId) {
1623        if (!sUserManager.exists(userId)) return;
1624        mDirtyUsers.add(userId);
1625        if (!mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) {
1626            mHandler.sendEmptyMessageDelayed(WRITE_PACKAGE_RESTRICTIONS, WRITE_SETTINGS_DELAY);
1627        }
1628    }
1629
1630    public static PackageManagerService main(Context context, Installer installer,
1631            boolean factoryTest, boolean onlyCore) {
1632        PackageManagerService m = new PackageManagerService(context, installer,
1633                factoryTest, onlyCore);
1634        ServiceManager.addService("package", m);
1635        return m;
1636    }
1637
1638    static String[] splitString(String str, char sep) {
1639        int count = 1;
1640        int i = 0;
1641        while ((i=str.indexOf(sep, i)) >= 0) {
1642            count++;
1643            i++;
1644        }
1645
1646        String[] res = new String[count];
1647        i=0;
1648        count = 0;
1649        int lastI=0;
1650        while ((i=str.indexOf(sep, i)) >= 0) {
1651            res[count] = str.substring(lastI, i);
1652            count++;
1653            i++;
1654            lastI = i;
1655        }
1656        res[count] = str.substring(lastI, str.length());
1657        return res;
1658    }
1659
1660    private static void getDefaultDisplayMetrics(Context context, DisplayMetrics metrics) {
1661        DisplayManager displayManager = (DisplayManager) context.getSystemService(
1662                Context.DISPLAY_SERVICE);
1663        displayManager.getDisplay(Display.DEFAULT_DISPLAY).getMetrics(metrics);
1664    }
1665
1666    public PackageManagerService(Context context, Installer installer,
1667            boolean factoryTest, boolean onlyCore) {
1668        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START,
1669                SystemClock.uptimeMillis());
1670
1671        if (mSdkVersion <= 0) {
1672            Slog.w(TAG, "**** ro.build.version.sdk not set!");
1673        }
1674
1675        mContext = context;
1676        mFactoryTest = factoryTest;
1677        mOnlyCore = onlyCore;
1678        mLazyDexOpt = "eng".equals(SystemProperties.get("ro.build.type"));
1679        mMetrics = new DisplayMetrics();
1680        mSettings = new Settings(mPackages);
1681        mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID,
1682                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
1683        mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID,
1684                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
1685        mSettings.addSharedUserLPw("android.uid.log", LOG_UID,
1686                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
1687        mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID,
1688                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
1689        mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID,
1690                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
1691        mSettings.addSharedUserLPw("android.uid.shell", SHELL_UID,
1692                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
1693
1694        // TODO: add a property to control this?
1695        long dexOptLRUThresholdInMinutes;
1696        if (mLazyDexOpt) {
1697            dexOptLRUThresholdInMinutes = 30; // only last 30 minutes of apps for eng builds.
1698        } else {
1699            dexOptLRUThresholdInMinutes = 7 * 24 * 60; // apps used in the 7 days for users.
1700        }
1701        mDexOptLRUThresholdInMills = dexOptLRUThresholdInMinutes * 60 * 1000;
1702
1703        String separateProcesses = SystemProperties.get("debug.separate_processes");
1704        if (separateProcesses != null && separateProcesses.length() > 0) {
1705            if ("*".equals(separateProcesses)) {
1706                mDefParseFlags = PackageParser.PARSE_IGNORE_PROCESSES;
1707                mSeparateProcesses = null;
1708                Slog.w(TAG, "Running with debug.separate_processes: * (ALL)");
1709            } else {
1710                mDefParseFlags = 0;
1711                mSeparateProcesses = separateProcesses.split(",");
1712                Slog.w(TAG, "Running with debug.separate_processes: "
1713                        + separateProcesses);
1714            }
1715        } else {
1716            mDefParseFlags = 0;
1717            mSeparateProcesses = null;
1718        }
1719
1720        mInstaller = installer;
1721        mPackageDexOptimizer = new PackageDexOptimizer(this);
1722        mMoveCallbacks = new MoveCallbacks(FgThread.get().getLooper());
1723
1724        getDefaultDisplayMetrics(context, mMetrics);
1725
1726        SystemConfig systemConfig = SystemConfig.getInstance();
1727        mGlobalGids = systemConfig.getGlobalGids();
1728        mSystemPermissions = systemConfig.getSystemPermissions();
1729        mAvailableFeatures = systemConfig.getAvailableFeatures();
1730
1731        synchronized (mInstallLock) {
1732        // writer
1733        synchronized (mPackages) {
1734            mHandlerThread = new ServiceThread(TAG,
1735                    Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
1736            mHandlerThread.start();
1737            mHandler = new PackageHandler(mHandlerThread.getLooper());
1738            Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT);
1739
1740            File dataDir = Environment.getDataDirectory();
1741            mAppDataDir = new File(dataDir, "data");
1742            mAppInstallDir = new File(dataDir, "app");
1743            mAppLib32InstallDir = new File(dataDir, "app-lib");
1744            mAsecInternalPath = new File(dataDir, "app-asec").getPath();
1745            mUserAppDataDir = new File(dataDir, "user");
1746            mDrmAppPrivateInstallDir = new File(dataDir, "app-private");
1747
1748            sUserManager = new UserManagerService(context, this,
1749                    mInstallLock, mPackages);
1750
1751            // Propagate permission configuration in to package manager.
1752            ArrayMap<String, SystemConfig.PermissionEntry> permConfig
1753                    = systemConfig.getPermissions();
1754            for (int i=0; i<permConfig.size(); i++) {
1755                SystemConfig.PermissionEntry perm = permConfig.valueAt(i);
1756                BasePermission bp = mSettings.mPermissions.get(perm.name);
1757                if (bp == null) {
1758                    bp = new BasePermission(perm.name, "android", BasePermission.TYPE_BUILTIN);
1759                    mSettings.mPermissions.put(perm.name, bp);
1760                }
1761                if (perm.gids != null) {
1762                    bp.setGids(perm.gids, perm.perUser);
1763                }
1764            }
1765
1766            ArrayMap<String, String> libConfig = systemConfig.getSharedLibraries();
1767            for (int i=0; i<libConfig.size(); i++) {
1768                mSharedLibraries.put(libConfig.keyAt(i),
1769                        new SharedLibraryEntry(libConfig.valueAt(i), null));
1770            }
1771
1772            mFoundPolicyFile = SELinuxMMAC.readInstallPolicy();
1773
1774            mRestoredSettings = mSettings.readLPw(this, sUserManager.getUsers(false),
1775                    mSdkVersion, mOnlyCore);
1776
1777            String customResolverActivity = Resources.getSystem().getString(
1778                    R.string.config_customResolverActivity);
1779            if (TextUtils.isEmpty(customResolverActivity)) {
1780                customResolverActivity = null;
1781            } else {
1782                mCustomResolverComponentName = ComponentName.unflattenFromString(
1783                        customResolverActivity);
1784            }
1785
1786            long startTime = SystemClock.uptimeMillis();
1787
1788            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START,
1789                    startTime);
1790
1791            // Set flag to monitor and not change apk file paths when
1792            // scanning install directories.
1793            final int scanFlags = SCAN_NO_PATHS | SCAN_DEFER_DEX | SCAN_BOOTING;
1794
1795            final ArraySet<String> alreadyDexOpted = new ArraySet<String>();
1796
1797            /**
1798             * Add everything in the in the boot class path to the
1799             * list of process files because dexopt will have been run
1800             * if necessary during zygote startup.
1801             */
1802            final String bootClassPath = System.getenv("BOOTCLASSPATH");
1803            final String systemServerClassPath = System.getenv("SYSTEMSERVERCLASSPATH");
1804
1805            if (bootClassPath != null) {
1806                String[] bootClassPathElements = splitString(bootClassPath, ':');
1807                for (String element : bootClassPathElements) {
1808                    alreadyDexOpted.add(element);
1809                }
1810            } else {
1811                Slog.w(TAG, "No BOOTCLASSPATH found!");
1812            }
1813
1814            if (systemServerClassPath != null) {
1815                String[] systemServerClassPathElements = splitString(systemServerClassPath, ':');
1816                for (String element : systemServerClassPathElements) {
1817                    alreadyDexOpted.add(element);
1818                }
1819            } else {
1820                Slog.w(TAG, "No SYSTEMSERVERCLASSPATH found!");
1821            }
1822
1823            final List<String> allInstructionSets = InstructionSets.getAllInstructionSets();
1824            final String[] dexCodeInstructionSets =
1825                    getDexCodeInstructionSets(
1826                            allInstructionSets.toArray(new String[allInstructionSets.size()]));
1827
1828            /**
1829             * Ensure all external libraries have had dexopt run on them.
1830             */
1831            if (mSharedLibraries.size() > 0) {
1832                // NOTE: For now, we're compiling these system "shared libraries"
1833                // (and framework jars) into all available architectures. It's possible
1834                // to compile them only when we come across an app that uses them (there's
1835                // already logic for that in scanPackageLI) but that adds some complexity.
1836                for (String dexCodeInstructionSet : dexCodeInstructionSets) {
1837                    for (SharedLibraryEntry libEntry : mSharedLibraries.values()) {
1838                        final String lib = libEntry.path;
1839                        if (lib == null) {
1840                            continue;
1841                        }
1842
1843                        try {
1844                            int dexoptNeeded = DexFile.getDexOptNeeded(lib, null, dexCodeInstructionSet, false);
1845                            if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) {
1846                                alreadyDexOpted.add(lib);
1847                                mInstaller.dexopt(lib, Process.SYSTEM_UID, true, dexCodeInstructionSet, dexoptNeeded);
1848                            }
1849                        } catch (FileNotFoundException e) {
1850                            Slog.w(TAG, "Library not found: " + lib);
1851                        } catch (IOException e) {
1852                            Slog.w(TAG, "Cannot dexopt " + lib + "; is it an APK or JAR? "
1853                                    + e.getMessage());
1854                        }
1855                    }
1856                }
1857            }
1858
1859            File frameworkDir = new File(Environment.getRootDirectory(), "framework");
1860
1861            // Gross hack for now: we know this file doesn't contain any
1862            // code, so don't dexopt it to avoid the resulting log spew.
1863            alreadyDexOpted.add(frameworkDir.getPath() + "/framework-res.apk");
1864
1865            // Gross hack for now: we know this file is only part of
1866            // the boot class path for art, so don't dexopt it to
1867            // avoid the resulting log spew.
1868            alreadyDexOpted.add(frameworkDir.getPath() + "/core-libart.jar");
1869
1870            /**
1871             * And there are a number of commands implemented in Java, which
1872             * we currently need to do the dexopt on so that they can be
1873             * run from a non-root shell.
1874             */
1875            String[] frameworkFiles = frameworkDir.list();
1876            if (frameworkFiles != null) {
1877                // TODO: We could compile these only for the most preferred ABI. We should
1878                // first double check that the dex files for these commands are not referenced
1879                // by other system apps.
1880                for (String dexCodeInstructionSet : dexCodeInstructionSets) {
1881                    for (int i=0; i<frameworkFiles.length; i++) {
1882                        File libPath = new File(frameworkDir, frameworkFiles[i]);
1883                        String path = libPath.getPath();
1884                        // Skip the file if we already did it.
1885                        if (alreadyDexOpted.contains(path)) {
1886                            continue;
1887                        }
1888                        // Skip the file if it is not a type we want to dexopt.
1889                        if (!path.endsWith(".apk") && !path.endsWith(".jar")) {
1890                            continue;
1891                        }
1892                        try {
1893                            int dexoptNeeded = DexFile.getDexOptNeeded(path, null, dexCodeInstructionSet, false);
1894                            if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) {
1895                                mInstaller.dexopt(path, Process.SYSTEM_UID, true, dexCodeInstructionSet, dexoptNeeded);
1896                            }
1897                        } catch (FileNotFoundException e) {
1898                            Slog.w(TAG, "Jar not found: " + path);
1899                        } catch (IOException e) {
1900                            Slog.w(TAG, "Exception reading jar: " + path, e);
1901                        }
1902                    }
1903                }
1904            }
1905
1906            // Collect vendor overlay packages.
1907            // (Do this before scanning any apps.)
1908            // For security and version matching reason, only consider
1909            // overlay packages if they reside in VENDOR_OVERLAY_DIR.
1910            File vendorOverlayDir = new File(VENDOR_OVERLAY_DIR);
1911            scanDirLI(vendorOverlayDir, PackageParser.PARSE_IS_SYSTEM
1912                    | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags | SCAN_TRUSTED_OVERLAY, 0);
1913
1914            // Find base frameworks (resource packages without code).
1915            scanDirLI(frameworkDir, PackageParser.PARSE_IS_SYSTEM
1916                    | PackageParser.PARSE_IS_SYSTEM_DIR
1917                    | PackageParser.PARSE_IS_PRIVILEGED,
1918                    scanFlags | SCAN_NO_DEX, 0);
1919
1920            // Collected privileged system packages.
1921            final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app");
1922            scanDirLI(privilegedAppDir, PackageParser.PARSE_IS_SYSTEM
1923                    | PackageParser.PARSE_IS_SYSTEM_DIR
1924                    | PackageParser.PARSE_IS_PRIVILEGED, scanFlags, 0);
1925
1926            // Collect ordinary system packages.
1927            final File systemAppDir = new File(Environment.getRootDirectory(), "app");
1928            scanDirLI(systemAppDir, PackageParser.PARSE_IS_SYSTEM
1929                    | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
1930
1931            // Collect all vendor packages.
1932            File vendorAppDir = new File("/vendor/app");
1933            try {
1934                vendorAppDir = vendorAppDir.getCanonicalFile();
1935            } catch (IOException e) {
1936                // failed to look up canonical path, continue with original one
1937            }
1938            scanDirLI(vendorAppDir, PackageParser.PARSE_IS_SYSTEM
1939                    | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
1940
1941            // Collect all OEM packages.
1942            final File oemAppDir = new File(Environment.getOemDirectory(), "app");
1943            scanDirLI(oemAppDir, PackageParser.PARSE_IS_SYSTEM
1944                    | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
1945
1946            if (DEBUG_UPGRADE) Log.v(TAG, "Running installd update commands");
1947            mInstaller.moveFiles();
1948
1949            // Prune any system packages that no longer exist.
1950            final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<String>();
1951            final ArrayMap<String, File> expectingBetter = new ArrayMap<>();
1952            if (!mOnlyCore) {
1953                Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
1954                while (psit.hasNext()) {
1955                    PackageSetting ps = psit.next();
1956
1957                    /*
1958                     * If this is not a system app, it can't be a
1959                     * disable system app.
1960                     */
1961                    if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
1962                        continue;
1963                    }
1964
1965                    /*
1966                     * If the package is scanned, it's not erased.
1967                     */
1968                    final PackageParser.Package scannedPkg = mPackages.get(ps.name);
1969                    if (scannedPkg != null) {
1970                        /*
1971                         * If the system app is both scanned and in the
1972                         * disabled packages list, then it must have been
1973                         * added via OTA. Remove it from the currently
1974                         * scanned package so the previously user-installed
1975                         * application can be scanned.
1976                         */
1977                        if (mSettings.isDisabledSystemPackageLPr(ps.name)) {
1978                            logCriticalInfo(Log.WARN, "Expecting better updated system app for "
1979                                    + ps.name + "; removing system app.  Last known codePath="
1980                                    + ps.codePathString + ", installStatus=" + ps.installStatus
1981                                    + ", versionCode=" + ps.versionCode + "; scanned versionCode="
1982                                    + scannedPkg.mVersionCode);
1983                            removePackageLI(ps, true);
1984                            expectingBetter.put(ps.name, ps.codePath);
1985                        }
1986
1987                        continue;
1988                    }
1989
1990                    if (!mSettings.isDisabledSystemPackageLPr(ps.name)) {
1991                        psit.remove();
1992                        logCriticalInfo(Log.WARN, "System package " + ps.name
1993                                + " no longer exists; wiping its data");
1994                        removeDataDirsLI(null, ps.name);
1995                    } else {
1996                        final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(ps.name);
1997                        if (disabledPs.codePath == null || !disabledPs.codePath.exists()) {
1998                            possiblyDeletedUpdatedSystemApps.add(ps.name);
1999                        }
2000                    }
2001                }
2002            }
2003
2004            //look for any incomplete package installations
2005            ArrayList<PackageSetting> deletePkgsList = mSettings.getListOfIncompleteInstallPackagesLPr();
2006            //clean up list
2007            for(int i = 0; i < deletePkgsList.size(); i++) {
2008                //clean up here
2009                cleanupInstallFailedPackage(deletePkgsList.get(i));
2010            }
2011            //delete tmp files
2012            deleteTempPackageFiles();
2013
2014            // Remove any shared userIDs that have no associated packages
2015            mSettings.pruneSharedUsersLPw();
2016
2017            if (!mOnlyCore) {
2018                EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,
2019                        SystemClock.uptimeMillis());
2020                scanDirLI(mAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0);
2021
2022                scanDirLI(mDrmAppPrivateInstallDir, PackageParser.PARSE_FORWARD_LOCK,
2023                        scanFlags | SCAN_REQUIRE_KNOWN, 0);
2024
2025                /**
2026                 * Remove disable package settings for any updated system
2027                 * apps that were removed via an OTA. If they're not a
2028                 * previously-updated app, remove them completely.
2029                 * Otherwise, just revoke their system-level permissions.
2030                 */
2031                for (String deletedAppName : possiblyDeletedUpdatedSystemApps) {
2032                    PackageParser.Package deletedPkg = mPackages.get(deletedAppName);
2033                    mSettings.removeDisabledSystemPackageLPw(deletedAppName);
2034
2035                    String msg;
2036                    if (deletedPkg == null) {
2037                        msg = "Updated system package " + deletedAppName
2038                                + " no longer exists; wiping its data";
2039                        removeDataDirsLI(null, deletedAppName);
2040                    } else {
2041                        msg = "Updated system app + " + deletedAppName
2042                                + " no longer present; removing system privileges for "
2043                                + deletedAppName;
2044
2045                        deletedPkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM;
2046
2047                        PackageSetting deletedPs = mSettings.mPackages.get(deletedAppName);
2048                        deletedPs.pkgFlags &= ~ApplicationInfo.FLAG_SYSTEM;
2049                    }
2050                    logCriticalInfo(Log.WARN, msg);
2051                }
2052
2053                /**
2054                 * Make sure all system apps that we expected to appear on
2055                 * the userdata partition actually showed up. If they never
2056                 * appeared, crawl back and revive the system version.
2057                 */
2058                for (int i = 0; i < expectingBetter.size(); i++) {
2059                    final String packageName = expectingBetter.keyAt(i);
2060                    if (!mPackages.containsKey(packageName)) {
2061                        final File scanFile = expectingBetter.valueAt(i);
2062
2063                        logCriticalInfo(Log.WARN, "Expected better " + packageName
2064                                + " but never showed up; reverting to system");
2065
2066                        final int reparseFlags;
2067                        if (FileUtils.contains(privilegedAppDir, scanFile)) {
2068                            reparseFlags = PackageParser.PARSE_IS_SYSTEM
2069                                    | PackageParser.PARSE_IS_SYSTEM_DIR
2070                                    | PackageParser.PARSE_IS_PRIVILEGED;
2071                        } else if (FileUtils.contains(systemAppDir, scanFile)) {
2072                            reparseFlags = PackageParser.PARSE_IS_SYSTEM
2073                                    | PackageParser.PARSE_IS_SYSTEM_DIR;
2074                        } else if (FileUtils.contains(vendorAppDir, scanFile)) {
2075                            reparseFlags = PackageParser.PARSE_IS_SYSTEM
2076                                    | PackageParser.PARSE_IS_SYSTEM_DIR;
2077                        } else if (FileUtils.contains(oemAppDir, scanFile)) {
2078                            reparseFlags = PackageParser.PARSE_IS_SYSTEM
2079                                    | PackageParser.PARSE_IS_SYSTEM_DIR;
2080                        } else {
2081                            Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile);
2082                            continue;
2083                        }
2084
2085                        mSettings.enableSystemPackageLPw(packageName);
2086
2087                        try {
2088                            scanPackageLI(scanFile, reparseFlags, scanFlags, 0, null);
2089                        } catch (PackageManagerException e) {
2090                            Slog.e(TAG, "Failed to parse original system package: "
2091                                    + e.getMessage());
2092                        }
2093                    }
2094                }
2095            }
2096
2097            // Now that we know all of the shared libraries, update all clients to have
2098            // the correct library paths.
2099            updateAllSharedLibrariesLPw();
2100
2101            for (SharedUserSetting setting : mSettings.getAllSharedUsersLPw()) {
2102                // NOTE: We ignore potential failures here during a system scan (like
2103                // the rest of the commands above) because there's precious little we
2104                // can do about it. A settings error is reported, though.
2105                adjustCpuAbisForSharedUserLPw(setting.packages, null /* scanned package */,
2106                        false /* force dexopt */, false /* defer dexopt */);
2107            }
2108
2109            // Now that we know all the packages we are keeping,
2110            // read and update their last usage times.
2111            mPackageUsage.readLP();
2112
2113            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END,
2114                    SystemClock.uptimeMillis());
2115            Slog.i(TAG, "Time to scan packages: "
2116                    + ((SystemClock.uptimeMillis()-startTime)/1000f)
2117                    + " seconds");
2118
2119            // If the platform SDK has changed since the last time we booted,
2120            // we need to re-grant app permission to catch any new ones that
2121            // appear.  This is really a hack, and means that apps can in some
2122            // cases get permissions that the user didn't initially explicitly
2123            // allow...  it would be nice to have some better way to handle
2124            // this situation.
2125            final boolean regrantPermissions = mSettings.mInternalSdkPlatform
2126                    != mSdkVersion;
2127            if (regrantPermissions) Slog.i(TAG, "Platform changed from "
2128                    + mSettings.mInternalSdkPlatform + " to " + mSdkVersion
2129                    + "; regranting permissions for internal storage");
2130            mSettings.mInternalSdkPlatform = mSdkVersion;
2131
2132            updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL
2133                    | (regrantPermissions
2134                            ? (UPDATE_PERMISSIONS_REPLACE_PKG|UPDATE_PERMISSIONS_REPLACE_ALL)
2135                            : 0));
2136
2137            // If this is the first boot, and it is a normal boot, then
2138            // we need to initialize the default preferred apps.
2139            if (!mRestoredSettings && !onlyCore) {
2140                mSettings.readDefaultPreferredAppsLPw(this, 0);
2141            }
2142
2143            // If this is first boot after an OTA, and a normal boot, then
2144            // we need to clear code cache directories.
2145            mIsUpgrade = !Build.FINGERPRINT.equals(mSettings.mFingerprint);
2146            if (mIsUpgrade && !onlyCore) {
2147                Slog.i(TAG, "Build fingerprint changed; clearing code caches");
2148                for (int i = 0; i < mSettings.mPackages.size(); i++) {
2149                    final PackageSetting ps = mSettings.mPackages.valueAt(i);
2150                    deleteCodeCacheDirsLI(ps.volumeUuid, ps.name);
2151                }
2152                mSettings.mFingerprint = Build.FINGERPRINT;
2153            }
2154
2155            primeDomainVerificationsLPw(false);
2156
2157            // All the changes are done during package scanning.
2158            mSettings.updateInternalDatabaseVersion();
2159
2160            // can downgrade to reader
2161            mSettings.writeLPr();
2162
2163            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY,
2164                    SystemClock.uptimeMillis());
2165
2166            mRequiredVerifierPackage = getRequiredVerifierLPr();
2167
2168            mInstallerService = new PackageInstallerService(context, this);
2169
2170            mIntentFilterVerifierComponent = getIntentFilterVerifierComponentNameLPr();
2171            mIntentFilterVerifier = new IntentVerifierProxy(mContext,
2172                    mIntentFilterVerifierComponent);
2173
2174        } // synchronized (mPackages)
2175        } // synchronized (mInstallLock)
2176
2177        // Now after opening every single application zip, make sure they
2178        // are all flushed.  Not really needed, but keeps things nice and
2179        // tidy.
2180        Runtime.getRuntime().gc();
2181    }
2182
2183    @Override
2184    public boolean isFirstBoot() {
2185        return !mRestoredSettings;
2186    }
2187
2188    @Override
2189    public boolean isOnlyCoreApps() {
2190        return mOnlyCore;
2191    }
2192
2193    @Override
2194    public boolean isUpgrade() {
2195        return mIsUpgrade;
2196    }
2197
2198    private String getRequiredVerifierLPr() {
2199        final Intent verification = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
2200        final List<ResolveInfo> receivers = queryIntentReceivers(verification, PACKAGE_MIME_TYPE,
2201                PackageManager.GET_DISABLED_COMPONENTS, 0 /* TODO: Which userId? */);
2202
2203        String requiredVerifier = null;
2204
2205        final int N = receivers.size();
2206        for (int i = 0; i < N; i++) {
2207            final ResolveInfo info = receivers.get(i);
2208
2209            if (info.activityInfo == null) {
2210                continue;
2211            }
2212
2213            final String packageName = info.activityInfo.packageName;
2214
2215            if (checkPermission(android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
2216                    packageName, UserHandle.USER_OWNER) != PackageManager.PERMISSION_GRANTED) {
2217                continue;
2218            }
2219
2220            if (requiredVerifier != null) {
2221                throw new RuntimeException("There can be only one required verifier");
2222            }
2223
2224            requiredVerifier = packageName;
2225        }
2226
2227        return requiredVerifier;
2228    }
2229
2230    private ComponentName getIntentFilterVerifierComponentNameLPr() {
2231        final Intent verification = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION);
2232        final List<ResolveInfo> receivers = queryIntentReceivers(verification, PACKAGE_MIME_TYPE,
2233                PackageManager.GET_DISABLED_COMPONENTS, 0 /* userId */);
2234
2235        ComponentName verifierComponentName = null;
2236
2237        int priority = -1000;
2238        final int N = receivers.size();
2239        for (int i = 0; i < N; i++) {
2240            final ResolveInfo info = receivers.get(i);
2241
2242            if (info.activityInfo == null) {
2243                continue;
2244            }
2245
2246            final String packageName = info.activityInfo.packageName;
2247
2248            final PackageSetting ps = mSettings.mPackages.get(packageName);
2249            if (ps == null) {
2250                continue;
2251            }
2252
2253            if (checkPermission(android.Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT,
2254                    packageName, UserHandle.USER_OWNER) != PackageManager.PERMISSION_GRANTED) {
2255                continue;
2256            }
2257
2258            // Select the IntentFilterVerifier with the highest priority
2259            if (priority < info.priority) {
2260                priority = info.priority;
2261                verifierComponentName = new ComponentName(packageName, info.activityInfo.name);
2262                Slog.d(TAG, "Selecting IntentFilterVerifier: " + verifierComponentName +
2263                        " with priority: " + info.priority);
2264            }
2265        }
2266
2267        return verifierComponentName;
2268    }
2269
2270    private void primeDomainVerificationsLPw(boolean logging) {
2271        Slog.d(TAG, "Start priming domain verifications");
2272        boolean updated = false;
2273        ArraySet<String> allHostsSet = new ArraySet<>();
2274        for (PackageParser.Package pkg : mPackages.values()) {
2275            final String packageName = pkg.packageName;
2276            if (!hasDomainURLs(pkg)) {
2277                if (logging) {
2278                    Slog.d(TAG, "No priming domain verifications for " +
2279                            "package with no domain URLs: " + packageName);
2280                }
2281                continue;
2282            }
2283            if (!pkg.isSystemApp()) {
2284                if (logging) {
2285                    Slog.d(TAG, "No priming domain verifications for a non system package : " +
2286                            packageName);
2287                }
2288                continue;
2289            }
2290            for (PackageParser.Activity a : pkg.activities) {
2291                for (ActivityIntentInfo filter : a.intents) {
2292                    if (hasValidDomains(filter, false)) {
2293                        allHostsSet.addAll(filter.getHostsList());
2294                    }
2295                }
2296            }
2297            if (allHostsSet.size() == 0) {
2298                allHostsSet.add("*");
2299            }
2300            ArrayList<String> allHostsList = new ArrayList<>(allHostsSet);
2301            IntentFilterVerificationInfo ivi =
2302                    mSettings.createIntentFilterVerificationIfNeededLPw(packageName, allHostsList);
2303            if (ivi != null) {
2304                // We will always log this
2305                Slog.d(TAG, "Priming domain verifications for package: " + packageName +
2306                        " with hosts:" + ivi.getDomainsString());
2307                ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS);
2308                updated = true;
2309            }
2310            else {
2311                if (logging) {
2312                    Slog.d(TAG, "No priming domain verifications for package: " + packageName);
2313                }
2314            }
2315            allHostsSet.clear();
2316        }
2317        if (updated) {
2318            if (logging) {
2319                Slog.d(TAG, "Will need to write primed domain verifications");
2320            }
2321        }
2322        Slog.d(TAG, "End priming domain verifications");
2323    }
2324
2325    @Override
2326    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2327            throws RemoteException {
2328        try {
2329            return super.onTransact(code, data, reply, flags);
2330        } catch (RuntimeException e) {
2331            if (!(e instanceof SecurityException) && !(e instanceof IllegalArgumentException)) {
2332                Slog.wtf(TAG, "Package Manager Crash", e);
2333            }
2334            throw e;
2335        }
2336    }
2337
2338    void cleanupInstallFailedPackage(PackageSetting ps) {
2339        logCriticalInfo(Log.WARN, "Cleaning up incompletely installed app: " + ps.name);
2340
2341        removeDataDirsLI(ps.volumeUuid, ps.name);
2342        if (ps.codePath != null) {
2343            if (ps.codePath.isDirectory()) {
2344                mInstaller.rmPackageDir(ps.codePath.getAbsolutePath());
2345            } else {
2346                ps.codePath.delete();
2347            }
2348        }
2349        if (ps.resourcePath != null && !ps.resourcePath.equals(ps.codePath)) {
2350            if (ps.resourcePath.isDirectory()) {
2351                FileUtils.deleteContents(ps.resourcePath);
2352            }
2353            ps.resourcePath.delete();
2354        }
2355        mSettings.removePackageLPw(ps.name);
2356    }
2357
2358    static int[] appendInts(int[] cur, int[] add) {
2359        if (add == null) return cur;
2360        if (cur == null) return add;
2361        final int N = add.length;
2362        for (int i=0; i<N; i++) {
2363            cur = appendInt(cur, add[i]);
2364        }
2365        return cur;
2366    }
2367
2368    PackageInfo generatePackageInfo(PackageParser.Package p, int flags, int userId) {
2369        if (!sUserManager.exists(userId)) return null;
2370        final PackageSetting ps = (PackageSetting) p.mExtras;
2371        if (ps == null) {
2372            return null;
2373        }
2374
2375        final PermissionsState permissionsState = ps.getPermissionsState();
2376
2377        final int[] gids = permissionsState.computeGids(userId);
2378        final Set<String> permissions = permissionsState.getPermissions(userId);
2379        final PackageUserState state = ps.readUserState(userId);
2380
2381        return PackageParser.generatePackageInfo(p, gids, flags,
2382                ps.firstInstallTime, ps.lastUpdateTime, permissions, state, userId);
2383    }
2384
2385    @Override
2386    public boolean isPackageFrozen(String packageName) {
2387        synchronized (mPackages) {
2388            final PackageSetting ps = mSettings.mPackages.get(packageName);
2389            if (ps != null) {
2390                return ps.frozen;
2391            }
2392        }
2393        Slog.w(TAG, "Package " + packageName + " is missing; assuming frozen");
2394        return true;
2395    }
2396
2397    @Override
2398    public boolean isPackageAvailable(String packageName, int userId) {
2399        if (!sUserManager.exists(userId)) return false;
2400        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "is package available");
2401        synchronized (mPackages) {
2402            PackageParser.Package p = mPackages.get(packageName);
2403            if (p != null) {
2404                final PackageSetting ps = (PackageSetting) p.mExtras;
2405                if (ps != null) {
2406                    final PackageUserState state = ps.readUserState(userId);
2407                    if (state != null) {
2408                        return PackageParser.isAvailable(state);
2409                    }
2410                }
2411            }
2412        }
2413        return false;
2414    }
2415
2416    @Override
2417    public PackageInfo getPackageInfo(String packageName, int flags, int userId) {
2418        if (!sUserManager.exists(userId)) return null;
2419        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get package info");
2420        // reader
2421        synchronized (mPackages) {
2422            PackageParser.Package p = mPackages.get(packageName);
2423            if (DEBUG_PACKAGE_INFO)
2424                Log.v(TAG, "getPackageInfo " + packageName + ": " + p);
2425            if (p != null) {
2426                return generatePackageInfo(p, flags, userId);
2427            }
2428            if((flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0) {
2429                return generatePackageInfoFromSettingsLPw(packageName, flags, userId);
2430            }
2431        }
2432        return null;
2433    }
2434
2435    @Override
2436    public String[] currentToCanonicalPackageNames(String[] names) {
2437        String[] out = new String[names.length];
2438        // reader
2439        synchronized (mPackages) {
2440            for (int i=names.length-1; i>=0; i--) {
2441                PackageSetting ps = mSettings.mPackages.get(names[i]);
2442                out[i] = ps != null && ps.realName != null ? ps.realName : names[i];
2443            }
2444        }
2445        return out;
2446    }
2447
2448    @Override
2449    public String[] canonicalToCurrentPackageNames(String[] names) {
2450        String[] out = new String[names.length];
2451        // reader
2452        synchronized (mPackages) {
2453            for (int i=names.length-1; i>=0; i--) {
2454                String cur = mSettings.mRenamedPackages.get(names[i]);
2455                out[i] = cur != null ? cur : names[i];
2456            }
2457        }
2458        return out;
2459    }
2460
2461    @Override
2462    public int getPackageUid(String packageName, int userId) {
2463        if (!sUserManager.exists(userId)) return -1;
2464        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get package uid");
2465
2466        // reader
2467        synchronized (mPackages) {
2468            PackageParser.Package p = mPackages.get(packageName);
2469            if(p != null) {
2470                return UserHandle.getUid(userId, p.applicationInfo.uid);
2471            }
2472            PackageSetting ps = mSettings.mPackages.get(packageName);
2473            if((ps == null) || (ps.pkg == null) || (ps.pkg.applicationInfo == null)) {
2474                return -1;
2475            }
2476            p = ps.pkg;
2477            return p != null ? UserHandle.getUid(userId, p.applicationInfo.uid) : -1;
2478        }
2479    }
2480
2481    @Override
2482    public int[] getPackageGids(String packageName, int userId) throws RemoteException {
2483        if (!sUserManager.exists(userId)) {
2484            return null;
2485        }
2486
2487        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false,
2488                "getPackageGids");
2489
2490        // reader
2491        synchronized (mPackages) {
2492            PackageParser.Package p = mPackages.get(packageName);
2493            if (DEBUG_PACKAGE_INFO) {
2494                Log.v(TAG, "getPackageGids" + packageName + ": " + p);
2495            }
2496            if (p != null) {
2497                PackageSetting ps = (PackageSetting) p.mExtras;
2498                return ps.getPermissionsState().computeGids(userId);
2499            }
2500        }
2501
2502        return null;
2503    }
2504
2505    static PermissionInfo generatePermissionInfo(
2506            BasePermission bp, int flags) {
2507        if (bp.perm != null) {
2508            return PackageParser.generatePermissionInfo(bp.perm, flags);
2509        }
2510        PermissionInfo pi = new PermissionInfo();
2511        pi.name = bp.name;
2512        pi.packageName = bp.sourcePackage;
2513        pi.nonLocalizedLabel = bp.name;
2514        pi.protectionLevel = bp.protectionLevel;
2515        return pi;
2516    }
2517
2518    @Override
2519    public PermissionInfo getPermissionInfo(String name, int flags) {
2520        // reader
2521        synchronized (mPackages) {
2522            final BasePermission p = mSettings.mPermissions.get(name);
2523            if (p != null) {
2524                return generatePermissionInfo(p, flags);
2525            }
2526            return null;
2527        }
2528    }
2529
2530    @Override
2531    public List<PermissionInfo> queryPermissionsByGroup(String group, int flags) {
2532        // reader
2533        synchronized (mPackages) {
2534            ArrayList<PermissionInfo> out = new ArrayList<PermissionInfo>(10);
2535            for (BasePermission p : mSettings.mPermissions.values()) {
2536                if (group == null) {
2537                    if (p.perm == null || p.perm.info.group == null) {
2538                        out.add(generatePermissionInfo(p, flags));
2539                    }
2540                } else {
2541                    if (p.perm != null && group.equals(p.perm.info.group)) {
2542                        out.add(PackageParser.generatePermissionInfo(p.perm, flags));
2543                    }
2544                }
2545            }
2546
2547            if (out.size() > 0) {
2548                return out;
2549            }
2550            return mPermissionGroups.containsKey(group) ? out : null;
2551        }
2552    }
2553
2554    @Override
2555    public PermissionGroupInfo getPermissionGroupInfo(String name, int flags) {
2556        // reader
2557        synchronized (mPackages) {
2558            return PackageParser.generatePermissionGroupInfo(
2559                    mPermissionGroups.get(name), flags);
2560        }
2561    }
2562
2563    @Override
2564    public List<PermissionGroupInfo> getAllPermissionGroups(int flags) {
2565        // reader
2566        synchronized (mPackages) {
2567            final int N = mPermissionGroups.size();
2568            ArrayList<PermissionGroupInfo> out
2569                    = new ArrayList<PermissionGroupInfo>(N);
2570            for (PackageParser.PermissionGroup pg : mPermissionGroups.values()) {
2571                out.add(PackageParser.generatePermissionGroupInfo(pg, flags));
2572            }
2573            return out;
2574        }
2575    }
2576
2577    private ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName, int flags,
2578            int userId) {
2579        if (!sUserManager.exists(userId)) return null;
2580        PackageSetting ps = mSettings.mPackages.get(packageName);
2581        if (ps != null) {
2582            if (ps.pkg == null) {
2583                PackageInfo pInfo = generatePackageInfoFromSettingsLPw(packageName,
2584                        flags, userId);
2585                if (pInfo != null) {
2586                    return pInfo.applicationInfo;
2587                }
2588                return null;
2589            }
2590            return PackageParser.generateApplicationInfo(ps.pkg, flags,
2591                    ps.readUserState(userId), userId);
2592        }
2593        return null;
2594    }
2595
2596    private PackageInfo generatePackageInfoFromSettingsLPw(String packageName, int flags,
2597            int userId) {
2598        if (!sUserManager.exists(userId)) return null;
2599        PackageSetting ps = mSettings.mPackages.get(packageName);
2600        if (ps != null) {
2601            PackageParser.Package pkg = ps.pkg;
2602            if (pkg == null) {
2603                if ((flags & PackageManager.GET_UNINSTALLED_PACKAGES) == 0) {
2604                    return null;
2605                }
2606                // Only data remains, so we aren't worried about code paths
2607                pkg = new PackageParser.Package(packageName);
2608                pkg.applicationInfo.packageName = packageName;
2609                pkg.applicationInfo.flags = ps.pkgFlags | ApplicationInfo.FLAG_IS_DATA_ONLY;
2610                pkg.applicationInfo.privateFlags = ps.pkgPrivateFlags;
2611                pkg.applicationInfo.dataDir = PackageManager.getDataDirForUser(ps.volumeUuid,
2612                        packageName, userId).getAbsolutePath();
2613                pkg.applicationInfo.primaryCpuAbi = ps.primaryCpuAbiString;
2614                pkg.applicationInfo.secondaryCpuAbi = ps.secondaryCpuAbiString;
2615            }
2616            return generatePackageInfo(pkg, flags, userId);
2617        }
2618        return null;
2619    }
2620
2621    @Override
2622    public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) {
2623        if (!sUserManager.exists(userId)) return null;
2624        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get application info");
2625        // writer
2626        synchronized (mPackages) {
2627            PackageParser.Package p = mPackages.get(packageName);
2628            if (DEBUG_PACKAGE_INFO) Log.v(
2629                    TAG, "getApplicationInfo " + packageName
2630                    + ": " + p);
2631            if (p != null) {
2632                PackageSetting ps = mSettings.mPackages.get(packageName);
2633                if (ps == null) return null;
2634                // Note: isEnabledLP() does not apply here - always return info
2635                return PackageParser.generateApplicationInfo(
2636                        p, flags, ps.readUserState(userId), userId);
2637            }
2638            if ("android".equals(packageName)||"system".equals(packageName)) {
2639                return mAndroidApplication;
2640            }
2641            if ((flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0) {
2642                return generateApplicationInfoFromSettingsLPw(packageName, flags, userId);
2643            }
2644        }
2645        return null;
2646    }
2647
2648    @Override
2649    public void freeStorageAndNotify(final String volumeUuid, final long freeStorageSize,
2650            final IPackageDataObserver observer) {
2651        mContext.enforceCallingOrSelfPermission(
2652                android.Manifest.permission.CLEAR_APP_CACHE, null);
2653        // Queue up an async operation since clearing cache may take a little while.
2654        mHandler.post(new Runnable() {
2655            public void run() {
2656                mHandler.removeCallbacks(this);
2657                int retCode = -1;
2658                synchronized (mInstallLock) {
2659                    retCode = mInstaller.freeCache(volumeUuid, freeStorageSize);
2660                    if (retCode < 0) {
2661                        Slog.w(TAG, "Couldn't clear application caches");
2662                    }
2663                }
2664                if (observer != null) {
2665                    try {
2666                        observer.onRemoveCompleted(null, (retCode >= 0));
2667                    } catch (RemoteException e) {
2668                        Slog.w(TAG, "RemoveException when invoking call back");
2669                    }
2670                }
2671            }
2672        });
2673    }
2674
2675    @Override
2676    public void freeStorage(final String volumeUuid, final long freeStorageSize,
2677            final IntentSender pi) {
2678        mContext.enforceCallingOrSelfPermission(
2679                android.Manifest.permission.CLEAR_APP_CACHE, null);
2680        // Queue up an async operation since clearing cache may take a little while.
2681        mHandler.post(new Runnable() {
2682            public void run() {
2683                mHandler.removeCallbacks(this);
2684                int retCode = -1;
2685                synchronized (mInstallLock) {
2686                    retCode = mInstaller.freeCache(volumeUuid, freeStorageSize);
2687                    if (retCode < 0) {
2688                        Slog.w(TAG, "Couldn't clear application caches");
2689                    }
2690                }
2691                if(pi != null) {
2692                    try {
2693                        // Callback via pending intent
2694                        int code = (retCode >= 0) ? 1 : 0;
2695                        pi.sendIntent(null, code, null,
2696                                null, null);
2697                    } catch (SendIntentException e1) {
2698                        Slog.i(TAG, "Failed to send pending intent");
2699                    }
2700                }
2701            }
2702        });
2703    }
2704
2705    void freeStorage(String volumeUuid, long freeStorageSize) throws IOException {
2706        synchronized (mInstallLock) {
2707            if (mInstaller.freeCache(volumeUuid, freeStorageSize) < 0) {
2708                throw new IOException("Failed to free enough space");
2709            }
2710        }
2711    }
2712
2713    @Override
2714    public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) {
2715        if (!sUserManager.exists(userId)) return null;
2716        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get activity info");
2717        synchronized (mPackages) {
2718            PackageParser.Activity a = mActivities.mActivities.get(component);
2719
2720            if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a);
2721            if (a != null && mSettings.isEnabledLPr(a.info, flags, userId)) {
2722                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
2723                if (ps == null) return null;
2724                return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId),
2725                        userId);
2726            }
2727            if (mResolveComponentName.equals(component)) {
2728                return PackageParser.generateActivityInfo(mResolveActivity, flags,
2729                        new PackageUserState(), userId);
2730            }
2731        }
2732        return null;
2733    }
2734
2735    @Override
2736    public boolean activitySupportsIntent(ComponentName component, Intent intent,
2737            String resolvedType) {
2738        synchronized (mPackages) {
2739            PackageParser.Activity a = mActivities.mActivities.get(component);
2740            if (a == null) {
2741                return false;
2742            }
2743            for (int i=0; i<a.intents.size(); i++) {
2744                if (a.intents.get(i).match(intent.getAction(), resolvedType, intent.getScheme(),
2745                        intent.getData(), intent.getCategories(), TAG) >= 0) {
2746                    return true;
2747                }
2748            }
2749            return false;
2750        }
2751    }
2752
2753    @Override
2754    public ActivityInfo getReceiverInfo(ComponentName component, int flags, int userId) {
2755        if (!sUserManager.exists(userId)) return null;
2756        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get receiver info");
2757        synchronized (mPackages) {
2758            PackageParser.Activity a = mReceivers.mActivities.get(component);
2759            if (DEBUG_PACKAGE_INFO) Log.v(
2760                TAG, "getReceiverInfo " + component + ": " + a);
2761            if (a != null && mSettings.isEnabledLPr(a.info, flags, userId)) {
2762                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
2763                if (ps == null) return null;
2764                return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId),
2765                        userId);
2766            }
2767        }
2768        return null;
2769    }
2770
2771    @Override
2772    public ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) {
2773        if (!sUserManager.exists(userId)) return null;
2774        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get service info");
2775        synchronized (mPackages) {
2776            PackageParser.Service s = mServices.mServices.get(component);
2777            if (DEBUG_PACKAGE_INFO) Log.v(
2778                TAG, "getServiceInfo " + component + ": " + s);
2779            if (s != null && mSettings.isEnabledLPr(s.info, flags, userId)) {
2780                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
2781                if (ps == null) return null;
2782                return PackageParser.generateServiceInfo(s, flags, ps.readUserState(userId),
2783                        userId);
2784            }
2785        }
2786        return null;
2787    }
2788
2789    @Override
2790    public ProviderInfo getProviderInfo(ComponentName component, int flags, int userId) {
2791        if (!sUserManager.exists(userId)) return null;
2792        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get provider info");
2793        synchronized (mPackages) {
2794            PackageParser.Provider p = mProviders.mProviders.get(component);
2795            if (DEBUG_PACKAGE_INFO) Log.v(
2796                TAG, "getProviderInfo " + component + ": " + p);
2797            if (p != null && mSettings.isEnabledLPr(p.info, flags, userId)) {
2798                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
2799                if (ps == null) return null;
2800                return PackageParser.generateProviderInfo(p, flags, ps.readUserState(userId),
2801                        userId);
2802            }
2803        }
2804        return null;
2805    }
2806
2807    @Override
2808    public String[] getSystemSharedLibraryNames() {
2809        Set<String> libSet;
2810        synchronized (mPackages) {
2811            libSet = mSharedLibraries.keySet();
2812            int size = libSet.size();
2813            if (size > 0) {
2814                String[] libs = new String[size];
2815                libSet.toArray(libs);
2816                return libs;
2817            }
2818        }
2819        return null;
2820    }
2821
2822    /**
2823     * @hide
2824     */
2825    PackageParser.Package findSharedNonSystemLibrary(String libName) {
2826        synchronized (mPackages) {
2827            PackageManagerService.SharedLibraryEntry lib = mSharedLibraries.get(libName);
2828            if (lib != null && lib.apk != null) {
2829                return mPackages.get(lib.apk);
2830            }
2831        }
2832        return null;
2833    }
2834
2835    @Override
2836    public FeatureInfo[] getSystemAvailableFeatures() {
2837        Collection<FeatureInfo> featSet;
2838        synchronized (mPackages) {
2839            featSet = mAvailableFeatures.values();
2840            int size = featSet.size();
2841            if (size > 0) {
2842                FeatureInfo[] features = new FeatureInfo[size+1];
2843                featSet.toArray(features);
2844                FeatureInfo fi = new FeatureInfo();
2845                fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version",
2846                        FeatureInfo.GL_ES_VERSION_UNDEFINED);
2847                features[size] = fi;
2848                return features;
2849            }
2850        }
2851        return null;
2852    }
2853
2854    @Override
2855    public boolean hasSystemFeature(String name) {
2856        synchronized (mPackages) {
2857            return mAvailableFeatures.containsKey(name);
2858        }
2859    }
2860
2861    private void checkValidCaller(int uid, int userId) {
2862        if (UserHandle.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0)
2863            return;
2864
2865        throw new SecurityException("Caller uid=" + uid
2866                + " is not privileged to communicate with user=" + userId);
2867    }
2868
2869    @Override
2870    public int checkPermission(String permName, String pkgName, int userId) {
2871        if (!sUserManager.exists(userId)) {
2872            return PackageManager.PERMISSION_DENIED;
2873        }
2874
2875        synchronized (mPackages) {
2876            final PackageParser.Package p = mPackages.get(pkgName);
2877            if (p != null && p.mExtras != null) {
2878                final PackageSetting ps = (PackageSetting) p.mExtras;
2879                if (ps.getPermissionsState().hasPermission(permName, userId)) {
2880                    return PackageManager.PERMISSION_GRANTED;
2881                }
2882            }
2883        }
2884
2885        return PackageManager.PERMISSION_DENIED;
2886    }
2887
2888    @Override
2889    public int checkUidPermission(String permName, int uid) {
2890        final int userId = UserHandle.getUserId(uid);
2891
2892        if (!sUserManager.exists(userId)) {
2893            return PackageManager.PERMISSION_DENIED;
2894        }
2895
2896        synchronized (mPackages) {
2897            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
2898            if (obj != null) {
2899                final SettingBase ps = (SettingBase) obj;
2900                if (ps.getPermissionsState().hasPermission(permName, userId)) {
2901                    return PackageManager.PERMISSION_GRANTED;
2902                }
2903            } else {
2904                ArraySet<String> perms = mSystemPermissions.get(uid);
2905                if (perms != null && perms.contains(permName)) {
2906                    return PackageManager.PERMISSION_GRANTED;
2907                }
2908            }
2909        }
2910
2911        return PackageManager.PERMISSION_DENIED;
2912    }
2913
2914    /**
2915     * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS
2916     * or INTERACT_ACROSS_USERS_FULL permissions, if the userid is not for the caller.
2917     * @param checkShell TODO(yamasani):
2918     * @param message the message to log on security exception
2919     */
2920    void enforceCrossUserPermission(int callingUid, int userId, boolean requireFullPermission,
2921            boolean checkShell, String message) {
2922        if (userId < 0) {
2923            throw new IllegalArgumentException("Invalid userId " + userId);
2924        }
2925        if (checkShell) {
2926            enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId);
2927        }
2928        if (userId == UserHandle.getUserId(callingUid)) return;
2929        if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
2930            if (requireFullPermission) {
2931                mContext.enforceCallingOrSelfPermission(
2932                        android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
2933            } else {
2934                try {
2935                    mContext.enforceCallingOrSelfPermission(
2936                            android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
2937                } catch (SecurityException se) {
2938                    mContext.enforceCallingOrSelfPermission(
2939                            android.Manifest.permission.INTERACT_ACROSS_USERS, message);
2940                }
2941            }
2942        }
2943    }
2944
2945    void enforceShellRestriction(String restriction, int callingUid, int userHandle) {
2946        if (callingUid == Process.SHELL_UID) {
2947            if (userHandle >= 0
2948                    && sUserManager.hasUserRestriction(restriction, userHandle)) {
2949                throw new SecurityException("Shell does not have permission to access user "
2950                        + userHandle);
2951            } else if (userHandle < 0) {
2952                Slog.e(TAG, "Unable to check shell permission for user " + userHandle + "\n\t"
2953                        + Debug.getCallers(3));
2954            }
2955        }
2956    }
2957
2958    private BasePermission findPermissionTreeLP(String permName) {
2959        for(BasePermission bp : mSettings.mPermissionTrees.values()) {
2960            if (permName.startsWith(bp.name) &&
2961                    permName.length() > bp.name.length() &&
2962                    permName.charAt(bp.name.length()) == '.') {
2963                return bp;
2964            }
2965        }
2966        return null;
2967    }
2968
2969    private BasePermission checkPermissionTreeLP(String permName) {
2970        if (permName != null) {
2971            BasePermission bp = findPermissionTreeLP(permName);
2972            if (bp != null) {
2973                if (bp.uid == UserHandle.getAppId(Binder.getCallingUid())) {
2974                    return bp;
2975                }
2976                throw new SecurityException("Calling uid "
2977                        + Binder.getCallingUid()
2978                        + " is not allowed to add to permission tree "
2979                        + bp.name + " owned by uid " + bp.uid);
2980            }
2981        }
2982        throw new SecurityException("No permission tree found for " + permName);
2983    }
2984
2985    static boolean compareStrings(CharSequence s1, CharSequence s2) {
2986        if (s1 == null) {
2987            return s2 == null;
2988        }
2989        if (s2 == null) {
2990            return false;
2991        }
2992        if (s1.getClass() != s2.getClass()) {
2993            return false;
2994        }
2995        return s1.equals(s2);
2996    }
2997
2998    static boolean comparePermissionInfos(PermissionInfo pi1, PermissionInfo pi2) {
2999        if (pi1.icon != pi2.icon) return false;
3000        if (pi1.logo != pi2.logo) return false;
3001        if (pi1.protectionLevel != pi2.protectionLevel) return false;
3002        if (!compareStrings(pi1.name, pi2.name)) return false;
3003        if (!compareStrings(pi1.nonLocalizedLabel, pi2.nonLocalizedLabel)) return false;
3004        // We'll take care of setting this one.
3005        if (!compareStrings(pi1.packageName, pi2.packageName)) return false;
3006        // These are not currently stored in settings.
3007        //if (!compareStrings(pi1.group, pi2.group)) return false;
3008        //if (!compareStrings(pi1.nonLocalizedDescription, pi2.nonLocalizedDescription)) return false;
3009        //if (pi1.labelRes != pi2.labelRes) return false;
3010        //if (pi1.descriptionRes != pi2.descriptionRes) return false;
3011        return true;
3012    }
3013
3014    int permissionInfoFootprint(PermissionInfo info) {
3015        int size = info.name.length();
3016        if (info.nonLocalizedLabel != null) size += info.nonLocalizedLabel.length();
3017        if (info.nonLocalizedDescription != null) size += info.nonLocalizedDescription.length();
3018        return size;
3019    }
3020
3021    int calculateCurrentPermissionFootprintLocked(BasePermission tree) {
3022        int size = 0;
3023        for (BasePermission perm : mSettings.mPermissions.values()) {
3024            if (perm.uid == tree.uid) {
3025                size += perm.name.length() + permissionInfoFootprint(perm.perm.info);
3026            }
3027        }
3028        return size;
3029    }
3030
3031    void enforcePermissionCapLocked(PermissionInfo info, BasePermission tree) {
3032        // We calculate the max size of permissions defined by this uid and throw
3033        // if that plus the size of 'info' would exceed our stated maximum.
3034        if (tree.uid != Process.SYSTEM_UID) {
3035            final int curTreeSize = calculateCurrentPermissionFootprintLocked(tree);
3036            if (curTreeSize + permissionInfoFootprint(info) > MAX_PERMISSION_TREE_FOOTPRINT) {
3037                throw new SecurityException("Permission tree size cap exceeded");
3038            }
3039        }
3040    }
3041
3042    boolean addPermissionLocked(PermissionInfo info, boolean async) {
3043        if (info.labelRes == 0 && info.nonLocalizedLabel == null) {
3044            throw new SecurityException("Label must be specified in permission");
3045        }
3046        BasePermission tree = checkPermissionTreeLP(info.name);
3047        BasePermission bp = mSettings.mPermissions.get(info.name);
3048        boolean added = bp == null;
3049        boolean changed = true;
3050        int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel);
3051        if (added) {
3052            enforcePermissionCapLocked(info, tree);
3053            bp = new BasePermission(info.name, tree.sourcePackage,
3054                    BasePermission.TYPE_DYNAMIC);
3055        } else if (bp.type != BasePermission.TYPE_DYNAMIC) {
3056            throw new SecurityException(
3057                    "Not allowed to modify non-dynamic permission "
3058                    + info.name);
3059        } else {
3060            if (bp.protectionLevel == fixedLevel
3061                    && bp.perm.owner.equals(tree.perm.owner)
3062                    && bp.uid == tree.uid
3063                    && comparePermissionInfos(bp.perm.info, info)) {
3064                changed = false;
3065            }
3066        }
3067        bp.protectionLevel = fixedLevel;
3068        info = new PermissionInfo(info);
3069        info.protectionLevel = fixedLevel;
3070        bp.perm = new PackageParser.Permission(tree.perm.owner, info);
3071        bp.perm.info.packageName = tree.perm.info.packageName;
3072        bp.uid = tree.uid;
3073        if (added) {
3074            mSettings.mPermissions.put(info.name, bp);
3075        }
3076        if (changed) {
3077            if (!async) {
3078                mSettings.writeLPr();
3079            } else {
3080                scheduleWriteSettingsLocked();
3081            }
3082        }
3083        return added;
3084    }
3085
3086    @Override
3087    public boolean addPermission(PermissionInfo info) {
3088        synchronized (mPackages) {
3089            return addPermissionLocked(info, false);
3090        }
3091    }
3092
3093    @Override
3094    public boolean addPermissionAsync(PermissionInfo info) {
3095        synchronized (mPackages) {
3096            return addPermissionLocked(info, true);
3097        }
3098    }
3099
3100    @Override
3101    public void removePermission(String name) {
3102        synchronized (mPackages) {
3103            checkPermissionTreeLP(name);
3104            BasePermission bp = mSettings.mPermissions.get(name);
3105            if (bp != null) {
3106                if (bp.type != BasePermission.TYPE_DYNAMIC) {
3107                    throw new SecurityException(
3108                            "Not allowed to modify non-dynamic permission "
3109                            + name);
3110                }
3111                mSettings.mPermissions.remove(name);
3112                mSettings.writeLPr();
3113            }
3114        }
3115    }
3116
3117    private static void enforceDeclaredAsUsedAndRuntimePermission(PackageParser.Package pkg,
3118            BasePermission bp) {
3119        int index = pkg.requestedPermissions.indexOf(bp.name);
3120        if (index == -1) {
3121            throw new SecurityException("Package " + pkg.packageName
3122                    + " has not requested permission " + bp.name);
3123        }
3124        if (!bp.isRuntime()) {
3125            throw new SecurityException("Permission " + bp.name
3126                    + " is not a changeable permission type");
3127        }
3128    }
3129
3130    @Override
3131    public void grantPermission(String packageName, String name, int userId) {
3132        if (!sUserManager.exists(userId)) {
3133            return;
3134        }
3135
3136        mContext.enforceCallingOrSelfPermission(
3137                android.Manifest.permission.GRANT_REVOKE_PERMISSIONS,
3138                "grantPermission");
3139
3140        enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false,
3141                "grantPermission");
3142
3143        boolean gidsChanged = false;
3144        final SettingBase sb;
3145
3146        synchronized (mPackages) {
3147            final PackageParser.Package pkg = mPackages.get(packageName);
3148            if (pkg == null) {
3149                throw new IllegalArgumentException("Unknown package: " + packageName);
3150            }
3151
3152            final BasePermission bp = mSettings.mPermissions.get(name);
3153            if (bp == null) {
3154                throw new IllegalArgumentException("Unknown permission: " + name);
3155            }
3156
3157            enforceDeclaredAsUsedAndRuntimePermission(pkg, bp);
3158
3159            sb = (SettingBase) pkg.mExtras;
3160            if (sb == null) {
3161                throw new IllegalArgumentException("Unknown package: " + packageName);
3162            }
3163
3164            final PermissionsState permissionsState = sb.getPermissionsState();
3165
3166            final int result = permissionsState.grantRuntimePermission(bp, userId);
3167            switch (result) {
3168                case PermissionsState.PERMISSION_OPERATION_FAILURE: {
3169                    return;
3170                }
3171
3172                case PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
3173                    gidsChanged = true;
3174                }
3175                break;
3176            }
3177
3178            // Not critical if that is lost - app has to request again.
3179            mSettings.writeRuntimePermissionsForUserLPr(userId, false);
3180        }
3181
3182        if (gidsChanged) {
3183            killSettingPackagesForUser(sb, userId, KILL_APP_REASON_GIDS_CHANGED);
3184        }
3185    }
3186
3187    @Override
3188    public void revokePermission(String packageName, String name, int userId) {
3189        if (!sUserManager.exists(userId)) {
3190            return;
3191        }
3192
3193        mContext.enforceCallingOrSelfPermission(
3194                android.Manifest.permission.GRANT_REVOKE_PERMISSIONS,
3195                "revokePermission");
3196
3197        enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false,
3198                "revokePermission");
3199
3200        final SettingBase sb;
3201
3202        synchronized (mPackages) {
3203            final PackageParser.Package pkg = mPackages.get(packageName);
3204            if (pkg == null) {
3205                throw new IllegalArgumentException("Unknown package: " + packageName);
3206            }
3207
3208            final BasePermission bp = mSettings.mPermissions.get(name);
3209            if (bp == null) {
3210                throw new IllegalArgumentException("Unknown permission: " + name);
3211            }
3212
3213            enforceDeclaredAsUsedAndRuntimePermission(pkg, bp);
3214
3215            sb = (SettingBase) pkg.mExtras;
3216            if (sb == null) {
3217                throw new IllegalArgumentException("Unknown package: " + packageName);
3218            }
3219
3220            final PermissionsState permissionsState = sb.getPermissionsState();
3221
3222            if (permissionsState.revokeRuntimePermission(bp, userId) ==
3223                    PermissionsState.PERMISSION_OPERATION_FAILURE) {
3224                return;
3225            }
3226
3227            // Critical, after this call all should never have the permission.
3228            mSettings.writeRuntimePermissionsForUserLPr(userId, true);
3229        }
3230
3231        killSettingPackagesForUser(sb, userId, KILL_APP_REASON_PERMISSIONS_REVOKED);
3232    }
3233
3234    @Override
3235    public boolean isProtectedBroadcast(String actionName) {
3236        synchronized (mPackages) {
3237            return mProtectedBroadcasts.contains(actionName);
3238        }
3239    }
3240
3241    @Override
3242    public int checkSignatures(String pkg1, String pkg2) {
3243        synchronized (mPackages) {
3244            final PackageParser.Package p1 = mPackages.get(pkg1);
3245            final PackageParser.Package p2 = mPackages.get(pkg2);
3246            if (p1 == null || p1.mExtras == null
3247                    || p2 == null || p2.mExtras == null) {
3248                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
3249            }
3250            return compareSignatures(p1.mSignatures, p2.mSignatures);
3251        }
3252    }
3253
3254    @Override
3255    public int checkUidSignatures(int uid1, int uid2) {
3256        // Map to base uids.
3257        uid1 = UserHandle.getAppId(uid1);
3258        uid2 = UserHandle.getAppId(uid2);
3259        // reader
3260        synchronized (mPackages) {
3261            Signature[] s1;
3262            Signature[] s2;
3263            Object obj = mSettings.getUserIdLPr(uid1);
3264            if (obj != null) {
3265                if (obj instanceof SharedUserSetting) {
3266                    s1 = ((SharedUserSetting)obj).signatures.mSignatures;
3267                } else if (obj instanceof PackageSetting) {
3268                    s1 = ((PackageSetting)obj).signatures.mSignatures;
3269                } else {
3270                    return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
3271                }
3272            } else {
3273                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
3274            }
3275            obj = mSettings.getUserIdLPr(uid2);
3276            if (obj != null) {
3277                if (obj instanceof SharedUserSetting) {
3278                    s2 = ((SharedUserSetting)obj).signatures.mSignatures;
3279                } else if (obj instanceof PackageSetting) {
3280                    s2 = ((PackageSetting)obj).signatures.mSignatures;
3281                } else {
3282                    return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
3283                }
3284            } else {
3285                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
3286            }
3287            return compareSignatures(s1, s2);
3288        }
3289    }
3290
3291    private void killSettingPackagesForUser(SettingBase sb, int userId, String reason) {
3292        final long identity = Binder.clearCallingIdentity();
3293        try {
3294            if (sb instanceof SharedUserSetting) {
3295                SharedUserSetting sus = (SharedUserSetting) sb;
3296                final int packageCount = sus.packages.size();
3297                for (int i = 0; i < packageCount; i++) {
3298                    PackageSetting susPs = sus.packages.valueAt(i);
3299                    if (userId == UserHandle.USER_ALL) {
3300                        killApplication(susPs.pkg.packageName, susPs.appId, reason);
3301                    } else {
3302                        final int uid = UserHandle.getUid(userId, susPs.appId);
3303                        killUid(uid, reason);
3304                    }
3305                }
3306            } else if (sb instanceof PackageSetting) {
3307                PackageSetting ps = (PackageSetting) sb;
3308                if (userId == UserHandle.USER_ALL) {
3309                    killApplication(ps.pkg.packageName, ps.appId, reason);
3310                } else {
3311                    final int uid = UserHandle.getUid(userId, ps.appId);
3312                    killUid(uid, reason);
3313                }
3314            }
3315        } finally {
3316            Binder.restoreCallingIdentity(identity);
3317        }
3318    }
3319
3320    private static void killUid(int uid, String reason) {
3321        IActivityManager am = ActivityManagerNative.getDefault();
3322        if (am != null) {
3323            try {
3324                am.killUid(uid, reason);
3325            } catch (RemoteException e) {
3326                /* ignore - same process */
3327            }
3328        }
3329    }
3330
3331    /**
3332     * Compares two sets of signatures. Returns:
3333     * <br />
3334     * {@link PackageManager#SIGNATURE_NEITHER_SIGNED}: if both signature sets are null,
3335     * <br />
3336     * {@link PackageManager#SIGNATURE_FIRST_NOT_SIGNED}: if the first signature set is null,
3337     * <br />
3338     * {@link PackageManager#SIGNATURE_SECOND_NOT_SIGNED}: if the second signature set is null,
3339     * <br />
3340     * {@link PackageManager#SIGNATURE_MATCH}: if the two signature sets are identical,
3341     * <br />
3342     * {@link PackageManager#SIGNATURE_NO_MATCH}: if the two signature sets differ.
3343     */
3344    static int compareSignatures(Signature[] s1, Signature[] s2) {
3345        if (s1 == null) {
3346            return s2 == null
3347                    ? PackageManager.SIGNATURE_NEITHER_SIGNED
3348                    : PackageManager.SIGNATURE_FIRST_NOT_SIGNED;
3349        }
3350
3351        if (s2 == null) {
3352            return PackageManager.SIGNATURE_SECOND_NOT_SIGNED;
3353        }
3354
3355        if (s1.length != s2.length) {
3356            return PackageManager.SIGNATURE_NO_MATCH;
3357        }
3358
3359        // Since both signature sets are of size 1, we can compare without HashSets.
3360        if (s1.length == 1) {
3361            return s1[0].equals(s2[0]) ?
3362                    PackageManager.SIGNATURE_MATCH :
3363                    PackageManager.SIGNATURE_NO_MATCH;
3364        }
3365
3366        ArraySet<Signature> set1 = new ArraySet<Signature>();
3367        for (Signature sig : s1) {
3368            set1.add(sig);
3369        }
3370        ArraySet<Signature> set2 = new ArraySet<Signature>();
3371        for (Signature sig : s2) {
3372            set2.add(sig);
3373        }
3374        // Make sure s2 contains all signatures in s1.
3375        if (set1.equals(set2)) {
3376            return PackageManager.SIGNATURE_MATCH;
3377        }
3378        return PackageManager.SIGNATURE_NO_MATCH;
3379    }
3380
3381    /**
3382     * If the database version for this type of package (internal storage or
3383     * external storage) is less than the version where package signatures
3384     * were updated, return true.
3385     */
3386    private boolean isCompatSignatureUpdateNeeded(PackageParser.Package scannedPkg) {
3387        return (isExternal(scannedPkg) && mSettings.isExternalDatabaseVersionOlderThan(
3388                DatabaseVersion.SIGNATURE_END_ENTITY))
3389                || (!isExternal(scannedPkg) && mSettings.isInternalDatabaseVersionOlderThan(
3390                        DatabaseVersion.SIGNATURE_END_ENTITY));
3391    }
3392
3393    /**
3394     * Used for backward compatibility to make sure any packages with
3395     * certificate chains get upgraded to the new style. {@code existingSigs}
3396     * will be in the old format (since they were stored on disk from before the
3397     * system upgrade) and {@code scannedSigs} will be in the newer format.
3398     */
3399    private int compareSignaturesCompat(PackageSignatures existingSigs,
3400            PackageParser.Package scannedPkg) {
3401        if (!isCompatSignatureUpdateNeeded(scannedPkg)) {
3402            return PackageManager.SIGNATURE_NO_MATCH;
3403        }
3404
3405        ArraySet<Signature> existingSet = new ArraySet<Signature>();
3406        for (Signature sig : existingSigs.mSignatures) {
3407            existingSet.add(sig);
3408        }
3409        ArraySet<Signature> scannedCompatSet = new ArraySet<Signature>();
3410        for (Signature sig : scannedPkg.mSignatures) {
3411            try {
3412                Signature[] chainSignatures = sig.getChainSignatures();
3413                for (Signature chainSig : chainSignatures) {
3414                    scannedCompatSet.add(chainSig);
3415                }
3416            } catch (CertificateEncodingException e) {
3417                scannedCompatSet.add(sig);
3418            }
3419        }
3420        /*
3421         * Make sure the expanded scanned set contains all signatures in the
3422         * existing one.
3423         */
3424        if (scannedCompatSet.equals(existingSet)) {
3425            // Migrate the old signatures to the new scheme.
3426            existingSigs.assignSignatures(scannedPkg.mSignatures);
3427            // The new KeySets will be re-added later in the scanning process.
3428            synchronized (mPackages) {
3429                mSettings.mKeySetManagerService.removeAppKeySetDataLPw(scannedPkg.packageName);
3430            }
3431            return PackageManager.SIGNATURE_MATCH;
3432        }
3433        return PackageManager.SIGNATURE_NO_MATCH;
3434    }
3435
3436    private boolean isRecoverSignatureUpdateNeeded(PackageParser.Package scannedPkg) {
3437        if (isExternal(scannedPkg)) {
3438            return mSettings.isExternalDatabaseVersionOlderThan(
3439                    DatabaseVersion.SIGNATURE_MALFORMED_RECOVER);
3440        } else {
3441            return mSettings.isInternalDatabaseVersionOlderThan(
3442                    DatabaseVersion.SIGNATURE_MALFORMED_RECOVER);
3443        }
3444    }
3445
3446    private int compareSignaturesRecover(PackageSignatures existingSigs,
3447            PackageParser.Package scannedPkg) {
3448        if (!isRecoverSignatureUpdateNeeded(scannedPkg)) {
3449            return PackageManager.SIGNATURE_NO_MATCH;
3450        }
3451
3452        String msg = null;
3453        try {
3454            if (Signature.areEffectiveMatch(existingSigs.mSignatures, scannedPkg.mSignatures)) {
3455                logCriticalInfo(Log.INFO, "Recovered effectively matching certificates for "
3456                        + scannedPkg.packageName);
3457                return PackageManager.SIGNATURE_MATCH;
3458            }
3459        } catch (CertificateException e) {
3460            msg = e.getMessage();
3461        }
3462
3463        logCriticalInfo(Log.INFO,
3464                "Failed to recover certificates for " + scannedPkg.packageName + ": " + msg);
3465        return PackageManager.SIGNATURE_NO_MATCH;
3466    }
3467
3468    @Override
3469    public String[] getPackagesForUid(int uid) {
3470        uid = UserHandle.getAppId(uid);
3471        // reader
3472        synchronized (mPackages) {
3473            Object obj = mSettings.getUserIdLPr(uid);
3474            if (obj instanceof SharedUserSetting) {
3475                final SharedUserSetting sus = (SharedUserSetting) obj;
3476                final int N = sus.packages.size();
3477                final String[] res = new String[N];
3478                final Iterator<PackageSetting> it = sus.packages.iterator();
3479                int i = 0;
3480                while (it.hasNext()) {
3481                    res[i++] = it.next().name;
3482                }
3483                return res;
3484            } else if (obj instanceof PackageSetting) {
3485                final PackageSetting ps = (PackageSetting) obj;
3486                return new String[] { ps.name };
3487            }
3488        }
3489        return null;
3490    }
3491
3492    @Override
3493    public String getNameForUid(int uid) {
3494        // reader
3495        synchronized (mPackages) {
3496            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
3497            if (obj instanceof SharedUserSetting) {
3498                final SharedUserSetting sus = (SharedUserSetting) obj;
3499                return sus.name + ":" + sus.userId;
3500            } else if (obj instanceof PackageSetting) {
3501                final PackageSetting ps = (PackageSetting) obj;
3502                return ps.name;
3503            }
3504        }
3505        return null;
3506    }
3507
3508    @Override
3509    public int getUidForSharedUser(String sharedUserName) {
3510        if(sharedUserName == null) {
3511            return -1;
3512        }
3513        // reader
3514        synchronized (mPackages) {
3515            final SharedUserSetting suid = mSettings.getSharedUserLPw(sharedUserName, 0, 0, false);
3516            if (suid == null) {
3517                return -1;
3518            }
3519            return suid.userId;
3520        }
3521    }
3522
3523    @Override
3524    public int getFlagsForUid(int uid) {
3525        synchronized (mPackages) {
3526            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
3527            if (obj instanceof SharedUserSetting) {
3528                final SharedUserSetting sus = (SharedUserSetting) obj;
3529                return sus.pkgFlags;
3530            } else if (obj instanceof PackageSetting) {
3531                final PackageSetting ps = (PackageSetting) obj;
3532                return ps.pkgFlags;
3533            }
3534        }
3535        return 0;
3536    }
3537
3538    @Override
3539    public int getPrivateFlagsForUid(int uid) {
3540        synchronized (mPackages) {
3541            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
3542            if (obj instanceof SharedUserSetting) {
3543                final SharedUserSetting sus = (SharedUserSetting) obj;
3544                return sus.pkgPrivateFlags;
3545            } else if (obj instanceof PackageSetting) {
3546                final PackageSetting ps = (PackageSetting) obj;
3547                return ps.pkgPrivateFlags;
3548            }
3549        }
3550        return 0;
3551    }
3552
3553    @Override
3554    public boolean isUidPrivileged(int uid) {
3555        uid = UserHandle.getAppId(uid);
3556        // reader
3557        synchronized (mPackages) {
3558            Object obj = mSettings.getUserIdLPr(uid);
3559            if (obj instanceof SharedUserSetting) {
3560                final SharedUserSetting sus = (SharedUserSetting) obj;
3561                final Iterator<PackageSetting> it = sus.packages.iterator();
3562                while (it.hasNext()) {
3563                    if (it.next().isPrivileged()) {
3564                        return true;
3565                    }
3566                }
3567            } else if (obj instanceof PackageSetting) {
3568                final PackageSetting ps = (PackageSetting) obj;
3569                return ps.isPrivileged();
3570            }
3571        }
3572        return false;
3573    }
3574
3575    @Override
3576    public String[] getAppOpPermissionPackages(String permissionName) {
3577        synchronized (mPackages) {
3578            ArraySet<String> pkgs = mAppOpPermissionPackages.get(permissionName);
3579            if (pkgs == null) {
3580                return null;
3581            }
3582            return pkgs.toArray(new String[pkgs.size()]);
3583        }
3584    }
3585
3586    @Override
3587    public ResolveInfo resolveIntent(Intent intent, String resolvedType,
3588            int flags, int userId) {
3589        if (!sUserManager.exists(userId)) return null;
3590        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "resolve intent");
3591        List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId);
3592        return chooseBestActivity(intent, resolvedType, flags, query, userId);
3593    }
3594
3595    @Override
3596    public void setLastChosenActivity(Intent intent, String resolvedType, int flags,
3597            IntentFilter filter, int match, ComponentName activity) {
3598        final int userId = UserHandle.getCallingUserId();
3599        if (DEBUG_PREFERRED) {
3600            Log.v(TAG, "setLastChosenActivity intent=" + intent
3601                + " resolvedType=" + resolvedType
3602                + " flags=" + flags
3603                + " filter=" + filter
3604                + " match=" + match
3605                + " activity=" + activity);
3606            filter.dump(new PrintStreamPrinter(System.out), "    ");
3607        }
3608        intent.setComponent(null);
3609        List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId);
3610        // Find any earlier preferred or last chosen entries and nuke them
3611        findPreferredActivity(intent, resolvedType,
3612                flags, query, 0, false, true, false, userId);
3613        // Add the new activity as the last chosen for this filter
3614        addPreferredActivityInternal(filter, match, null, activity, false, userId,
3615                "Setting last chosen");
3616    }
3617
3618    @Override
3619    public ResolveInfo getLastChosenActivity(Intent intent, String resolvedType, int flags) {
3620        final int userId = UserHandle.getCallingUserId();
3621        if (DEBUG_PREFERRED) Log.v(TAG, "Querying last chosen activity for " + intent);
3622        List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId);
3623        return findPreferredActivity(intent, resolvedType, flags, query, 0,
3624                false, false, false, userId);
3625    }
3626
3627    private ResolveInfo chooseBestActivity(Intent intent, String resolvedType,
3628            int flags, List<ResolveInfo> query, int userId) {
3629        if (query != null) {
3630            final int N = query.size();
3631            if (N == 1) {
3632                return query.get(0);
3633            } else if (N > 1) {
3634                final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3635                // If there is more than one activity with the same priority,
3636                // then let the user decide between them.
3637                ResolveInfo r0 = query.get(0);
3638                ResolveInfo r1 = query.get(1);
3639                if (DEBUG_INTENT_MATCHING || debug) {
3640                    Slog.v(TAG, r0.activityInfo.name + "=" + r0.priority + " vs "
3641                            + r1.activityInfo.name + "=" + r1.priority);
3642                }
3643                // If the first activity has a higher priority, or a different
3644                // default, then it is always desireable to pick it.
3645                if (r0.priority != r1.priority
3646                        || r0.preferredOrder != r1.preferredOrder
3647                        || r0.isDefault != r1.isDefault) {
3648                    return query.get(0);
3649                }
3650                // If we have saved a preference for a preferred activity for
3651                // this Intent, use that.
3652                ResolveInfo ri = findPreferredActivity(intent, resolvedType,
3653                        flags, query, r0.priority, true, false, debug, userId);
3654                if (ri != null) {
3655                    return ri;
3656                }
3657                if (userId != 0) {
3658                    ri = new ResolveInfo(mResolveInfo);
3659                    ri.activityInfo = new ActivityInfo(ri.activityInfo);
3660                    ri.activityInfo.applicationInfo = new ApplicationInfo(
3661                            ri.activityInfo.applicationInfo);
3662                    ri.activityInfo.applicationInfo.uid = UserHandle.getUid(userId,
3663                            UserHandle.getAppId(ri.activityInfo.applicationInfo.uid));
3664                    return ri;
3665                }
3666                return mResolveInfo;
3667            }
3668        }
3669        return null;
3670    }
3671
3672    private ResolveInfo findPersistentPreferredActivityLP(Intent intent, String resolvedType,
3673            int flags, List<ResolveInfo> query, boolean debug, int userId) {
3674        final int N = query.size();
3675        PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
3676                .get(userId);
3677        // Get the list of persistent preferred activities that handle the intent
3678        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for presistent preferred activities...");
3679        List<PersistentPreferredActivity> pprefs = ppir != null
3680                ? ppir.queryIntent(intent, resolvedType,
3681                        (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId)
3682                : null;
3683        if (pprefs != null && pprefs.size() > 0) {
3684            final int M = pprefs.size();
3685            for (int i=0; i<M; i++) {
3686                final PersistentPreferredActivity ppa = pprefs.get(i);
3687                if (DEBUG_PREFERRED || debug) {
3688                    Slog.v(TAG, "Checking PersistentPreferredActivity ds="
3689                            + (ppa.countDataSchemes() > 0 ? ppa.getDataScheme(0) : "<none>")
3690                            + "\n  component=" + ppa.mComponent);
3691                    ppa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
3692                }
3693                final ActivityInfo ai = getActivityInfo(ppa.mComponent,
3694                        flags | PackageManager.GET_DISABLED_COMPONENTS, userId);
3695                if (DEBUG_PREFERRED || debug) {
3696                    Slog.v(TAG, "Found persistent preferred activity:");
3697                    if (ai != null) {
3698                        ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
3699                    } else {
3700                        Slog.v(TAG, "  null");
3701                    }
3702                }
3703                if (ai == null) {
3704                    // This previously registered persistent preferred activity
3705                    // component is no longer known. Ignore it and do NOT remove it.
3706                    continue;
3707                }
3708                for (int j=0; j<N; j++) {
3709                    final ResolveInfo ri = query.get(j);
3710                    if (!ri.activityInfo.applicationInfo.packageName
3711                            .equals(ai.applicationInfo.packageName)) {
3712                        continue;
3713                    }
3714                    if (!ri.activityInfo.name.equals(ai.name)) {
3715                        continue;
3716                    }
3717                    //  Found a persistent preference that can handle the intent.
3718                    if (DEBUG_PREFERRED || debug) {
3719                        Slog.v(TAG, "Returning persistent preferred activity: " +
3720                                ri.activityInfo.packageName + "/" + ri.activityInfo.name);
3721                    }
3722                    return ri;
3723                }
3724            }
3725        }
3726        return null;
3727    }
3728
3729    ResolveInfo findPreferredActivity(Intent intent, String resolvedType, int flags,
3730            List<ResolveInfo> query, int priority, boolean always,
3731            boolean removeMatches, boolean debug, int userId) {
3732        if (!sUserManager.exists(userId)) return null;
3733        // writer
3734        synchronized (mPackages) {
3735            if (intent.getSelector() != null) {
3736                intent = intent.getSelector();
3737            }
3738            if (DEBUG_PREFERRED) intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION);
3739
3740            // Try to find a matching persistent preferred activity.
3741            ResolveInfo pri = findPersistentPreferredActivityLP(intent, resolvedType, flags, query,
3742                    debug, userId);
3743
3744            // If a persistent preferred activity matched, use it.
3745            if (pri != null) {
3746                return pri;
3747            }
3748
3749            PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
3750            // Get the list of preferred activities that handle the intent
3751            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for preferred activities...");
3752            List<PreferredActivity> prefs = pir != null
3753                    ? pir.queryIntent(intent, resolvedType,
3754                            (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId)
3755                    : null;
3756            if (prefs != null && prefs.size() > 0) {
3757                boolean changed = false;
3758                try {
3759                    // First figure out how good the original match set is.
3760                    // We will only allow preferred activities that came
3761                    // from the same match quality.
3762                    int match = 0;
3763
3764                    if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Figuring out best match...");
3765
3766                    final int N = query.size();
3767                    for (int j=0; j<N; j++) {
3768                        final ResolveInfo ri = query.get(j);
3769                        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Match for " + ri.activityInfo
3770                                + ": 0x" + Integer.toHexString(match));
3771                        if (ri.match > match) {
3772                            match = ri.match;
3773                        }
3774                    }
3775
3776                    if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Best match: 0x"
3777                            + Integer.toHexString(match));
3778
3779                    match &= IntentFilter.MATCH_CATEGORY_MASK;
3780                    final int M = prefs.size();
3781                    for (int i=0; i<M; i++) {
3782                        final PreferredActivity pa = prefs.get(i);
3783                        if (DEBUG_PREFERRED || debug) {
3784                            Slog.v(TAG, "Checking PreferredActivity ds="
3785                                    + (pa.countDataSchemes() > 0 ? pa.getDataScheme(0) : "<none>")
3786                                    + "\n  component=" + pa.mPref.mComponent);
3787                            pa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
3788                        }
3789                        if (pa.mPref.mMatch != match) {
3790                            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping bad match "
3791                                    + Integer.toHexString(pa.mPref.mMatch));
3792                            continue;
3793                        }
3794                        // If it's not an "always" type preferred activity and that's what we're
3795                        // looking for, skip it.
3796                        if (always && !pa.mPref.mAlways) {
3797                            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping mAlways=false entry");
3798                            continue;
3799                        }
3800                        final ActivityInfo ai = getActivityInfo(pa.mPref.mComponent,
3801                                flags | PackageManager.GET_DISABLED_COMPONENTS, userId);
3802                        if (DEBUG_PREFERRED || debug) {
3803                            Slog.v(TAG, "Found preferred activity:");
3804                            if (ai != null) {
3805                                ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
3806                            } else {
3807                                Slog.v(TAG, "  null");
3808                            }
3809                        }
3810                        if (ai == null) {
3811                            // This previously registered preferred activity
3812                            // component is no longer known.  Most likely an update
3813                            // to the app was installed and in the new version this
3814                            // component no longer exists.  Clean it up by removing
3815                            // it from the preferred activities list, and skip it.
3816                            Slog.w(TAG, "Removing dangling preferred activity: "
3817                                    + pa.mPref.mComponent);
3818                            pir.removeFilter(pa);
3819                            changed = true;
3820                            continue;
3821                        }
3822                        for (int j=0; j<N; j++) {
3823                            final ResolveInfo ri = query.get(j);
3824                            if (!ri.activityInfo.applicationInfo.packageName
3825                                    .equals(ai.applicationInfo.packageName)) {
3826                                continue;
3827                            }
3828                            if (!ri.activityInfo.name.equals(ai.name)) {
3829                                continue;
3830                            }
3831
3832                            if (removeMatches) {
3833                                pir.removeFilter(pa);
3834                                changed = true;
3835                                if (DEBUG_PREFERRED) {
3836                                    Slog.v(TAG, "Removing match " + pa.mPref.mComponent);
3837                                }
3838                                break;
3839                            }
3840
3841                            // Okay we found a previously set preferred or last chosen app.
3842                            // If the result set is different from when this
3843                            // was created, we need to clear it and re-ask the
3844                            // user their preference, if we're looking for an "always" type entry.
3845                            if (always && !pa.mPref.sameSet(query)) {
3846                                Slog.i(TAG, "Result set changed, dropping preferred activity for "
3847                                        + intent + " type " + resolvedType);
3848                                if (DEBUG_PREFERRED) {
3849                                    Slog.v(TAG, "Removing preferred activity since set changed "
3850                                            + pa.mPref.mComponent);
3851                                }
3852                                pir.removeFilter(pa);
3853                                // Re-add the filter as a "last chosen" entry (!always)
3854                                PreferredActivity lastChosen = new PreferredActivity(
3855                                        pa, pa.mPref.mMatch, null, pa.mPref.mComponent, false);
3856                                pir.addFilter(lastChosen);
3857                                changed = true;
3858                                return null;
3859                            }
3860
3861                            // Yay! Either the set matched or we're looking for the last chosen
3862                            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Returning preferred activity: "
3863                                    + ri.activityInfo.packageName + "/" + ri.activityInfo.name);
3864                            return ri;
3865                        }
3866                    }
3867                } finally {
3868                    if (changed) {
3869                        if (DEBUG_PREFERRED) {
3870                            Slog.v(TAG, "Preferred activity bookkeeping changed; writing restrictions");
3871                        }
3872                        scheduleWritePackageRestrictionsLocked(userId);
3873                    }
3874                }
3875            }
3876        }
3877        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "No preferred activity to return");
3878        return null;
3879    }
3880
3881    /*
3882     * Returns if intent can be forwarded from the sourceUserId to the targetUserId
3883     */
3884    @Override
3885    public boolean canForwardTo(Intent intent, String resolvedType, int sourceUserId,
3886            int targetUserId) {
3887        mContext.enforceCallingOrSelfPermission(
3888                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
3889        List<CrossProfileIntentFilter> matches =
3890                getMatchingCrossProfileIntentFilters(intent, resolvedType, sourceUserId);
3891        if (matches != null) {
3892            int size = matches.size();
3893            for (int i = 0; i < size; i++) {
3894                if (matches.get(i).getTargetUserId() == targetUserId) return true;
3895            }
3896        }
3897        return false;
3898    }
3899
3900    private List<CrossProfileIntentFilter> getMatchingCrossProfileIntentFilters(Intent intent,
3901            String resolvedType, int userId) {
3902        CrossProfileIntentResolver resolver = mSettings.mCrossProfileIntentResolvers.get(userId);
3903        if (resolver != null) {
3904            return resolver.queryIntent(intent, resolvedType, false, userId);
3905        }
3906        return null;
3907    }
3908
3909    @Override
3910    public List<ResolveInfo> queryIntentActivities(Intent intent,
3911            String resolvedType, int flags, int userId) {
3912        if (!sUserManager.exists(userId)) return Collections.emptyList();
3913        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "query intent activities");
3914        ComponentName comp = intent.getComponent();
3915        if (comp == null) {
3916            if (intent.getSelector() != null) {
3917                intent = intent.getSelector();
3918                comp = intent.getComponent();
3919            }
3920        }
3921
3922        if (comp != null) {
3923            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
3924            final ActivityInfo ai = getActivityInfo(comp, flags, userId);
3925            if (ai != null) {
3926                final ResolveInfo ri = new ResolveInfo();
3927                ri.activityInfo = ai;
3928                list.add(ri);
3929            }
3930            return list;
3931        }
3932
3933        // reader
3934        synchronized (mPackages) {
3935            final String pkgName = intent.getPackage();
3936            if (pkgName == null) {
3937                List<CrossProfileIntentFilter> matchingFilters =
3938                        getMatchingCrossProfileIntentFilters(intent, resolvedType, userId);
3939                // Check for results that need to skip the current profile.
3940                ResolveInfo resolveInfo  = querySkipCurrentProfileIntents(matchingFilters, intent,
3941                        resolvedType, flags, userId);
3942                if (resolveInfo != null && isUserEnabled(resolveInfo.targetUserId)) {
3943                    List<ResolveInfo> result = new ArrayList<ResolveInfo>(1);
3944                    result.add(resolveInfo);
3945                    return filterIfNotPrimaryUser(result, userId);
3946                }
3947
3948                // Check for results in the current profile.
3949                List<ResolveInfo> result = mActivities.queryIntent(
3950                        intent, resolvedType, flags, userId);
3951
3952                // Check for cross profile results.
3953                resolveInfo = queryCrossProfileIntents(
3954                        matchingFilters, intent, resolvedType, flags, userId);
3955                if (resolveInfo != null && isUserEnabled(resolveInfo.targetUserId)) {
3956                    result.add(resolveInfo);
3957                    Collections.sort(result, mResolvePrioritySorter);
3958                }
3959                result = filterIfNotPrimaryUser(result, userId);
3960                if (result.size() > 1 && hasWebURI(intent)) {
3961                    return filterCandidatesWithDomainPreferedActivitiesLPr(flags, result);
3962                }
3963                return result;
3964            }
3965            final PackageParser.Package pkg = mPackages.get(pkgName);
3966            if (pkg != null) {
3967                return filterIfNotPrimaryUser(
3968                        mActivities.queryIntentForPackage(
3969                                intent, resolvedType, flags, pkg.activities, userId),
3970                        userId);
3971            }
3972            return new ArrayList<ResolveInfo>();
3973        }
3974    }
3975
3976    private boolean isUserEnabled(int userId) {
3977        long callingId = Binder.clearCallingIdentity();
3978        try {
3979            UserInfo userInfo = sUserManager.getUserInfo(userId);
3980            return userInfo != null && userInfo.isEnabled();
3981        } finally {
3982            Binder.restoreCallingIdentity(callingId);
3983        }
3984    }
3985
3986    /**
3987     * Filter out activities with primaryUserOnly flag set, when current user is not the owner.
3988     *
3989     * @return filtered list
3990     */
3991    private List<ResolveInfo> filterIfNotPrimaryUser(List<ResolveInfo> resolveInfos, int userId) {
3992        if (userId == UserHandle.USER_OWNER) {
3993            return resolveInfos;
3994        }
3995        for (int i = resolveInfos.size() - 1; i >= 0; i--) {
3996            ResolveInfo info = resolveInfos.get(i);
3997            if ((info.activityInfo.flags & ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
3998                resolveInfos.remove(i);
3999            }
4000        }
4001        return resolveInfos;
4002    }
4003
4004    private static boolean hasWebURI(Intent intent) {
4005        if (intent.getData() == null) {
4006            return false;
4007        }
4008        final String scheme = intent.getScheme();
4009        if (TextUtils.isEmpty(scheme)) {
4010            return false;
4011        }
4012        return scheme.equals(IntentFilter.SCHEME_HTTP) || scheme.equals(IntentFilter.SCHEME_HTTPS);
4013    }
4014
4015    private List<ResolveInfo> filterCandidatesWithDomainPreferedActivitiesLPr(
4016            int flags, List<ResolveInfo> candidates) {
4017        if (DEBUG_PREFERRED) {
4018            Slog.v("TAG", "Filtering results with prefered activities. Candidates count: " +
4019                    candidates.size());
4020        }
4021
4022        final int userId = UserHandle.getCallingUserId();
4023        ArrayList<ResolveInfo> result = new ArrayList<ResolveInfo>();
4024        ArrayList<ResolveInfo> undefinedList = new ArrayList<ResolveInfo>();
4025        ArrayList<ResolveInfo> neverList = new ArrayList<ResolveInfo>();
4026        ArrayList<ResolveInfo> matchAllList = new ArrayList<ResolveInfo>();
4027
4028        synchronized (mPackages) {
4029            final int count = candidates.size();
4030            // First, try to use the domain prefered App
4031            for (int n=0; n<count; n++) {
4032                ResolveInfo info = candidates.get(n);
4033                String packageName = info.activityInfo.packageName;
4034                PackageSetting ps = mSettings.mPackages.get(packageName);
4035                if (ps != null) {
4036                    // Add to the special match all list (Browser use case)
4037                    if (info.handleAllWebDataURI) {
4038                        matchAllList.add(info);
4039                        continue;
4040                    }
4041                    // Try to get the status from User settings first
4042                    int status = getDomainVerificationStatusLPr(ps, userId);
4043                    if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) {
4044                        result.add(info);
4045                    } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
4046                        neverList.add(info);
4047                    } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) {
4048                        undefinedList.add(info);
4049                    }
4050                }
4051            }
4052            // If there is nothing selected, add all candidates and remove the ones that the User
4053            // has explicitely put into the INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER state and
4054            // also remove any Browser Apps ones.
4055            // If there is still none after this pass, add all undefined one and Browser Apps and
4056            // let the User decide with the Disambiguation dialog if there are several ones.
4057            if (result.size() == 0) {
4058                result.addAll(candidates);
4059            }
4060            result.removeAll(neverList);
4061            result.removeAll(matchAllList);
4062            if (result.size() == 0) {
4063                result.addAll(undefinedList);
4064                if ((flags & MATCH_ALL) != 0) {
4065                    result.addAll(matchAllList);
4066                } else {
4067                    // Try to add the Default Browser if we can
4068                    final String defaultBrowserPackageName = getDefaultBrowserPackageName(
4069                            UserHandle.myUserId());
4070                    if (!TextUtils.isEmpty(defaultBrowserPackageName)) {
4071                        boolean defaultBrowserFound = false;
4072                        final int browserCount = matchAllList.size();
4073                        for (int n=0; n<browserCount; n++) {
4074                            ResolveInfo browser = matchAllList.get(n);
4075                            if (browser.activityInfo.packageName.equals(defaultBrowserPackageName)) {
4076                                result.add(browser);
4077                                defaultBrowserFound = true;
4078                                break;
4079                            }
4080                        }
4081                        if (!defaultBrowserFound) {
4082                            result.addAll(matchAllList);
4083                        }
4084                    } else {
4085                        result.addAll(matchAllList);
4086                    }
4087                }
4088            }
4089        }
4090        if (DEBUG_PREFERRED) {
4091            Slog.v("TAG", "Filtered results with prefered activities. New candidates count: " +
4092                    result.size());
4093        }
4094        return result;
4095    }
4096
4097    private int getDomainVerificationStatusLPr(PackageSetting ps, int userId) {
4098        int status = ps.getDomainVerificationStatusForUser(userId);
4099        // if none available, get the master status
4100        if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) {
4101            if (ps.getIntentFilterVerificationInfo() != null) {
4102                status = ps.getIntentFilterVerificationInfo().getStatus();
4103            }
4104        }
4105        return status;
4106    }
4107
4108    private ResolveInfo querySkipCurrentProfileIntents(
4109            List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
4110            int flags, int sourceUserId) {
4111        if (matchingFilters != null) {
4112            int size = matchingFilters.size();
4113            for (int i = 0; i < size; i ++) {
4114                CrossProfileIntentFilter filter = matchingFilters.get(i);
4115                if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0) {
4116                    // Checking if there are activities in the target user that can handle the
4117                    // intent.
4118                    ResolveInfo resolveInfo = checkTargetCanHandle(filter, intent, resolvedType,
4119                            flags, sourceUserId);
4120                    if (resolveInfo != null) {
4121                        return resolveInfo;
4122                    }
4123                }
4124            }
4125        }
4126        return null;
4127    }
4128
4129    // Return matching ResolveInfo if any for skip current profile intent filters.
4130    private ResolveInfo queryCrossProfileIntents(
4131            List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
4132            int flags, int sourceUserId) {
4133        if (matchingFilters != null) {
4134            // Two {@link CrossProfileIntentFilter}s can have the same targetUserId and
4135            // match the same intent. For performance reasons, it is better not to
4136            // run queryIntent twice for the same userId
4137            SparseBooleanArray alreadyTriedUserIds = new SparseBooleanArray();
4138            int size = matchingFilters.size();
4139            for (int i = 0; i < size; i++) {
4140                CrossProfileIntentFilter filter = matchingFilters.get(i);
4141                int targetUserId = filter.getTargetUserId();
4142                if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) == 0
4143                        && !alreadyTriedUserIds.get(targetUserId)) {
4144                    // Checking if there are activities in the target user that can handle the
4145                    // intent.
4146                    ResolveInfo resolveInfo = checkTargetCanHandle(filter, intent, resolvedType,
4147                            flags, sourceUserId);
4148                    if (resolveInfo != null) return resolveInfo;
4149                    alreadyTriedUserIds.put(targetUserId, true);
4150                }
4151            }
4152        }
4153        return null;
4154    }
4155
4156    private ResolveInfo checkTargetCanHandle(CrossProfileIntentFilter filter, Intent intent,
4157            String resolvedType, int flags, int sourceUserId) {
4158        List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent,
4159                resolvedType, flags, filter.getTargetUserId());
4160        if (resultTargetUser != null && !resultTargetUser.isEmpty()) {
4161            return createForwardingResolveInfo(filter, sourceUserId, filter.getTargetUserId());
4162        }
4163        return null;
4164    }
4165
4166    private ResolveInfo createForwardingResolveInfo(IntentFilter filter,
4167            int sourceUserId, int targetUserId) {
4168        ResolveInfo forwardingResolveInfo = new ResolveInfo();
4169        String className;
4170        if (targetUserId == UserHandle.USER_OWNER) {
4171            className = FORWARD_INTENT_TO_USER_OWNER;
4172        } else {
4173            className = FORWARD_INTENT_TO_MANAGED_PROFILE;
4174        }
4175        ComponentName forwardingActivityComponentName = new ComponentName(
4176                mAndroidApplication.packageName, className);
4177        ActivityInfo forwardingActivityInfo = getActivityInfo(forwardingActivityComponentName, 0,
4178                sourceUserId);
4179        if (targetUserId == UserHandle.USER_OWNER) {
4180            forwardingActivityInfo.showUserIcon = UserHandle.USER_OWNER;
4181            forwardingResolveInfo.noResourceId = true;
4182        }
4183        forwardingResolveInfo.activityInfo = forwardingActivityInfo;
4184        forwardingResolveInfo.priority = 0;
4185        forwardingResolveInfo.preferredOrder = 0;
4186        forwardingResolveInfo.match = 0;
4187        forwardingResolveInfo.isDefault = true;
4188        forwardingResolveInfo.filter = filter;
4189        forwardingResolveInfo.targetUserId = targetUserId;
4190        return forwardingResolveInfo;
4191    }
4192
4193    @Override
4194    public List<ResolveInfo> queryIntentActivityOptions(ComponentName caller,
4195            Intent[] specifics, String[] specificTypes, Intent intent,
4196            String resolvedType, int flags, int userId) {
4197        if (!sUserManager.exists(userId)) return Collections.emptyList();
4198        enforceCrossUserPermission(Binder.getCallingUid(), userId, false,
4199                false, "query intent activity options");
4200        final String resultsAction = intent.getAction();
4201
4202        List<ResolveInfo> results = queryIntentActivities(intent, resolvedType, flags
4203                | PackageManager.GET_RESOLVED_FILTER, userId);
4204
4205        if (DEBUG_INTENT_MATCHING) {
4206            Log.v(TAG, "Query " + intent + ": " + results);
4207        }
4208
4209        int specificsPos = 0;
4210        int N;
4211
4212        // todo: note that the algorithm used here is O(N^2).  This
4213        // isn't a problem in our current environment, but if we start running
4214        // into situations where we have more than 5 or 10 matches then this
4215        // should probably be changed to something smarter...
4216
4217        // First we go through and resolve each of the specific items
4218        // that were supplied, taking care of removing any corresponding
4219        // duplicate items in the generic resolve list.
4220        if (specifics != null) {
4221            for (int i=0; i<specifics.length; i++) {
4222                final Intent sintent = specifics[i];
4223                if (sintent == null) {
4224                    continue;
4225                }
4226
4227                if (DEBUG_INTENT_MATCHING) {
4228                    Log.v(TAG, "Specific #" + i + ": " + sintent);
4229                }
4230
4231                String action = sintent.getAction();
4232                if (resultsAction != null && resultsAction.equals(action)) {
4233                    // If this action was explicitly requested, then don't
4234                    // remove things that have it.
4235                    action = null;
4236                }
4237
4238                ResolveInfo ri = null;
4239                ActivityInfo ai = null;
4240
4241                ComponentName comp = sintent.getComponent();
4242                if (comp == null) {
4243                    ri = resolveIntent(
4244                        sintent,
4245                        specificTypes != null ? specificTypes[i] : null,
4246                            flags, userId);
4247                    if (ri == null) {
4248                        continue;
4249                    }
4250                    if (ri == mResolveInfo) {
4251                        // ACK!  Must do something better with this.
4252                    }
4253                    ai = ri.activityInfo;
4254                    comp = new ComponentName(ai.applicationInfo.packageName,
4255                            ai.name);
4256                } else {
4257                    ai = getActivityInfo(comp, flags, userId);
4258                    if (ai == null) {
4259                        continue;
4260                    }
4261                }
4262
4263                // Look for any generic query activities that are duplicates
4264                // of this specific one, and remove them from the results.
4265                if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Specific #" + i + ": " + ai);
4266                N = results.size();
4267                int j;
4268                for (j=specificsPos; j<N; j++) {
4269                    ResolveInfo sri = results.get(j);
4270                    if ((sri.activityInfo.name.equals(comp.getClassName())
4271                            && sri.activityInfo.applicationInfo.packageName.equals(
4272                                    comp.getPackageName()))
4273                        || (action != null && sri.filter.matchAction(action))) {
4274                        results.remove(j);
4275                        if (DEBUG_INTENT_MATCHING) Log.v(
4276                            TAG, "Removing duplicate item from " + j
4277                            + " due to specific " + specificsPos);
4278                        if (ri == null) {
4279                            ri = sri;
4280                        }
4281                        j--;
4282                        N--;
4283                    }
4284                }
4285
4286                // Add this specific item to its proper place.
4287                if (ri == null) {
4288                    ri = new ResolveInfo();
4289                    ri.activityInfo = ai;
4290                }
4291                results.add(specificsPos, ri);
4292                ri.specificIndex = i;
4293                specificsPos++;
4294            }
4295        }
4296
4297        // Now we go through the remaining generic results and remove any
4298        // duplicate actions that are found here.
4299        N = results.size();
4300        for (int i=specificsPos; i<N-1; i++) {
4301            final ResolveInfo rii = results.get(i);
4302            if (rii.filter == null) {
4303                continue;
4304            }
4305
4306            // Iterate over all of the actions of this result's intent
4307            // filter...  typically this should be just one.
4308            final Iterator<String> it = rii.filter.actionsIterator();
4309            if (it == null) {
4310                continue;
4311            }
4312            while (it.hasNext()) {
4313                final String action = it.next();
4314                if (resultsAction != null && resultsAction.equals(action)) {
4315                    // If this action was explicitly requested, then don't
4316                    // remove things that have it.
4317                    continue;
4318                }
4319                for (int j=i+1; j<N; j++) {
4320                    final ResolveInfo rij = results.get(j);
4321                    if (rij.filter != null && rij.filter.hasAction(action)) {
4322                        results.remove(j);
4323                        if (DEBUG_INTENT_MATCHING) Log.v(
4324                            TAG, "Removing duplicate item from " + j
4325                            + " due to action " + action + " at " + i);
4326                        j--;
4327                        N--;
4328                    }
4329                }
4330            }
4331
4332            // If the caller didn't request filter information, drop it now
4333            // so we don't have to marshall/unmarshall it.
4334            if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
4335                rii.filter = null;
4336            }
4337        }
4338
4339        // Filter out the caller activity if so requested.
4340        if (caller != null) {
4341            N = results.size();
4342            for (int i=0; i<N; i++) {
4343                ActivityInfo ainfo = results.get(i).activityInfo;
4344                if (caller.getPackageName().equals(ainfo.applicationInfo.packageName)
4345                        && caller.getClassName().equals(ainfo.name)) {
4346                    results.remove(i);
4347                    break;
4348                }
4349            }
4350        }
4351
4352        // If the caller didn't request filter information,
4353        // drop them now so we don't have to
4354        // marshall/unmarshall it.
4355        if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
4356            N = results.size();
4357            for (int i=0; i<N; i++) {
4358                results.get(i).filter = null;
4359            }
4360        }
4361
4362        if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Result: " + results);
4363        return results;
4364    }
4365
4366    @Override
4367    public List<ResolveInfo> queryIntentReceivers(Intent intent, String resolvedType, int flags,
4368            int userId) {
4369        if (!sUserManager.exists(userId)) return Collections.emptyList();
4370        ComponentName comp = intent.getComponent();
4371        if (comp == null) {
4372            if (intent.getSelector() != null) {
4373                intent = intent.getSelector();
4374                comp = intent.getComponent();
4375            }
4376        }
4377        if (comp != null) {
4378            List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
4379            ActivityInfo ai = getReceiverInfo(comp, flags, userId);
4380            if (ai != null) {
4381                ResolveInfo ri = new ResolveInfo();
4382                ri.activityInfo = ai;
4383                list.add(ri);
4384            }
4385            return list;
4386        }
4387
4388        // reader
4389        synchronized (mPackages) {
4390            String pkgName = intent.getPackage();
4391            if (pkgName == null) {
4392                return mReceivers.queryIntent(intent, resolvedType, flags, userId);
4393            }
4394            final PackageParser.Package pkg = mPackages.get(pkgName);
4395            if (pkg != null) {
4396                return mReceivers.queryIntentForPackage(intent, resolvedType, flags, pkg.receivers,
4397                        userId);
4398            }
4399            return null;
4400        }
4401    }
4402
4403    @Override
4404    public ResolveInfo resolveService(Intent intent, String resolvedType, int flags, int userId) {
4405        List<ResolveInfo> query = queryIntentServices(intent, resolvedType, flags, userId);
4406        if (!sUserManager.exists(userId)) return null;
4407        if (query != null) {
4408            if (query.size() >= 1) {
4409                // If there is more than one service with the same priority,
4410                // just arbitrarily pick the first one.
4411                return query.get(0);
4412            }
4413        }
4414        return null;
4415    }
4416
4417    @Override
4418    public List<ResolveInfo> queryIntentServices(Intent intent, String resolvedType, int flags,
4419            int userId) {
4420        if (!sUserManager.exists(userId)) return Collections.emptyList();
4421        ComponentName comp = intent.getComponent();
4422        if (comp == null) {
4423            if (intent.getSelector() != null) {
4424                intent = intent.getSelector();
4425                comp = intent.getComponent();
4426            }
4427        }
4428        if (comp != null) {
4429            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
4430            final ServiceInfo si = getServiceInfo(comp, flags, userId);
4431            if (si != null) {
4432                final ResolveInfo ri = new ResolveInfo();
4433                ri.serviceInfo = si;
4434                list.add(ri);
4435            }
4436            return list;
4437        }
4438
4439        // reader
4440        synchronized (mPackages) {
4441            String pkgName = intent.getPackage();
4442            if (pkgName == null) {
4443                return mServices.queryIntent(intent, resolvedType, flags, userId);
4444            }
4445            final PackageParser.Package pkg = mPackages.get(pkgName);
4446            if (pkg != null) {
4447                return mServices.queryIntentForPackage(intent, resolvedType, flags, pkg.services,
4448                        userId);
4449            }
4450            return null;
4451        }
4452    }
4453
4454    @Override
4455    public List<ResolveInfo> queryIntentContentProviders(
4456            Intent intent, String resolvedType, int flags, int userId) {
4457        if (!sUserManager.exists(userId)) return Collections.emptyList();
4458        ComponentName comp = intent.getComponent();
4459        if (comp == null) {
4460            if (intent.getSelector() != null) {
4461                intent = intent.getSelector();
4462                comp = intent.getComponent();
4463            }
4464        }
4465        if (comp != null) {
4466            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
4467            final ProviderInfo pi = getProviderInfo(comp, flags, userId);
4468            if (pi != null) {
4469                final ResolveInfo ri = new ResolveInfo();
4470                ri.providerInfo = pi;
4471                list.add(ri);
4472            }
4473            return list;
4474        }
4475
4476        // reader
4477        synchronized (mPackages) {
4478            String pkgName = intent.getPackage();
4479            if (pkgName == null) {
4480                return mProviders.queryIntent(intent, resolvedType, flags, userId);
4481            }
4482            final PackageParser.Package pkg = mPackages.get(pkgName);
4483            if (pkg != null) {
4484                return mProviders.queryIntentForPackage(
4485                        intent, resolvedType, flags, pkg.providers, userId);
4486            }
4487            return null;
4488        }
4489    }
4490
4491    @Override
4492    public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) {
4493        final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0;
4494
4495        enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, "get installed packages");
4496
4497        // writer
4498        synchronized (mPackages) {
4499            ArrayList<PackageInfo> list;
4500            if (listUninstalled) {
4501                list = new ArrayList<PackageInfo>(mSettings.mPackages.size());
4502                for (PackageSetting ps : mSettings.mPackages.values()) {
4503                    PackageInfo pi;
4504                    if (ps.pkg != null) {
4505                        pi = generatePackageInfo(ps.pkg, flags, userId);
4506                    } else {
4507                        pi = generatePackageInfoFromSettingsLPw(ps.name, flags, userId);
4508                    }
4509                    if (pi != null) {
4510                        list.add(pi);
4511                    }
4512                }
4513            } else {
4514                list = new ArrayList<PackageInfo>(mPackages.size());
4515                for (PackageParser.Package p : mPackages.values()) {
4516                    PackageInfo pi = generatePackageInfo(p, flags, userId);
4517                    if (pi != null) {
4518                        list.add(pi);
4519                    }
4520                }
4521            }
4522
4523            return new ParceledListSlice<PackageInfo>(list);
4524        }
4525    }
4526
4527    private void addPackageHoldingPermissions(ArrayList<PackageInfo> list, PackageSetting ps,
4528            String[] permissions, boolean[] tmp, int flags, int userId) {
4529        int numMatch = 0;
4530        final PermissionsState permissionsState = ps.getPermissionsState();
4531        for (int i=0; i<permissions.length; i++) {
4532            final String permission = permissions[i];
4533            if (permissionsState.hasPermission(permission, userId)) {
4534                tmp[i] = true;
4535                numMatch++;
4536            } else {
4537                tmp[i] = false;
4538            }
4539        }
4540        if (numMatch == 0) {
4541            return;
4542        }
4543        PackageInfo pi;
4544        if (ps.pkg != null) {
4545            pi = generatePackageInfo(ps.pkg, flags, userId);
4546        } else {
4547            pi = generatePackageInfoFromSettingsLPw(ps.name, flags, userId);
4548        }
4549        // The above might return null in cases of uninstalled apps or install-state
4550        // skew across users/profiles.
4551        if (pi != null) {
4552            if ((flags&PackageManager.GET_PERMISSIONS) == 0) {
4553                if (numMatch == permissions.length) {
4554                    pi.requestedPermissions = permissions;
4555                } else {
4556                    pi.requestedPermissions = new String[numMatch];
4557                    numMatch = 0;
4558                    for (int i=0; i<permissions.length; i++) {
4559                        if (tmp[i]) {
4560                            pi.requestedPermissions[numMatch] = permissions[i];
4561                            numMatch++;
4562                        }
4563                    }
4564                }
4565            }
4566            list.add(pi);
4567        }
4568    }
4569
4570    @Override
4571    public ParceledListSlice<PackageInfo> getPackagesHoldingPermissions(
4572            String[] permissions, int flags, int userId) {
4573        if (!sUserManager.exists(userId)) return null;
4574        final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0;
4575
4576        // writer
4577        synchronized (mPackages) {
4578            ArrayList<PackageInfo> list = new ArrayList<PackageInfo>();
4579            boolean[] tmpBools = new boolean[permissions.length];
4580            if (listUninstalled) {
4581                for (PackageSetting ps : mSettings.mPackages.values()) {
4582                    addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags, userId);
4583                }
4584            } else {
4585                for (PackageParser.Package pkg : mPackages.values()) {
4586                    PackageSetting ps = (PackageSetting)pkg.mExtras;
4587                    if (ps != null) {
4588                        addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags,
4589                                userId);
4590                    }
4591                }
4592            }
4593
4594            return new ParceledListSlice<PackageInfo>(list);
4595        }
4596    }
4597
4598    @Override
4599    public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags, int userId) {
4600        if (!sUserManager.exists(userId)) return null;
4601        final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0;
4602
4603        // writer
4604        synchronized (mPackages) {
4605            ArrayList<ApplicationInfo> list;
4606            if (listUninstalled) {
4607                list = new ArrayList<ApplicationInfo>(mSettings.mPackages.size());
4608                for (PackageSetting ps : mSettings.mPackages.values()) {
4609                    ApplicationInfo ai;
4610                    if (ps.pkg != null) {
4611                        ai = PackageParser.generateApplicationInfo(ps.pkg, flags,
4612                                ps.readUserState(userId), userId);
4613                    } else {
4614                        ai = generateApplicationInfoFromSettingsLPw(ps.name, flags, userId);
4615                    }
4616                    if (ai != null) {
4617                        list.add(ai);
4618                    }
4619                }
4620            } else {
4621                list = new ArrayList<ApplicationInfo>(mPackages.size());
4622                for (PackageParser.Package p : mPackages.values()) {
4623                    if (p.mExtras != null) {
4624                        ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
4625                                ((PackageSetting)p.mExtras).readUserState(userId), userId);
4626                        if (ai != null) {
4627                            list.add(ai);
4628                        }
4629                    }
4630                }
4631            }
4632
4633            return new ParceledListSlice<ApplicationInfo>(list);
4634        }
4635    }
4636
4637    public List<ApplicationInfo> getPersistentApplications(int flags) {
4638        final ArrayList<ApplicationInfo> finalList = new ArrayList<ApplicationInfo>();
4639
4640        // reader
4641        synchronized (mPackages) {
4642            final Iterator<PackageParser.Package> i = mPackages.values().iterator();
4643            final int userId = UserHandle.getCallingUserId();
4644            while (i.hasNext()) {
4645                final PackageParser.Package p = i.next();
4646                if (p.applicationInfo != null
4647                        && (p.applicationInfo.flags&ApplicationInfo.FLAG_PERSISTENT) != 0
4648                        && (!mSafeMode || isSystemApp(p))) {
4649                    PackageSetting ps = mSettings.mPackages.get(p.packageName);
4650                    if (ps != null) {
4651                        ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
4652                                ps.readUserState(userId), userId);
4653                        if (ai != null) {
4654                            finalList.add(ai);
4655                        }
4656                    }
4657                }
4658            }
4659        }
4660
4661        return finalList;
4662    }
4663
4664    @Override
4665    public ProviderInfo resolveContentProvider(String name, int flags, int userId) {
4666        if (!sUserManager.exists(userId)) return null;
4667        // reader
4668        synchronized (mPackages) {
4669            final PackageParser.Provider provider = mProvidersByAuthority.get(name);
4670            PackageSetting ps = provider != null
4671                    ? mSettings.mPackages.get(provider.owner.packageName)
4672                    : null;
4673            return ps != null
4674                    && mSettings.isEnabledLPr(provider.info, flags, userId)
4675                    && (!mSafeMode || (provider.info.applicationInfo.flags
4676                            &ApplicationInfo.FLAG_SYSTEM) != 0)
4677                    ? PackageParser.generateProviderInfo(provider, flags,
4678                            ps.readUserState(userId), userId)
4679                    : null;
4680        }
4681    }
4682
4683    /**
4684     * @deprecated
4685     */
4686    @Deprecated
4687    public void querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo) {
4688        // reader
4689        synchronized (mPackages) {
4690            final Iterator<Map.Entry<String, PackageParser.Provider>> i = mProvidersByAuthority
4691                    .entrySet().iterator();
4692            final int userId = UserHandle.getCallingUserId();
4693            while (i.hasNext()) {
4694                Map.Entry<String, PackageParser.Provider> entry = i.next();
4695                PackageParser.Provider p = entry.getValue();
4696                PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
4697
4698                if (ps != null && p.syncable
4699                        && (!mSafeMode || (p.info.applicationInfo.flags
4700                                &ApplicationInfo.FLAG_SYSTEM) != 0)) {
4701                    ProviderInfo info = PackageParser.generateProviderInfo(p, 0,
4702                            ps.readUserState(userId), userId);
4703                    if (info != null) {
4704                        outNames.add(entry.getKey());
4705                        outInfo.add(info);
4706                    }
4707                }
4708            }
4709        }
4710    }
4711
4712    @Override
4713    public List<ProviderInfo> queryContentProviders(String processName,
4714            int uid, int flags) {
4715        ArrayList<ProviderInfo> finalList = null;
4716        // reader
4717        synchronized (mPackages) {
4718            final Iterator<PackageParser.Provider> i = mProviders.mProviders.values().iterator();
4719            final int userId = processName != null ?
4720                    UserHandle.getUserId(uid) : UserHandle.getCallingUserId();
4721            while (i.hasNext()) {
4722                final PackageParser.Provider p = i.next();
4723                PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
4724                if (ps != null && p.info.authority != null
4725                        && (processName == null
4726                                || (p.info.processName.equals(processName)
4727                                        && UserHandle.isSameApp(p.info.applicationInfo.uid, uid)))
4728                        && mSettings.isEnabledLPr(p.info, flags, userId)
4729                        && (!mSafeMode
4730                                || (p.info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0)) {
4731                    if (finalList == null) {
4732                        finalList = new ArrayList<ProviderInfo>(3);
4733                    }
4734                    ProviderInfo info = PackageParser.generateProviderInfo(p, flags,
4735                            ps.readUserState(userId), userId);
4736                    if (info != null) {
4737                        finalList.add(info);
4738                    }
4739                }
4740            }
4741        }
4742
4743        if (finalList != null) {
4744            Collections.sort(finalList, mProviderInitOrderSorter);
4745        }
4746
4747        return finalList;
4748    }
4749
4750    @Override
4751    public InstrumentationInfo getInstrumentationInfo(ComponentName name,
4752            int flags) {
4753        // reader
4754        synchronized (mPackages) {
4755            final PackageParser.Instrumentation i = mInstrumentation.get(name);
4756            return PackageParser.generateInstrumentationInfo(i, flags);
4757        }
4758    }
4759
4760    @Override
4761    public List<InstrumentationInfo> queryInstrumentation(String targetPackage,
4762            int flags) {
4763        ArrayList<InstrumentationInfo> finalList =
4764            new ArrayList<InstrumentationInfo>();
4765
4766        // reader
4767        synchronized (mPackages) {
4768            final Iterator<PackageParser.Instrumentation> i = mInstrumentation.values().iterator();
4769            while (i.hasNext()) {
4770                final PackageParser.Instrumentation p = i.next();
4771                if (targetPackage == null
4772                        || targetPackage.equals(p.info.targetPackage)) {
4773                    InstrumentationInfo ii = PackageParser.generateInstrumentationInfo(p,
4774                            flags);
4775                    if (ii != null) {
4776                        finalList.add(ii);
4777                    }
4778                }
4779            }
4780        }
4781
4782        return finalList;
4783    }
4784
4785    private void createIdmapsForPackageLI(PackageParser.Package pkg) {
4786        ArrayMap<String, PackageParser.Package> overlays = mOverlays.get(pkg.packageName);
4787        if (overlays == null) {
4788            Slog.w(TAG, "Unable to create idmap for " + pkg.packageName + ": no overlay packages");
4789            return;
4790        }
4791        for (PackageParser.Package opkg : overlays.values()) {
4792            // Not much to do if idmap fails: we already logged the error
4793            // and we certainly don't want to abort installation of pkg simply
4794            // because an overlay didn't fit properly. For these reasons,
4795            // ignore the return value of createIdmapForPackagePairLI.
4796            createIdmapForPackagePairLI(pkg, opkg);
4797        }
4798    }
4799
4800    private boolean createIdmapForPackagePairLI(PackageParser.Package pkg,
4801            PackageParser.Package opkg) {
4802        if (!opkg.mTrustedOverlay) {
4803            Slog.w(TAG, "Skipping target and overlay pair " + pkg.baseCodePath + " and " +
4804                    opkg.baseCodePath + ": overlay not trusted");
4805            return false;
4806        }
4807        ArrayMap<String, PackageParser.Package> overlaySet = mOverlays.get(pkg.packageName);
4808        if (overlaySet == null) {
4809            Slog.e(TAG, "was about to create idmap for " + pkg.baseCodePath + " and " +
4810                    opkg.baseCodePath + " but target package has no known overlays");
4811            return false;
4812        }
4813        final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
4814        // TODO: generate idmap for split APKs
4815        if (mInstaller.idmap(pkg.baseCodePath, opkg.baseCodePath, sharedGid) != 0) {
4816            Slog.e(TAG, "Failed to generate idmap for " + pkg.baseCodePath + " and "
4817                    + opkg.baseCodePath);
4818            return false;
4819        }
4820        PackageParser.Package[] overlayArray =
4821            overlaySet.values().toArray(new PackageParser.Package[0]);
4822        Comparator<PackageParser.Package> cmp = new Comparator<PackageParser.Package>() {
4823            public int compare(PackageParser.Package p1, PackageParser.Package p2) {
4824                return p1.mOverlayPriority - p2.mOverlayPriority;
4825            }
4826        };
4827        Arrays.sort(overlayArray, cmp);
4828
4829        pkg.applicationInfo.resourceDirs = new String[overlayArray.length];
4830        int i = 0;
4831        for (PackageParser.Package p : overlayArray) {
4832            pkg.applicationInfo.resourceDirs[i++] = p.baseCodePath;
4833        }
4834        return true;
4835    }
4836
4837    private void scanDirLI(File dir, int parseFlags, int scanFlags, long currentTime) {
4838        final File[] files = dir.listFiles();
4839        if (ArrayUtils.isEmpty(files)) {
4840            Log.d(TAG, "No files in app dir " + dir);
4841            return;
4842        }
4843
4844        if (DEBUG_PACKAGE_SCANNING) {
4845            Log.d(TAG, "Scanning app dir " + dir + " scanFlags=" + scanFlags
4846                    + " flags=0x" + Integer.toHexString(parseFlags));
4847        }
4848
4849        for (File file : files) {
4850            final boolean isPackage = (isApkFile(file) || file.isDirectory())
4851                    && !PackageInstallerService.isStageName(file.getName());
4852            if (!isPackage) {
4853                // Ignore entries which are not packages
4854                continue;
4855            }
4856            try {
4857                scanPackageLI(file, parseFlags | PackageParser.PARSE_MUST_BE_APK,
4858                        scanFlags, currentTime, null);
4859            } catch (PackageManagerException e) {
4860                Slog.w(TAG, "Failed to parse " + file + ": " + e.getMessage());
4861
4862                // Delete invalid userdata apps
4863                if ((parseFlags & PackageParser.PARSE_IS_SYSTEM) == 0 &&
4864                        e.error == PackageManager.INSTALL_FAILED_INVALID_APK) {
4865                    logCriticalInfo(Log.WARN, "Deleting invalid package at " + file);
4866                    if (file.isDirectory()) {
4867                        mInstaller.rmPackageDir(file.getAbsolutePath());
4868                    } else {
4869                        file.delete();
4870                    }
4871                }
4872            }
4873        }
4874    }
4875
4876    private static File getSettingsProblemFile() {
4877        File dataDir = Environment.getDataDirectory();
4878        File systemDir = new File(dataDir, "system");
4879        File fname = new File(systemDir, "uiderrors.txt");
4880        return fname;
4881    }
4882
4883    static void reportSettingsProblem(int priority, String msg) {
4884        logCriticalInfo(priority, msg);
4885    }
4886
4887    static void logCriticalInfo(int priority, String msg) {
4888        Slog.println(priority, TAG, msg);
4889        EventLogTags.writePmCriticalInfo(msg);
4890        try {
4891            File fname = getSettingsProblemFile();
4892            FileOutputStream out = new FileOutputStream(fname, true);
4893            PrintWriter pw = new FastPrintWriter(out);
4894            SimpleDateFormat formatter = new SimpleDateFormat();
4895            String dateString = formatter.format(new Date(System.currentTimeMillis()));
4896            pw.println(dateString + ": " + msg);
4897            pw.close();
4898            FileUtils.setPermissions(
4899                    fname.toString(),
4900                    FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IROTH,
4901                    -1, -1);
4902        } catch (java.io.IOException e) {
4903        }
4904    }
4905
4906    private void collectCertificatesLI(PackageParser pp, PackageSetting ps,
4907            PackageParser.Package pkg, File srcFile, int parseFlags)
4908            throws PackageManagerException {
4909        if (ps != null
4910                && ps.codePath.equals(srcFile)
4911                && ps.timeStamp == srcFile.lastModified()
4912                && !isCompatSignatureUpdateNeeded(pkg)
4913                && !isRecoverSignatureUpdateNeeded(pkg)) {
4914            long mSigningKeySetId = ps.keySetData.getProperSigningKeySet();
4915            if (ps.signatures.mSignatures != null
4916                    && ps.signatures.mSignatures.length != 0
4917                    && mSigningKeySetId != PackageKeySetData.KEYSET_UNASSIGNED) {
4918                // Optimization: reuse the existing cached certificates
4919                // if the package appears to be unchanged.
4920                pkg.mSignatures = ps.signatures.mSignatures;
4921                KeySetManagerService ksms = mSettings.mKeySetManagerService;
4922                synchronized (mPackages) {
4923                    pkg.mSigningKeys = ksms.getPublicKeysFromKeySetLPr(mSigningKeySetId);
4924                }
4925                return;
4926            }
4927
4928            Slog.w(TAG, "PackageSetting for " + ps.name
4929                    + " is missing signatures.  Collecting certs again to recover them.");
4930        } else {
4931            Log.i(TAG, srcFile.toString() + " changed; collecting certs");
4932        }
4933
4934        try {
4935            pp.collectCertificates(pkg, parseFlags);
4936            pp.collectManifestDigest(pkg);
4937        } catch (PackageParserException e) {
4938            throw PackageManagerException.from(e);
4939        }
4940    }
4941
4942    /*
4943     *  Scan a package and return the newly parsed package.
4944     *  Returns null in case of errors and the error code is stored in mLastScanError
4945     */
4946    private PackageParser.Package scanPackageLI(File scanFile, int parseFlags, int scanFlags,
4947            long currentTime, UserHandle user) throws PackageManagerException {
4948        if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanFile);
4949        parseFlags |= mDefParseFlags;
4950        PackageParser pp = new PackageParser();
4951        pp.setSeparateProcesses(mSeparateProcesses);
4952        pp.setOnlyCoreApps(mOnlyCore);
4953        pp.setDisplayMetrics(mMetrics);
4954
4955        if ((scanFlags & SCAN_TRUSTED_OVERLAY) != 0) {
4956            parseFlags |= PackageParser.PARSE_TRUSTED_OVERLAY;
4957        }
4958
4959        final PackageParser.Package pkg;
4960        try {
4961            pkg = pp.parsePackage(scanFile, parseFlags);
4962        } catch (PackageParserException e) {
4963            throw PackageManagerException.from(e);
4964        }
4965
4966        PackageSetting ps = null;
4967        PackageSetting updatedPkg;
4968        // reader
4969        synchronized (mPackages) {
4970            // Look to see if we already know about this package.
4971            String oldName = mSettings.mRenamedPackages.get(pkg.packageName);
4972            if (pkg.mOriginalPackages != null && pkg.mOriginalPackages.contains(oldName)) {
4973                // This package has been renamed to its original name.  Let's
4974                // use that.
4975                ps = mSettings.peekPackageLPr(oldName);
4976            }
4977            // If there was no original package, see one for the real package name.
4978            if (ps == null) {
4979                ps = mSettings.peekPackageLPr(pkg.packageName);
4980            }
4981            // Check to see if this package could be hiding/updating a system
4982            // package.  Must look for it either under the original or real
4983            // package name depending on our state.
4984            updatedPkg = mSettings.getDisabledSystemPkgLPr(ps != null ? ps.name : pkg.packageName);
4985            if (DEBUG_INSTALL && updatedPkg != null) Slog.d(TAG, "updatedPkg = " + updatedPkg);
4986        }
4987        boolean updatedPkgBetter = false;
4988        // First check if this is a system package that may involve an update
4989        if (updatedPkg != null && (parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) {
4990            // If new package is not located in "/system/priv-app" (e.g. due to an OTA),
4991            // it needs to drop FLAG_PRIVILEGED.
4992            if (locationIsPrivileged(scanFile)) {
4993                updatedPkg.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
4994            } else {
4995                updatedPkg.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
4996            }
4997
4998            if (ps != null && !ps.codePath.equals(scanFile)) {
4999                // The path has changed from what was last scanned...  check the
5000                // version of the new path against what we have stored to determine
5001                // what to do.
5002                if (DEBUG_INSTALL) Slog.d(TAG, "Path changing from " + ps.codePath);
5003                if (pkg.mVersionCode <= ps.versionCode) {
5004                    // The system package has been updated and the code path does not match
5005                    // Ignore entry. Skip it.
5006                    Slog.i(TAG, "Package " + ps.name + " at " + scanFile
5007                            + " ignored: updated version " + ps.versionCode
5008                            + " better than this " + pkg.mVersionCode);
5009                    if (!updatedPkg.codePath.equals(scanFile)) {
5010                        Slog.w(PackageManagerService.TAG, "Code path for hidden system pkg : "
5011                                + ps.name + " changing from " + updatedPkg.codePathString
5012                                + " to " + scanFile);
5013                        updatedPkg.codePath = scanFile;
5014                        updatedPkg.codePathString = scanFile.toString();
5015                        updatedPkg.resourcePath = scanFile;
5016                        updatedPkg.resourcePathString = scanFile.toString();
5017                    }
5018                    updatedPkg.pkg = pkg;
5019                    throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE, null);
5020                } else {
5021                    // The current app on the system partition is better than
5022                    // what we have updated to on the data partition; switch
5023                    // back to the system partition version.
5024                    // At this point, its safely assumed that package installation for
5025                    // apps in system partition will go through. If not there won't be a working
5026                    // version of the app
5027                    // writer
5028                    synchronized (mPackages) {
5029                        // Just remove the loaded entries from package lists.
5030                        mPackages.remove(ps.name);
5031                    }
5032
5033                    logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile
5034                            + " reverting from " + ps.codePathString
5035                            + ": new version " + pkg.mVersionCode
5036                            + " better than installed " + ps.versionCode);
5037
5038                    InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
5039                            ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
5040                    synchronized (mInstallLock) {
5041                        args.cleanUpResourcesLI();
5042                    }
5043                    synchronized (mPackages) {
5044                        mSettings.enableSystemPackageLPw(ps.name);
5045                    }
5046                    updatedPkgBetter = true;
5047                }
5048            }
5049        }
5050
5051        if (updatedPkg != null) {
5052            // An updated system app will not have the PARSE_IS_SYSTEM flag set
5053            // initially
5054            parseFlags |= PackageParser.PARSE_IS_SYSTEM;
5055
5056            // An updated privileged app will not have the PARSE_IS_PRIVILEGED
5057            // flag set initially
5058            if ((updatedPkg.pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0) {
5059                parseFlags |= PackageParser.PARSE_IS_PRIVILEGED;
5060            }
5061        }
5062
5063        // Verify certificates against what was last scanned
5064        collectCertificatesLI(pp, ps, pkg, scanFile, parseFlags);
5065
5066        /*
5067         * A new system app appeared, but we already had a non-system one of the
5068         * same name installed earlier.
5069         */
5070        boolean shouldHideSystemApp = false;
5071        if (updatedPkg == null && ps != null
5072                && (parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0 && !isSystemApp(ps)) {
5073            /*
5074             * Check to make sure the signatures match first. If they don't,
5075             * wipe the installed application and its data.
5076             */
5077            if (compareSignatures(ps.signatures.mSignatures, pkg.mSignatures)
5078                    != PackageManager.SIGNATURE_MATCH) {
5079                logCriticalInfo(Log.WARN, "Package " + ps.name + " appeared on system, but"
5080                        + " signatures don't match existing userdata copy; removing");
5081                deletePackageLI(pkg.packageName, null, true, null, null, 0, null, false);
5082                ps = null;
5083            } else {
5084                /*
5085                 * If the newly-added system app is an older version than the
5086                 * already installed version, hide it. It will be scanned later
5087                 * and re-added like an update.
5088                 */
5089                if (pkg.mVersionCode <= ps.versionCode) {
5090                    shouldHideSystemApp = true;
5091                    logCriticalInfo(Log.INFO, "Package " + ps.name + " appeared at " + scanFile
5092                            + " but new version " + pkg.mVersionCode + " better than installed "
5093                            + ps.versionCode + "; hiding system");
5094                } else {
5095                    /*
5096                     * The newly found system app is a newer version that the
5097                     * one previously installed. Simply remove the
5098                     * already-installed application and replace it with our own
5099                     * while keeping the application data.
5100                     */
5101                    logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile
5102                            + " reverting from " + ps.codePathString + ": new version "
5103                            + pkg.mVersionCode + " better than installed " + ps.versionCode);
5104                    InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
5105                            ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
5106                    synchronized (mInstallLock) {
5107                        args.cleanUpResourcesLI();
5108                    }
5109                }
5110            }
5111        }
5112
5113        // The apk is forward locked (not public) if its code and resources
5114        // are kept in different files. (except for app in either system or
5115        // vendor path).
5116        // TODO grab this value from PackageSettings
5117        if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
5118            if (ps != null && !ps.codePath.equals(ps.resourcePath)) {
5119                parseFlags |= PackageParser.PARSE_FORWARD_LOCK;
5120            }
5121        }
5122
5123        // TODO: extend to support forward-locked splits
5124        String resourcePath = null;
5125        String baseResourcePath = null;
5126        if ((parseFlags & PackageParser.PARSE_FORWARD_LOCK) != 0 && !updatedPkgBetter) {
5127            if (ps != null && ps.resourcePathString != null) {
5128                resourcePath = ps.resourcePathString;
5129                baseResourcePath = ps.resourcePathString;
5130            } else {
5131                // Should not happen at all. Just log an error.
5132                Slog.e(TAG, "Resource path not set for pkg : " + pkg.packageName);
5133            }
5134        } else {
5135            resourcePath = pkg.codePath;
5136            baseResourcePath = pkg.baseCodePath;
5137        }
5138
5139        // Set application objects path explicitly.
5140        pkg.applicationInfo.volumeUuid = pkg.volumeUuid;
5141        pkg.applicationInfo.setCodePath(pkg.codePath);
5142        pkg.applicationInfo.setBaseCodePath(pkg.baseCodePath);
5143        pkg.applicationInfo.setSplitCodePaths(pkg.splitCodePaths);
5144        pkg.applicationInfo.setResourcePath(resourcePath);
5145        pkg.applicationInfo.setBaseResourcePath(baseResourcePath);
5146        pkg.applicationInfo.setSplitResourcePaths(pkg.splitCodePaths);
5147
5148        // Note that we invoke the following method only if we are about to unpack an application
5149        PackageParser.Package scannedPkg = scanPackageLI(pkg, parseFlags, scanFlags
5150                | SCAN_UPDATE_SIGNATURE, currentTime, user);
5151
5152        /*
5153         * If the system app should be overridden by a previously installed
5154         * data, hide the system app now and let the /data/app scan pick it up
5155         * again.
5156         */
5157        if (shouldHideSystemApp) {
5158            synchronized (mPackages) {
5159                /*
5160                 * We have to grant systems permissions before we hide, because
5161                 * grantPermissions will assume the package update is trying to
5162                 * expand its permissions.
5163                 */
5164                grantPermissionsLPw(pkg, true, pkg.packageName);
5165                mSettings.disableSystemPackageLPw(pkg.packageName);
5166            }
5167        }
5168
5169        return scannedPkg;
5170    }
5171
5172    private static String fixProcessName(String defProcessName,
5173            String processName, int uid) {
5174        if (processName == null) {
5175            return defProcessName;
5176        }
5177        return processName;
5178    }
5179
5180    private void verifySignaturesLP(PackageSetting pkgSetting, PackageParser.Package pkg)
5181            throws PackageManagerException {
5182        if (pkgSetting.signatures.mSignatures != null) {
5183            // Already existing package. Make sure signatures match
5184            boolean match = compareSignatures(pkgSetting.signatures.mSignatures, pkg.mSignatures)
5185                    == PackageManager.SIGNATURE_MATCH;
5186            if (!match) {
5187                match = compareSignaturesCompat(pkgSetting.signatures, pkg)
5188                        == PackageManager.SIGNATURE_MATCH;
5189            }
5190            if (!match) {
5191                match = compareSignaturesRecover(pkgSetting.signatures, pkg)
5192                        == PackageManager.SIGNATURE_MATCH;
5193            }
5194            if (!match) {
5195                throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
5196                        + pkg.packageName + " signatures do not match the "
5197                        + "previously installed version; ignoring!");
5198            }
5199        }
5200
5201        // Check for shared user signatures
5202        if (pkgSetting.sharedUser != null && pkgSetting.sharedUser.signatures.mSignatures != null) {
5203            // Already existing package. Make sure signatures match
5204            boolean match = compareSignatures(pkgSetting.sharedUser.signatures.mSignatures,
5205                    pkg.mSignatures) == PackageManager.SIGNATURE_MATCH;
5206            if (!match) {
5207                match = compareSignaturesCompat(pkgSetting.sharedUser.signatures, pkg)
5208                        == PackageManager.SIGNATURE_MATCH;
5209            }
5210            if (!match) {
5211                match = compareSignaturesRecover(pkgSetting.sharedUser.signatures, pkg)
5212                        == PackageManager.SIGNATURE_MATCH;
5213            }
5214            if (!match) {
5215                throw new PackageManagerException(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
5216                        "Package " + pkg.packageName
5217                        + " has no signatures that match those in shared user "
5218                        + pkgSetting.sharedUser.name + "; ignoring!");
5219            }
5220        }
5221    }
5222
5223    /**
5224     * Enforces that only the system UID or root's UID can call a method exposed
5225     * via Binder.
5226     *
5227     * @param message used as message if SecurityException is thrown
5228     * @throws SecurityException if the caller is not system or root
5229     */
5230    private static final void enforceSystemOrRoot(String message) {
5231        final int uid = Binder.getCallingUid();
5232        if (uid != Process.SYSTEM_UID && uid != 0) {
5233            throw new SecurityException(message);
5234        }
5235    }
5236
5237    @Override
5238    public void performBootDexOpt() {
5239        enforceSystemOrRoot("Only the system can request dexopt be performed");
5240
5241        // Before everything else, see whether we need to fstrim.
5242        try {
5243            IMountService ms = PackageHelper.getMountService();
5244            if (ms != null) {
5245                final boolean isUpgrade = isUpgrade();
5246                boolean doTrim = isUpgrade;
5247                if (doTrim) {
5248                    Slog.w(TAG, "Running disk maintenance immediately due to system update");
5249                } else {
5250                    final long interval = android.provider.Settings.Global.getLong(
5251                            mContext.getContentResolver(),
5252                            android.provider.Settings.Global.FSTRIM_MANDATORY_INTERVAL,
5253                            DEFAULT_MANDATORY_FSTRIM_INTERVAL);
5254                    if (interval > 0) {
5255                        final long timeSinceLast = System.currentTimeMillis() - ms.lastMaintenance();
5256                        if (timeSinceLast > interval) {
5257                            doTrim = true;
5258                            Slog.w(TAG, "No disk maintenance in " + timeSinceLast
5259                                    + "; running immediately");
5260                        }
5261                    }
5262                }
5263                if (doTrim) {
5264                    if (!isFirstBoot()) {
5265                        try {
5266                            ActivityManagerNative.getDefault().showBootMessage(
5267                                    mContext.getResources().getString(
5268                                            R.string.android_upgrading_fstrim), true);
5269                        } catch (RemoteException e) {
5270                        }
5271                    }
5272                    ms.runMaintenance();
5273                }
5274            } else {
5275                Slog.e(TAG, "Mount service unavailable!");
5276            }
5277        } catch (RemoteException e) {
5278            // Can't happen; MountService is local
5279        }
5280
5281        final ArraySet<PackageParser.Package> pkgs;
5282        synchronized (mPackages) {
5283            pkgs = mPackageDexOptimizer.clearDeferredDexOptPackages();
5284        }
5285
5286        if (pkgs != null) {
5287            // Sort apps by importance for dexopt ordering. Important apps are given more priority
5288            // in case the device runs out of space.
5289            ArrayList<PackageParser.Package> sortedPkgs = new ArrayList<PackageParser.Package>();
5290            // Give priority to core apps.
5291            for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) {
5292                PackageParser.Package pkg = it.next();
5293                if (pkg.coreApp) {
5294                    if (DEBUG_DEXOPT) {
5295                        Log.i(TAG, "Adding core app " + sortedPkgs.size() + ": " + pkg.packageName);
5296                    }
5297                    sortedPkgs.add(pkg);
5298                    it.remove();
5299                }
5300            }
5301            // Give priority to system apps that listen for pre boot complete.
5302            Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
5303            ArraySet<String> pkgNames = getPackageNamesForIntent(intent);
5304            for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) {
5305                PackageParser.Package pkg = it.next();
5306                if (pkgNames.contains(pkg.packageName)) {
5307                    if (DEBUG_DEXOPT) {
5308                        Log.i(TAG, "Adding pre boot system app " + sortedPkgs.size() + ": " + pkg.packageName);
5309                    }
5310                    sortedPkgs.add(pkg);
5311                    it.remove();
5312                }
5313            }
5314            // Give priority to system apps.
5315            for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) {
5316                PackageParser.Package pkg = it.next();
5317                if (isSystemApp(pkg) && !pkg.isUpdatedSystemApp()) {
5318                    if (DEBUG_DEXOPT) {
5319                        Log.i(TAG, "Adding system app " + sortedPkgs.size() + ": " + pkg.packageName);
5320                    }
5321                    sortedPkgs.add(pkg);
5322                    it.remove();
5323                }
5324            }
5325            // Give priority to updated system apps.
5326            for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) {
5327                PackageParser.Package pkg = it.next();
5328                if (pkg.isUpdatedSystemApp()) {
5329                    if (DEBUG_DEXOPT) {
5330                        Log.i(TAG, "Adding updated system app " + sortedPkgs.size() + ": " + pkg.packageName);
5331                    }
5332                    sortedPkgs.add(pkg);
5333                    it.remove();
5334                }
5335            }
5336            // Give priority to apps that listen for boot complete.
5337            intent = new Intent(Intent.ACTION_BOOT_COMPLETED);
5338            pkgNames = getPackageNamesForIntent(intent);
5339            for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) {
5340                PackageParser.Package pkg = it.next();
5341                if (pkgNames.contains(pkg.packageName)) {
5342                    if (DEBUG_DEXOPT) {
5343                        Log.i(TAG, "Adding boot app " + sortedPkgs.size() + ": " + pkg.packageName);
5344                    }
5345                    sortedPkgs.add(pkg);
5346                    it.remove();
5347                }
5348            }
5349            // Filter out packages that aren't recently used.
5350            filterRecentlyUsedApps(pkgs);
5351            // Add all remaining apps.
5352            for (PackageParser.Package pkg : pkgs) {
5353                if (DEBUG_DEXOPT) {
5354                    Log.i(TAG, "Adding app " + sortedPkgs.size() + ": " + pkg.packageName);
5355                }
5356                sortedPkgs.add(pkg);
5357            }
5358
5359            // If we want to be lazy, filter everything that wasn't recently used.
5360            if (mLazyDexOpt) {
5361                filterRecentlyUsedApps(sortedPkgs);
5362            }
5363
5364            int i = 0;
5365            int total = sortedPkgs.size();
5366            File dataDir = Environment.getDataDirectory();
5367            long lowThreshold = StorageManager.from(mContext).getStorageLowBytes(dataDir);
5368            if (lowThreshold == 0) {
5369                throw new IllegalStateException("Invalid low memory threshold");
5370            }
5371            for (PackageParser.Package pkg : sortedPkgs) {
5372                long usableSpace = dataDir.getUsableSpace();
5373                if (usableSpace < lowThreshold) {
5374                    Log.w(TAG, "Not running dexopt on remaining apps due to low memory: " + usableSpace);
5375                    break;
5376                }
5377                performBootDexOpt(pkg, ++i, total);
5378            }
5379        }
5380    }
5381
5382    private void filterRecentlyUsedApps(Collection<PackageParser.Package> pkgs) {
5383        // Filter out packages that aren't recently used.
5384        //
5385        // The exception is first boot of a non-eng device (aka !mLazyDexOpt), which
5386        // should do a full dexopt.
5387        if (mLazyDexOpt || (!isFirstBoot() && mPackageUsage.isHistoricalPackageUsageAvailable())) {
5388            int total = pkgs.size();
5389            int skipped = 0;
5390            long now = System.currentTimeMillis();
5391            for (Iterator<PackageParser.Package> i = pkgs.iterator(); i.hasNext();) {
5392                PackageParser.Package pkg = i.next();
5393                long then = pkg.mLastPackageUsageTimeInMills;
5394                if (then + mDexOptLRUThresholdInMills < now) {
5395                    if (DEBUG_DEXOPT) {
5396                        Log.i(TAG, "Skipping dexopt of " + pkg.packageName + " last resumed: " +
5397                              ((then == 0) ? "never" : new Date(then)));
5398                    }
5399                    i.remove();
5400                    skipped++;
5401                }
5402            }
5403            if (DEBUG_DEXOPT) {
5404                Log.i(TAG, "Skipped optimizing " + skipped + " of " + total);
5405            }
5406        }
5407    }
5408
5409    private ArraySet<String> getPackageNamesForIntent(Intent intent) {
5410        List<ResolveInfo> ris = null;
5411        try {
5412            ris = AppGlobals.getPackageManager().queryIntentReceivers(
5413                    intent, null, 0, UserHandle.USER_OWNER);
5414        } catch (RemoteException e) {
5415        }
5416        ArraySet<String> pkgNames = new ArraySet<String>();
5417        if (ris != null) {
5418            for (ResolveInfo ri : ris) {
5419                pkgNames.add(ri.activityInfo.packageName);
5420            }
5421        }
5422        return pkgNames;
5423    }
5424
5425    private void performBootDexOpt(PackageParser.Package pkg, int curr, int total) {
5426        if (DEBUG_DEXOPT) {
5427            Log.i(TAG, "Optimizing app " + curr + " of " + total + ": " + pkg.packageName);
5428        }
5429        if (!isFirstBoot()) {
5430            try {
5431                ActivityManagerNative.getDefault().showBootMessage(
5432                        mContext.getResources().getString(R.string.android_upgrading_apk,
5433                                curr, total), true);
5434            } catch (RemoteException e) {
5435            }
5436        }
5437        PackageParser.Package p = pkg;
5438        synchronized (mInstallLock) {
5439            mPackageDexOptimizer.performDexOpt(p, null /* instruction sets */,
5440                    false /* force dex */, false /* defer */, true /* include dependencies */);
5441        }
5442    }
5443
5444    @Override
5445    public boolean performDexOptIfNeeded(String packageName, String instructionSet) {
5446        return performDexOpt(packageName, instructionSet, false);
5447    }
5448
5449    public boolean performDexOpt(String packageName, String instructionSet, boolean backgroundDexopt) {
5450        boolean dexopt = mLazyDexOpt || backgroundDexopt;
5451        boolean updateUsage = !backgroundDexopt;  // Don't update usage if this is just a backgroundDexopt
5452        if (!dexopt && !updateUsage) {
5453            // We aren't going to dexopt or update usage, so bail early.
5454            return false;
5455        }
5456        PackageParser.Package p;
5457        final String targetInstructionSet;
5458        synchronized (mPackages) {
5459            p = mPackages.get(packageName);
5460            if (p == null) {
5461                return false;
5462            }
5463            if (updateUsage) {
5464                p.mLastPackageUsageTimeInMills = System.currentTimeMillis();
5465            }
5466            mPackageUsage.write(false);
5467            if (!dexopt) {
5468                // We aren't going to dexopt, so bail early.
5469                return false;
5470            }
5471
5472            targetInstructionSet = instructionSet != null ? instructionSet :
5473                    getPrimaryInstructionSet(p.applicationInfo);
5474            if (p.mDexOptPerformed.contains(targetInstructionSet)) {
5475                return false;
5476            }
5477        }
5478
5479        synchronized (mInstallLock) {
5480            final String[] instructionSets = new String[] { targetInstructionSet };
5481            int result = mPackageDexOptimizer.performDexOpt(p, instructionSets,
5482                    false /* forceDex */, false /* defer */, true /* inclDependencies */);
5483            return result == PackageDexOptimizer.DEX_OPT_PERFORMED;
5484        }
5485    }
5486
5487    public ArraySet<String> getPackagesThatNeedDexOpt() {
5488        ArraySet<String> pkgs = null;
5489        synchronized (mPackages) {
5490            for (PackageParser.Package p : mPackages.values()) {
5491                if (DEBUG_DEXOPT) {
5492                    Log.i(TAG, p.packageName + " mDexOptPerformed=" + p.mDexOptPerformed.toArray());
5493                }
5494                if (!p.mDexOptPerformed.isEmpty()) {
5495                    continue;
5496                }
5497                if (pkgs == null) {
5498                    pkgs = new ArraySet<String>();
5499                }
5500                pkgs.add(p.packageName);
5501            }
5502        }
5503        return pkgs;
5504    }
5505
5506    public void shutdown() {
5507        mPackageUsage.write(true);
5508    }
5509
5510    @Override
5511    public void forceDexOpt(String packageName) {
5512        enforceSystemOrRoot("forceDexOpt");
5513
5514        PackageParser.Package pkg;
5515        synchronized (mPackages) {
5516            pkg = mPackages.get(packageName);
5517            if (pkg == null) {
5518                throw new IllegalArgumentException("Missing package: " + packageName);
5519            }
5520        }
5521
5522        synchronized (mInstallLock) {
5523            final String[] instructionSets = new String[] {
5524                    getPrimaryInstructionSet(pkg.applicationInfo) };
5525            final int res = mPackageDexOptimizer.performDexOpt(pkg, instructionSets,
5526                    true /*forceDex*/, false /* defer */, true /* inclDependencies */);
5527            if (res != PackageDexOptimizer.DEX_OPT_PERFORMED) {
5528                throw new IllegalStateException("Failed to dexopt: " + res);
5529            }
5530        }
5531    }
5532
5533    private boolean verifyPackageUpdateLPr(PackageSetting oldPkg, PackageParser.Package newPkg) {
5534        if ((oldPkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) {
5535            Slog.w(TAG, "Unable to update from " + oldPkg.name
5536                    + " to " + newPkg.packageName
5537                    + ": old package not in system partition");
5538            return false;
5539        } else if (mPackages.get(oldPkg.name) != null) {
5540            Slog.w(TAG, "Unable to update from " + oldPkg.name
5541                    + " to " + newPkg.packageName
5542                    + ": old package still exists");
5543            return false;
5544        }
5545        return true;
5546    }
5547
5548    private int createDataDirsLI(String volumeUuid, String packageName, int uid, String seinfo) {
5549        int[] users = sUserManager.getUserIds();
5550        int res = mInstaller.install(volumeUuid, packageName, uid, uid, seinfo);
5551        if (res < 0) {
5552            return res;
5553        }
5554        for (int user : users) {
5555            if (user != 0) {
5556                res = mInstaller.createUserData(volumeUuid, packageName,
5557                        UserHandle.getUid(user, uid), user, seinfo);
5558                if (res < 0) {
5559                    return res;
5560                }
5561            }
5562        }
5563        return res;
5564    }
5565
5566    private int removeDataDirsLI(String volumeUuid, String packageName) {
5567        int[] users = sUserManager.getUserIds();
5568        int res = 0;
5569        for (int user : users) {
5570            int resInner = mInstaller.remove(volumeUuid, packageName, user);
5571            if (resInner < 0) {
5572                res = resInner;
5573            }
5574        }
5575
5576        return res;
5577    }
5578
5579    private int deleteCodeCacheDirsLI(String volumeUuid, String packageName) {
5580        int[] users = sUserManager.getUserIds();
5581        int res = 0;
5582        for (int user : users) {
5583            int resInner = mInstaller.deleteCodeCacheFiles(volumeUuid, packageName, user);
5584            if (resInner < 0) {
5585                res = resInner;
5586            }
5587        }
5588        return res;
5589    }
5590
5591    private void addSharedLibraryLPw(ArraySet<String> usesLibraryFiles, SharedLibraryEntry file,
5592            PackageParser.Package changingLib) {
5593        if (file.path != null) {
5594            usesLibraryFiles.add(file.path);
5595            return;
5596        }
5597        PackageParser.Package p = mPackages.get(file.apk);
5598        if (changingLib != null && changingLib.packageName.equals(file.apk)) {
5599            // If we are doing this while in the middle of updating a library apk,
5600            // then we need to make sure to use that new apk for determining the
5601            // dependencies here.  (We haven't yet finished committing the new apk
5602            // to the package manager state.)
5603            if (p == null || p.packageName.equals(changingLib.packageName)) {
5604                p = changingLib;
5605            }
5606        }
5607        if (p != null) {
5608            usesLibraryFiles.addAll(p.getAllCodePaths());
5609        }
5610    }
5611
5612    private void updateSharedLibrariesLPw(PackageParser.Package pkg,
5613            PackageParser.Package changingLib) throws PackageManagerException {
5614        if (pkg.usesLibraries != null || pkg.usesOptionalLibraries != null) {
5615            final ArraySet<String> usesLibraryFiles = new ArraySet<>();
5616            int N = pkg.usesLibraries != null ? pkg.usesLibraries.size() : 0;
5617            for (int i=0; i<N; i++) {
5618                final SharedLibraryEntry file = mSharedLibraries.get(pkg.usesLibraries.get(i));
5619                if (file == null) {
5620                    throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
5621                            "Package " + pkg.packageName + " requires unavailable shared library "
5622                            + pkg.usesLibraries.get(i) + "; failing!");
5623                }
5624                addSharedLibraryLPw(usesLibraryFiles, file, changingLib);
5625            }
5626            N = pkg.usesOptionalLibraries != null ? pkg.usesOptionalLibraries.size() : 0;
5627            for (int i=0; i<N; i++) {
5628                final SharedLibraryEntry file = mSharedLibraries.get(pkg.usesOptionalLibraries.get(i));
5629                if (file == null) {
5630                    Slog.w(TAG, "Package " + pkg.packageName
5631                            + " desires unavailable shared library "
5632                            + pkg.usesOptionalLibraries.get(i) + "; ignoring!");
5633                } else {
5634                    addSharedLibraryLPw(usesLibraryFiles, file, changingLib);
5635                }
5636            }
5637            N = usesLibraryFiles.size();
5638            if (N > 0) {
5639                pkg.usesLibraryFiles = usesLibraryFiles.toArray(new String[N]);
5640            } else {
5641                pkg.usesLibraryFiles = null;
5642            }
5643        }
5644    }
5645
5646    private static boolean hasString(List<String> list, List<String> which) {
5647        if (list == null) {
5648            return false;
5649        }
5650        for (int i=list.size()-1; i>=0; i--) {
5651            for (int j=which.size()-1; j>=0; j--) {
5652                if (which.get(j).equals(list.get(i))) {
5653                    return true;
5654                }
5655            }
5656        }
5657        return false;
5658    }
5659
5660    private void updateAllSharedLibrariesLPw() {
5661        for (PackageParser.Package pkg : mPackages.values()) {
5662            try {
5663                updateSharedLibrariesLPw(pkg, null);
5664            } catch (PackageManagerException e) {
5665                Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
5666            }
5667        }
5668    }
5669
5670    private ArrayList<PackageParser.Package> updateAllSharedLibrariesLPw(
5671            PackageParser.Package changingPkg) {
5672        ArrayList<PackageParser.Package> res = null;
5673        for (PackageParser.Package pkg : mPackages.values()) {
5674            if (hasString(pkg.usesLibraries, changingPkg.libraryNames)
5675                    || hasString(pkg.usesOptionalLibraries, changingPkg.libraryNames)) {
5676                if (res == null) {
5677                    res = new ArrayList<PackageParser.Package>();
5678                }
5679                res.add(pkg);
5680                try {
5681                    updateSharedLibrariesLPw(pkg, changingPkg);
5682                } catch (PackageManagerException e) {
5683                    Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
5684                }
5685            }
5686        }
5687        return res;
5688    }
5689
5690    /**
5691     * Derive the value of the {@code cpuAbiOverride} based on the provided
5692     * value and an optional stored value from the package settings.
5693     */
5694    private static String deriveAbiOverride(String abiOverride, PackageSetting settings) {
5695        String cpuAbiOverride = null;
5696
5697        if (NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(abiOverride)) {
5698            cpuAbiOverride = null;
5699        } else if (abiOverride != null) {
5700            cpuAbiOverride = abiOverride;
5701        } else if (settings != null) {
5702            cpuAbiOverride = settings.cpuAbiOverrideString;
5703        }
5704
5705        return cpuAbiOverride;
5706    }
5707
5708    private PackageParser.Package scanPackageLI(PackageParser.Package pkg, int parseFlags,
5709            int scanFlags, long currentTime, UserHandle user) throws PackageManagerException {
5710        boolean success = false;
5711        try {
5712            final PackageParser.Package res = scanPackageDirtyLI(pkg, parseFlags, scanFlags,
5713                    currentTime, user);
5714            success = true;
5715            return res;
5716        } finally {
5717            if (!success && (scanFlags & SCAN_DELETE_DATA_ON_FAILURES) != 0) {
5718                removeDataDirsLI(pkg.volumeUuid, pkg.packageName);
5719            }
5720        }
5721    }
5722
5723    private PackageParser.Package scanPackageDirtyLI(PackageParser.Package pkg, int parseFlags,
5724            int scanFlags, long currentTime, UserHandle user) throws PackageManagerException {
5725        final File scanFile = new File(pkg.codePath);
5726        if (pkg.applicationInfo.getCodePath() == null ||
5727                pkg.applicationInfo.getResourcePath() == null) {
5728            // Bail out. The resource and code paths haven't been set.
5729            throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
5730                    "Code and resource paths haven't been set correctly");
5731        }
5732
5733        if ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) {
5734            pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
5735        } else {
5736            // Only allow system apps to be flagged as core apps.
5737            pkg.coreApp = false;
5738        }
5739
5740        if ((parseFlags&PackageParser.PARSE_IS_PRIVILEGED) != 0) {
5741            pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
5742        }
5743
5744        if (mCustomResolverComponentName != null &&
5745                mCustomResolverComponentName.getPackageName().equals(pkg.packageName)) {
5746            setUpCustomResolverActivity(pkg);
5747        }
5748
5749        if (pkg.packageName.equals("android")) {
5750            synchronized (mPackages) {
5751                if (mAndroidApplication != null) {
5752                    Slog.w(TAG, "*************************************************");
5753                    Slog.w(TAG, "Core android package being redefined.  Skipping.");
5754                    Slog.w(TAG, " file=" + scanFile);
5755                    Slog.w(TAG, "*************************************************");
5756                    throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
5757                            "Core android package being redefined.  Skipping.");
5758                }
5759
5760                // Set up information for our fall-back user intent resolution activity.
5761                mPlatformPackage = pkg;
5762                pkg.mVersionCode = mSdkVersion;
5763                mAndroidApplication = pkg.applicationInfo;
5764
5765                if (!mResolverReplaced) {
5766                    mResolveActivity.applicationInfo = mAndroidApplication;
5767                    mResolveActivity.name = ResolverActivity.class.getName();
5768                    mResolveActivity.packageName = mAndroidApplication.packageName;
5769                    mResolveActivity.processName = "system:ui";
5770                    mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
5771                    mResolveActivity.documentLaunchMode = ActivityInfo.DOCUMENT_LAUNCH_NEVER;
5772                    mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS;
5773                    mResolveActivity.theme = R.style.Theme_Holo_Dialog_Alert;
5774                    mResolveActivity.exported = true;
5775                    mResolveActivity.enabled = true;
5776                    mResolveInfo.activityInfo = mResolveActivity;
5777                    mResolveInfo.priority = 0;
5778                    mResolveInfo.preferredOrder = 0;
5779                    mResolveInfo.match = 0;
5780                    mResolveComponentName = new ComponentName(
5781                            mAndroidApplication.packageName, mResolveActivity.name);
5782                }
5783            }
5784        }
5785
5786        if (DEBUG_PACKAGE_SCANNING) {
5787            if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
5788                Log.d(TAG, "Scanning package " + pkg.packageName);
5789        }
5790
5791        if (mPackages.containsKey(pkg.packageName)
5792                || mSharedLibraries.containsKey(pkg.packageName)) {
5793            throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
5794                    "Application package " + pkg.packageName
5795                    + " already installed.  Skipping duplicate.");
5796        }
5797
5798        // If we're only installing presumed-existing packages, require that the
5799        // scanned APK is both already known and at the path previously established
5800        // for it.  Previously unknown packages we pick up normally, but if we have an
5801        // a priori expectation about this package's install presence, enforce it.
5802        if ((scanFlags & SCAN_REQUIRE_KNOWN) != 0) {
5803            PackageSetting known = mSettings.peekPackageLPr(pkg.packageName);
5804            if (known != null) {
5805                if (DEBUG_PACKAGE_SCANNING) {
5806                    Log.d(TAG, "Examining " + pkg.codePath
5807                            + " and requiring known paths " + known.codePathString
5808                            + " & " + known.resourcePathString);
5809                }
5810                if (!pkg.applicationInfo.getCodePath().equals(known.codePathString)
5811                        || !pkg.applicationInfo.getResourcePath().equals(known.resourcePathString)) {
5812                    throw new PackageManagerException(INSTALL_FAILED_PACKAGE_CHANGED,
5813                            "Application package " + pkg.packageName
5814                            + " found at " + pkg.applicationInfo.getCodePath()
5815                            + " but expected at " + known.codePathString + "; ignoring.");
5816                }
5817            }
5818        }
5819
5820        // Initialize package source and resource directories
5821        File destCodeFile = new File(pkg.applicationInfo.getCodePath());
5822        File destResourceFile = new File(pkg.applicationInfo.getResourcePath());
5823
5824        SharedUserSetting suid = null;
5825        PackageSetting pkgSetting = null;
5826
5827        if (!isSystemApp(pkg)) {
5828            // Only system apps can use these features.
5829            pkg.mOriginalPackages = null;
5830            pkg.mRealPackage = null;
5831            pkg.mAdoptPermissions = null;
5832        }
5833
5834        // writer
5835        synchronized (mPackages) {
5836            if (pkg.mSharedUserId != null) {
5837                suid = mSettings.getSharedUserLPw(pkg.mSharedUserId, 0, 0, true);
5838                if (suid == null) {
5839                    throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE,
5840                            "Creating application package " + pkg.packageName
5841                            + " for shared user failed");
5842                }
5843                if (DEBUG_PACKAGE_SCANNING) {
5844                    if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
5845                        Log.d(TAG, "Shared UserID " + pkg.mSharedUserId + " (uid=" + suid.userId
5846                                + "): packages=" + suid.packages);
5847                }
5848            }
5849
5850            // Check if we are renaming from an original package name.
5851            PackageSetting origPackage = null;
5852            String realName = null;
5853            if (pkg.mOriginalPackages != null) {
5854                // This package may need to be renamed to a previously
5855                // installed name.  Let's check on that...
5856                final String renamed = mSettings.mRenamedPackages.get(pkg.mRealPackage);
5857                if (pkg.mOriginalPackages.contains(renamed)) {
5858                    // This package had originally been installed as the
5859                    // original name, and we have already taken care of
5860                    // transitioning to the new one.  Just update the new
5861                    // one to continue using the old name.
5862                    realName = pkg.mRealPackage;
5863                    if (!pkg.packageName.equals(renamed)) {
5864                        // Callers into this function may have already taken
5865                        // care of renaming the package; only do it here if
5866                        // it is not already done.
5867                        pkg.setPackageName(renamed);
5868                    }
5869
5870                } else {
5871                    for (int i=pkg.mOriginalPackages.size()-1; i>=0; i--) {
5872                        if ((origPackage = mSettings.peekPackageLPr(
5873                                pkg.mOriginalPackages.get(i))) != null) {
5874                            // We do have the package already installed under its
5875                            // original name...  should we use it?
5876                            if (!verifyPackageUpdateLPr(origPackage, pkg)) {
5877                                // New package is not compatible with original.
5878                                origPackage = null;
5879                                continue;
5880                            } else if (origPackage.sharedUser != null) {
5881                                // Make sure uid is compatible between packages.
5882                                if (!origPackage.sharedUser.name.equals(pkg.mSharedUserId)) {
5883                                    Slog.w(TAG, "Unable to migrate data from " + origPackage.name
5884                                            + " to " + pkg.packageName + ": old uid "
5885                                            + origPackage.sharedUser.name
5886                                            + " differs from " + pkg.mSharedUserId);
5887                                    origPackage = null;
5888                                    continue;
5889                                }
5890                            } else {
5891                                if (DEBUG_UPGRADE) Log.v(TAG, "Renaming new package "
5892                                        + pkg.packageName + " to old name " + origPackage.name);
5893                            }
5894                            break;
5895                        }
5896                    }
5897                }
5898            }
5899
5900            if (mTransferedPackages.contains(pkg.packageName)) {
5901                Slog.w(TAG, "Package " + pkg.packageName
5902                        + " was transferred to another, but its .apk remains");
5903            }
5904
5905            // Just create the setting, don't add it yet. For already existing packages
5906            // the PkgSetting exists already and doesn't have to be created.
5907            pkgSetting = mSettings.getPackageLPw(pkg, origPackage, realName, suid, destCodeFile,
5908                    destResourceFile, pkg.applicationInfo.nativeLibraryRootDir,
5909                    pkg.applicationInfo.primaryCpuAbi,
5910                    pkg.applicationInfo.secondaryCpuAbi,
5911                    pkg.applicationInfo.flags, pkg.applicationInfo.privateFlags,
5912                    user, false);
5913            if (pkgSetting == null) {
5914                throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE,
5915                        "Creating application package " + pkg.packageName + " failed");
5916            }
5917
5918            if (pkgSetting.origPackage != null) {
5919                // If we are first transitioning from an original package,
5920                // fix up the new package's name now.  We need to do this after
5921                // looking up the package under its new name, so getPackageLP
5922                // can take care of fiddling things correctly.
5923                pkg.setPackageName(origPackage.name);
5924
5925                // File a report about this.
5926                String msg = "New package " + pkgSetting.realName
5927                        + " renamed to replace old package " + pkgSetting.name;
5928                reportSettingsProblem(Log.WARN, msg);
5929
5930                // Make a note of it.
5931                mTransferedPackages.add(origPackage.name);
5932
5933                // No longer need to retain this.
5934                pkgSetting.origPackage = null;
5935            }
5936
5937            if (realName != null) {
5938                // Make a note of it.
5939                mTransferedPackages.add(pkg.packageName);
5940            }
5941
5942            if (mSettings.isDisabledSystemPackageLPr(pkg.packageName)) {
5943                pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
5944            }
5945
5946            if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
5947                // Check all shared libraries and map to their actual file path.
5948                // We only do this here for apps not on a system dir, because those
5949                // are the only ones that can fail an install due to this.  We
5950                // will take care of the system apps by updating all of their
5951                // library paths after the scan is done.
5952                updateSharedLibrariesLPw(pkg, null);
5953            }
5954
5955            if (mFoundPolicyFile) {
5956                SELinuxMMAC.assignSeinfoValue(pkg);
5957            }
5958
5959            pkg.applicationInfo.uid = pkgSetting.appId;
5960            pkg.mExtras = pkgSetting;
5961            if (!pkgSetting.keySetData.isUsingUpgradeKeySets() || pkgSetting.sharedUser != null) {
5962                try {
5963                    verifySignaturesLP(pkgSetting, pkg);
5964                    // We just determined the app is signed correctly, so bring
5965                    // over the latest parsed certs.
5966                    pkgSetting.signatures.mSignatures = pkg.mSignatures;
5967                } catch (PackageManagerException e) {
5968                    if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
5969                        throw e;
5970                    }
5971                    // The signature has changed, but this package is in the system
5972                    // image...  let's recover!
5973                    pkgSetting.signatures.mSignatures = pkg.mSignatures;
5974                    // However...  if this package is part of a shared user, but it
5975                    // doesn't match the signature of the shared user, let's fail.
5976                    // What this means is that you can't change the signatures
5977                    // associated with an overall shared user, which doesn't seem all
5978                    // that unreasonable.
5979                    if (pkgSetting.sharedUser != null) {
5980                        if (compareSignatures(pkgSetting.sharedUser.signatures.mSignatures,
5981                                              pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) {
5982                            throw new PackageManagerException(
5983                                    INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES,
5984                                            "Signature mismatch for shared user : "
5985                                            + pkgSetting.sharedUser);
5986                        }
5987                    }
5988                    // File a report about this.
5989                    String msg = "System package " + pkg.packageName
5990                        + " signature changed; retaining data.";
5991                    reportSettingsProblem(Log.WARN, msg);
5992                }
5993            } else {
5994                if (!checkUpgradeKeySetLP(pkgSetting, pkg)) {
5995                    throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
5996                            + pkg.packageName + " upgrade keys do not match the "
5997                            + "previously installed version");
5998                } else {
5999                    // We just determined the app is signed correctly, so bring
6000                    // over the latest parsed certs.
6001                    pkgSetting.signatures.mSignatures = pkg.mSignatures;
6002                }
6003            }
6004            // Verify that this new package doesn't have any content providers
6005            // that conflict with existing packages.  Only do this if the
6006            // package isn't already installed, since we don't want to break
6007            // things that are installed.
6008            if ((scanFlags & SCAN_NEW_INSTALL) != 0) {
6009                final int N = pkg.providers.size();
6010                int i;
6011                for (i=0; i<N; i++) {
6012                    PackageParser.Provider p = pkg.providers.get(i);
6013                    if (p.info.authority != null) {
6014                        String names[] = p.info.authority.split(";");
6015                        for (int j = 0; j < names.length; j++) {
6016                            if (mProvidersByAuthority.containsKey(names[j])) {
6017                                PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
6018                                final String otherPackageName =
6019                                        ((other != null && other.getComponentName() != null) ?
6020                                                other.getComponentName().getPackageName() : "?");
6021                                throw new PackageManagerException(
6022                                        INSTALL_FAILED_CONFLICTING_PROVIDER,
6023                                                "Can't install because provider name " + names[j]
6024                                                + " (in package " + pkg.applicationInfo.packageName
6025                                                + ") is already used by " + otherPackageName);
6026                            }
6027                        }
6028                    }
6029                }
6030            }
6031
6032            if (pkg.mAdoptPermissions != null) {
6033                // This package wants to adopt ownership of permissions from
6034                // another package.
6035                for (int i = pkg.mAdoptPermissions.size() - 1; i >= 0; i--) {
6036                    final String origName = pkg.mAdoptPermissions.get(i);
6037                    final PackageSetting orig = mSettings.peekPackageLPr(origName);
6038                    if (orig != null) {
6039                        if (verifyPackageUpdateLPr(orig, pkg)) {
6040                            Slog.i(TAG, "Adopting permissions from " + origName + " to "
6041                                    + pkg.packageName);
6042                            mSettings.transferPermissionsLPw(origName, pkg.packageName);
6043                        }
6044                    }
6045                }
6046            }
6047        }
6048
6049        final String pkgName = pkg.packageName;
6050
6051        final long scanFileTime = scanFile.lastModified();
6052        final boolean forceDex = (scanFlags & SCAN_FORCE_DEX) != 0;
6053        pkg.applicationInfo.processName = fixProcessName(
6054                pkg.applicationInfo.packageName,
6055                pkg.applicationInfo.processName,
6056                pkg.applicationInfo.uid);
6057
6058        File dataPath;
6059        if (mPlatformPackage == pkg) {
6060            // The system package is special.
6061            dataPath = new File(Environment.getDataDirectory(), "system");
6062
6063            pkg.applicationInfo.dataDir = dataPath.getPath();
6064
6065        } else {
6066            // This is a normal package, need to make its data directory.
6067            dataPath = PackageManager.getDataDirForUser(pkg.volumeUuid, pkg.packageName,
6068                    UserHandle.USER_OWNER);
6069
6070            boolean uidError = false;
6071            if (dataPath.exists()) {
6072                int currentUid = 0;
6073                try {
6074                    StructStat stat = Os.stat(dataPath.getPath());
6075                    currentUid = stat.st_uid;
6076                } catch (ErrnoException e) {
6077                    Slog.e(TAG, "Couldn't stat path " + dataPath.getPath(), e);
6078                }
6079
6080                // If we have mismatched owners for the data path, we have a problem.
6081                if (currentUid != pkg.applicationInfo.uid) {
6082                    boolean recovered = false;
6083                    if (currentUid == 0) {
6084                        // The directory somehow became owned by root.  Wow.
6085                        // This is probably because the system was stopped while
6086                        // installd was in the middle of messing with its libs
6087                        // directory.  Ask installd to fix that.
6088                        int ret = mInstaller.fixUid(pkg.volumeUuid, pkgName,
6089                                pkg.applicationInfo.uid, pkg.applicationInfo.uid);
6090                        if (ret >= 0) {
6091                            recovered = true;
6092                            String msg = "Package " + pkg.packageName
6093                                    + " unexpectedly changed to uid 0; recovered to " +
6094                                    + pkg.applicationInfo.uid;
6095                            reportSettingsProblem(Log.WARN, msg);
6096                        }
6097                    }
6098                    if (!recovered && ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0
6099                            || (scanFlags&SCAN_BOOTING) != 0)) {
6100                        // If this is a system app, we can at least delete its
6101                        // current data so the application will still work.
6102                        int ret = removeDataDirsLI(pkg.volumeUuid, pkgName);
6103                        if (ret >= 0) {
6104                            // TODO: Kill the processes first
6105                            // Old data gone!
6106                            String prefix = (parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0
6107                                    ? "System package " : "Third party package ";
6108                            String msg = prefix + pkg.packageName
6109                                    + " has changed from uid: "
6110                                    + currentUid + " to "
6111                                    + pkg.applicationInfo.uid + "; old data erased";
6112                            reportSettingsProblem(Log.WARN, msg);
6113                            recovered = true;
6114
6115                            // And now re-install the app.
6116                            ret = createDataDirsLI(pkg.volumeUuid, pkgName, pkg.applicationInfo.uid,
6117                                    pkg.applicationInfo.seinfo);
6118                            if (ret == -1) {
6119                                // Ack should not happen!
6120                                msg = prefix + pkg.packageName
6121                                        + " could not have data directory re-created after delete.";
6122                                reportSettingsProblem(Log.WARN, msg);
6123                                throw new PackageManagerException(
6124                                        INSTALL_FAILED_INSUFFICIENT_STORAGE, msg);
6125                            }
6126                        }
6127                        if (!recovered) {
6128                            mHasSystemUidErrors = true;
6129                        }
6130                    } else if (!recovered) {
6131                        // If we allow this install to proceed, we will be broken.
6132                        // Abort, abort!
6133                        throw new PackageManagerException(INSTALL_FAILED_UID_CHANGED,
6134                                "scanPackageLI");
6135                    }
6136                    if (!recovered) {
6137                        pkg.applicationInfo.dataDir = "/mismatched_uid/settings_"
6138                            + pkg.applicationInfo.uid + "/fs_"
6139                            + currentUid;
6140                        pkg.applicationInfo.nativeLibraryDir = pkg.applicationInfo.dataDir;
6141                        pkg.applicationInfo.nativeLibraryRootDir = pkg.applicationInfo.dataDir;
6142                        String msg = "Package " + pkg.packageName
6143                                + " has mismatched uid: "
6144                                + currentUid + " on disk, "
6145                                + pkg.applicationInfo.uid + " in settings";
6146                        // writer
6147                        synchronized (mPackages) {
6148                            mSettings.mReadMessages.append(msg);
6149                            mSettings.mReadMessages.append('\n');
6150                            uidError = true;
6151                            if (!pkgSetting.uidError) {
6152                                reportSettingsProblem(Log.ERROR, msg);
6153                            }
6154                        }
6155                    }
6156                }
6157                pkg.applicationInfo.dataDir = dataPath.getPath();
6158                if (mShouldRestoreconData) {
6159                    Slog.i(TAG, "SELinux relabeling of " + pkg.packageName + " issued.");
6160                    mInstaller.restoreconData(pkg.volumeUuid, pkg.packageName,
6161                            pkg.applicationInfo.seinfo, pkg.applicationInfo.uid);
6162                }
6163            } else {
6164                if (DEBUG_PACKAGE_SCANNING) {
6165                    if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
6166                        Log.v(TAG, "Want this data dir: " + dataPath);
6167                }
6168                //invoke installer to do the actual installation
6169                int ret = createDataDirsLI(pkg.volumeUuid, pkgName, pkg.applicationInfo.uid,
6170                        pkg.applicationInfo.seinfo);
6171                if (ret < 0) {
6172                    // Error from installer
6173                    throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE,
6174                            "Unable to create data dirs [errorCode=" + ret + "]");
6175                }
6176
6177                if (dataPath.exists()) {
6178                    pkg.applicationInfo.dataDir = dataPath.getPath();
6179                } else {
6180                    Slog.w(TAG, "Unable to create data directory: " + dataPath);
6181                    pkg.applicationInfo.dataDir = null;
6182                }
6183            }
6184
6185            pkgSetting.uidError = uidError;
6186        }
6187
6188        final String path = scanFile.getPath();
6189        final String codePath = pkg.applicationInfo.getCodePath();
6190        final String cpuAbiOverride = deriveAbiOverride(pkg.cpuAbiOverride, pkgSetting);
6191        if (isSystemApp(pkg) && !pkg.isUpdatedSystemApp()) {
6192            setBundledAppAbisAndRoots(pkg, pkgSetting);
6193
6194            // If we haven't found any native libraries for the app, check if it has
6195            // renderscript code. We'll need to force the app to 32 bit if it has
6196            // renderscript bitcode.
6197            if (pkg.applicationInfo.primaryCpuAbi == null
6198                    && pkg.applicationInfo.secondaryCpuAbi == null
6199                    && Build.SUPPORTED_64_BIT_ABIS.length >  0) {
6200                NativeLibraryHelper.Handle handle = null;
6201                try {
6202                    handle = NativeLibraryHelper.Handle.create(scanFile);
6203                    if (NativeLibraryHelper.hasRenderscriptBitcode(handle)) {
6204                        pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
6205                    }
6206                } catch (IOException ioe) {
6207                    Slog.w(TAG, "Error scanning system app : " + ioe);
6208                } finally {
6209                    IoUtils.closeQuietly(handle);
6210                }
6211            }
6212
6213            setNativeLibraryPaths(pkg);
6214        } else {
6215            // TODO: We can probably be smarter about this stuff. For installed apps,
6216            // we can calculate this information at install time once and for all. For
6217            // system apps, we can probably assume that this information doesn't change
6218            // after the first boot scan. As things stand, we do lots of unnecessary work.
6219
6220            // Give ourselves some initial paths; we'll come back for another
6221            // pass once we've determined ABI below.
6222            setNativeLibraryPaths(pkg);
6223
6224            final boolean isAsec = pkg.isForwardLocked() || isExternal(pkg);
6225            final String nativeLibraryRootStr = pkg.applicationInfo.nativeLibraryRootDir;
6226            final boolean useIsaSpecificSubdirs = pkg.applicationInfo.nativeLibraryRootRequiresIsa;
6227
6228            NativeLibraryHelper.Handle handle = null;
6229            try {
6230                handle = NativeLibraryHelper.Handle.create(scanFile);
6231                // TODO(multiArch): This can be null for apps that didn't go through the
6232                // usual installation process. We can calculate it again, like we
6233                // do during install time.
6234                //
6235                // TODO(multiArch): Why do we need to rescan ASEC apps again ? It seems totally
6236                // unnecessary.
6237                final File nativeLibraryRoot = new File(nativeLibraryRootStr);
6238
6239                // Null out the abis so that they can be recalculated.
6240                pkg.applicationInfo.primaryCpuAbi = null;
6241                pkg.applicationInfo.secondaryCpuAbi = null;
6242                if (isMultiArch(pkg.applicationInfo)) {
6243                    // Warn if we've set an abiOverride for multi-lib packages..
6244                    // By definition, we need to copy both 32 and 64 bit libraries for
6245                    // such packages.
6246                    if (pkg.cpuAbiOverride != null
6247                            && !NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(pkg.cpuAbiOverride)) {
6248                        Slog.w(TAG, "Ignoring abiOverride for multi arch application.");
6249                    }
6250
6251                    int abi32 = PackageManager.NO_NATIVE_LIBRARIES;
6252                    int abi64 = PackageManager.NO_NATIVE_LIBRARIES;
6253                    if (Build.SUPPORTED_32_BIT_ABIS.length > 0) {
6254                        if (isAsec) {
6255                            abi32 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_32_BIT_ABIS);
6256                        } else {
6257                            abi32 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
6258                                    nativeLibraryRoot, Build.SUPPORTED_32_BIT_ABIS,
6259                                    useIsaSpecificSubdirs);
6260                        }
6261                    }
6262
6263                    maybeThrowExceptionForMultiArchCopy(
6264                            "Error unpackaging 32 bit native libs for multiarch app.", abi32);
6265
6266                    if (Build.SUPPORTED_64_BIT_ABIS.length > 0) {
6267                        if (isAsec) {
6268                            abi64 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_64_BIT_ABIS);
6269                        } else {
6270                            abi64 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
6271                                    nativeLibraryRoot, Build.SUPPORTED_64_BIT_ABIS,
6272                                    useIsaSpecificSubdirs);
6273                        }
6274                    }
6275
6276                    maybeThrowExceptionForMultiArchCopy(
6277                            "Error unpackaging 64 bit native libs for multiarch app.", abi64);
6278
6279                    if (abi64 >= 0) {
6280                        pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[abi64];
6281                    }
6282
6283                    if (abi32 >= 0) {
6284                        final String abi = Build.SUPPORTED_32_BIT_ABIS[abi32];
6285                        if (abi64 >= 0) {
6286                            pkg.applicationInfo.secondaryCpuAbi = abi;
6287                        } else {
6288                            pkg.applicationInfo.primaryCpuAbi = abi;
6289                        }
6290                    }
6291                } else {
6292                    String[] abiList = (cpuAbiOverride != null) ?
6293                            new String[] { cpuAbiOverride } : Build.SUPPORTED_ABIS;
6294
6295                    // Enable gross and lame hacks for apps that are built with old
6296                    // SDK tools. We must scan their APKs for renderscript bitcode and
6297                    // not launch them if it's present. Don't bother checking on devices
6298                    // that don't have 64 bit support.
6299                    boolean needsRenderScriptOverride = false;
6300                    if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && cpuAbiOverride == null &&
6301                            NativeLibraryHelper.hasRenderscriptBitcode(handle)) {
6302                        abiList = Build.SUPPORTED_32_BIT_ABIS;
6303                        needsRenderScriptOverride = true;
6304                    }
6305
6306                    final int copyRet;
6307                    if (isAsec) {
6308                        copyRet = NativeLibraryHelper.findSupportedAbi(handle, abiList);
6309                    } else {
6310                        copyRet = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
6311                                nativeLibraryRoot, abiList, useIsaSpecificSubdirs);
6312                    }
6313
6314                    if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) {
6315                        throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
6316                                "Error unpackaging native libs for app, errorCode=" + copyRet);
6317                    }
6318
6319                    if (copyRet >= 0) {
6320                        pkg.applicationInfo.primaryCpuAbi = abiList[copyRet];
6321                    } else if (copyRet == PackageManager.NO_NATIVE_LIBRARIES && cpuAbiOverride != null) {
6322                        pkg.applicationInfo.primaryCpuAbi = cpuAbiOverride;
6323                    } else if (needsRenderScriptOverride) {
6324                        pkg.applicationInfo.primaryCpuAbi = abiList[0];
6325                    }
6326                }
6327            } catch (IOException ioe) {
6328                Slog.e(TAG, "Unable to get canonical file " + ioe.toString());
6329            } finally {
6330                IoUtils.closeQuietly(handle);
6331            }
6332
6333            // Now that we've calculated the ABIs and determined if it's an internal app,
6334            // we will go ahead and populate the nativeLibraryPath.
6335            setNativeLibraryPaths(pkg);
6336
6337            if (DEBUG_INSTALL) Slog.i(TAG, "Linking native library dir for " + path);
6338            final int[] userIds = sUserManager.getUserIds();
6339            synchronized (mInstallLock) {
6340                // Create a native library symlink only if we have native libraries
6341                // and if the native libraries are 32 bit libraries. We do not provide
6342                // this symlink for 64 bit libraries.
6343                if (pkg.applicationInfo.primaryCpuAbi != null &&
6344                        !VMRuntime.is64BitAbi(pkg.applicationInfo.primaryCpuAbi)) {
6345                    final String nativeLibPath = pkg.applicationInfo.nativeLibraryDir;
6346                    for (int userId : userIds) {
6347                        if (mInstaller.linkNativeLibraryDirectory(pkg.volumeUuid, pkg.packageName,
6348                                nativeLibPath, userId) < 0) {
6349                            throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
6350                                    "Failed linking native library dir (user=" + userId + ")");
6351                        }
6352                    }
6353                }
6354            }
6355        }
6356
6357        // This is a special case for the "system" package, where the ABI is
6358        // dictated by the zygote configuration (and init.rc). We should keep track
6359        // of this ABI so that we can deal with "normal" applications that run under
6360        // the same UID correctly.
6361        if (mPlatformPackage == pkg) {
6362            pkg.applicationInfo.primaryCpuAbi = VMRuntime.getRuntime().is64Bit() ?
6363                    Build.SUPPORTED_64_BIT_ABIS[0] : Build.SUPPORTED_32_BIT_ABIS[0];
6364        }
6365
6366        pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
6367        pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
6368        pkgSetting.cpuAbiOverrideString = cpuAbiOverride;
6369        // Copy the derived override back to the parsed package, so that we can
6370        // update the package settings accordingly.
6371        pkg.cpuAbiOverride = cpuAbiOverride;
6372
6373        if (DEBUG_ABI_SELECTION) {
6374            Slog.d(TAG, "Resolved nativeLibraryRoot for " + pkg.applicationInfo.packageName
6375                    + " to root=" + pkg.applicationInfo.nativeLibraryRootDir + ", isa="
6376                    + pkg.applicationInfo.nativeLibraryRootRequiresIsa);
6377        }
6378
6379        // Push the derived path down into PackageSettings so we know what to
6380        // clean up at uninstall time.
6381        pkgSetting.legacyNativeLibraryPathString = pkg.applicationInfo.nativeLibraryRootDir;
6382
6383        if (DEBUG_ABI_SELECTION) {
6384            Log.d(TAG, "Abis for package[" + pkg.packageName + "] are" +
6385                    " primary=" + pkg.applicationInfo.primaryCpuAbi +
6386                    " secondary=" + pkg.applicationInfo.secondaryCpuAbi);
6387        }
6388
6389        if ((scanFlags&SCAN_BOOTING) == 0 && pkgSetting.sharedUser != null) {
6390            // We don't do this here during boot because we can do it all
6391            // at once after scanning all existing packages.
6392            //
6393            // We also do this *before* we perform dexopt on this package, so that
6394            // we can avoid redundant dexopts, and also to make sure we've got the
6395            // code and package path correct.
6396            adjustCpuAbisForSharedUserLPw(pkgSetting.sharedUser.packages,
6397                    pkg, forceDex, (scanFlags & SCAN_DEFER_DEX) != 0);
6398        }
6399
6400        if ((scanFlags & SCAN_NO_DEX) == 0) {
6401            int result = mPackageDexOptimizer.performDexOpt(pkg, null /* instruction sets */,
6402                    forceDex, (scanFlags & SCAN_DEFER_DEX) != 0, false /* inclDependencies */);
6403            if (result == PackageDexOptimizer.DEX_OPT_FAILED) {
6404                throw new PackageManagerException(INSTALL_FAILED_DEXOPT, "scanPackageLI");
6405            }
6406        }
6407        if (mFactoryTest && pkg.requestedPermissions.contains(
6408                android.Manifest.permission.FACTORY_TEST)) {
6409            pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST;
6410        }
6411
6412        ArrayList<PackageParser.Package> clientLibPkgs = null;
6413
6414        // writer
6415        synchronized (mPackages) {
6416            if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
6417                // Only system apps can add new shared libraries.
6418                if (pkg.libraryNames != null) {
6419                    for (int i=0; i<pkg.libraryNames.size(); i++) {
6420                        String name = pkg.libraryNames.get(i);
6421                        boolean allowed = false;
6422                        if (pkg.isUpdatedSystemApp()) {
6423                            // New library entries can only be added through the
6424                            // system image.  This is important to get rid of a lot
6425                            // of nasty edge cases: for example if we allowed a non-
6426                            // system update of the app to add a library, then uninstalling
6427                            // the update would make the library go away, and assumptions
6428                            // we made such as through app install filtering would now
6429                            // have allowed apps on the device which aren't compatible
6430                            // with it.  Better to just have the restriction here, be
6431                            // conservative, and create many fewer cases that can negatively
6432                            // impact the user experience.
6433                            final PackageSetting sysPs = mSettings
6434                                    .getDisabledSystemPkgLPr(pkg.packageName);
6435                            if (sysPs.pkg != null && sysPs.pkg.libraryNames != null) {
6436                                for (int j=0; j<sysPs.pkg.libraryNames.size(); j++) {
6437                                    if (name.equals(sysPs.pkg.libraryNames.get(j))) {
6438                                        allowed = true;
6439                                        allowed = true;
6440                                        break;
6441                                    }
6442                                }
6443                            }
6444                        } else {
6445                            allowed = true;
6446                        }
6447                        if (allowed) {
6448                            if (!mSharedLibraries.containsKey(name)) {
6449                                mSharedLibraries.put(name, new SharedLibraryEntry(null, pkg.packageName));
6450                            } else if (!name.equals(pkg.packageName)) {
6451                                Slog.w(TAG, "Package " + pkg.packageName + " library "
6452                                        + name + " already exists; skipping");
6453                            }
6454                        } else {
6455                            Slog.w(TAG, "Package " + pkg.packageName + " declares lib "
6456                                    + name + " that is not declared on system image; skipping");
6457                        }
6458                    }
6459                    if ((scanFlags&SCAN_BOOTING) == 0) {
6460                        // If we are not booting, we need to update any applications
6461                        // that are clients of our shared library.  If we are booting,
6462                        // this will all be done once the scan is complete.
6463                        clientLibPkgs = updateAllSharedLibrariesLPw(pkg);
6464                    }
6465                }
6466            }
6467        }
6468
6469        // We also need to dexopt any apps that are dependent on this library.  Note that
6470        // if these fail, we should abort the install since installing the library will
6471        // result in some apps being broken.
6472        if (clientLibPkgs != null) {
6473            if ((scanFlags & SCAN_NO_DEX) == 0) {
6474                for (int i = 0; i < clientLibPkgs.size(); i++) {
6475                    PackageParser.Package clientPkg = clientLibPkgs.get(i);
6476                    int result = mPackageDexOptimizer.performDexOpt(clientPkg,
6477                            null /* instruction sets */, forceDex,
6478                            (scanFlags & SCAN_DEFER_DEX) != 0, false);
6479                    if (result == PackageDexOptimizer.DEX_OPT_FAILED) {
6480                        throw new PackageManagerException(INSTALL_FAILED_DEXOPT,
6481                                "scanPackageLI failed to dexopt clientLibPkgs");
6482                    }
6483                }
6484            }
6485        }
6486
6487        // Also need to kill any apps that are dependent on the library.
6488        if (clientLibPkgs != null) {
6489            for (int i=0; i<clientLibPkgs.size(); i++) {
6490                PackageParser.Package clientPkg = clientLibPkgs.get(i);
6491                killApplication(clientPkg.applicationInfo.packageName,
6492                        clientPkg.applicationInfo.uid, "update lib");
6493            }
6494        }
6495
6496        // writer
6497        synchronized (mPackages) {
6498            // We don't expect installation to fail beyond this point
6499
6500            // Add the new setting to mSettings
6501            mSettings.insertPackageSettingLPw(pkgSetting, pkg);
6502            // Add the new setting to mPackages
6503            mPackages.put(pkg.applicationInfo.packageName, pkg);
6504            // Make sure we don't accidentally delete its data.
6505            final Iterator<PackageCleanItem> iter = mSettings.mPackagesToBeCleaned.iterator();
6506            while (iter.hasNext()) {
6507                PackageCleanItem item = iter.next();
6508                if (pkgName.equals(item.packageName)) {
6509                    iter.remove();
6510                }
6511            }
6512
6513            // Take care of first install / last update times.
6514            if (currentTime != 0) {
6515                if (pkgSetting.firstInstallTime == 0) {
6516                    pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = currentTime;
6517                } else if ((scanFlags&SCAN_UPDATE_TIME) != 0) {
6518                    pkgSetting.lastUpdateTime = currentTime;
6519                }
6520            } else if (pkgSetting.firstInstallTime == 0) {
6521                // We need *something*.  Take time time stamp of the file.
6522                pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = scanFileTime;
6523            } else if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) != 0) {
6524                if (scanFileTime != pkgSetting.timeStamp) {
6525                    // A package on the system image has changed; consider this
6526                    // to be an update.
6527                    pkgSetting.lastUpdateTime = scanFileTime;
6528                }
6529            }
6530
6531            // Add the package's KeySets to the global KeySetManagerService
6532            KeySetManagerService ksms = mSettings.mKeySetManagerService;
6533            try {
6534                ksms.addSigningKeySetToPackageLPw(pkg.packageName, pkg.mSigningKeys);
6535                if (pkg.mKeySetMapping != null) {
6536                    ksms.addDefinedKeySetsToPackageLPw(pkg.packageName, pkg.mKeySetMapping);
6537                    if (pkg.mUpgradeKeySets != null) {
6538                        ksms.addUpgradeKeySetsToPackageLPw(pkg.packageName, pkg.mUpgradeKeySets);
6539                    }
6540                }
6541            } catch (NullPointerException e) {
6542                Slog.e(TAG, "Could not add KeySet to " + pkg.packageName, e);
6543            } catch (IllegalArgumentException e) {
6544                Slog.e(TAG, "Could not add KeySet to malformed package" + pkg.packageName, e);
6545            }
6546
6547            int N = pkg.providers.size();
6548            StringBuilder r = null;
6549            int i;
6550            for (i=0; i<N; i++) {
6551                PackageParser.Provider p = pkg.providers.get(i);
6552                p.info.processName = fixProcessName(pkg.applicationInfo.processName,
6553                        p.info.processName, pkg.applicationInfo.uid);
6554                mProviders.addProvider(p);
6555                p.syncable = p.info.isSyncable;
6556                if (p.info.authority != null) {
6557                    String names[] = p.info.authority.split(";");
6558                    p.info.authority = null;
6559                    for (int j = 0; j < names.length; j++) {
6560                        if (j == 1 && p.syncable) {
6561                            // We only want the first authority for a provider to possibly be
6562                            // syncable, so if we already added this provider using a different
6563                            // authority clear the syncable flag. We copy the provider before
6564                            // changing it because the mProviders object contains a reference
6565                            // to a provider that we don't want to change.
6566                            // Only do this for the second authority since the resulting provider
6567                            // object can be the same for all future authorities for this provider.
6568                            p = new PackageParser.Provider(p);
6569                            p.syncable = false;
6570                        }
6571                        if (!mProvidersByAuthority.containsKey(names[j])) {
6572                            mProvidersByAuthority.put(names[j], p);
6573                            if (p.info.authority == null) {
6574                                p.info.authority = names[j];
6575                            } else {
6576                                p.info.authority = p.info.authority + ";" + names[j];
6577                            }
6578                            if (DEBUG_PACKAGE_SCANNING) {
6579                                if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
6580                                    Log.d(TAG, "Registered content provider: " + names[j]
6581                                            + ", className = " + p.info.name + ", isSyncable = "
6582                                            + p.info.isSyncable);
6583                            }
6584                        } else {
6585                            PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
6586                            Slog.w(TAG, "Skipping provider name " + names[j] +
6587                                    " (in package " + pkg.applicationInfo.packageName +
6588                                    "): name already used by "
6589                                    + ((other != null && other.getComponentName() != null)
6590                                            ? other.getComponentName().getPackageName() : "?"));
6591                        }
6592                    }
6593                }
6594                if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
6595                    if (r == null) {
6596                        r = new StringBuilder(256);
6597                    } else {
6598                        r.append(' ');
6599                    }
6600                    r.append(p.info.name);
6601                }
6602            }
6603            if (r != null) {
6604                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Providers: " + r);
6605            }
6606
6607            N = pkg.services.size();
6608            r = null;
6609            for (i=0; i<N; i++) {
6610                PackageParser.Service s = pkg.services.get(i);
6611                s.info.processName = fixProcessName(pkg.applicationInfo.processName,
6612                        s.info.processName, pkg.applicationInfo.uid);
6613                mServices.addService(s);
6614                if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
6615                    if (r == null) {
6616                        r = new StringBuilder(256);
6617                    } else {
6618                        r.append(' ');
6619                    }
6620                    r.append(s.info.name);
6621                }
6622            }
6623            if (r != null) {
6624                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Services: " + r);
6625            }
6626
6627            N = pkg.receivers.size();
6628            r = null;
6629            for (i=0; i<N; i++) {
6630                PackageParser.Activity a = pkg.receivers.get(i);
6631                a.info.processName = fixProcessName(pkg.applicationInfo.processName,
6632                        a.info.processName, pkg.applicationInfo.uid);
6633                mReceivers.addActivity(a, "receiver");
6634                if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
6635                    if (r == null) {
6636                        r = new StringBuilder(256);
6637                    } else {
6638                        r.append(' ');
6639                    }
6640                    r.append(a.info.name);
6641                }
6642            }
6643            if (r != null) {
6644                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Receivers: " + r);
6645            }
6646
6647            N = pkg.activities.size();
6648            r = null;
6649            for (i=0; i<N; i++) {
6650                PackageParser.Activity a = pkg.activities.get(i);
6651                a.info.processName = fixProcessName(pkg.applicationInfo.processName,
6652                        a.info.processName, pkg.applicationInfo.uid);
6653                mActivities.addActivity(a, "activity");
6654                if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
6655                    if (r == null) {
6656                        r = new StringBuilder(256);
6657                    } else {
6658                        r.append(' ');
6659                    }
6660                    r.append(a.info.name);
6661                }
6662            }
6663            if (r != null) {
6664                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Activities: " + r);
6665            }
6666
6667            N = pkg.permissionGroups.size();
6668            r = null;
6669            for (i=0; i<N; i++) {
6670                PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i);
6671                PackageParser.PermissionGroup cur = mPermissionGroups.get(pg.info.name);
6672                if (cur == null) {
6673                    mPermissionGroups.put(pg.info.name, pg);
6674                    if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
6675                        if (r == null) {
6676                            r = new StringBuilder(256);
6677                        } else {
6678                            r.append(' ');
6679                        }
6680                        r.append(pg.info.name);
6681                    }
6682                } else {
6683                    Slog.w(TAG, "Permission group " + pg.info.name + " from package "
6684                            + pg.info.packageName + " ignored: original from "
6685                            + cur.info.packageName);
6686                    if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
6687                        if (r == null) {
6688                            r = new StringBuilder(256);
6689                        } else {
6690                            r.append(' ');
6691                        }
6692                        r.append("DUP:");
6693                        r.append(pg.info.name);
6694                    }
6695                }
6696            }
6697            if (r != null) {
6698                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Permission Groups: " + r);
6699            }
6700
6701            N = pkg.permissions.size();
6702            r = null;
6703            for (i=0; i<N; i++) {
6704                PackageParser.Permission p = pkg.permissions.get(i);
6705
6706                // Now that permission groups have a special meaning, we ignore permission
6707                // groups for legacy apps to prevent unexpected behavior. In particular,
6708                // permissions for one app being granted to someone just becuase they happen
6709                // to be in a group defined by another app (before this had no implications).
6710                if (pkg.applicationInfo.targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1) {
6711                    p.group = mPermissionGroups.get(p.info.group);
6712                    // Warn for a permission in an unknown group.
6713                    if (p.info.group != null && p.group == null) {
6714                        Slog.w(TAG, "Permission " + p.info.name + " from package "
6715                                + p.info.packageName + " in an unknown group " + p.info.group);
6716                    }
6717                }
6718
6719                ArrayMap<String, BasePermission> permissionMap =
6720                        p.tree ? mSettings.mPermissionTrees
6721                                : mSettings.mPermissions;
6722                BasePermission bp = permissionMap.get(p.info.name);
6723
6724                // Allow system apps to redefine non-system permissions
6725                if (bp != null && !Objects.equals(bp.sourcePackage, p.info.packageName)) {
6726                    final boolean currentOwnerIsSystem = (bp.perm != null
6727                            && isSystemApp(bp.perm.owner));
6728                    if (isSystemApp(p.owner)) {
6729                        if (bp.type == BasePermission.TYPE_BUILTIN && bp.perm == null) {
6730                            // It's a built-in permission and no owner, take ownership now
6731                            bp.packageSetting = pkgSetting;
6732                            bp.perm = p;
6733                            bp.uid = pkg.applicationInfo.uid;
6734                            bp.sourcePackage = p.info.packageName;
6735                        } else if (!currentOwnerIsSystem) {
6736                            String msg = "New decl " + p.owner + " of permission  "
6737                                    + p.info.name + " is system; overriding " + bp.sourcePackage;
6738                            reportSettingsProblem(Log.WARN, msg);
6739                            bp = null;
6740                        }
6741                    }
6742                }
6743
6744                if (bp == null) {
6745                    bp = new BasePermission(p.info.name, p.info.packageName,
6746                            BasePermission.TYPE_NORMAL);
6747                    permissionMap.put(p.info.name, bp);
6748                }
6749
6750                if (bp.perm == null) {
6751                    if (bp.sourcePackage == null
6752                            || bp.sourcePackage.equals(p.info.packageName)) {
6753                        BasePermission tree = findPermissionTreeLP(p.info.name);
6754                        if (tree == null
6755                                || tree.sourcePackage.equals(p.info.packageName)) {
6756                            bp.packageSetting = pkgSetting;
6757                            bp.perm = p;
6758                            bp.uid = pkg.applicationInfo.uid;
6759                            bp.sourcePackage = p.info.packageName;
6760                            if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
6761                                if (r == null) {
6762                                    r = new StringBuilder(256);
6763                                } else {
6764                                    r.append(' ');
6765                                }
6766                                r.append(p.info.name);
6767                            }
6768                        } else {
6769                            Slog.w(TAG, "Permission " + p.info.name + " from package "
6770                                    + p.info.packageName + " ignored: base tree "
6771                                    + tree.name + " is from package "
6772                                    + tree.sourcePackage);
6773                        }
6774                    } else {
6775                        Slog.w(TAG, "Permission " + p.info.name + " from package "
6776                                + p.info.packageName + " ignored: original from "
6777                                + bp.sourcePackage);
6778                    }
6779                } else if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
6780                    if (r == null) {
6781                        r = new StringBuilder(256);
6782                    } else {
6783                        r.append(' ');
6784                    }
6785                    r.append("DUP:");
6786                    r.append(p.info.name);
6787                }
6788                if (bp.perm == p) {
6789                    bp.protectionLevel = p.info.protectionLevel;
6790                }
6791            }
6792
6793            if (r != null) {
6794                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Permissions: " + r);
6795            }
6796
6797            N = pkg.instrumentation.size();
6798            r = null;
6799            for (i=0; i<N; i++) {
6800                PackageParser.Instrumentation a = pkg.instrumentation.get(i);
6801                a.info.packageName = pkg.applicationInfo.packageName;
6802                a.info.sourceDir = pkg.applicationInfo.sourceDir;
6803                a.info.publicSourceDir = pkg.applicationInfo.publicSourceDir;
6804                a.info.splitSourceDirs = pkg.applicationInfo.splitSourceDirs;
6805                a.info.splitPublicSourceDirs = pkg.applicationInfo.splitPublicSourceDirs;
6806                a.info.dataDir = pkg.applicationInfo.dataDir;
6807
6808                // TODO: Update instrumentation.nativeLibraryDir as well ? Does it
6809                // need other information about the application, like the ABI and what not ?
6810                a.info.nativeLibraryDir = pkg.applicationInfo.nativeLibraryDir;
6811                mInstrumentation.put(a.getComponentName(), a);
6812                if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
6813                    if (r == null) {
6814                        r = new StringBuilder(256);
6815                    } else {
6816                        r.append(' ');
6817                    }
6818                    r.append(a.info.name);
6819                }
6820            }
6821            if (r != null) {
6822                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Instrumentation: " + r);
6823            }
6824
6825            if (pkg.protectedBroadcasts != null) {
6826                N = pkg.protectedBroadcasts.size();
6827                for (i=0; i<N; i++) {
6828                    mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i));
6829                }
6830            }
6831
6832            pkgSetting.setTimeStamp(scanFileTime);
6833
6834            // Create idmap files for pairs of (packages, overlay packages).
6835            // Note: "android", ie framework-res.apk, is handled by native layers.
6836            if (pkg.mOverlayTarget != null) {
6837                // This is an overlay package.
6838                if (pkg.mOverlayTarget != null && !pkg.mOverlayTarget.equals("android")) {
6839                    if (!mOverlays.containsKey(pkg.mOverlayTarget)) {
6840                        mOverlays.put(pkg.mOverlayTarget,
6841                                new ArrayMap<String, PackageParser.Package>());
6842                    }
6843                    ArrayMap<String, PackageParser.Package> map = mOverlays.get(pkg.mOverlayTarget);
6844                    map.put(pkg.packageName, pkg);
6845                    PackageParser.Package orig = mPackages.get(pkg.mOverlayTarget);
6846                    if (orig != null && !createIdmapForPackagePairLI(orig, pkg)) {
6847                        throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
6848                                "scanPackageLI failed to createIdmap");
6849                    }
6850                }
6851            } else if (mOverlays.containsKey(pkg.packageName) &&
6852                    !pkg.packageName.equals("android")) {
6853                // This is a regular package, with one or more known overlay packages.
6854                createIdmapsForPackageLI(pkg);
6855            }
6856        }
6857
6858        return pkg;
6859    }
6860
6861    /**
6862     * Adjusts ABIs for a set of packages belonging to a shared user so that they all match.
6863     * i.e, so that all packages can be run inside a single process if required.
6864     *
6865     * Optionally, callers can pass in a parsed package via {@code newPackage} in which case
6866     * this function will either try and make the ABI for all packages in {@code packagesForUser}
6867     * match {@code scannedPackage} or will update the ABI of {@code scannedPackage} to match
6868     * the ABI selected for {@code packagesForUser}. This variant is used when installing or
6869     * updating a package that belongs to a shared user.
6870     *
6871     * NOTE: We currently only match for the primary CPU abi string. Matching the secondary
6872     * adds unnecessary complexity.
6873     */
6874    private void adjustCpuAbisForSharedUserLPw(Set<PackageSetting> packagesForUser,
6875            PackageParser.Package scannedPackage, boolean forceDexOpt, boolean deferDexOpt) {
6876        String requiredInstructionSet = null;
6877        if (scannedPackage != null && scannedPackage.applicationInfo.primaryCpuAbi != null) {
6878            requiredInstructionSet = VMRuntime.getInstructionSet(
6879                     scannedPackage.applicationInfo.primaryCpuAbi);
6880        }
6881
6882        PackageSetting requirer = null;
6883        for (PackageSetting ps : packagesForUser) {
6884            // If packagesForUser contains scannedPackage, we skip it. This will happen
6885            // when scannedPackage is an update of an existing package. Without this check,
6886            // we will never be able to change the ABI of any package belonging to a shared
6887            // user, even if it's compatible with other packages.
6888            if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
6889                if (ps.primaryCpuAbiString == null) {
6890                    continue;
6891                }
6892
6893                final String instructionSet = VMRuntime.getInstructionSet(ps.primaryCpuAbiString);
6894                if (requiredInstructionSet != null && !instructionSet.equals(requiredInstructionSet)) {
6895                    // We have a mismatch between instruction sets (say arm vs arm64) warn about
6896                    // this but there's not much we can do.
6897                    String errorMessage = "Instruction set mismatch, "
6898                            + ((requirer == null) ? "[caller]" : requirer)
6899                            + " requires " + requiredInstructionSet + " whereas " + ps
6900                            + " requires " + instructionSet;
6901                    Slog.w(TAG, errorMessage);
6902                }
6903
6904                if (requiredInstructionSet == null) {
6905                    requiredInstructionSet = instructionSet;
6906                    requirer = ps;
6907                }
6908            }
6909        }
6910
6911        if (requiredInstructionSet != null) {
6912            String adjustedAbi;
6913            if (requirer != null) {
6914                // requirer != null implies that either scannedPackage was null or that scannedPackage
6915                // did not require an ABI, in which case we have to adjust scannedPackage to match
6916                // the ABI of the set (which is the same as requirer's ABI)
6917                adjustedAbi = requirer.primaryCpuAbiString;
6918                if (scannedPackage != null) {
6919                    scannedPackage.applicationInfo.primaryCpuAbi = adjustedAbi;
6920                }
6921            } else {
6922                // requirer == null implies that we're updating all ABIs in the set to
6923                // match scannedPackage.
6924                adjustedAbi =  scannedPackage.applicationInfo.primaryCpuAbi;
6925            }
6926
6927            for (PackageSetting ps : packagesForUser) {
6928                if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
6929                    if (ps.primaryCpuAbiString != null) {
6930                        continue;
6931                    }
6932
6933                    ps.primaryCpuAbiString = adjustedAbi;
6934                    if (ps.pkg != null && ps.pkg.applicationInfo != null) {
6935                        ps.pkg.applicationInfo.primaryCpuAbi = adjustedAbi;
6936                        Slog.i(TAG, "Adjusting ABI for : " + ps.name + " to " + adjustedAbi);
6937
6938                        int result = mPackageDexOptimizer.performDexOpt(ps.pkg,
6939                                null /* instruction sets */, forceDexOpt, deferDexOpt, true);
6940                        if (result == PackageDexOptimizer.DEX_OPT_FAILED) {
6941                            ps.primaryCpuAbiString = null;
6942                            ps.pkg.applicationInfo.primaryCpuAbi = null;
6943                            return;
6944                        } else {
6945                            mInstaller.rmdex(ps.codePathString,
6946                                    getDexCodeInstructionSet(getPreferredInstructionSet()));
6947                        }
6948                    }
6949                }
6950            }
6951        }
6952    }
6953
6954    private void setUpCustomResolverActivity(PackageParser.Package pkg) {
6955        synchronized (mPackages) {
6956            mResolverReplaced = true;
6957            // Set up information for custom user intent resolution activity.
6958            mResolveActivity.applicationInfo = pkg.applicationInfo;
6959            mResolveActivity.name = mCustomResolverComponentName.getClassName();
6960            mResolveActivity.packageName = pkg.applicationInfo.packageName;
6961            mResolveActivity.processName = pkg.applicationInfo.packageName;
6962            mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
6963            mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS |
6964                    ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
6965            mResolveActivity.theme = 0;
6966            mResolveActivity.exported = true;
6967            mResolveActivity.enabled = true;
6968            mResolveInfo.activityInfo = mResolveActivity;
6969            mResolveInfo.priority = 0;
6970            mResolveInfo.preferredOrder = 0;
6971            mResolveInfo.match = 0;
6972            mResolveComponentName = mCustomResolverComponentName;
6973            Slog.i(TAG, "Replacing default ResolverActivity with custom activity: " +
6974                    mResolveComponentName);
6975        }
6976    }
6977
6978    private static String calculateBundledApkRoot(final String codePathString) {
6979        final File codePath = new File(codePathString);
6980        final File codeRoot;
6981        if (FileUtils.contains(Environment.getRootDirectory(), codePath)) {
6982            codeRoot = Environment.getRootDirectory();
6983        } else if (FileUtils.contains(Environment.getOemDirectory(), codePath)) {
6984            codeRoot = Environment.getOemDirectory();
6985        } else if (FileUtils.contains(Environment.getVendorDirectory(), codePath)) {
6986            codeRoot = Environment.getVendorDirectory();
6987        } else {
6988            // Unrecognized code path; take its top real segment as the apk root:
6989            // e.g. /something/app/blah.apk => /something
6990            try {
6991                File f = codePath.getCanonicalFile();
6992                File parent = f.getParentFile();    // non-null because codePath is a file
6993                File tmp;
6994                while ((tmp = parent.getParentFile()) != null) {
6995                    f = parent;
6996                    parent = tmp;
6997                }
6998                codeRoot = f;
6999                Slog.w(TAG, "Unrecognized code path "
7000                        + codePath + " - using " + codeRoot);
7001            } catch (IOException e) {
7002                // Can't canonicalize the code path -- shenanigans?
7003                Slog.w(TAG, "Can't canonicalize code path " + codePath);
7004                return Environment.getRootDirectory().getPath();
7005            }
7006        }
7007        return codeRoot.getPath();
7008    }
7009
7010    /**
7011     * Derive and set the location of native libraries for the given package,
7012     * which varies depending on where and how the package was installed.
7013     */
7014    private void setNativeLibraryPaths(PackageParser.Package pkg) {
7015        final ApplicationInfo info = pkg.applicationInfo;
7016        final String codePath = pkg.codePath;
7017        final File codeFile = new File(codePath);
7018        final boolean bundledApp = info.isSystemApp() && !info.isUpdatedSystemApp();
7019        final boolean asecApp = info.isForwardLocked() || isExternal(info);
7020
7021        info.nativeLibraryRootDir = null;
7022        info.nativeLibraryRootRequiresIsa = false;
7023        info.nativeLibraryDir = null;
7024        info.secondaryNativeLibraryDir = null;
7025
7026        if (isApkFile(codeFile)) {
7027            // Monolithic install
7028            if (bundledApp) {
7029                // If "/system/lib64/apkname" exists, assume that is the per-package
7030                // native library directory to use; otherwise use "/system/lib/apkname".
7031                final String apkRoot = calculateBundledApkRoot(info.sourceDir);
7032                final boolean is64Bit = VMRuntime.is64BitInstructionSet(
7033                        getPrimaryInstructionSet(info));
7034
7035                // This is a bundled system app so choose the path based on the ABI.
7036                // if it's a 64 bit abi, use lib64 otherwise use lib32. Note that this
7037                // is just the default path.
7038                final String apkName = deriveCodePathName(codePath);
7039                final String libDir = is64Bit ? LIB64_DIR_NAME : LIB_DIR_NAME;
7040                info.nativeLibraryRootDir = Environment.buildPath(new File(apkRoot), libDir,
7041                        apkName).getAbsolutePath();
7042
7043                if (info.secondaryCpuAbi != null) {
7044                    final String secondaryLibDir = is64Bit ? LIB_DIR_NAME : LIB64_DIR_NAME;
7045                    info.secondaryNativeLibraryDir = Environment.buildPath(new File(apkRoot),
7046                            secondaryLibDir, apkName).getAbsolutePath();
7047                }
7048            } else if (asecApp) {
7049                info.nativeLibraryRootDir = new File(codeFile.getParentFile(), LIB_DIR_NAME)
7050                        .getAbsolutePath();
7051            } else {
7052                final String apkName = deriveCodePathName(codePath);
7053                info.nativeLibraryRootDir = new File(mAppLib32InstallDir, apkName)
7054                        .getAbsolutePath();
7055            }
7056
7057            info.nativeLibraryRootRequiresIsa = false;
7058            info.nativeLibraryDir = info.nativeLibraryRootDir;
7059        } else {
7060            // Cluster install
7061            info.nativeLibraryRootDir = new File(codeFile, LIB_DIR_NAME).getAbsolutePath();
7062            info.nativeLibraryRootRequiresIsa = true;
7063
7064            info.nativeLibraryDir = new File(info.nativeLibraryRootDir,
7065                    getPrimaryInstructionSet(info)).getAbsolutePath();
7066
7067            if (info.secondaryCpuAbi != null) {
7068                info.secondaryNativeLibraryDir = new File(info.nativeLibraryRootDir,
7069                        VMRuntime.getInstructionSet(info.secondaryCpuAbi)).getAbsolutePath();
7070            }
7071        }
7072    }
7073
7074    /**
7075     * Calculate the abis and roots for a bundled app. These can uniquely
7076     * be determined from the contents of the system partition, i.e whether
7077     * it contains 64 or 32 bit shared libraries etc. We do not validate any
7078     * of this information, and instead assume that the system was built
7079     * sensibly.
7080     */
7081    private void setBundledAppAbisAndRoots(PackageParser.Package pkg,
7082                                           PackageSetting pkgSetting) {
7083        final String apkName = deriveCodePathName(pkg.applicationInfo.getCodePath());
7084
7085        // If "/system/lib64/apkname" exists, assume that is the per-package
7086        // native library directory to use; otherwise use "/system/lib/apkname".
7087        final String apkRoot = calculateBundledApkRoot(pkg.applicationInfo.sourceDir);
7088        setBundledAppAbi(pkg, apkRoot, apkName);
7089        // pkgSetting might be null during rescan following uninstall of updates
7090        // to a bundled app, so accommodate that possibility.  The settings in
7091        // that case will be established later from the parsed package.
7092        //
7093        // If the settings aren't null, sync them up with what we've just derived.
7094        // note that apkRoot isn't stored in the package settings.
7095        if (pkgSetting != null) {
7096            pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
7097            pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
7098        }
7099    }
7100
7101    /**
7102     * Deduces the ABI of a bundled app and sets the relevant fields on the
7103     * parsed pkg object.
7104     *
7105     * @param apkRoot the root of the installed apk, something like {@code /system} or {@code /oem}
7106     *        under which system libraries are installed.
7107     * @param apkName the name of the installed package.
7108     */
7109    private static void setBundledAppAbi(PackageParser.Package pkg, String apkRoot, String apkName) {
7110        final File codeFile = new File(pkg.codePath);
7111
7112        final boolean has64BitLibs;
7113        final boolean has32BitLibs;
7114        if (isApkFile(codeFile)) {
7115            // Monolithic install
7116            has64BitLibs = (new File(apkRoot, new File(LIB64_DIR_NAME, apkName).getPath())).exists();
7117            has32BitLibs = (new File(apkRoot, new File(LIB_DIR_NAME, apkName).getPath())).exists();
7118        } else {
7119            // Cluster install
7120            final File rootDir = new File(codeFile, LIB_DIR_NAME);
7121            if (!ArrayUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS)
7122                    && !TextUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS[0])) {
7123                final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_64_BIT_ABIS[0]);
7124                has64BitLibs = (new File(rootDir, isa)).exists();
7125            } else {
7126                has64BitLibs = false;
7127            }
7128            if (!ArrayUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS)
7129                    && !TextUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS[0])) {
7130                final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_32_BIT_ABIS[0]);
7131                has32BitLibs = (new File(rootDir, isa)).exists();
7132            } else {
7133                has32BitLibs = false;
7134            }
7135        }
7136
7137        if (has64BitLibs && !has32BitLibs) {
7138            // The package has 64 bit libs, but not 32 bit libs. Its primary
7139            // ABI should be 64 bit. We can safely assume here that the bundled
7140            // native libraries correspond to the most preferred ABI in the list.
7141
7142            pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
7143            pkg.applicationInfo.secondaryCpuAbi = null;
7144        } else if (has32BitLibs && !has64BitLibs) {
7145            // The package has 32 bit libs but not 64 bit libs. Its primary
7146            // ABI should be 32 bit.
7147
7148            pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
7149            pkg.applicationInfo.secondaryCpuAbi = null;
7150        } else if (has32BitLibs && has64BitLibs) {
7151            // The application has both 64 and 32 bit bundled libraries. We check
7152            // here that the app declares multiArch support, and warn if it doesn't.
7153            //
7154            // We will be lenient here and record both ABIs. The primary will be the
7155            // ABI that's higher on the list, i.e, a device that's configured to prefer
7156            // 64 bit apps will see a 64 bit primary ABI,
7157
7158            if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) == 0) {
7159                Slog.e(TAG, "Package: " + pkg + " has multiple bundled libs, but is not multiarch.");
7160            }
7161
7162            if (VMRuntime.is64BitInstructionSet(getPreferredInstructionSet())) {
7163                pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
7164                pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
7165            } else {
7166                pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
7167                pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
7168            }
7169        } else {
7170            pkg.applicationInfo.primaryCpuAbi = null;
7171            pkg.applicationInfo.secondaryCpuAbi = null;
7172        }
7173    }
7174
7175    private void killApplication(String pkgName, int appId, String reason) {
7176        // Request the ActivityManager to kill the process(only for existing packages)
7177        // so that we do not end up in a confused state while the user is still using the older
7178        // version of the application while the new one gets installed.
7179        IActivityManager am = ActivityManagerNative.getDefault();
7180        if (am != null) {
7181            try {
7182                am.killApplicationWithAppId(pkgName, appId, reason);
7183            } catch (RemoteException e) {
7184            }
7185        }
7186    }
7187
7188    void removePackageLI(PackageSetting ps, boolean chatty) {
7189        if (DEBUG_INSTALL) {
7190            if (chatty)
7191                Log.d(TAG, "Removing package " + ps.name);
7192        }
7193
7194        // writer
7195        synchronized (mPackages) {
7196            mPackages.remove(ps.name);
7197            final PackageParser.Package pkg = ps.pkg;
7198            if (pkg != null) {
7199                cleanPackageDataStructuresLILPw(pkg, chatty);
7200            }
7201        }
7202    }
7203
7204    void removeInstalledPackageLI(PackageParser.Package pkg, boolean chatty) {
7205        if (DEBUG_INSTALL) {
7206            if (chatty)
7207                Log.d(TAG, "Removing package " + pkg.applicationInfo.packageName);
7208        }
7209
7210        // writer
7211        synchronized (mPackages) {
7212            mPackages.remove(pkg.applicationInfo.packageName);
7213            cleanPackageDataStructuresLILPw(pkg, chatty);
7214        }
7215    }
7216
7217    void cleanPackageDataStructuresLILPw(PackageParser.Package pkg, boolean chatty) {
7218        int N = pkg.providers.size();
7219        StringBuilder r = null;
7220        int i;
7221        for (i=0; i<N; i++) {
7222            PackageParser.Provider p = pkg.providers.get(i);
7223            mProviders.removeProvider(p);
7224            if (p.info.authority == null) {
7225
7226                /* There was another ContentProvider with this authority when
7227                 * this app was installed so this authority is null,
7228                 * Ignore it as we don't have to unregister the provider.
7229                 */
7230                continue;
7231            }
7232            String names[] = p.info.authority.split(";");
7233            for (int j = 0; j < names.length; j++) {
7234                if (mProvidersByAuthority.get(names[j]) == p) {
7235                    mProvidersByAuthority.remove(names[j]);
7236                    if (DEBUG_REMOVE) {
7237                        if (chatty)
7238                            Log.d(TAG, "Unregistered content provider: " + names[j]
7239                                    + ", className = " + p.info.name + ", isSyncable = "
7240                                    + p.info.isSyncable);
7241                    }
7242                }
7243            }
7244            if (DEBUG_REMOVE && chatty) {
7245                if (r == null) {
7246                    r = new StringBuilder(256);
7247                } else {
7248                    r.append(' ');
7249                }
7250                r.append(p.info.name);
7251            }
7252        }
7253        if (r != null) {
7254            if (DEBUG_REMOVE) Log.d(TAG, "  Providers: " + r);
7255        }
7256
7257        N = pkg.services.size();
7258        r = null;
7259        for (i=0; i<N; i++) {
7260            PackageParser.Service s = pkg.services.get(i);
7261            mServices.removeService(s);
7262            if (chatty) {
7263                if (r == null) {
7264                    r = new StringBuilder(256);
7265                } else {
7266                    r.append(' ');
7267                }
7268                r.append(s.info.name);
7269            }
7270        }
7271        if (r != null) {
7272            if (DEBUG_REMOVE) Log.d(TAG, "  Services: " + r);
7273        }
7274
7275        N = pkg.receivers.size();
7276        r = null;
7277        for (i=0; i<N; i++) {
7278            PackageParser.Activity a = pkg.receivers.get(i);
7279            mReceivers.removeActivity(a, "receiver");
7280            if (DEBUG_REMOVE && chatty) {
7281                if (r == null) {
7282                    r = new StringBuilder(256);
7283                } else {
7284                    r.append(' ');
7285                }
7286                r.append(a.info.name);
7287            }
7288        }
7289        if (r != null) {
7290            if (DEBUG_REMOVE) Log.d(TAG, "  Receivers: " + r);
7291        }
7292
7293        N = pkg.activities.size();
7294        r = null;
7295        for (i=0; i<N; i++) {
7296            PackageParser.Activity a = pkg.activities.get(i);
7297            mActivities.removeActivity(a, "activity");
7298            if (DEBUG_REMOVE && chatty) {
7299                if (r == null) {
7300                    r = new StringBuilder(256);
7301                } else {
7302                    r.append(' ');
7303                }
7304                r.append(a.info.name);
7305            }
7306        }
7307        if (r != null) {
7308            if (DEBUG_REMOVE) Log.d(TAG, "  Activities: " + r);
7309        }
7310
7311        N = pkg.permissions.size();
7312        r = null;
7313        for (i=0; i<N; i++) {
7314            PackageParser.Permission p = pkg.permissions.get(i);
7315            BasePermission bp = mSettings.mPermissions.get(p.info.name);
7316            if (bp == null) {
7317                bp = mSettings.mPermissionTrees.get(p.info.name);
7318            }
7319            if (bp != null && bp.perm == p) {
7320                bp.perm = null;
7321                if (DEBUG_REMOVE && chatty) {
7322                    if (r == null) {
7323                        r = new StringBuilder(256);
7324                    } else {
7325                        r.append(' ');
7326                    }
7327                    r.append(p.info.name);
7328                }
7329            }
7330            if ((p.info.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
7331                ArraySet<String> appOpPerms = mAppOpPermissionPackages.get(p.info.name);
7332                if (appOpPerms != null) {
7333                    appOpPerms.remove(pkg.packageName);
7334                }
7335            }
7336        }
7337        if (r != null) {
7338            if (DEBUG_REMOVE) Log.d(TAG, "  Permissions: " + r);
7339        }
7340
7341        N = pkg.requestedPermissions.size();
7342        r = null;
7343        for (i=0; i<N; i++) {
7344            String perm = pkg.requestedPermissions.get(i);
7345            BasePermission bp = mSettings.mPermissions.get(perm);
7346            if (bp != null && (bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
7347                ArraySet<String> appOpPerms = mAppOpPermissionPackages.get(perm);
7348                if (appOpPerms != null) {
7349                    appOpPerms.remove(pkg.packageName);
7350                    if (appOpPerms.isEmpty()) {
7351                        mAppOpPermissionPackages.remove(perm);
7352                    }
7353                }
7354            }
7355        }
7356        if (r != null) {
7357            if (DEBUG_REMOVE) Log.d(TAG, "  Permissions: " + r);
7358        }
7359
7360        N = pkg.instrumentation.size();
7361        r = null;
7362        for (i=0; i<N; i++) {
7363            PackageParser.Instrumentation a = pkg.instrumentation.get(i);
7364            mInstrumentation.remove(a.getComponentName());
7365            if (DEBUG_REMOVE && chatty) {
7366                if (r == null) {
7367                    r = new StringBuilder(256);
7368                } else {
7369                    r.append(' ');
7370                }
7371                r.append(a.info.name);
7372            }
7373        }
7374        if (r != null) {
7375            if (DEBUG_REMOVE) Log.d(TAG, "  Instrumentation: " + r);
7376        }
7377
7378        r = null;
7379        if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
7380            // Only system apps can hold shared libraries.
7381            if (pkg.libraryNames != null) {
7382                for (i=0; i<pkg.libraryNames.size(); i++) {
7383                    String name = pkg.libraryNames.get(i);
7384                    SharedLibraryEntry cur = mSharedLibraries.get(name);
7385                    if (cur != null && cur.apk != null && cur.apk.equals(pkg.packageName)) {
7386                        mSharedLibraries.remove(name);
7387                        if (DEBUG_REMOVE && chatty) {
7388                            if (r == null) {
7389                                r = new StringBuilder(256);
7390                            } else {
7391                                r.append(' ');
7392                            }
7393                            r.append(name);
7394                        }
7395                    }
7396                }
7397            }
7398        }
7399        if (r != null) {
7400            if (DEBUG_REMOVE) Log.d(TAG, "  Libraries: " + r);
7401        }
7402    }
7403
7404    private static boolean hasPermission(PackageParser.Package pkgInfo, String perm) {
7405        for (int i=pkgInfo.permissions.size()-1; i>=0; i--) {
7406            if (pkgInfo.permissions.get(i).info.name.equals(perm)) {
7407                return true;
7408            }
7409        }
7410        return false;
7411    }
7412
7413    static final int UPDATE_PERMISSIONS_ALL = 1<<0;
7414    static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1<<1;
7415    static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1<<2;
7416
7417    private void updatePermissionsLPw(String changingPkg,
7418            PackageParser.Package pkgInfo, int flags) {
7419        // Make sure there are no dangling permission trees.
7420        Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator();
7421        while (it.hasNext()) {
7422            final BasePermission bp = it.next();
7423            if (bp.packageSetting == null) {
7424                // We may not yet have parsed the package, so just see if
7425                // we still know about its settings.
7426                bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage);
7427            }
7428            if (bp.packageSetting == null) {
7429                Slog.w(TAG, "Removing dangling permission tree: " + bp.name
7430                        + " from package " + bp.sourcePackage);
7431                it.remove();
7432            } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) {
7433                if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
7434                    Slog.i(TAG, "Removing old permission tree: " + bp.name
7435                            + " from package " + bp.sourcePackage);
7436                    flags |= UPDATE_PERMISSIONS_ALL;
7437                    it.remove();
7438                }
7439            }
7440        }
7441
7442        // Make sure all dynamic permissions have been assigned to a package,
7443        // and make sure there are no dangling permissions.
7444        it = mSettings.mPermissions.values().iterator();
7445        while (it.hasNext()) {
7446            final BasePermission bp = it.next();
7447            if (bp.type == BasePermission.TYPE_DYNAMIC) {
7448                if (DEBUG_SETTINGS) Log.v(TAG, "Dynamic permission: name="
7449                        + bp.name + " pkg=" + bp.sourcePackage
7450                        + " info=" + bp.pendingInfo);
7451                if (bp.packageSetting == null && bp.pendingInfo != null) {
7452                    final BasePermission tree = findPermissionTreeLP(bp.name);
7453                    if (tree != null && tree.perm != null) {
7454                        bp.packageSetting = tree.packageSetting;
7455                        bp.perm = new PackageParser.Permission(tree.perm.owner,
7456                                new PermissionInfo(bp.pendingInfo));
7457                        bp.perm.info.packageName = tree.perm.info.packageName;
7458                        bp.perm.info.name = bp.name;
7459                        bp.uid = tree.uid;
7460                    }
7461                }
7462            }
7463            if (bp.packageSetting == null) {
7464                // We may not yet have parsed the package, so just see if
7465                // we still know about its settings.
7466                bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage);
7467            }
7468            if (bp.packageSetting == null) {
7469                Slog.w(TAG, "Removing dangling permission: " + bp.name
7470                        + " from package " + bp.sourcePackage);
7471                it.remove();
7472            } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) {
7473                if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
7474                    Slog.i(TAG, "Removing old permission: " + bp.name
7475                            + " from package " + bp.sourcePackage);
7476                    flags |= UPDATE_PERMISSIONS_ALL;
7477                    it.remove();
7478                }
7479            }
7480        }
7481
7482        // Now update the permissions for all packages, in particular
7483        // replace the granted permissions of the system packages.
7484        if ((flags&UPDATE_PERMISSIONS_ALL) != 0) {
7485            for (PackageParser.Package pkg : mPackages.values()) {
7486                if (pkg != pkgInfo) {
7487                    grantPermissionsLPw(pkg, (flags&UPDATE_PERMISSIONS_REPLACE_ALL) != 0,
7488                            changingPkg);
7489                }
7490            }
7491        }
7492
7493        if (pkgInfo != null) {
7494            grantPermissionsLPw(pkgInfo, (flags&UPDATE_PERMISSIONS_REPLACE_PKG) != 0, changingPkg);
7495        }
7496    }
7497
7498    private void grantPermissionsLPw(PackageParser.Package pkg, boolean replace,
7499            String packageOfInterest) {
7500        // IMPORTANT: There are two types of permissions: install and runtime.
7501        // Install time permissions are granted when the app is installed to
7502        // all device users and users added in the future. Runtime permissions
7503        // are granted at runtime explicitly to specific users. Normal and signature
7504        // protected permissions are install time permissions. Dangerous permissions
7505        // are install permissions if the app's target SDK is Lollipop MR1 or older,
7506        // otherwise they are runtime permissions. This function does not manage
7507        // runtime permissions except for the case an app targeting Lollipop MR1
7508        // being upgraded to target a newer SDK, in which case dangerous permissions
7509        // are transformed from install time to runtime ones.
7510
7511        final PackageSetting ps = (PackageSetting) pkg.mExtras;
7512        if (ps == null) {
7513            return;
7514        }
7515
7516        PermissionsState permissionsState = ps.getPermissionsState();
7517        PermissionsState origPermissions = permissionsState;
7518
7519        final int[] currentUserIds = UserManagerService.getInstance().getUserIds();
7520
7521        int[] upgradeUserIds = PermissionsState.USERS_NONE;
7522        int[] changedRuntimePermissionUserIds = PermissionsState.USERS_NONE;
7523
7524        boolean changedInstallPermission = false;
7525
7526        if (replace) {
7527            ps.installPermissionsFixed = false;
7528            if (!ps.isSharedUser()) {
7529                origPermissions = new PermissionsState(permissionsState);
7530                permissionsState.reset();
7531            }
7532        }
7533
7534        permissionsState.setGlobalGids(mGlobalGids);
7535
7536        final int N = pkg.requestedPermissions.size();
7537        for (int i=0; i<N; i++) {
7538            final String name = pkg.requestedPermissions.get(i);
7539            final BasePermission bp = mSettings.mPermissions.get(name);
7540
7541            if (DEBUG_INSTALL) {
7542                Log.i(TAG, "Package " + pkg.packageName + " checking " + name + ": " + bp);
7543            }
7544
7545            if (bp == null || bp.packageSetting == null) {
7546                if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) {
7547                    Slog.w(TAG, "Unknown permission " + name
7548                            + " in package " + pkg.packageName);
7549                }
7550                continue;
7551            }
7552
7553            final String perm = bp.name;
7554            boolean allowedSig = false;
7555            int grant = GRANT_DENIED;
7556
7557            // Keep track of app op permissions.
7558            if ((bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
7559                ArraySet<String> pkgs = mAppOpPermissionPackages.get(bp.name);
7560                if (pkgs == null) {
7561                    pkgs = new ArraySet<>();
7562                    mAppOpPermissionPackages.put(bp.name, pkgs);
7563                }
7564                pkgs.add(pkg.packageName);
7565            }
7566
7567            final int level = bp.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE;
7568            switch (level) {
7569                case PermissionInfo.PROTECTION_NORMAL: {
7570                    // For all apps normal permissions are install time ones.
7571                    grant = GRANT_INSTALL;
7572                } break;
7573
7574                case PermissionInfo.PROTECTION_DANGEROUS: {
7575                    if (pkg.applicationInfo.targetSdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1) {
7576                        // For legacy apps dangerous permissions are install time ones.
7577                        grant = GRANT_INSTALL;
7578                    } else if (ps.isSystem()) {
7579                        final int[] updatedUserIds = ps.getPermissionsUpdatedForUserIds();
7580                        if (origPermissions.hasInstallPermission(bp.name)) {
7581                            // If a system app had an install permission, then the app was
7582                            // upgraded and we grant the permissions as runtime to all users.
7583                            grant = GRANT_UPGRADE;
7584                            upgradeUserIds = currentUserIds;
7585                        } else if (!Arrays.equals(updatedUserIds, currentUserIds)) {
7586                            // If users changed since the last permissions update for a
7587                            // system app, we grant the permission as runtime to the new users.
7588                            grant = GRANT_UPGRADE;
7589                            upgradeUserIds = currentUserIds;
7590                            for (int userId : updatedUserIds) {
7591                                upgradeUserIds = ArrayUtils.removeInt(upgradeUserIds, userId);
7592                            }
7593                        } else {
7594                            // Otherwise, we grant the permission as runtime if the app
7595                            // already had it, i.e. we preserve runtime permissions.
7596                            grant = GRANT_RUNTIME;
7597                        }
7598                    } else if (origPermissions.hasInstallPermission(bp.name)) {
7599                        // For legacy apps that became modern, install becomes runtime.
7600                        grant = GRANT_UPGRADE;
7601                        upgradeUserIds = currentUserIds;
7602                    } else if (replace) {
7603                        // For upgraded modern apps keep runtime permissions unchanged.
7604                        grant = GRANT_RUNTIME;
7605                    }
7606                } break;
7607
7608                case PermissionInfo.PROTECTION_SIGNATURE: {
7609                    // For all apps signature permissions are install time ones.
7610                    allowedSig = grantSignaturePermission(perm, pkg, bp, origPermissions);
7611                    if (allowedSig) {
7612                        grant = GRANT_INSTALL;
7613                    }
7614                } break;
7615            }
7616
7617            if (DEBUG_INSTALL) {
7618                Log.i(TAG, "Package " + pkg.packageName + " granting " + perm);
7619            }
7620
7621            if (grant != GRANT_DENIED) {
7622                if (!isSystemApp(ps) && ps.installPermissionsFixed) {
7623                    // If this is an existing, non-system package, then
7624                    // we can't add any new permissions to it.
7625                    if (!allowedSig && !origPermissions.hasInstallPermission(perm)) {
7626                        // Except...  if this is a permission that was added
7627                        // to the platform (note: need to only do this when
7628                        // updating the platform).
7629                        if (!isNewPlatformPermissionForPackage(perm, pkg)) {
7630                            grant = GRANT_DENIED;
7631                        }
7632                    }
7633                }
7634
7635                switch (grant) {
7636                    case GRANT_INSTALL: {
7637                        // Grant an install permission.
7638                        if (permissionsState.grantInstallPermission(bp) !=
7639                                PermissionsState.PERMISSION_OPERATION_FAILURE) {
7640                            changedInstallPermission = true;
7641                        }
7642                    } break;
7643
7644                    case GRANT_RUNTIME: {
7645                        // Grant previously granted runtime permissions.
7646                        for (int userId : UserManagerService.getInstance().getUserIds()) {
7647                            if (origPermissions.hasRuntimePermission(bp.name, userId)) {
7648                                if (permissionsState.grantRuntimePermission(bp, userId) ==
7649                                        PermissionsState.PERMISSION_OPERATION_FAILURE) {
7650                                    // If we cannot put the permission as it was, we have to write.
7651                                    changedRuntimePermissionUserIds = ArrayUtils.appendInt(
7652                                            changedRuntimePermissionUserIds, userId);
7653                                }
7654                            }
7655                        }
7656                    } break;
7657
7658                    case GRANT_UPGRADE: {
7659                        // Grant runtime permissions for a previously held install permission.
7660                        permissionsState.revokeInstallPermission(bp);
7661                        for (int userId : upgradeUserIds) {
7662                            if (permissionsState.grantRuntimePermission(bp, userId) !=
7663                                    PermissionsState.PERMISSION_OPERATION_FAILURE) {
7664                                // If we granted the permission, we have to write.
7665                                changedRuntimePermissionUserIds = ArrayUtils.appendInt(
7666                                        changedRuntimePermissionUserIds, userId);
7667                            }
7668                        }
7669                    } break;
7670
7671                    default: {
7672                        if (packageOfInterest == null
7673                                || packageOfInterest.equals(pkg.packageName)) {
7674                            Slog.w(TAG, "Not granting permission " + perm
7675                                    + " to package " + pkg.packageName
7676                                    + " because it was previously installed without");
7677                        }
7678                    } break;
7679                }
7680            } else {
7681                if (permissionsState.revokeInstallPermission(bp) !=
7682                        PermissionsState.PERMISSION_OPERATION_FAILURE) {
7683                    changedInstallPermission = true;
7684                    Slog.i(TAG, "Un-granting permission " + perm
7685                            + " from package " + pkg.packageName
7686                            + " (protectionLevel=" + bp.protectionLevel
7687                            + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
7688                            + ")");
7689                } else if ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) == 0) {
7690                    // Don't print warning for app op permissions, since it is fine for them
7691                    // not to be granted, there is a UI for the user to decide.
7692                    if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) {
7693                        Slog.w(TAG, "Not granting permission " + perm
7694                                + " to package " + pkg.packageName
7695                                + " (protectionLevel=" + bp.protectionLevel
7696                                + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
7697                                + ")");
7698                    }
7699                }
7700            }
7701        }
7702
7703        if ((changedInstallPermission || replace) && !ps.installPermissionsFixed &&
7704                !isSystemApp(ps) || isUpdatedSystemApp(ps)){
7705            // This is the first that we have heard about this package, so the
7706            // permissions we have now selected are fixed until explicitly
7707            // changed.
7708            ps.installPermissionsFixed = true;
7709        }
7710
7711        ps.setPermissionsUpdatedForUserIds(currentUserIds);
7712
7713        // Persist the runtime permissions state for users with changes.
7714        for (int userId : changedRuntimePermissionUserIds) {
7715            mSettings.writeRuntimePermissionsForUserLPr(userId, true);
7716        }
7717    }
7718
7719    private boolean isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg) {
7720        boolean allowed = false;
7721        final int NP = PackageParser.NEW_PERMISSIONS.length;
7722        for (int ip=0; ip<NP; ip++) {
7723            final PackageParser.NewPermissionInfo npi
7724                    = PackageParser.NEW_PERMISSIONS[ip];
7725            if (npi.name.equals(perm)
7726                    && pkg.applicationInfo.targetSdkVersion < npi.sdkVersion) {
7727                allowed = true;
7728                Log.i(TAG, "Auto-granting " + perm + " to old pkg "
7729                        + pkg.packageName);
7730                break;
7731            }
7732        }
7733        return allowed;
7734    }
7735
7736    private boolean grantSignaturePermission(String perm, PackageParser.Package pkg,
7737            BasePermission bp, PermissionsState origPermissions) {
7738        boolean allowed;
7739        allowed = (compareSignatures(
7740                bp.packageSetting.signatures.mSignatures, pkg.mSignatures)
7741                        == PackageManager.SIGNATURE_MATCH)
7742                || (compareSignatures(mPlatformPackage.mSignatures, pkg.mSignatures)
7743                        == PackageManager.SIGNATURE_MATCH);
7744        if (!allowed && (bp.protectionLevel
7745                & PermissionInfo.PROTECTION_FLAG_SYSTEM) != 0) {
7746            if (isSystemApp(pkg)) {
7747                // For updated system applications, a system permission
7748                // is granted only if it had been defined by the original application.
7749                if (pkg.isUpdatedSystemApp()) {
7750                    final PackageSetting sysPs = mSettings
7751                            .getDisabledSystemPkgLPr(pkg.packageName);
7752                    if (sysPs.getPermissionsState().hasInstallPermission(perm)) {
7753                        // If the original was granted this permission, we take
7754                        // that grant decision as read and propagate it to the
7755                        // update.
7756                        if (sysPs.isPrivileged()) {
7757                            allowed = true;
7758                        }
7759                    } else {
7760                        // The system apk may have been updated with an older
7761                        // version of the one on the data partition, but which
7762                        // granted a new system permission that it didn't have
7763                        // before.  In this case we do want to allow the app to
7764                        // now get the new permission if the ancestral apk is
7765                        // privileged to get it.
7766                        if (sysPs.pkg != null && sysPs.isPrivileged()) {
7767                            for (int j=0;
7768                                    j<sysPs.pkg.requestedPermissions.size(); j++) {
7769                                if (perm.equals(
7770                                        sysPs.pkg.requestedPermissions.get(j))) {
7771                                    allowed = true;
7772                                    break;
7773                                }
7774                            }
7775                        }
7776                    }
7777                } else {
7778                    allowed = isPrivilegedApp(pkg);
7779                }
7780            }
7781        }
7782        if (!allowed && (bp.protectionLevel
7783                & PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0) {
7784            // For development permissions, a development permission
7785            // is granted only if it was already granted.
7786            allowed = origPermissions.hasInstallPermission(perm);
7787        }
7788        return allowed;
7789    }
7790
7791    final class ActivityIntentResolver
7792            extends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo> {
7793        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
7794                boolean defaultOnly, int userId) {
7795            if (!sUserManager.exists(userId)) return null;
7796            mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
7797            return super.queryIntent(intent, resolvedType, defaultOnly, userId);
7798        }
7799
7800        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
7801                int userId) {
7802            if (!sUserManager.exists(userId)) return null;
7803            mFlags = flags;
7804            return super.queryIntent(intent, resolvedType,
7805                    (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId);
7806        }
7807
7808        public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
7809                int flags, ArrayList<PackageParser.Activity> packageActivities, int userId) {
7810            if (!sUserManager.exists(userId)) return null;
7811            if (packageActivities == null) {
7812                return null;
7813            }
7814            mFlags = flags;
7815            final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0;
7816            final int N = packageActivities.size();
7817            ArrayList<PackageParser.ActivityIntentInfo[]> listCut =
7818                new ArrayList<PackageParser.ActivityIntentInfo[]>(N);
7819
7820            ArrayList<PackageParser.ActivityIntentInfo> intentFilters;
7821            for (int i = 0; i < N; ++i) {
7822                intentFilters = packageActivities.get(i).intents;
7823                if (intentFilters != null && intentFilters.size() > 0) {
7824                    PackageParser.ActivityIntentInfo[] array =
7825                            new PackageParser.ActivityIntentInfo[intentFilters.size()];
7826                    intentFilters.toArray(array);
7827                    listCut.add(array);
7828                }
7829            }
7830            return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
7831        }
7832
7833        public final void addActivity(PackageParser.Activity a, String type) {
7834            final boolean systemApp = a.info.applicationInfo.isSystemApp();
7835            mActivities.put(a.getComponentName(), a);
7836            if (DEBUG_SHOW_INFO)
7837                Log.v(
7838                TAG, "  " + type + " " +
7839                (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel : a.info.name) + ":");
7840            if (DEBUG_SHOW_INFO)
7841                Log.v(TAG, "    Class=" + a.info.name);
7842            final int NI = a.intents.size();
7843            for (int j=0; j<NI; j++) {
7844                PackageParser.ActivityIntentInfo intent = a.intents.get(j);
7845                if (!systemApp && intent.getPriority() > 0 && "activity".equals(type)) {
7846                    intent.setPriority(0);
7847                    Log.w(TAG, "Package " + a.info.applicationInfo.packageName + " has activity "
7848                            + a.className + " with priority > 0, forcing to 0");
7849                }
7850                if (DEBUG_SHOW_INFO) {
7851                    Log.v(TAG, "    IntentFilter:");
7852                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
7853                }
7854                if (!intent.debugCheck()) {
7855                    Log.w(TAG, "==> For Activity " + a.info.name);
7856                }
7857                addFilter(intent);
7858            }
7859        }
7860
7861        public final void removeActivity(PackageParser.Activity a, String type) {
7862            mActivities.remove(a.getComponentName());
7863            if (DEBUG_SHOW_INFO) {
7864                Log.v(TAG, "  " + type + " "
7865                        + (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel
7866                                : a.info.name) + ":");
7867                Log.v(TAG, "    Class=" + a.info.name);
7868            }
7869            final int NI = a.intents.size();
7870            for (int j=0; j<NI; j++) {
7871                PackageParser.ActivityIntentInfo intent = a.intents.get(j);
7872                if (DEBUG_SHOW_INFO) {
7873                    Log.v(TAG, "    IntentFilter:");
7874                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
7875                }
7876                removeFilter(intent);
7877            }
7878        }
7879
7880        @Override
7881        protected boolean allowFilterResult(
7882                PackageParser.ActivityIntentInfo filter, List<ResolveInfo> dest) {
7883            ActivityInfo filterAi = filter.activity.info;
7884            for (int i=dest.size()-1; i>=0; i--) {
7885                ActivityInfo destAi = dest.get(i).activityInfo;
7886                if (destAi.name == filterAi.name
7887                        && destAi.packageName == filterAi.packageName) {
7888                    return false;
7889                }
7890            }
7891            return true;
7892        }
7893
7894        @Override
7895        protected ActivityIntentInfo[] newArray(int size) {
7896            return new ActivityIntentInfo[size];
7897        }
7898
7899        @Override
7900        protected boolean isFilterStopped(PackageParser.ActivityIntentInfo filter, int userId) {
7901            if (!sUserManager.exists(userId)) return true;
7902            PackageParser.Package p = filter.activity.owner;
7903            if (p != null) {
7904                PackageSetting ps = (PackageSetting)p.mExtras;
7905                if (ps != null) {
7906                    // System apps are never considered stopped for purposes of
7907                    // filtering, because there may be no way for the user to
7908                    // actually re-launch them.
7909                    return (ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0
7910                            && ps.getStopped(userId);
7911                }
7912            }
7913            return false;
7914        }
7915
7916        @Override
7917        protected boolean isPackageForFilter(String packageName,
7918                PackageParser.ActivityIntentInfo info) {
7919            return packageName.equals(info.activity.owner.packageName);
7920        }
7921
7922        @Override
7923        protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info,
7924                int match, int userId) {
7925            if (!sUserManager.exists(userId)) return null;
7926            if (!mSettings.isEnabledLPr(info.activity.info, mFlags, userId)) {
7927                return null;
7928            }
7929            final PackageParser.Activity activity = info.activity;
7930            if (mSafeMode && (activity.info.applicationInfo.flags
7931                    &ApplicationInfo.FLAG_SYSTEM) == 0) {
7932                return null;
7933            }
7934            PackageSetting ps = (PackageSetting) activity.owner.mExtras;
7935            if (ps == null) {
7936                return null;
7937            }
7938            ActivityInfo ai = PackageParser.generateActivityInfo(activity, mFlags,
7939                    ps.readUserState(userId), userId);
7940            if (ai == null) {
7941                return null;
7942            }
7943            final ResolveInfo res = new ResolveInfo();
7944            res.activityInfo = ai;
7945            if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
7946                res.filter = info;
7947            }
7948            if (info != null) {
7949                res.handleAllWebDataURI = info.handleAllWebDataURI();
7950            }
7951            res.priority = info.getPriority();
7952            res.preferredOrder = activity.owner.mPreferredOrder;
7953            //System.out.println("Result: " + res.activityInfo.className +
7954            //                   " = " + res.priority);
7955            res.match = match;
7956            res.isDefault = info.hasDefault;
7957            res.labelRes = info.labelRes;
7958            res.nonLocalizedLabel = info.nonLocalizedLabel;
7959            if (userNeedsBadging(userId)) {
7960                res.noResourceId = true;
7961            } else {
7962                res.icon = info.icon;
7963            }
7964            res.system = res.activityInfo.applicationInfo.isSystemApp();
7965            return res;
7966        }
7967
7968        @Override
7969        protected void sortResults(List<ResolveInfo> results) {
7970            Collections.sort(results, mResolvePrioritySorter);
7971        }
7972
7973        @Override
7974        protected void dumpFilter(PrintWriter out, String prefix,
7975                PackageParser.ActivityIntentInfo filter) {
7976            out.print(prefix); out.print(
7977                    Integer.toHexString(System.identityHashCode(filter.activity)));
7978                    out.print(' ');
7979                    filter.activity.printComponentShortName(out);
7980                    out.print(" filter ");
7981                    out.println(Integer.toHexString(System.identityHashCode(filter)));
7982        }
7983
7984        @Override
7985        protected Object filterToLabel(PackageParser.ActivityIntentInfo filter) {
7986            return filter.activity;
7987        }
7988
7989        protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
7990            PackageParser.Activity activity = (PackageParser.Activity)label;
7991            out.print(prefix); out.print(
7992                    Integer.toHexString(System.identityHashCode(activity)));
7993                    out.print(' ');
7994                    activity.printComponentShortName(out);
7995            if (count > 1) {
7996                out.print(" ("); out.print(count); out.print(" filters)");
7997            }
7998            out.println();
7999        }
8000
8001//        List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) {
8002//            final Iterator<ResolveInfo> i = resolveInfoList.iterator();
8003//            final List<ResolveInfo> retList = Lists.newArrayList();
8004//            while (i.hasNext()) {
8005//                final ResolveInfo resolveInfo = i.next();
8006//                if (isEnabledLP(resolveInfo.activityInfo)) {
8007//                    retList.add(resolveInfo);
8008//                }
8009//            }
8010//            return retList;
8011//        }
8012
8013        // Keys are String (activity class name), values are Activity.
8014        private final ArrayMap<ComponentName, PackageParser.Activity> mActivities
8015                = new ArrayMap<ComponentName, PackageParser.Activity>();
8016        private int mFlags;
8017    }
8018
8019    private final class ServiceIntentResolver
8020            extends IntentResolver<PackageParser.ServiceIntentInfo, ResolveInfo> {
8021        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
8022                boolean defaultOnly, int userId) {
8023            mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
8024            return super.queryIntent(intent, resolvedType, defaultOnly, userId);
8025        }
8026
8027        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
8028                int userId) {
8029            if (!sUserManager.exists(userId)) return null;
8030            mFlags = flags;
8031            return super.queryIntent(intent, resolvedType,
8032                    (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId);
8033        }
8034
8035        public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
8036                int flags, ArrayList<PackageParser.Service> packageServices, int userId) {
8037            if (!sUserManager.exists(userId)) return null;
8038            if (packageServices == null) {
8039                return null;
8040            }
8041            mFlags = flags;
8042            final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0;
8043            final int N = packageServices.size();
8044            ArrayList<PackageParser.ServiceIntentInfo[]> listCut =
8045                new ArrayList<PackageParser.ServiceIntentInfo[]>(N);
8046
8047            ArrayList<PackageParser.ServiceIntentInfo> intentFilters;
8048            for (int i = 0; i < N; ++i) {
8049                intentFilters = packageServices.get(i).intents;
8050                if (intentFilters != null && intentFilters.size() > 0) {
8051                    PackageParser.ServiceIntentInfo[] array =
8052                            new PackageParser.ServiceIntentInfo[intentFilters.size()];
8053                    intentFilters.toArray(array);
8054                    listCut.add(array);
8055                }
8056            }
8057            return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
8058        }
8059
8060        public final void addService(PackageParser.Service s) {
8061            mServices.put(s.getComponentName(), s);
8062            if (DEBUG_SHOW_INFO) {
8063                Log.v(TAG, "  "
8064                        + (s.info.nonLocalizedLabel != null
8065                        ? s.info.nonLocalizedLabel : s.info.name) + ":");
8066                Log.v(TAG, "    Class=" + s.info.name);
8067            }
8068            final int NI = s.intents.size();
8069            int j;
8070            for (j=0; j<NI; j++) {
8071                PackageParser.ServiceIntentInfo intent = s.intents.get(j);
8072                if (DEBUG_SHOW_INFO) {
8073                    Log.v(TAG, "    IntentFilter:");
8074                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
8075                }
8076                if (!intent.debugCheck()) {
8077                    Log.w(TAG, "==> For Service " + s.info.name);
8078                }
8079                addFilter(intent);
8080            }
8081        }
8082
8083        public final void removeService(PackageParser.Service s) {
8084            mServices.remove(s.getComponentName());
8085            if (DEBUG_SHOW_INFO) {
8086                Log.v(TAG, "  " + (s.info.nonLocalizedLabel != null
8087                        ? s.info.nonLocalizedLabel : s.info.name) + ":");
8088                Log.v(TAG, "    Class=" + s.info.name);
8089            }
8090            final int NI = s.intents.size();
8091            int j;
8092            for (j=0; j<NI; j++) {
8093                PackageParser.ServiceIntentInfo intent = s.intents.get(j);
8094                if (DEBUG_SHOW_INFO) {
8095                    Log.v(TAG, "    IntentFilter:");
8096                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
8097                }
8098                removeFilter(intent);
8099            }
8100        }
8101
8102        @Override
8103        protected boolean allowFilterResult(
8104                PackageParser.ServiceIntentInfo filter, List<ResolveInfo> dest) {
8105            ServiceInfo filterSi = filter.service.info;
8106            for (int i=dest.size()-1; i>=0; i--) {
8107                ServiceInfo destAi = dest.get(i).serviceInfo;
8108                if (destAi.name == filterSi.name
8109                        && destAi.packageName == filterSi.packageName) {
8110                    return false;
8111                }
8112            }
8113            return true;
8114        }
8115
8116        @Override
8117        protected PackageParser.ServiceIntentInfo[] newArray(int size) {
8118            return new PackageParser.ServiceIntentInfo[size];
8119        }
8120
8121        @Override
8122        protected boolean isFilterStopped(PackageParser.ServiceIntentInfo filter, int userId) {
8123            if (!sUserManager.exists(userId)) return true;
8124            PackageParser.Package p = filter.service.owner;
8125            if (p != null) {
8126                PackageSetting ps = (PackageSetting)p.mExtras;
8127                if (ps != null) {
8128                    // System apps are never considered stopped for purposes of
8129                    // filtering, because there may be no way for the user to
8130                    // actually re-launch them.
8131                    return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
8132                            && ps.getStopped(userId);
8133                }
8134            }
8135            return false;
8136        }
8137
8138        @Override
8139        protected boolean isPackageForFilter(String packageName,
8140                PackageParser.ServiceIntentInfo info) {
8141            return packageName.equals(info.service.owner.packageName);
8142        }
8143
8144        @Override
8145        protected ResolveInfo newResult(PackageParser.ServiceIntentInfo filter,
8146                int match, int userId) {
8147            if (!sUserManager.exists(userId)) return null;
8148            final PackageParser.ServiceIntentInfo info = (PackageParser.ServiceIntentInfo)filter;
8149            if (!mSettings.isEnabledLPr(info.service.info, mFlags, userId)) {
8150                return null;
8151            }
8152            final PackageParser.Service service = info.service;
8153            if (mSafeMode && (service.info.applicationInfo.flags
8154                    &ApplicationInfo.FLAG_SYSTEM) == 0) {
8155                return null;
8156            }
8157            PackageSetting ps = (PackageSetting) service.owner.mExtras;
8158            if (ps == null) {
8159                return null;
8160            }
8161            ServiceInfo si = PackageParser.generateServiceInfo(service, mFlags,
8162                    ps.readUserState(userId), userId);
8163            if (si == null) {
8164                return null;
8165            }
8166            final ResolveInfo res = new ResolveInfo();
8167            res.serviceInfo = si;
8168            if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
8169                res.filter = filter;
8170            }
8171            res.priority = info.getPriority();
8172            res.preferredOrder = service.owner.mPreferredOrder;
8173            res.match = match;
8174            res.isDefault = info.hasDefault;
8175            res.labelRes = info.labelRes;
8176            res.nonLocalizedLabel = info.nonLocalizedLabel;
8177            res.icon = info.icon;
8178            res.system = res.serviceInfo.applicationInfo.isSystemApp();
8179            return res;
8180        }
8181
8182        @Override
8183        protected void sortResults(List<ResolveInfo> results) {
8184            Collections.sort(results, mResolvePrioritySorter);
8185        }
8186
8187        @Override
8188        protected void dumpFilter(PrintWriter out, String prefix,
8189                PackageParser.ServiceIntentInfo filter) {
8190            out.print(prefix); out.print(
8191                    Integer.toHexString(System.identityHashCode(filter.service)));
8192                    out.print(' ');
8193                    filter.service.printComponentShortName(out);
8194                    out.print(" filter ");
8195                    out.println(Integer.toHexString(System.identityHashCode(filter)));
8196        }
8197
8198        @Override
8199        protected Object filterToLabel(PackageParser.ServiceIntentInfo filter) {
8200            return filter.service;
8201        }
8202
8203        protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
8204            PackageParser.Service service = (PackageParser.Service)label;
8205            out.print(prefix); out.print(
8206                    Integer.toHexString(System.identityHashCode(service)));
8207                    out.print(' ');
8208                    service.printComponentShortName(out);
8209            if (count > 1) {
8210                out.print(" ("); out.print(count); out.print(" filters)");
8211            }
8212            out.println();
8213        }
8214
8215//        List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) {
8216//            final Iterator<ResolveInfo> i = resolveInfoList.iterator();
8217//            final List<ResolveInfo> retList = Lists.newArrayList();
8218//            while (i.hasNext()) {
8219//                final ResolveInfo resolveInfo = (ResolveInfo) i;
8220//                if (isEnabledLP(resolveInfo.serviceInfo)) {
8221//                    retList.add(resolveInfo);
8222//                }
8223//            }
8224//            return retList;
8225//        }
8226
8227        // Keys are String (activity class name), values are Activity.
8228        private final ArrayMap<ComponentName, PackageParser.Service> mServices
8229                = new ArrayMap<ComponentName, PackageParser.Service>();
8230        private int mFlags;
8231    };
8232
8233    private final class ProviderIntentResolver
8234            extends IntentResolver<PackageParser.ProviderIntentInfo, ResolveInfo> {
8235        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
8236                boolean defaultOnly, int userId) {
8237            mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
8238            return super.queryIntent(intent, resolvedType, defaultOnly, userId);
8239        }
8240
8241        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
8242                int userId) {
8243            if (!sUserManager.exists(userId))
8244                return null;
8245            mFlags = flags;
8246            return super.queryIntent(intent, resolvedType,
8247                    (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId);
8248        }
8249
8250        public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
8251                int flags, ArrayList<PackageParser.Provider> packageProviders, int userId) {
8252            if (!sUserManager.exists(userId))
8253                return null;
8254            if (packageProviders == null) {
8255                return null;
8256            }
8257            mFlags = flags;
8258            final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0;
8259            final int N = packageProviders.size();
8260            ArrayList<PackageParser.ProviderIntentInfo[]> listCut =
8261                    new ArrayList<PackageParser.ProviderIntentInfo[]>(N);
8262
8263            ArrayList<PackageParser.ProviderIntentInfo> intentFilters;
8264            for (int i = 0; i < N; ++i) {
8265                intentFilters = packageProviders.get(i).intents;
8266                if (intentFilters != null && intentFilters.size() > 0) {
8267                    PackageParser.ProviderIntentInfo[] array =
8268                            new PackageParser.ProviderIntentInfo[intentFilters.size()];
8269                    intentFilters.toArray(array);
8270                    listCut.add(array);
8271                }
8272            }
8273            return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
8274        }
8275
8276        public final void addProvider(PackageParser.Provider p) {
8277            if (mProviders.containsKey(p.getComponentName())) {
8278                Slog.w(TAG, "Provider " + p.getComponentName() + " already defined; ignoring");
8279                return;
8280            }
8281
8282            mProviders.put(p.getComponentName(), p);
8283            if (DEBUG_SHOW_INFO) {
8284                Log.v(TAG, "  "
8285                        + (p.info.nonLocalizedLabel != null
8286                                ? p.info.nonLocalizedLabel : p.info.name) + ":");
8287                Log.v(TAG, "    Class=" + p.info.name);
8288            }
8289            final int NI = p.intents.size();
8290            int j;
8291            for (j = 0; j < NI; j++) {
8292                PackageParser.ProviderIntentInfo intent = p.intents.get(j);
8293                if (DEBUG_SHOW_INFO) {
8294                    Log.v(TAG, "    IntentFilter:");
8295                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
8296                }
8297                if (!intent.debugCheck()) {
8298                    Log.w(TAG, "==> For Provider " + p.info.name);
8299                }
8300                addFilter(intent);
8301            }
8302        }
8303
8304        public final void removeProvider(PackageParser.Provider p) {
8305            mProviders.remove(p.getComponentName());
8306            if (DEBUG_SHOW_INFO) {
8307                Log.v(TAG, "  " + (p.info.nonLocalizedLabel != null
8308                        ? p.info.nonLocalizedLabel : p.info.name) + ":");
8309                Log.v(TAG, "    Class=" + p.info.name);
8310            }
8311            final int NI = p.intents.size();
8312            int j;
8313            for (j = 0; j < NI; j++) {
8314                PackageParser.ProviderIntentInfo intent = p.intents.get(j);
8315                if (DEBUG_SHOW_INFO) {
8316                    Log.v(TAG, "    IntentFilter:");
8317                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
8318                }
8319                removeFilter(intent);
8320            }
8321        }
8322
8323        @Override
8324        protected boolean allowFilterResult(
8325                PackageParser.ProviderIntentInfo filter, List<ResolveInfo> dest) {
8326            ProviderInfo filterPi = filter.provider.info;
8327            for (int i = dest.size() - 1; i >= 0; i--) {
8328                ProviderInfo destPi = dest.get(i).providerInfo;
8329                if (destPi.name == filterPi.name
8330                        && destPi.packageName == filterPi.packageName) {
8331                    return false;
8332                }
8333            }
8334            return true;
8335        }
8336
8337        @Override
8338        protected PackageParser.ProviderIntentInfo[] newArray(int size) {
8339            return new PackageParser.ProviderIntentInfo[size];
8340        }
8341
8342        @Override
8343        protected boolean isFilterStopped(PackageParser.ProviderIntentInfo filter, int userId) {
8344            if (!sUserManager.exists(userId))
8345                return true;
8346            PackageParser.Package p = filter.provider.owner;
8347            if (p != null) {
8348                PackageSetting ps = (PackageSetting) p.mExtras;
8349                if (ps != null) {
8350                    // System apps are never considered stopped for purposes of
8351                    // filtering, because there may be no way for the user to
8352                    // actually re-launch them.
8353                    return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
8354                            && ps.getStopped(userId);
8355                }
8356            }
8357            return false;
8358        }
8359
8360        @Override
8361        protected boolean isPackageForFilter(String packageName,
8362                PackageParser.ProviderIntentInfo info) {
8363            return packageName.equals(info.provider.owner.packageName);
8364        }
8365
8366        @Override
8367        protected ResolveInfo newResult(PackageParser.ProviderIntentInfo filter,
8368                int match, int userId) {
8369            if (!sUserManager.exists(userId))
8370                return null;
8371            final PackageParser.ProviderIntentInfo info = filter;
8372            if (!mSettings.isEnabledLPr(info.provider.info, mFlags, userId)) {
8373                return null;
8374            }
8375            final PackageParser.Provider provider = info.provider;
8376            if (mSafeMode && (provider.info.applicationInfo.flags
8377                    & ApplicationInfo.FLAG_SYSTEM) == 0) {
8378                return null;
8379            }
8380            PackageSetting ps = (PackageSetting) provider.owner.mExtras;
8381            if (ps == null) {
8382                return null;
8383            }
8384            ProviderInfo pi = PackageParser.generateProviderInfo(provider, mFlags,
8385                    ps.readUserState(userId), userId);
8386            if (pi == null) {
8387                return null;
8388            }
8389            final ResolveInfo res = new ResolveInfo();
8390            res.providerInfo = pi;
8391            if ((mFlags & PackageManager.GET_RESOLVED_FILTER) != 0) {
8392                res.filter = filter;
8393            }
8394            res.priority = info.getPriority();
8395            res.preferredOrder = provider.owner.mPreferredOrder;
8396            res.match = match;
8397            res.isDefault = info.hasDefault;
8398            res.labelRes = info.labelRes;
8399            res.nonLocalizedLabel = info.nonLocalizedLabel;
8400            res.icon = info.icon;
8401            res.system = res.providerInfo.applicationInfo.isSystemApp();
8402            return res;
8403        }
8404
8405        @Override
8406        protected void sortResults(List<ResolveInfo> results) {
8407            Collections.sort(results, mResolvePrioritySorter);
8408        }
8409
8410        @Override
8411        protected void dumpFilter(PrintWriter out, String prefix,
8412                PackageParser.ProviderIntentInfo filter) {
8413            out.print(prefix);
8414            out.print(
8415                    Integer.toHexString(System.identityHashCode(filter.provider)));
8416            out.print(' ');
8417            filter.provider.printComponentShortName(out);
8418            out.print(" filter ");
8419            out.println(Integer.toHexString(System.identityHashCode(filter)));
8420        }
8421
8422        @Override
8423        protected Object filterToLabel(PackageParser.ProviderIntentInfo filter) {
8424            return filter.provider;
8425        }
8426
8427        protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
8428            PackageParser.Provider provider = (PackageParser.Provider)label;
8429            out.print(prefix); out.print(
8430                    Integer.toHexString(System.identityHashCode(provider)));
8431                    out.print(' ');
8432                    provider.printComponentShortName(out);
8433            if (count > 1) {
8434                out.print(" ("); out.print(count); out.print(" filters)");
8435            }
8436            out.println();
8437        }
8438
8439        private final ArrayMap<ComponentName, PackageParser.Provider> mProviders
8440                = new ArrayMap<ComponentName, PackageParser.Provider>();
8441        private int mFlags;
8442    };
8443
8444    private static final Comparator<ResolveInfo> mResolvePrioritySorter =
8445            new Comparator<ResolveInfo>() {
8446        public int compare(ResolveInfo r1, ResolveInfo r2) {
8447            int v1 = r1.priority;
8448            int v2 = r2.priority;
8449            //System.out.println("Comparing: q1=" + q1 + " q2=" + q2);
8450            if (v1 != v2) {
8451                return (v1 > v2) ? -1 : 1;
8452            }
8453            v1 = r1.preferredOrder;
8454            v2 = r2.preferredOrder;
8455            if (v1 != v2) {
8456                return (v1 > v2) ? -1 : 1;
8457            }
8458            if (r1.isDefault != r2.isDefault) {
8459                return r1.isDefault ? -1 : 1;
8460            }
8461            v1 = r1.match;
8462            v2 = r2.match;
8463            //System.out.println("Comparing: m1=" + m1 + " m2=" + m2);
8464            if (v1 != v2) {
8465                return (v1 > v2) ? -1 : 1;
8466            }
8467            if (r1.system != r2.system) {
8468                return r1.system ? -1 : 1;
8469            }
8470            return 0;
8471        }
8472    };
8473
8474    private static final Comparator<ProviderInfo> mProviderInitOrderSorter =
8475            new Comparator<ProviderInfo>() {
8476        public int compare(ProviderInfo p1, ProviderInfo p2) {
8477            final int v1 = p1.initOrder;
8478            final int v2 = p2.initOrder;
8479            return (v1 > v2) ? -1 : ((v1 < v2) ? 1 : 0);
8480        }
8481    };
8482
8483    final void sendPackageBroadcast(final String action, final String pkg,
8484            final Bundle extras, final String targetPkg, final IIntentReceiver finishedReceiver,
8485            final int[] userIds) {
8486        mHandler.post(new Runnable() {
8487            @Override
8488            public void run() {
8489                try {
8490                    final IActivityManager am = ActivityManagerNative.getDefault();
8491                    if (am == null) return;
8492                    final int[] resolvedUserIds;
8493                    if (userIds == null) {
8494                        resolvedUserIds = am.getRunningUserIds();
8495                    } else {
8496                        resolvedUserIds = userIds;
8497                    }
8498                    for (int id : resolvedUserIds) {
8499                        final Intent intent = new Intent(action,
8500                                pkg != null ? Uri.fromParts("package", pkg, null) : null);
8501                        if (extras != null) {
8502                            intent.putExtras(extras);
8503                        }
8504                        if (targetPkg != null) {
8505                            intent.setPackage(targetPkg);
8506                        }
8507                        // Modify the UID when posting to other users
8508                        int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
8509                        if (uid > 0 && UserHandle.getUserId(uid) != id) {
8510                            uid = UserHandle.getUid(id, UserHandle.getAppId(uid));
8511                            intent.putExtra(Intent.EXTRA_UID, uid);
8512                        }
8513                        intent.putExtra(Intent.EXTRA_USER_HANDLE, id);
8514                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
8515                        if (DEBUG_BROADCASTS) {
8516                            RuntimeException here = new RuntimeException("here");
8517                            here.fillInStackTrace();
8518                            Slog.d(TAG, "Sending to user " + id + ": "
8519                                    + intent.toShortString(false, true, false, false)
8520                                    + " " + intent.getExtras(), here);
8521                        }
8522                        am.broadcastIntent(null, intent, null, finishedReceiver,
8523                                0, null, null, null, android.app.AppOpsManager.OP_NONE,
8524                                finishedReceiver != null, false, id);
8525                    }
8526                } catch (RemoteException ex) {
8527                }
8528            }
8529        });
8530    }
8531
8532    /**
8533     * Check if the external storage media is available. This is true if there
8534     * is a mounted external storage medium or if the external storage is
8535     * emulated.
8536     */
8537    private boolean isExternalMediaAvailable() {
8538        return mMediaMounted || Environment.isExternalStorageEmulated();
8539    }
8540
8541    @Override
8542    public PackageCleanItem nextPackageToClean(PackageCleanItem lastPackage) {
8543        // writer
8544        synchronized (mPackages) {
8545            if (!isExternalMediaAvailable()) {
8546                // If the external storage is no longer mounted at this point,
8547                // the caller may not have been able to delete all of this
8548                // packages files and can not delete any more.  Bail.
8549                return null;
8550            }
8551            final ArrayList<PackageCleanItem> pkgs = mSettings.mPackagesToBeCleaned;
8552            if (lastPackage != null) {
8553                pkgs.remove(lastPackage);
8554            }
8555            if (pkgs.size() > 0) {
8556                return pkgs.get(0);
8557            }
8558        }
8559        return null;
8560    }
8561
8562    void schedulePackageCleaning(String packageName, int userId, boolean andCode) {
8563        final Message msg = mHandler.obtainMessage(START_CLEANING_PACKAGE,
8564                userId, andCode ? 1 : 0, packageName);
8565        if (mSystemReady) {
8566            msg.sendToTarget();
8567        } else {
8568            if (mPostSystemReadyMessages == null) {
8569                mPostSystemReadyMessages = new ArrayList<>();
8570            }
8571            mPostSystemReadyMessages.add(msg);
8572        }
8573    }
8574
8575    void startCleaningPackages() {
8576        // reader
8577        synchronized (mPackages) {
8578            if (!isExternalMediaAvailable()) {
8579                return;
8580            }
8581            if (mSettings.mPackagesToBeCleaned.isEmpty()) {
8582                return;
8583            }
8584        }
8585        Intent intent = new Intent(PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE);
8586        intent.setComponent(DEFAULT_CONTAINER_COMPONENT);
8587        IActivityManager am = ActivityManagerNative.getDefault();
8588        if (am != null) {
8589            try {
8590                am.startService(null, intent, null, UserHandle.USER_OWNER);
8591            } catch (RemoteException e) {
8592            }
8593        }
8594    }
8595
8596    @Override
8597    public void installPackage(String originPath, IPackageInstallObserver2 observer,
8598            int installFlags, String installerPackageName, VerificationParams verificationParams,
8599            String packageAbiOverride) {
8600        installPackageAsUser(originPath, observer, installFlags, installerPackageName,
8601                verificationParams, packageAbiOverride, UserHandle.getCallingUserId());
8602    }
8603
8604    @Override
8605    public void installPackageAsUser(String originPath, IPackageInstallObserver2 observer,
8606            int installFlags, String installerPackageName, VerificationParams verificationParams,
8607            String packageAbiOverride, int userId) {
8608        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null);
8609
8610        final int callingUid = Binder.getCallingUid();
8611        enforceCrossUserPermission(callingUid, userId, true, true, "installPackageAsUser");
8612
8613        if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
8614            try {
8615                if (observer != null) {
8616                    observer.onPackageInstalled("", INSTALL_FAILED_USER_RESTRICTED, null, null);
8617                }
8618            } catch (RemoteException re) {
8619            }
8620            return;
8621        }
8622
8623        if ((callingUid == Process.SHELL_UID) || (callingUid == Process.ROOT_UID)) {
8624            installFlags |= PackageManager.INSTALL_FROM_ADB;
8625
8626        } else {
8627            // Caller holds INSTALL_PACKAGES permission, so we're less strict
8628            // about installerPackageName.
8629
8630            installFlags &= ~PackageManager.INSTALL_FROM_ADB;
8631            installFlags &= ~PackageManager.INSTALL_ALL_USERS;
8632        }
8633
8634        UserHandle user;
8635        if ((installFlags & PackageManager.INSTALL_ALL_USERS) != 0) {
8636            user = UserHandle.ALL;
8637        } else {
8638            user = new UserHandle(userId);
8639        }
8640
8641        // Only system components can circumvent runtime permissions when installing.
8642        if ((installFlags & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0
8643                && mContext.checkCallingOrSelfPermission(Manifest.permission
8644                .INSTALL_GRANT_RUNTIME_PERMISSIONS) == PackageManager.PERMISSION_DENIED) {
8645            throw new SecurityException("You need the "
8646                    + "android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS permission "
8647                    + "to use the PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS flag");
8648        }
8649
8650        verificationParams.setInstallerUid(callingUid);
8651
8652        final File originFile = new File(originPath);
8653        final OriginInfo origin = OriginInfo.fromUntrustedFile(originFile);
8654
8655        final Message msg = mHandler.obtainMessage(INIT_COPY);
8656        msg.obj = new InstallParams(origin, null, observer, installFlags, installerPackageName,
8657                null, verificationParams, user, packageAbiOverride);
8658        mHandler.sendMessage(msg);
8659    }
8660
8661    void installStage(String packageName, File stagedDir, String stagedCid,
8662            IPackageInstallObserver2 observer, PackageInstaller.SessionParams params,
8663            String installerPackageName, int installerUid, UserHandle user) {
8664        final VerificationParams verifParams = new VerificationParams(null, params.originatingUri,
8665                params.referrerUri, installerUid, null);
8666
8667        final OriginInfo origin;
8668        if (stagedDir != null) {
8669            origin = OriginInfo.fromStagedFile(stagedDir);
8670        } else {
8671            origin = OriginInfo.fromStagedContainer(stagedCid);
8672        }
8673
8674        final Message msg = mHandler.obtainMessage(INIT_COPY);
8675        msg.obj = new InstallParams(origin, null, observer, params.installFlags,
8676                installerPackageName, params.volumeUuid, verifParams, user, params.abiOverride);
8677        mHandler.sendMessage(msg);
8678    }
8679
8680    private void sendPackageAddedForUser(String packageName, PackageSetting pkgSetting, int userId) {
8681        Bundle extras = new Bundle(1);
8682        extras.putInt(Intent.EXTRA_UID, UserHandle.getUid(userId, pkgSetting.appId));
8683
8684        sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
8685                packageName, extras, null, null, new int[] {userId});
8686        try {
8687            IActivityManager am = ActivityManagerNative.getDefault();
8688            final boolean isSystem =
8689                    isSystemApp(pkgSetting) || isUpdatedSystemApp(pkgSetting);
8690            if (isSystem && am.isUserRunning(userId, false)) {
8691                // The just-installed/enabled app is bundled on the system, so presumed
8692                // to be able to run automatically without needing an explicit launch.
8693                // Send it a BOOT_COMPLETED if it would ordinarily have gotten one.
8694                Intent bcIntent = new Intent(Intent.ACTION_BOOT_COMPLETED)
8695                        .addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES)
8696                        .setPackage(packageName);
8697                am.broadcastIntent(null, bcIntent, null, null, 0, null, null, null,
8698                        android.app.AppOpsManager.OP_NONE, false, false, userId);
8699            }
8700        } catch (RemoteException e) {
8701            // shouldn't happen
8702            Slog.w(TAG, "Unable to bootstrap installed package", e);
8703        }
8704    }
8705
8706    @Override
8707    public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden,
8708            int userId) {
8709        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
8710        PackageSetting pkgSetting;
8711        final int uid = Binder.getCallingUid();
8712        enforceCrossUserPermission(uid, userId, true, true,
8713                "setApplicationHiddenSetting for user " + userId);
8714
8715        if (hidden && isPackageDeviceAdmin(packageName, userId)) {
8716            Slog.w(TAG, "Not hiding package " + packageName + ": has active device admin");
8717            return false;
8718        }
8719
8720        long callingId = Binder.clearCallingIdentity();
8721        try {
8722            boolean sendAdded = false;
8723            boolean sendRemoved = false;
8724            // writer
8725            synchronized (mPackages) {
8726                pkgSetting = mSettings.mPackages.get(packageName);
8727                if (pkgSetting == null) {
8728                    return false;
8729                }
8730                if (pkgSetting.getHidden(userId) != hidden) {
8731                    pkgSetting.setHidden(hidden, userId);
8732                    mSettings.writePackageRestrictionsLPr(userId);
8733                    if (hidden) {
8734                        sendRemoved = true;
8735                    } else {
8736                        sendAdded = true;
8737                    }
8738                }
8739            }
8740            if (sendAdded) {
8741                sendPackageAddedForUser(packageName, pkgSetting, userId);
8742                return true;
8743            }
8744            if (sendRemoved) {
8745                killApplication(packageName, UserHandle.getUid(userId, pkgSetting.appId),
8746                        "hiding pkg");
8747                sendApplicationHiddenForUser(packageName, pkgSetting, userId);
8748            }
8749        } finally {
8750            Binder.restoreCallingIdentity(callingId);
8751        }
8752        return false;
8753    }
8754
8755    private void sendApplicationHiddenForUser(String packageName, PackageSetting pkgSetting,
8756            int userId) {
8757        final PackageRemovedInfo info = new PackageRemovedInfo();
8758        info.removedPackage = packageName;
8759        info.removedUsers = new int[] {userId};
8760        info.uid = UserHandle.getUid(userId, pkgSetting.appId);
8761        info.sendBroadcast(false, false, false);
8762    }
8763
8764    /**
8765     * Returns true if application is not found or there was an error. Otherwise it returns
8766     * the hidden state of the package for the given user.
8767     */
8768    @Override
8769    public boolean getApplicationHiddenSettingAsUser(String packageName, int userId) {
8770        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
8771        enforceCrossUserPermission(Binder.getCallingUid(), userId, true,
8772                false, "getApplicationHidden for user " + userId);
8773        PackageSetting pkgSetting;
8774        long callingId = Binder.clearCallingIdentity();
8775        try {
8776            // writer
8777            synchronized (mPackages) {
8778                pkgSetting = mSettings.mPackages.get(packageName);
8779                if (pkgSetting == null) {
8780                    return true;
8781                }
8782                return pkgSetting.getHidden(userId);
8783            }
8784        } finally {
8785            Binder.restoreCallingIdentity(callingId);
8786        }
8787    }
8788
8789    /**
8790     * @hide
8791     */
8792    @Override
8793    public int installExistingPackageAsUser(String packageName, int userId) {
8794        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES,
8795                null);
8796        PackageSetting pkgSetting;
8797        final int uid = Binder.getCallingUid();
8798        enforceCrossUserPermission(uid, userId, true, true, "installExistingPackage for user "
8799                + userId);
8800        if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
8801            return PackageManager.INSTALL_FAILED_USER_RESTRICTED;
8802        }
8803
8804        long callingId = Binder.clearCallingIdentity();
8805        try {
8806            boolean sendAdded = false;
8807
8808            // writer
8809            synchronized (mPackages) {
8810                pkgSetting = mSettings.mPackages.get(packageName);
8811                if (pkgSetting == null) {
8812                    return PackageManager.INSTALL_FAILED_INVALID_URI;
8813                }
8814                if (!pkgSetting.getInstalled(userId)) {
8815                    pkgSetting.setInstalled(true, userId);
8816                    pkgSetting.setHidden(false, userId);
8817                    mSettings.writePackageRestrictionsLPr(userId);
8818                    sendAdded = true;
8819                }
8820            }
8821
8822            if (sendAdded) {
8823                sendPackageAddedForUser(packageName, pkgSetting, userId);
8824            }
8825        } finally {
8826            Binder.restoreCallingIdentity(callingId);
8827        }
8828
8829        return PackageManager.INSTALL_SUCCEEDED;
8830    }
8831
8832    boolean isUserRestricted(int userId, String restrictionKey) {
8833        Bundle restrictions = sUserManager.getUserRestrictions(userId);
8834        if (restrictions.getBoolean(restrictionKey, false)) {
8835            Log.w(TAG, "User is restricted: " + restrictionKey);
8836            return true;
8837        }
8838        return false;
8839    }
8840
8841    @Override
8842    public void verifyPendingInstall(int id, int verificationCode) throws RemoteException {
8843        mContext.enforceCallingOrSelfPermission(
8844                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
8845                "Only package verification agents can verify applications");
8846
8847        final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
8848        final PackageVerificationResponse response = new PackageVerificationResponse(
8849                verificationCode, Binder.getCallingUid());
8850        msg.arg1 = id;
8851        msg.obj = response;
8852        mHandler.sendMessage(msg);
8853    }
8854
8855    @Override
8856    public void extendVerificationTimeout(int id, int verificationCodeAtTimeout,
8857            long millisecondsToDelay) {
8858        mContext.enforceCallingOrSelfPermission(
8859                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
8860                "Only package verification agents can extend verification timeouts");
8861
8862        final PackageVerificationState state = mPendingVerification.get(id);
8863        final PackageVerificationResponse response = new PackageVerificationResponse(
8864                verificationCodeAtTimeout, Binder.getCallingUid());
8865
8866        if (millisecondsToDelay > PackageManager.MAXIMUM_VERIFICATION_TIMEOUT) {
8867            millisecondsToDelay = PackageManager.MAXIMUM_VERIFICATION_TIMEOUT;
8868        }
8869        if (millisecondsToDelay < 0) {
8870            millisecondsToDelay = 0;
8871        }
8872        if ((verificationCodeAtTimeout != PackageManager.VERIFICATION_ALLOW)
8873                && (verificationCodeAtTimeout != PackageManager.VERIFICATION_REJECT)) {
8874            verificationCodeAtTimeout = PackageManager.VERIFICATION_REJECT;
8875        }
8876
8877        if ((state != null) && !state.timeoutExtended()) {
8878            state.extendTimeout();
8879
8880            final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
8881            msg.arg1 = id;
8882            msg.obj = response;
8883            mHandler.sendMessageDelayed(msg, millisecondsToDelay);
8884        }
8885    }
8886
8887    private void broadcastPackageVerified(int verificationId, Uri packageUri,
8888            int verificationCode, UserHandle user) {
8889        final Intent intent = new Intent(Intent.ACTION_PACKAGE_VERIFIED);
8890        intent.setDataAndType(packageUri, PACKAGE_MIME_TYPE);
8891        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
8892        intent.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
8893        intent.putExtra(PackageManager.EXTRA_VERIFICATION_RESULT, verificationCode);
8894
8895        mContext.sendBroadcastAsUser(intent, user,
8896                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT);
8897    }
8898
8899    private ComponentName matchComponentForVerifier(String packageName,
8900            List<ResolveInfo> receivers) {
8901        ActivityInfo targetReceiver = null;
8902
8903        final int NR = receivers.size();
8904        for (int i = 0; i < NR; i++) {
8905            final ResolveInfo info = receivers.get(i);
8906            if (info.activityInfo == null) {
8907                continue;
8908            }
8909
8910            if (packageName.equals(info.activityInfo.packageName)) {
8911                targetReceiver = info.activityInfo;
8912                break;
8913            }
8914        }
8915
8916        if (targetReceiver == null) {
8917            return null;
8918        }
8919
8920        return new ComponentName(targetReceiver.packageName, targetReceiver.name);
8921    }
8922
8923    private List<ComponentName> matchVerifiers(PackageInfoLite pkgInfo,
8924            List<ResolveInfo> receivers, final PackageVerificationState verificationState) {
8925        if (pkgInfo.verifiers.length == 0) {
8926            return null;
8927        }
8928
8929        final int N = pkgInfo.verifiers.length;
8930        final List<ComponentName> sufficientVerifiers = new ArrayList<ComponentName>(N + 1);
8931        for (int i = 0; i < N; i++) {
8932            final VerifierInfo verifierInfo = pkgInfo.verifiers[i];
8933
8934            final ComponentName comp = matchComponentForVerifier(verifierInfo.packageName,
8935                    receivers);
8936            if (comp == null) {
8937                continue;
8938            }
8939
8940            final int verifierUid = getUidForVerifier(verifierInfo);
8941            if (verifierUid == -1) {
8942                continue;
8943            }
8944
8945            if (DEBUG_VERIFY) {
8946                Slog.d(TAG, "Added sufficient verifier " + verifierInfo.packageName
8947                        + " with the correct signature");
8948            }
8949            sufficientVerifiers.add(comp);
8950            verificationState.addSufficientVerifier(verifierUid);
8951        }
8952
8953        return sufficientVerifiers;
8954    }
8955
8956    private int getUidForVerifier(VerifierInfo verifierInfo) {
8957        synchronized (mPackages) {
8958            final PackageParser.Package pkg = mPackages.get(verifierInfo.packageName);
8959            if (pkg == null) {
8960                return -1;
8961            } else if (pkg.mSignatures.length != 1) {
8962                Slog.i(TAG, "Verifier package " + verifierInfo.packageName
8963                        + " has more than one signature; ignoring");
8964                return -1;
8965            }
8966
8967            /*
8968             * If the public key of the package's signature does not match
8969             * our expected public key, then this is a different package and
8970             * we should skip.
8971             */
8972
8973            final byte[] expectedPublicKey;
8974            try {
8975                final Signature verifierSig = pkg.mSignatures[0];
8976                final PublicKey publicKey = verifierSig.getPublicKey();
8977                expectedPublicKey = publicKey.getEncoded();
8978            } catch (CertificateException e) {
8979                return -1;
8980            }
8981
8982            final byte[] actualPublicKey = verifierInfo.publicKey.getEncoded();
8983
8984            if (!Arrays.equals(actualPublicKey, expectedPublicKey)) {
8985                Slog.i(TAG, "Verifier package " + verifierInfo.packageName
8986                        + " does not have the expected public key; ignoring");
8987                return -1;
8988            }
8989
8990            return pkg.applicationInfo.uid;
8991        }
8992    }
8993
8994    @Override
8995    public void finishPackageInstall(int token) {
8996        enforceSystemOrRoot("Only the system is allowed to finish installs");
8997
8998        if (DEBUG_INSTALL) {
8999            Slog.v(TAG, "BM finishing package install for " + token);
9000        }
9001
9002        final Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0);
9003        mHandler.sendMessage(msg);
9004    }
9005
9006    /**
9007     * Get the verification agent timeout.
9008     *
9009     * @return verification timeout in milliseconds
9010     */
9011    private long getVerificationTimeout() {
9012        return android.provider.Settings.Global.getLong(mContext.getContentResolver(),
9013                android.provider.Settings.Global.PACKAGE_VERIFIER_TIMEOUT,
9014                DEFAULT_VERIFICATION_TIMEOUT);
9015    }
9016
9017    /**
9018     * Get the default verification agent response code.
9019     *
9020     * @return default verification response code
9021     */
9022    private int getDefaultVerificationResponse() {
9023        return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
9024                android.provider.Settings.Global.PACKAGE_VERIFIER_DEFAULT_RESPONSE,
9025                DEFAULT_VERIFICATION_RESPONSE);
9026    }
9027
9028    /**
9029     * Check whether or not package verification has been enabled.
9030     *
9031     * @return true if verification should be performed
9032     */
9033    private boolean isVerificationEnabled(int userId, int installFlags) {
9034        if (!DEFAULT_VERIFY_ENABLE) {
9035            return false;
9036        }
9037
9038        boolean ensureVerifyAppsEnabled = isUserRestricted(userId, UserManager.ENSURE_VERIFY_APPS);
9039
9040        // Check if installing from ADB
9041        if ((installFlags & PackageManager.INSTALL_FROM_ADB) != 0) {
9042            // Do not run verification in a test harness environment
9043            if (ActivityManager.isRunningInTestHarness()) {
9044                return false;
9045            }
9046            if (ensureVerifyAppsEnabled) {
9047                return true;
9048            }
9049            // Check if the developer does not want package verification for ADB installs
9050            if (android.provider.Settings.Global.getInt(mContext.getContentResolver(),
9051                    android.provider.Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, 1) == 0) {
9052                return false;
9053            }
9054        }
9055
9056        if (ensureVerifyAppsEnabled) {
9057            return true;
9058        }
9059
9060        return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
9061                android.provider.Settings.Global.PACKAGE_VERIFIER_ENABLE, 1) == 1;
9062    }
9063
9064    @Override
9065    public void verifyIntentFilter(int id, int verificationCode, List<String> failedDomains)
9066            throws RemoteException {
9067        mContext.enforceCallingOrSelfPermission(
9068                Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT,
9069                "Only intentfilter verification agents can verify applications");
9070
9071        final Message msg = mHandler.obtainMessage(INTENT_FILTER_VERIFIED);
9072        final IntentFilterVerificationResponse response = new IntentFilterVerificationResponse(
9073                Binder.getCallingUid(), verificationCode, failedDomains);
9074        msg.arg1 = id;
9075        msg.obj = response;
9076        mHandler.sendMessage(msg);
9077    }
9078
9079    @Override
9080    public int getIntentVerificationStatus(String packageName, int userId) {
9081        synchronized (mPackages) {
9082            return mSettings.getIntentFilterVerificationStatusLPr(packageName, userId);
9083        }
9084    }
9085
9086    @Override
9087    public boolean updateIntentVerificationStatus(String packageName, int status, int userId) {
9088        boolean result = false;
9089        synchronized (mPackages) {
9090            result = mSettings.updateIntentFilterVerificationStatusLPw(packageName, status, userId);
9091        }
9092        scheduleWritePackageRestrictionsLocked(userId);
9093        return result;
9094    }
9095
9096    @Override
9097    public List<IntentFilterVerificationInfo> getIntentFilterVerifications(String packageName) {
9098        synchronized (mPackages) {
9099            return mSettings.getIntentFilterVerificationsLPr(packageName);
9100        }
9101    }
9102
9103    @Override
9104    public List<IntentFilter> getAllIntentFilters(String packageName) {
9105        if (TextUtils.isEmpty(packageName)) {
9106            return Collections.<IntentFilter>emptyList();
9107        }
9108        synchronized (mPackages) {
9109            PackageParser.Package pkg = mPackages.get(packageName);
9110            if (pkg == null || pkg.activities == null) {
9111                return Collections.<IntentFilter>emptyList();
9112            }
9113            final int count = pkg.activities.size();
9114            ArrayList<IntentFilter> result = new ArrayList<>();
9115            for (int n=0; n<count; n++) {
9116                PackageParser.Activity activity = pkg.activities.get(n);
9117                if (activity.intents != null || activity.intents.size() > 0) {
9118                    result.addAll(activity.intents);
9119                }
9120            }
9121            return result;
9122        }
9123    }
9124
9125    @Override
9126    public boolean setDefaultBrowserPackageName(String packageName, int userId) {
9127        synchronized (mPackages) {
9128            return mSettings.setDefaultBrowserPackageNameLPr(packageName, userId);
9129        }
9130    }
9131
9132    @Override
9133    public String getDefaultBrowserPackageName(int userId) {
9134        synchronized (mPackages) {
9135            return mSettings.getDefaultBrowserPackageNameLPw(userId);
9136        }
9137    }
9138
9139    /**
9140     * Get the "allow unknown sources" setting.
9141     *
9142     * @return the current "allow unknown sources" setting
9143     */
9144    private int getUnknownSourcesSettings() {
9145        return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
9146                android.provider.Settings.Global.INSTALL_NON_MARKET_APPS,
9147                -1);
9148    }
9149
9150    @Override
9151    public void setInstallerPackageName(String targetPackage, String installerPackageName) {
9152        final int uid = Binder.getCallingUid();
9153        // writer
9154        synchronized (mPackages) {
9155            PackageSetting targetPackageSetting = mSettings.mPackages.get(targetPackage);
9156            if (targetPackageSetting == null) {
9157                throw new IllegalArgumentException("Unknown target package: " + targetPackage);
9158            }
9159
9160            PackageSetting installerPackageSetting;
9161            if (installerPackageName != null) {
9162                installerPackageSetting = mSettings.mPackages.get(installerPackageName);
9163                if (installerPackageSetting == null) {
9164                    throw new IllegalArgumentException("Unknown installer package: "
9165                            + installerPackageName);
9166                }
9167            } else {
9168                installerPackageSetting = null;
9169            }
9170
9171            Signature[] callerSignature;
9172            Object obj = mSettings.getUserIdLPr(uid);
9173            if (obj != null) {
9174                if (obj instanceof SharedUserSetting) {
9175                    callerSignature = ((SharedUserSetting)obj).signatures.mSignatures;
9176                } else if (obj instanceof PackageSetting) {
9177                    callerSignature = ((PackageSetting)obj).signatures.mSignatures;
9178                } else {
9179                    throw new SecurityException("Bad object " + obj + " for uid " + uid);
9180                }
9181            } else {
9182                throw new SecurityException("Unknown calling uid " + uid);
9183            }
9184
9185            // Verify: can't set installerPackageName to a package that is
9186            // not signed with the same cert as the caller.
9187            if (installerPackageSetting != null) {
9188                if (compareSignatures(callerSignature,
9189                        installerPackageSetting.signatures.mSignatures)
9190                        != PackageManager.SIGNATURE_MATCH) {
9191                    throw new SecurityException(
9192                            "Caller does not have same cert as new installer package "
9193                            + installerPackageName);
9194                }
9195            }
9196
9197            // Verify: if target already has an installer package, it must
9198            // be signed with the same cert as the caller.
9199            if (targetPackageSetting.installerPackageName != null) {
9200                PackageSetting setting = mSettings.mPackages.get(
9201                        targetPackageSetting.installerPackageName);
9202                // If the currently set package isn't valid, then it's always
9203                // okay to change it.
9204                if (setting != null) {
9205                    if (compareSignatures(callerSignature,
9206                            setting.signatures.mSignatures)
9207                            != PackageManager.SIGNATURE_MATCH) {
9208                        throw new SecurityException(
9209                                "Caller does not have same cert as old installer package "
9210                                + targetPackageSetting.installerPackageName);
9211                    }
9212                }
9213            }
9214
9215            // Okay!
9216            targetPackageSetting.installerPackageName = installerPackageName;
9217            scheduleWriteSettingsLocked();
9218        }
9219    }
9220
9221    private void processPendingInstall(final InstallArgs args, final int currentStatus) {
9222        // Queue up an async operation since the package installation may take a little while.
9223        mHandler.post(new Runnable() {
9224            public void run() {
9225                mHandler.removeCallbacks(this);
9226                 // Result object to be returned
9227                PackageInstalledInfo res = new PackageInstalledInfo();
9228                res.returnCode = currentStatus;
9229                res.uid = -1;
9230                res.pkg = null;
9231                res.removedInfo = new PackageRemovedInfo();
9232                if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
9233                    args.doPreInstall(res.returnCode);
9234                    synchronized (mInstallLock) {
9235                        installPackageLI(args, res);
9236                    }
9237                    args.doPostInstall(res.returnCode, res.uid);
9238                }
9239
9240                // A restore should be performed at this point if (a) the install
9241                // succeeded, (b) the operation is not an update, and (c) the new
9242                // package has not opted out of backup participation.
9243                final boolean update = res.removedInfo.removedPackage != null;
9244                final int flags = (res.pkg == null) ? 0 : res.pkg.applicationInfo.flags;
9245                boolean doRestore = !update
9246                        && ((flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0);
9247
9248                // Set up the post-install work request bookkeeping.  This will be used
9249                // and cleaned up by the post-install event handling regardless of whether
9250                // there's a restore pass performed.  Token values are >= 1.
9251                int token;
9252                if (mNextInstallToken < 0) mNextInstallToken = 1;
9253                token = mNextInstallToken++;
9254
9255                PostInstallData data = new PostInstallData(args, res);
9256                mRunningInstalls.put(token, data);
9257                if (DEBUG_INSTALL) Log.v(TAG, "+ starting restore round-trip " + token);
9258
9259                if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && doRestore) {
9260                    // Pass responsibility to the Backup Manager.  It will perform a
9261                    // restore if appropriate, then pass responsibility back to the
9262                    // Package Manager to run the post-install observer callbacks
9263                    // and broadcasts.
9264                    IBackupManager bm = IBackupManager.Stub.asInterface(
9265                            ServiceManager.getService(Context.BACKUP_SERVICE));
9266                    if (bm != null) {
9267                        if (DEBUG_INSTALL) Log.v(TAG, "token " + token
9268                                + " to BM for possible restore");
9269                        try {
9270                            if (bm.isBackupServiceActive(UserHandle.USER_OWNER)) {
9271                                bm.restoreAtInstall(res.pkg.applicationInfo.packageName, token);
9272                            } else {
9273                                doRestore = false;
9274                            }
9275                        } catch (RemoteException e) {
9276                            // can't happen; the backup manager is local
9277                        } catch (Exception e) {
9278                            Slog.e(TAG, "Exception trying to enqueue restore", e);
9279                            doRestore = false;
9280                        }
9281                    } else {
9282                        Slog.e(TAG, "Backup Manager not found!");
9283                        doRestore = false;
9284                    }
9285                }
9286
9287                if (!doRestore) {
9288                    // No restore possible, or the Backup Manager was mysteriously not
9289                    // available -- just fire the post-install work request directly.
9290                    if (DEBUG_INSTALL) Log.v(TAG, "No restore - queue post-install for " + token);
9291                    Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0);
9292                    mHandler.sendMessage(msg);
9293                }
9294            }
9295        });
9296    }
9297
9298    private abstract class HandlerParams {
9299        private static final int MAX_RETRIES = 4;
9300
9301        /**
9302         * Number of times startCopy() has been attempted and had a non-fatal
9303         * error.
9304         */
9305        private int mRetries = 0;
9306
9307        /** User handle for the user requesting the information or installation. */
9308        private final UserHandle mUser;
9309
9310        HandlerParams(UserHandle user) {
9311            mUser = user;
9312        }
9313
9314        UserHandle getUser() {
9315            return mUser;
9316        }
9317
9318        final boolean startCopy() {
9319            boolean res;
9320            try {
9321                if (DEBUG_INSTALL) Slog.i(TAG, "startCopy " + mUser + ": " + this);
9322
9323                if (++mRetries > MAX_RETRIES) {
9324                    Slog.w(TAG, "Failed to invoke remote methods on default container service. Giving up");
9325                    mHandler.sendEmptyMessage(MCS_GIVE_UP);
9326                    handleServiceError();
9327                    return false;
9328                } else {
9329                    handleStartCopy();
9330                    res = true;
9331                }
9332            } catch (RemoteException e) {
9333                if (DEBUG_INSTALL) Slog.i(TAG, "Posting install MCS_RECONNECT");
9334                mHandler.sendEmptyMessage(MCS_RECONNECT);
9335                res = false;
9336            }
9337            handleReturnCode();
9338            return res;
9339        }
9340
9341        final void serviceError() {
9342            if (DEBUG_INSTALL) Slog.i(TAG, "serviceError");
9343            handleServiceError();
9344            handleReturnCode();
9345        }
9346
9347        abstract void handleStartCopy() throws RemoteException;
9348        abstract void handleServiceError();
9349        abstract void handleReturnCode();
9350    }
9351
9352    class MeasureParams extends HandlerParams {
9353        private final PackageStats mStats;
9354        private boolean mSuccess;
9355
9356        private final IPackageStatsObserver mObserver;
9357
9358        public MeasureParams(PackageStats stats, IPackageStatsObserver observer) {
9359            super(new UserHandle(stats.userHandle));
9360            mObserver = observer;
9361            mStats = stats;
9362        }
9363
9364        @Override
9365        public String toString() {
9366            return "MeasureParams{"
9367                + Integer.toHexString(System.identityHashCode(this))
9368                + " " + mStats.packageName + "}";
9369        }
9370
9371        @Override
9372        void handleStartCopy() throws RemoteException {
9373            synchronized (mInstallLock) {
9374                mSuccess = getPackageSizeInfoLI(mStats.packageName, mStats.userHandle, mStats);
9375            }
9376
9377            if (mSuccess) {
9378                final boolean mounted;
9379                if (Environment.isExternalStorageEmulated()) {
9380                    mounted = true;
9381                } else {
9382                    final String status = Environment.getExternalStorageState();
9383                    mounted = (Environment.MEDIA_MOUNTED.equals(status)
9384                            || Environment.MEDIA_MOUNTED_READ_ONLY.equals(status));
9385                }
9386
9387                if (mounted) {
9388                    final UserEnvironment userEnv = new UserEnvironment(mStats.userHandle);
9389
9390                    mStats.externalCacheSize = calculateDirectorySize(mContainerService,
9391                            userEnv.buildExternalStorageAppCacheDirs(mStats.packageName));
9392
9393                    mStats.externalDataSize = calculateDirectorySize(mContainerService,
9394                            userEnv.buildExternalStorageAppDataDirs(mStats.packageName));
9395
9396                    // Always subtract cache size, since it's a subdirectory
9397                    mStats.externalDataSize -= mStats.externalCacheSize;
9398
9399                    mStats.externalMediaSize = calculateDirectorySize(mContainerService,
9400                            userEnv.buildExternalStorageAppMediaDirs(mStats.packageName));
9401
9402                    mStats.externalObbSize = calculateDirectorySize(mContainerService,
9403                            userEnv.buildExternalStorageAppObbDirs(mStats.packageName));
9404                }
9405            }
9406        }
9407
9408        @Override
9409        void handleReturnCode() {
9410            if (mObserver != null) {
9411                try {
9412                    mObserver.onGetStatsCompleted(mStats, mSuccess);
9413                } catch (RemoteException e) {
9414                    Slog.i(TAG, "Observer no longer exists.");
9415                }
9416            }
9417        }
9418
9419        @Override
9420        void handleServiceError() {
9421            Slog.e(TAG, "Could not measure application " + mStats.packageName
9422                            + " external storage");
9423        }
9424    }
9425
9426    private static long calculateDirectorySize(IMediaContainerService mcs, File[] paths)
9427            throws RemoteException {
9428        long result = 0;
9429        for (File path : paths) {
9430            result += mcs.calculateDirectorySize(path.getAbsolutePath());
9431        }
9432        return result;
9433    }
9434
9435    private static void clearDirectory(IMediaContainerService mcs, File[] paths) {
9436        for (File path : paths) {
9437            try {
9438                mcs.clearDirectory(path.getAbsolutePath());
9439            } catch (RemoteException e) {
9440            }
9441        }
9442    }
9443
9444    static class OriginInfo {
9445        /**
9446         * Location where install is coming from, before it has been
9447         * copied/renamed into place. This could be a single monolithic APK
9448         * file, or a cluster directory. This location may be untrusted.
9449         */
9450        final File file;
9451        final String cid;
9452
9453        /**
9454         * Flag indicating that {@link #file} or {@link #cid} has already been
9455         * staged, meaning downstream users don't need to defensively copy the
9456         * contents.
9457         */
9458        final boolean staged;
9459
9460        /**
9461         * Flag indicating that {@link #file} or {@link #cid} is an already
9462         * installed app that is being moved.
9463         */
9464        final boolean existing;
9465
9466        final String resolvedPath;
9467        final File resolvedFile;
9468
9469        static OriginInfo fromNothing() {
9470            return new OriginInfo(null, null, false, false);
9471        }
9472
9473        static OriginInfo fromUntrustedFile(File file) {
9474            return new OriginInfo(file, null, false, false);
9475        }
9476
9477        static OriginInfo fromExistingFile(File file) {
9478            return new OriginInfo(file, null, false, true);
9479        }
9480
9481        static OriginInfo fromStagedFile(File file) {
9482            return new OriginInfo(file, null, true, false);
9483        }
9484
9485        static OriginInfo fromStagedContainer(String cid) {
9486            return new OriginInfo(null, cid, true, false);
9487        }
9488
9489        private OriginInfo(File file, String cid, boolean staged, boolean existing) {
9490            this.file = file;
9491            this.cid = cid;
9492            this.staged = staged;
9493            this.existing = existing;
9494
9495            if (cid != null) {
9496                resolvedPath = PackageHelper.getSdDir(cid);
9497                resolvedFile = new File(resolvedPath);
9498            } else if (file != null) {
9499                resolvedPath = file.getAbsolutePath();
9500                resolvedFile = file;
9501            } else {
9502                resolvedPath = null;
9503                resolvedFile = null;
9504            }
9505        }
9506    }
9507
9508    class MoveInfo {
9509        final int moveId;
9510        final String fromUuid;
9511        final String toUuid;
9512        final String packageName;
9513        final String dataAppName;
9514        final int appId;
9515        final String seinfo;
9516
9517        public MoveInfo(int moveId, String fromUuid, String toUuid, String packageName,
9518                String dataAppName, int appId, String seinfo) {
9519            this.moveId = moveId;
9520            this.fromUuid = fromUuid;
9521            this.toUuid = toUuid;
9522            this.packageName = packageName;
9523            this.dataAppName = dataAppName;
9524            this.appId = appId;
9525            this.seinfo = seinfo;
9526        }
9527    }
9528
9529    class InstallParams extends HandlerParams {
9530        final OriginInfo origin;
9531        final MoveInfo move;
9532        final IPackageInstallObserver2 observer;
9533        int installFlags;
9534        final String installerPackageName;
9535        final String volumeUuid;
9536        final VerificationParams verificationParams;
9537        private InstallArgs mArgs;
9538        private int mRet;
9539        final String packageAbiOverride;
9540
9541        InstallParams(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
9542                int installFlags, String installerPackageName, String volumeUuid,
9543                VerificationParams verificationParams, UserHandle user, String packageAbiOverride) {
9544            super(user);
9545            this.origin = origin;
9546            this.move = move;
9547            this.observer = observer;
9548            this.installFlags = installFlags;
9549            this.installerPackageName = installerPackageName;
9550            this.volumeUuid = volumeUuid;
9551            this.verificationParams = verificationParams;
9552            this.packageAbiOverride = packageAbiOverride;
9553        }
9554
9555        @Override
9556        public String toString() {
9557            return "InstallParams{" + Integer.toHexString(System.identityHashCode(this))
9558                    + " file=" + origin.file + " cid=" + origin.cid + "}";
9559        }
9560
9561        public ManifestDigest getManifestDigest() {
9562            if (verificationParams == null) {
9563                return null;
9564            }
9565            return verificationParams.getManifestDigest();
9566        }
9567
9568        private int installLocationPolicy(PackageInfoLite pkgLite) {
9569            String packageName = pkgLite.packageName;
9570            int installLocation = pkgLite.installLocation;
9571            boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
9572            // reader
9573            synchronized (mPackages) {
9574                PackageParser.Package pkg = mPackages.get(packageName);
9575                if (pkg != null) {
9576                    if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
9577                        // Check for downgrading.
9578                        if ((installFlags & PackageManager.INSTALL_ALLOW_DOWNGRADE) == 0) {
9579                            try {
9580                                checkDowngrade(pkg, pkgLite);
9581                            } catch (PackageManagerException e) {
9582                                Slog.w(TAG, "Downgrade detected: " + e.getMessage());
9583                                return PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE;
9584                            }
9585                        }
9586                        // Check for updated system application.
9587                        if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
9588                            if (onSd) {
9589                                Slog.w(TAG, "Cannot install update to system app on sdcard");
9590                                return PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION;
9591                            }
9592                            return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
9593                        } else {
9594                            if (onSd) {
9595                                // Install flag overrides everything.
9596                                return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
9597                            }
9598                            // If current upgrade specifies particular preference
9599                            if (installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) {
9600                                // Application explicitly specified internal.
9601                                return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
9602                            } else if (installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) {
9603                                // App explictly prefers external. Let policy decide
9604                            } else {
9605                                // Prefer previous location
9606                                if (isExternal(pkg)) {
9607                                    return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
9608                                }
9609                                return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
9610                            }
9611                        }
9612                    } else {
9613                        // Invalid install. Return error code
9614                        return PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS;
9615                    }
9616                }
9617            }
9618            // All the special cases have been taken care of.
9619            // Return result based on recommended install location.
9620            if (onSd) {
9621                return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
9622            }
9623            return pkgLite.recommendedInstallLocation;
9624        }
9625
9626        /*
9627         * Invoke remote method to get package information and install
9628         * location values. Override install location based on default
9629         * policy if needed and then create install arguments based
9630         * on the install location.
9631         */
9632        public void handleStartCopy() throws RemoteException {
9633            int ret = PackageManager.INSTALL_SUCCEEDED;
9634
9635            // If we're already staged, we've firmly committed to an install location
9636            if (origin.staged) {
9637                if (origin.file != null) {
9638                    installFlags |= PackageManager.INSTALL_INTERNAL;
9639                    installFlags &= ~PackageManager.INSTALL_EXTERNAL;
9640                } else if (origin.cid != null) {
9641                    installFlags |= PackageManager.INSTALL_EXTERNAL;
9642                    installFlags &= ~PackageManager.INSTALL_INTERNAL;
9643                } else {
9644                    throw new IllegalStateException("Invalid stage location");
9645                }
9646            }
9647
9648            final boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
9649            final boolean onInt = (installFlags & PackageManager.INSTALL_INTERNAL) != 0;
9650
9651            PackageInfoLite pkgLite = null;
9652
9653            if (onInt && onSd) {
9654                // Check if both bits are set.
9655                Slog.w(TAG, "Conflicting flags specified for installing on both internal and external");
9656                ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
9657            } else {
9658                pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, installFlags,
9659                        packageAbiOverride);
9660
9661                /*
9662                 * If we have too little free space, try to free cache
9663                 * before giving up.
9664                 */
9665                if (!origin.staged && pkgLite.recommendedInstallLocation
9666                        == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
9667                    // TODO: focus freeing disk space on the target device
9668                    final StorageManager storage = StorageManager.from(mContext);
9669                    final long lowThreshold = storage.getStorageLowBytes(
9670                            Environment.getDataDirectory());
9671
9672                    final long sizeBytes = mContainerService.calculateInstalledSize(
9673                            origin.resolvedPath, isForwardLocked(), packageAbiOverride);
9674
9675                    if (mInstaller.freeCache(null, sizeBytes + lowThreshold) >= 0) {
9676                        pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath,
9677                                installFlags, packageAbiOverride);
9678                    }
9679
9680                    /*
9681                     * The cache free must have deleted the file we
9682                     * downloaded to install.
9683                     *
9684                     * TODO: fix the "freeCache" call to not delete
9685                     *       the file we care about.
9686                     */
9687                    if (pkgLite.recommendedInstallLocation
9688                            == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
9689                        pkgLite.recommendedInstallLocation
9690                            = PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE;
9691                    }
9692                }
9693            }
9694
9695            if (ret == PackageManager.INSTALL_SUCCEEDED) {
9696                int loc = pkgLite.recommendedInstallLocation;
9697                if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION) {
9698                    ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
9699                } else if (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS) {
9700                    ret = PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
9701                } else if (loc == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
9702                    ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
9703                } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_APK) {
9704                    ret = PackageManager.INSTALL_FAILED_INVALID_APK;
9705                } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
9706                    ret = PackageManager.INSTALL_FAILED_INVALID_URI;
9707                } else if (loc == PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE) {
9708                    ret = PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE;
9709                } else {
9710                    // Override with defaults if needed.
9711                    loc = installLocationPolicy(pkgLite);
9712                    if (loc == PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE) {
9713                        ret = PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
9714                    } else if (!onSd && !onInt) {
9715                        // Override install location with flags
9716                        if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) {
9717                            // Set the flag to install on external media.
9718                            installFlags |= PackageManager.INSTALL_EXTERNAL;
9719                            installFlags &= ~PackageManager.INSTALL_INTERNAL;
9720                        } else {
9721                            // Make sure the flag for installing on external
9722                            // media is unset
9723                            installFlags |= PackageManager.INSTALL_INTERNAL;
9724                            installFlags &= ~PackageManager.INSTALL_EXTERNAL;
9725                        }
9726                    }
9727                }
9728            }
9729
9730            final InstallArgs args = createInstallArgs(this);
9731            mArgs = args;
9732
9733            if (ret == PackageManager.INSTALL_SUCCEEDED) {
9734                 /*
9735                 * ADB installs appear as UserHandle.USER_ALL, and can only be performed by
9736                 * UserHandle.USER_OWNER, so use the package verifier for UserHandle.USER_OWNER.
9737                 */
9738                int userIdentifier = getUser().getIdentifier();
9739                if (userIdentifier == UserHandle.USER_ALL
9740                        && ((installFlags & PackageManager.INSTALL_FROM_ADB) != 0)) {
9741                    userIdentifier = UserHandle.USER_OWNER;
9742                }
9743
9744                /*
9745                 * Determine if we have any installed package verifiers. If we
9746                 * do, then we'll defer to them to verify the packages.
9747                 */
9748                final int requiredUid = mRequiredVerifierPackage == null ? -1
9749                        : getPackageUid(mRequiredVerifierPackage, userIdentifier);
9750                if (!origin.existing && requiredUid != -1
9751                        && isVerificationEnabled(userIdentifier, installFlags)) {
9752                    final Intent verification = new Intent(
9753                            Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
9754                    verification.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
9755                    verification.setDataAndType(Uri.fromFile(new File(origin.resolvedPath)),
9756                            PACKAGE_MIME_TYPE);
9757                    verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
9758
9759                    final List<ResolveInfo> receivers = queryIntentReceivers(verification,
9760                            PACKAGE_MIME_TYPE, PackageManager.GET_DISABLED_COMPONENTS,
9761                            0 /* TODO: Which userId? */);
9762
9763                    if (DEBUG_VERIFY) {
9764                        Slog.d(TAG, "Found " + receivers.size() + " verifiers for intent "
9765                                + verification.toString() + " with " + pkgLite.verifiers.length
9766                                + " optional verifiers");
9767                    }
9768
9769                    final int verificationId = mPendingVerificationToken++;
9770
9771                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
9772
9773                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_PACKAGE,
9774                            installerPackageName);
9775
9776                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALL_FLAGS,
9777                            installFlags);
9778
9779                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_PACKAGE_NAME,
9780                            pkgLite.packageName);
9781
9782                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_VERSION_CODE,
9783                            pkgLite.versionCode);
9784
9785                    if (verificationParams != null) {
9786                        if (verificationParams.getVerificationURI() != null) {
9787                           verification.putExtra(PackageManager.EXTRA_VERIFICATION_URI,
9788                                 verificationParams.getVerificationURI());
9789                        }
9790                        if (verificationParams.getOriginatingURI() != null) {
9791                            verification.putExtra(Intent.EXTRA_ORIGINATING_URI,
9792                                  verificationParams.getOriginatingURI());
9793                        }
9794                        if (verificationParams.getReferrer() != null) {
9795                            verification.putExtra(Intent.EXTRA_REFERRER,
9796                                  verificationParams.getReferrer());
9797                        }
9798                        if (verificationParams.getOriginatingUid() >= 0) {
9799                            verification.putExtra(Intent.EXTRA_ORIGINATING_UID,
9800                                  verificationParams.getOriginatingUid());
9801                        }
9802                        if (verificationParams.getInstallerUid() >= 0) {
9803                            verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_UID,
9804                                  verificationParams.getInstallerUid());
9805                        }
9806                    }
9807
9808                    final PackageVerificationState verificationState = new PackageVerificationState(
9809                            requiredUid, args);
9810
9811                    mPendingVerification.append(verificationId, verificationState);
9812
9813                    final List<ComponentName> sufficientVerifiers = matchVerifiers(pkgLite,
9814                            receivers, verificationState);
9815
9816                    /*
9817                     * If any sufficient verifiers were listed in the package
9818                     * manifest, attempt to ask them.
9819                     */
9820                    if (sufficientVerifiers != null) {
9821                        final int N = sufficientVerifiers.size();
9822                        if (N == 0) {
9823                            Slog.i(TAG, "Additional verifiers required, but none installed.");
9824                            ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
9825                        } else {
9826                            for (int i = 0; i < N; i++) {
9827                                final ComponentName verifierComponent = sufficientVerifiers.get(i);
9828
9829                                final Intent sufficientIntent = new Intent(verification);
9830                                sufficientIntent.setComponent(verifierComponent);
9831
9832                                mContext.sendBroadcastAsUser(sufficientIntent, getUser());
9833                            }
9834                        }
9835                    }
9836
9837                    final ComponentName requiredVerifierComponent = matchComponentForVerifier(
9838                            mRequiredVerifierPackage, receivers);
9839                    if (ret == PackageManager.INSTALL_SUCCEEDED
9840                            && mRequiredVerifierPackage != null) {
9841                        /*
9842                         * Send the intent to the required verification agent,
9843                         * but only start the verification timeout after the
9844                         * target BroadcastReceivers have run.
9845                         */
9846                        verification.setComponent(requiredVerifierComponent);
9847                        mContext.sendOrderedBroadcastAsUser(verification, getUser(),
9848                                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
9849                                new BroadcastReceiver() {
9850                                    @Override
9851                                    public void onReceive(Context context, Intent intent) {
9852                                        final Message msg = mHandler
9853                                                .obtainMessage(CHECK_PENDING_VERIFICATION);
9854                                        msg.arg1 = verificationId;
9855                                        mHandler.sendMessageDelayed(msg, getVerificationTimeout());
9856                                    }
9857                                }, null, 0, null, null);
9858
9859                        /*
9860                         * We don't want the copy to proceed until verification
9861                         * succeeds, so null out this field.
9862                         */
9863                        mArgs = null;
9864                    }
9865                } else {
9866                    /*
9867                     * No package verification is enabled, so immediately start
9868                     * the remote call to initiate copy using temporary file.
9869                     */
9870                    ret = args.copyApk(mContainerService, true);
9871                }
9872            }
9873
9874            mRet = ret;
9875        }
9876
9877        @Override
9878        void handleReturnCode() {
9879            // If mArgs is null, then MCS couldn't be reached. When it
9880            // reconnects, it will try again to install. At that point, this
9881            // will succeed.
9882            if (mArgs != null) {
9883                processPendingInstall(mArgs, mRet);
9884            }
9885        }
9886
9887        @Override
9888        void handleServiceError() {
9889            mArgs = createInstallArgs(this);
9890            mRet = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
9891        }
9892
9893        public boolean isForwardLocked() {
9894            return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
9895        }
9896    }
9897
9898    /**
9899     * Used during creation of InstallArgs
9900     *
9901     * @param installFlags package installation flags
9902     * @return true if should be installed on external storage
9903     */
9904    private static boolean installOnExternalAsec(int installFlags) {
9905        if ((installFlags & PackageManager.INSTALL_INTERNAL) != 0) {
9906            return false;
9907        }
9908        if ((installFlags & PackageManager.INSTALL_EXTERNAL) != 0) {
9909            return true;
9910        }
9911        return false;
9912    }
9913
9914    /**
9915     * Used during creation of InstallArgs
9916     *
9917     * @param installFlags package installation flags
9918     * @return true if should be installed as forward locked
9919     */
9920    private static boolean installForwardLocked(int installFlags) {
9921        return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
9922    }
9923
9924    private InstallArgs createInstallArgs(InstallParams params) {
9925        if (params.move != null) {
9926            return new MoveInstallArgs(params);
9927        } else if (installOnExternalAsec(params.installFlags) || params.isForwardLocked()) {
9928            return new AsecInstallArgs(params);
9929        } else {
9930            return new FileInstallArgs(params);
9931        }
9932    }
9933
9934    /**
9935     * Create args that describe an existing installed package. Typically used
9936     * when cleaning up old installs, or used as a move source.
9937     */
9938    private InstallArgs createInstallArgsForExisting(int installFlags, String codePath,
9939            String resourcePath, String[] instructionSets) {
9940        final boolean isInAsec;
9941        if (installOnExternalAsec(installFlags)) {
9942            /* Apps on SD card are always in ASEC containers. */
9943            isInAsec = true;
9944        } else if (installForwardLocked(installFlags)
9945                && !codePath.startsWith(mDrmAppPrivateInstallDir.getAbsolutePath())) {
9946            /*
9947             * Forward-locked apps are only in ASEC containers if they're the
9948             * new style
9949             */
9950            isInAsec = true;
9951        } else {
9952            isInAsec = false;
9953        }
9954
9955        if (isInAsec) {
9956            return new AsecInstallArgs(codePath, instructionSets,
9957                    installOnExternalAsec(installFlags), installForwardLocked(installFlags));
9958        } else {
9959            return new FileInstallArgs(codePath, resourcePath, instructionSets);
9960        }
9961    }
9962
9963    static abstract class InstallArgs {
9964        /** @see InstallParams#origin */
9965        final OriginInfo origin;
9966        /** @see InstallParams#move */
9967        final MoveInfo move;
9968
9969        final IPackageInstallObserver2 observer;
9970        // Always refers to PackageManager flags only
9971        final int installFlags;
9972        final String installerPackageName;
9973        final String volumeUuid;
9974        final ManifestDigest manifestDigest;
9975        final UserHandle user;
9976        final String abiOverride;
9977
9978        // The list of instruction sets supported by this app. This is currently
9979        // only used during the rmdex() phase to clean up resources. We can get rid of this
9980        // if we move dex files under the common app path.
9981        /* nullable */ String[] instructionSets;
9982
9983        InstallArgs(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
9984                int installFlags, String installerPackageName, String volumeUuid,
9985                ManifestDigest manifestDigest, UserHandle user, String[] instructionSets,
9986                String abiOverride) {
9987            this.origin = origin;
9988            this.move = move;
9989            this.installFlags = installFlags;
9990            this.observer = observer;
9991            this.installerPackageName = installerPackageName;
9992            this.volumeUuid = volumeUuid;
9993            this.manifestDigest = manifestDigest;
9994            this.user = user;
9995            this.instructionSets = instructionSets;
9996            this.abiOverride = abiOverride;
9997        }
9998
9999        abstract int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException;
10000        abstract int doPreInstall(int status);
10001
10002        /**
10003         * Rename package into final resting place. All paths on the given
10004         * scanned package should be updated to reflect the rename.
10005         */
10006        abstract boolean doRename(int status, PackageParser.Package pkg, String oldCodePath);
10007        abstract int doPostInstall(int status, int uid);
10008
10009        /** @see PackageSettingBase#codePathString */
10010        abstract String getCodePath();
10011        /** @see PackageSettingBase#resourcePathString */
10012        abstract String getResourcePath();
10013
10014        // Need installer lock especially for dex file removal.
10015        abstract void cleanUpResourcesLI();
10016        abstract boolean doPostDeleteLI(boolean delete);
10017
10018        /**
10019         * Called before the source arguments are copied. This is used mostly
10020         * for MoveParams when it needs to read the source file to put it in the
10021         * destination.
10022         */
10023        int doPreCopy() {
10024            return PackageManager.INSTALL_SUCCEEDED;
10025        }
10026
10027        /**
10028         * Called after the source arguments are copied. This is used mostly for
10029         * MoveParams when it needs to read the source file to put it in the
10030         * destination.
10031         *
10032         * @return
10033         */
10034        int doPostCopy(int uid) {
10035            return PackageManager.INSTALL_SUCCEEDED;
10036        }
10037
10038        protected boolean isFwdLocked() {
10039            return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
10040        }
10041
10042        protected boolean isExternalAsec() {
10043            return (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
10044        }
10045
10046        UserHandle getUser() {
10047            return user;
10048        }
10049    }
10050
10051    private void removeDexFiles(List<String> allCodePaths, String[] instructionSets) {
10052        if (!allCodePaths.isEmpty()) {
10053            if (instructionSets == null) {
10054                throw new IllegalStateException("instructionSet == null");
10055            }
10056            String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
10057            for (String codePath : allCodePaths) {
10058                for (String dexCodeInstructionSet : dexCodeInstructionSets) {
10059                    int retCode = mInstaller.rmdex(codePath, dexCodeInstructionSet);
10060                    if (retCode < 0) {
10061                        Slog.w(TAG, "Couldn't remove dex file for package: "
10062                                + " at location " + codePath + ", retcode=" + retCode);
10063                        // we don't consider this to be a failure of the core package deletion
10064                    }
10065                }
10066            }
10067        }
10068    }
10069
10070    /**
10071     * Logic to handle installation of non-ASEC applications, including copying
10072     * and renaming logic.
10073     */
10074    class FileInstallArgs extends InstallArgs {
10075        private File codeFile;
10076        private File resourceFile;
10077
10078        // Example topology:
10079        // /data/app/com.example/base.apk
10080        // /data/app/com.example/split_foo.apk
10081        // /data/app/com.example/lib/arm/libfoo.so
10082        // /data/app/com.example/lib/arm64/libfoo.so
10083        // /data/app/com.example/dalvik/arm/base.apk@classes.dex
10084
10085        /** New install */
10086        FileInstallArgs(InstallParams params) {
10087            super(params.origin, params.move, params.observer, params.installFlags,
10088                    params.installerPackageName, params.volumeUuid, params.getManifestDigest(),
10089                    params.getUser(), null /* instruction sets */, params.packageAbiOverride);
10090            if (isFwdLocked()) {
10091                throw new IllegalArgumentException("Forward locking only supported in ASEC");
10092            }
10093        }
10094
10095        /** Existing install */
10096        FileInstallArgs(String codePath, String resourcePath, String[] instructionSets) {
10097            super(OriginInfo.fromNothing(), null, null, 0, null, null, null, null, instructionSets,
10098                    null);
10099            this.codeFile = (codePath != null) ? new File(codePath) : null;
10100            this.resourceFile = (resourcePath != null) ? new File(resourcePath) : null;
10101        }
10102
10103        int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
10104            if (origin.staged) {
10105                Slog.d(TAG, origin.file + " already staged; skipping copy");
10106                codeFile = origin.file;
10107                resourceFile = origin.file;
10108                return PackageManager.INSTALL_SUCCEEDED;
10109            }
10110
10111            try {
10112                final File tempDir = mInstallerService.allocateStageDirLegacy(volumeUuid);
10113                codeFile = tempDir;
10114                resourceFile = tempDir;
10115            } catch (IOException e) {
10116                Slog.w(TAG, "Failed to create copy file: " + e);
10117                return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
10118            }
10119
10120            final IParcelFileDescriptorFactory target = new IParcelFileDescriptorFactory.Stub() {
10121                @Override
10122                public ParcelFileDescriptor open(String name, int mode) throws RemoteException {
10123                    if (!FileUtils.isValidExtFilename(name)) {
10124                        throw new IllegalArgumentException("Invalid filename: " + name);
10125                    }
10126                    try {
10127                        final File file = new File(codeFile, name);
10128                        final FileDescriptor fd = Os.open(file.getAbsolutePath(),
10129                                O_RDWR | O_CREAT, 0644);
10130                        Os.chmod(file.getAbsolutePath(), 0644);
10131                        return new ParcelFileDescriptor(fd);
10132                    } catch (ErrnoException e) {
10133                        throw new RemoteException("Failed to open: " + e.getMessage());
10134                    }
10135                }
10136            };
10137
10138            int ret = PackageManager.INSTALL_SUCCEEDED;
10139            ret = imcs.copyPackage(origin.file.getAbsolutePath(), target);
10140            if (ret != PackageManager.INSTALL_SUCCEEDED) {
10141                Slog.e(TAG, "Failed to copy package");
10142                return ret;
10143            }
10144
10145            final File libraryRoot = new File(codeFile, LIB_DIR_NAME);
10146            NativeLibraryHelper.Handle handle = null;
10147            try {
10148                handle = NativeLibraryHelper.Handle.create(codeFile);
10149                ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot,
10150                        abiOverride);
10151            } catch (IOException e) {
10152                Slog.e(TAG, "Copying native libraries failed", e);
10153                ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
10154            } finally {
10155                IoUtils.closeQuietly(handle);
10156            }
10157
10158            return ret;
10159        }
10160
10161        int doPreInstall(int status) {
10162            if (status != PackageManager.INSTALL_SUCCEEDED) {
10163                cleanUp();
10164            }
10165            return status;
10166        }
10167
10168        boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
10169            if (status != PackageManager.INSTALL_SUCCEEDED) {
10170                cleanUp();
10171                return false;
10172            }
10173
10174            final File targetDir = codeFile.getParentFile();
10175            final File beforeCodeFile = codeFile;
10176            final File afterCodeFile = getNextCodePath(targetDir, pkg.packageName);
10177
10178            Slog.d(TAG, "Renaming " + beforeCodeFile + " to " + afterCodeFile);
10179            try {
10180                Os.rename(beforeCodeFile.getAbsolutePath(), afterCodeFile.getAbsolutePath());
10181            } catch (ErrnoException e) {
10182                Slog.d(TAG, "Failed to rename", e);
10183                return false;
10184            }
10185
10186            if (!SELinux.restoreconRecursive(afterCodeFile)) {
10187                Slog.d(TAG, "Failed to restorecon");
10188                return false;
10189            }
10190
10191            // Reflect the rename internally
10192            codeFile = afterCodeFile;
10193            resourceFile = afterCodeFile;
10194
10195            // Reflect the rename in scanned details
10196            pkg.codePath = afterCodeFile.getAbsolutePath();
10197            pkg.baseCodePath = FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile,
10198                    pkg.baseCodePath);
10199            pkg.splitCodePaths = FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile,
10200                    pkg.splitCodePaths);
10201
10202            // Reflect the rename in app info
10203            pkg.applicationInfo.volumeUuid = pkg.volumeUuid;
10204            pkg.applicationInfo.setCodePath(pkg.codePath);
10205            pkg.applicationInfo.setBaseCodePath(pkg.baseCodePath);
10206            pkg.applicationInfo.setSplitCodePaths(pkg.splitCodePaths);
10207            pkg.applicationInfo.setResourcePath(pkg.codePath);
10208            pkg.applicationInfo.setBaseResourcePath(pkg.baseCodePath);
10209            pkg.applicationInfo.setSplitResourcePaths(pkg.splitCodePaths);
10210
10211            return true;
10212        }
10213
10214        int doPostInstall(int status, int uid) {
10215            if (status != PackageManager.INSTALL_SUCCEEDED) {
10216                cleanUp();
10217            }
10218            return status;
10219        }
10220
10221        @Override
10222        String getCodePath() {
10223            return (codeFile != null) ? codeFile.getAbsolutePath() : null;
10224        }
10225
10226        @Override
10227        String getResourcePath() {
10228            return (resourceFile != null) ? resourceFile.getAbsolutePath() : null;
10229        }
10230
10231        private boolean cleanUp() {
10232            if (codeFile == null || !codeFile.exists()) {
10233                return false;
10234            }
10235
10236            if (codeFile.isDirectory()) {
10237                mInstaller.rmPackageDir(codeFile.getAbsolutePath());
10238            } else {
10239                codeFile.delete();
10240            }
10241
10242            if (resourceFile != null && !FileUtils.contains(codeFile, resourceFile)) {
10243                resourceFile.delete();
10244            }
10245
10246            return true;
10247        }
10248
10249        void cleanUpResourcesLI() {
10250            // Try enumerating all code paths before deleting
10251            List<String> allCodePaths = Collections.EMPTY_LIST;
10252            if (codeFile != null && codeFile.exists()) {
10253                try {
10254                    final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0);
10255                    allCodePaths = pkg.getAllCodePaths();
10256                } catch (PackageParserException e) {
10257                    // Ignored; we tried our best
10258                }
10259            }
10260
10261            cleanUp();
10262            removeDexFiles(allCodePaths, instructionSets);
10263        }
10264
10265        boolean doPostDeleteLI(boolean delete) {
10266            // XXX err, shouldn't we respect the delete flag?
10267            cleanUpResourcesLI();
10268            return true;
10269        }
10270    }
10271
10272    private boolean isAsecExternal(String cid) {
10273        final String asecPath = PackageHelper.getSdFilesystem(cid);
10274        return !asecPath.startsWith(mAsecInternalPath);
10275    }
10276
10277    private static void maybeThrowExceptionForMultiArchCopy(String message, int copyRet) throws
10278            PackageManagerException {
10279        if (copyRet < 0) {
10280            if (copyRet != PackageManager.NO_NATIVE_LIBRARIES &&
10281                    copyRet != PackageManager.INSTALL_FAILED_NO_MATCHING_ABIS) {
10282                throw new PackageManagerException(copyRet, message);
10283            }
10284        }
10285    }
10286
10287    /**
10288     * Extract the MountService "container ID" from the full code path of an
10289     * .apk.
10290     */
10291    static String cidFromCodePath(String fullCodePath) {
10292        int eidx = fullCodePath.lastIndexOf("/");
10293        String subStr1 = fullCodePath.substring(0, eidx);
10294        int sidx = subStr1.lastIndexOf("/");
10295        return subStr1.substring(sidx+1, eidx);
10296    }
10297
10298    /**
10299     * Logic to handle installation of ASEC applications, including copying and
10300     * renaming logic.
10301     */
10302    class AsecInstallArgs extends InstallArgs {
10303        static final String RES_FILE_NAME = "pkg.apk";
10304        static final String PUBLIC_RES_FILE_NAME = "res.zip";
10305
10306        String cid;
10307        String packagePath;
10308        String resourcePath;
10309
10310        /** New install */
10311        AsecInstallArgs(InstallParams params) {
10312            super(params.origin, params.move, params.observer, params.installFlags,
10313                    params.installerPackageName, params.volumeUuid, params.getManifestDigest(),
10314                    params.getUser(), null /* instruction sets */, params.packageAbiOverride);
10315        }
10316
10317        /** Existing install */
10318        AsecInstallArgs(String fullCodePath, String[] instructionSets,
10319                        boolean isExternal, boolean isForwardLocked) {
10320            super(OriginInfo.fromNothing(), null, null, (isExternal ? INSTALL_EXTERNAL : 0)
10321                    | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null, null,
10322                    instructionSets, null);
10323            // Hackily pretend we're still looking at a full code path
10324            if (!fullCodePath.endsWith(RES_FILE_NAME)) {
10325                fullCodePath = new File(fullCodePath, RES_FILE_NAME).getAbsolutePath();
10326            }
10327
10328            // Extract cid from fullCodePath
10329            int eidx = fullCodePath.lastIndexOf("/");
10330            String subStr1 = fullCodePath.substring(0, eidx);
10331            int sidx = subStr1.lastIndexOf("/");
10332            cid = subStr1.substring(sidx+1, eidx);
10333            setMountPath(subStr1);
10334        }
10335
10336        AsecInstallArgs(String cid, String[] instructionSets, boolean isForwardLocked) {
10337            super(OriginInfo.fromNothing(), null, null, (isAsecExternal(cid) ? INSTALL_EXTERNAL : 0)
10338                    | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null, null,
10339                    instructionSets, null);
10340            this.cid = cid;
10341            setMountPath(PackageHelper.getSdDir(cid));
10342        }
10343
10344        void createCopyFile() {
10345            cid = mInstallerService.allocateExternalStageCidLegacy();
10346        }
10347
10348        int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
10349            if (origin.staged) {
10350                Slog.d(TAG, origin.cid + " already staged; skipping copy");
10351                cid = origin.cid;
10352                setMountPath(PackageHelper.getSdDir(cid));
10353                return PackageManager.INSTALL_SUCCEEDED;
10354            }
10355
10356            if (temp) {
10357                createCopyFile();
10358            } else {
10359                /*
10360                 * Pre-emptively destroy the container since it's destroyed if
10361                 * copying fails due to it existing anyway.
10362                 */
10363                PackageHelper.destroySdDir(cid);
10364            }
10365
10366            final String newMountPath = imcs.copyPackageToContainer(
10367                    origin.file.getAbsolutePath(), cid, getEncryptKey(), isExternalAsec(),
10368                    isFwdLocked(), deriveAbiOverride(abiOverride, null /* settings */));
10369
10370            if (newMountPath != null) {
10371                setMountPath(newMountPath);
10372                return PackageManager.INSTALL_SUCCEEDED;
10373            } else {
10374                return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
10375            }
10376        }
10377
10378        @Override
10379        String getCodePath() {
10380            return packagePath;
10381        }
10382
10383        @Override
10384        String getResourcePath() {
10385            return resourcePath;
10386        }
10387
10388        int doPreInstall(int status) {
10389            if (status != PackageManager.INSTALL_SUCCEEDED) {
10390                // Destroy container
10391                PackageHelper.destroySdDir(cid);
10392            } else {
10393                boolean mounted = PackageHelper.isContainerMounted(cid);
10394                if (!mounted) {
10395                    String newMountPath = PackageHelper.mountSdDir(cid, getEncryptKey(),
10396                            Process.SYSTEM_UID);
10397                    if (newMountPath != null) {
10398                        setMountPath(newMountPath);
10399                    } else {
10400                        return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
10401                    }
10402                }
10403            }
10404            return status;
10405        }
10406
10407        boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
10408            String newCacheId = getNextCodePath(oldCodePath, pkg.packageName, "/" + RES_FILE_NAME);
10409            String newMountPath = null;
10410            if (PackageHelper.isContainerMounted(cid)) {
10411                // Unmount the container
10412                if (!PackageHelper.unMountSdDir(cid)) {
10413                    Slog.i(TAG, "Failed to unmount " + cid + " before renaming");
10414                    return false;
10415                }
10416            }
10417            if (!PackageHelper.renameSdDir(cid, newCacheId)) {
10418                Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId +
10419                        " which might be stale. Will try to clean up.");
10420                // Clean up the stale container and proceed to recreate.
10421                if (!PackageHelper.destroySdDir(newCacheId)) {
10422                    Slog.e(TAG, "Very strange. Cannot clean up stale container " + newCacheId);
10423                    return false;
10424                }
10425                // Successfully cleaned up stale container. Try to rename again.
10426                if (!PackageHelper.renameSdDir(cid, newCacheId)) {
10427                    Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId
10428                            + " inspite of cleaning it up.");
10429                    return false;
10430                }
10431            }
10432            if (!PackageHelper.isContainerMounted(newCacheId)) {
10433                Slog.w(TAG, "Mounting container " + newCacheId);
10434                newMountPath = PackageHelper.mountSdDir(newCacheId,
10435                        getEncryptKey(), Process.SYSTEM_UID);
10436            } else {
10437                newMountPath = PackageHelper.getSdDir(newCacheId);
10438            }
10439            if (newMountPath == null) {
10440                Slog.w(TAG, "Failed to get cache path for  " + newCacheId);
10441                return false;
10442            }
10443            Log.i(TAG, "Succesfully renamed " + cid +
10444                    " to " + newCacheId +
10445                    " at new path: " + newMountPath);
10446            cid = newCacheId;
10447
10448            final File beforeCodeFile = new File(packagePath);
10449            setMountPath(newMountPath);
10450            final File afterCodeFile = new File(packagePath);
10451
10452            // Reflect the rename in scanned details
10453            pkg.codePath = afterCodeFile.getAbsolutePath();
10454            pkg.baseCodePath = FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile,
10455                    pkg.baseCodePath);
10456            pkg.splitCodePaths = FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile,
10457                    pkg.splitCodePaths);
10458
10459            // Reflect the rename in app info
10460            pkg.applicationInfo.volumeUuid = pkg.volumeUuid;
10461            pkg.applicationInfo.setCodePath(pkg.codePath);
10462            pkg.applicationInfo.setBaseCodePath(pkg.baseCodePath);
10463            pkg.applicationInfo.setSplitCodePaths(pkg.splitCodePaths);
10464            pkg.applicationInfo.setResourcePath(pkg.codePath);
10465            pkg.applicationInfo.setBaseResourcePath(pkg.baseCodePath);
10466            pkg.applicationInfo.setSplitResourcePaths(pkg.splitCodePaths);
10467
10468            return true;
10469        }
10470
10471        private void setMountPath(String mountPath) {
10472            final File mountFile = new File(mountPath);
10473
10474            final File monolithicFile = new File(mountFile, RES_FILE_NAME);
10475            if (monolithicFile.exists()) {
10476                packagePath = monolithicFile.getAbsolutePath();
10477                if (isFwdLocked()) {
10478                    resourcePath = new File(mountFile, PUBLIC_RES_FILE_NAME).getAbsolutePath();
10479                } else {
10480                    resourcePath = packagePath;
10481                }
10482            } else {
10483                packagePath = mountFile.getAbsolutePath();
10484                resourcePath = packagePath;
10485            }
10486        }
10487
10488        int doPostInstall(int status, int uid) {
10489            if (status != PackageManager.INSTALL_SUCCEEDED) {
10490                cleanUp();
10491            } else {
10492                final int groupOwner;
10493                final String protectedFile;
10494                if (isFwdLocked()) {
10495                    groupOwner = UserHandle.getSharedAppGid(uid);
10496                    protectedFile = RES_FILE_NAME;
10497                } else {
10498                    groupOwner = -1;
10499                    protectedFile = null;
10500                }
10501
10502                if (uid < Process.FIRST_APPLICATION_UID
10503                        || !PackageHelper.fixSdPermissions(cid, groupOwner, protectedFile)) {
10504                    Slog.e(TAG, "Failed to finalize " + cid);
10505                    PackageHelper.destroySdDir(cid);
10506                    return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
10507                }
10508
10509                boolean mounted = PackageHelper.isContainerMounted(cid);
10510                if (!mounted) {
10511                    PackageHelper.mountSdDir(cid, getEncryptKey(), Process.myUid());
10512                }
10513            }
10514            return status;
10515        }
10516
10517        private void cleanUp() {
10518            if (DEBUG_SD_INSTALL) Slog.i(TAG, "cleanUp");
10519
10520            // Destroy secure container
10521            PackageHelper.destroySdDir(cid);
10522        }
10523
10524        private List<String> getAllCodePaths() {
10525            final File codeFile = new File(getCodePath());
10526            if (codeFile != null && codeFile.exists()) {
10527                try {
10528                    final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0);
10529                    return pkg.getAllCodePaths();
10530                } catch (PackageParserException e) {
10531                    // Ignored; we tried our best
10532                }
10533            }
10534            return Collections.EMPTY_LIST;
10535        }
10536
10537        void cleanUpResourcesLI() {
10538            // Enumerate all code paths before deleting
10539            cleanUpResourcesLI(getAllCodePaths());
10540        }
10541
10542        private void cleanUpResourcesLI(List<String> allCodePaths) {
10543            cleanUp();
10544            removeDexFiles(allCodePaths, instructionSets);
10545        }
10546
10547        String getPackageName() {
10548            return getAsecPackageName(cid);
10549        }
10550
10551        boolean doPostDeleteLI(boolean delete) {
10552            if (DEBUG_SD_INSTALL) Slog.i(TAG, "doPostDeleteLI() del=" + delete);
10553            final List<String> allCodePaths = getAllCodePaths();
10554            boolean mounted = PackageHelper.isContainerMounted(cid);
10555            if (mounted) {
10556                // Unmount first
10557                if (PackageHelper.unMountSdDir(cid)) {
10558                    mounted = false;
10559                }
10560            }
10561            if (!mounted && delete) {
10562                cleanUpResourcesLI(allCodePaths);
10563            }
10564            return !mounted;
10565        }
10566
10567        @Override
10568        int doPreCopy() {
10569            if (isFwdLocked()) {
10570                if (!PackageHelper.fixSdPermissions(cid,
10571                        getPackageUid(DEFAULT_CONTAINER_PACKAGE, 0), RES_FILE_NAME)) {
10572                    return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
10573                }
10574            }
10575
10576            return PackageManager.INSTALL_SUCCEEDED;
10577        }
10578
10579        @Override
10580        int doPostCopy(int uid) {
10581            if (isFwdLocked()) {
10582                if (uid < Process.FIRST_APPLICATION_UID
10583                        || !PackageHelper.fixSdPermissions(cid, UserHandle.getSharedAppGid(uid),
10584                                RES_FILE_NAME)) {
10585                    Slog.e(TAG, "Failed to finalize " + cid);
10586                    PackageHelper.destroySdDir(cid);
10587                    return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
10588                }
10589            }
10590
10591            return PackageManager.INSTALL_SUCCEEDED;
10592        }
10593    }
10594
10595    /**
10596     * Logic to handle movement of existing installed applications.
10597     */
10598    class MoveInstallArgs extends InstallArgs {
10599        private File codeFile;
10600        private File resourceFile;
10601
10602        /** New install */
10603        MoveInstallArgs(InstallParams params) {
10604            super(params.origin, params.move, params.observer, params.installFlags,
10605                    params.installerPackageName, params.volumeUuid, params.getManifestDigest(),
10606                    params.getUser(), null /* instruction sets */, params.packageAbiOverride);
10607        }
10608
10609        int copyApk(IMediaContainerService imcs, boolean temp) {
10610            Slog.d(TAG, "Moving " + move.packageName + " from " + move.fromUuid + " to "
10611                    + move.toUuid);
10612            synchronized (mInstaller) {
10613                if (mInstaller.moveCompleteApp(move.fromUuid, move.toUuid, move.packageName,
10614                        move.dataAppName, move.appId, move.seinfo) != 0) {
10615                    return PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
10616                }
10617            }
10618
10619            codeFile = new File(Environment.getDataAppDirectory(move.toUuid), move.dataAppName);
10620            resourceFile = codeFile;
10621            Slog.d(TAG, "codeFile after move is " + codeFile);
10622
10623            return PackageManager.INSTALL_SUCCEEDED;
10624        }
10625
10626        int doPreInstall(int status) {
10627            if (status != PackageManager.INSTALL_SUCCEEDED) {
10628                cleanUp();
10629            }
10630            return status;
10631        }
10632
10633        boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
10634            if (status != PackageManager.INSTALL_SUCCEEDED) {
10635                cleanUp();
10636                return false;
10637            }
10638
10639            // Reflect the move in app info
10640            pkg.applicationInfo.volumeUuid = pkg.volumeUuid;
10641            pkg.applicationInfo.setCodePath(pkg.codePath);
10642            pkg.applicationInfo.setBaseCodePath(pkg.baseCodePath);
10643            pkg.applicationInfo.setSplitCodePaths(pkg.splitCodePaths);
10644            pkg.applicationInfo.setResourcePath(pkg.codePath);
10645            pkg.applicationInfo.setBaseResourcePath(pkg.baseCodePath);
10646            pkg.applicationInfo.setSplitResourcePaths(pkg.splitCodePaths);
10647
10648            return true;
10649        }
10650
10651        int doPostInstall(int status, int uid) {
10652            if (status != PackageManager.INSTALL_SUCCEEDED) {
10653                cleanUp();
10654            }
10655            return status;
10656        }
10657
10658        @Override
10659        String getCodePath() {
10660            return (codeFile != null) ? codeFile.getAbsolutePath() : null;
10661        }
10662
10663        @Override
10664        String getResourcePath() {
10665            return (resourceFile != null) ? resourceFile.getAbsolutePath() : null;
10666        }
10667
10668        private boolean cleanUp() {
10669            if (codeFile == null || !codeFile.exists()) {
10670                return false;
10671            }
10672
10673            if (codeFile.isDirectory()) {
10674                mInstaller.rmPackageDir(codeFile.getAbsolutePath());
10675            } else {
10676                codeFile.delete();
10677            }
10678
10679            if (resourceFile != null && !FileUtils.contains(codeFile, resourceFile)) {
10680                resourceFile.delete();
10681            }
10682
10683            return true;
10684        }
10685
10686        void cleanUpResourcesLI() {
10687            cleanUp();
10688        }
10689
10690        boolean doPostDeleteLI(boolean delete) {
10691            // XXX err, shouldn't we respect the delete flag?
10692            cleanUpResourcesLI();
10693            return true;
10694        }
10695    }
10696
10697    static String getAsecPackageName(String packageCid) {
10698        int idx = packageCid.lastIndexOf("-");
10699        if (idx == -1) {
10700            return packageCid;
10701        }
10702        return packageCid.substring(0, idx);
10703    }
10704
10705    // Utility method used to create code paths based on package name and available index.
10706    private static String getNextCodePath(String oldCodePath, String prefix, String suffix) {
10707        String idxStr = "";
10708        int idx = 1;
10709        // Fall back to default value of idx=1 if prefix is not
10710        // part of oldCodePath
10711        if (oldCodePath != null) {
10712            String subStr = oldCodePath;
10713            // Drop the suffix right away
10714            if (suffix != null && subStr.endsWith(suffix)) {
10715                subStr = subStr.substring(0, subStr.length() - suffix.length());
10716            }
10717            // If oldCodePath already contains prefix find out the
10718            // ending index to either increment or decrement.
10719            int sidx = subStr.lastIndexOf(prefix);
10720            if (sidx != -1) {
10721                subStr = subStr.substring(sidx + prefix.length());
10722                if (subStr != null) {
10723                    if (subStr.startsWith(INSTALL_PACKAGE_SUFFIX)) {
10724                        subStr = subStr.substring(INSTALL_PACKAGE_SUFFIX.length());
10725                    }
10726                    try {
10727                        idx = Integer.parseInt(subStr);
10728                        if (idx <= 1) {
10729                            idx++;
10730                        } else {
10731                            idx--;
10732                        }
10733                    } catch(NumberFormatException e) {
10734                    }
10735                }
10736            }
10737        }
10738        idxStr = INSTALL_PACKAGE_SUFFIX + Integer.toString(idx);
10739        return prefix + idxStr;
10740    }
10741
10742    private File getNextCodePath(File targetDir, String packageName) {
10743        int suffix = 1;
10744        File result;
10745        do {
10746            result = new File(targetDir, packageName + "-" + suffix);
10747            suffix++;
10748        } while (result.exists());
10749        return result;
10750    }
10751
10752    // Utility method that returns the relative package path with respect
10753    // to the installation directory. Like say for /data/data/com.test-1.apk
10754    // string com.test-1 is returned.
10755    static String deriveCodePathName(String codePath) {
10756        if (codePath == null) {
10757            return null;
10758        }
10759        final File codeFile = new File(codePath);
10760        final String name = codeFile.getName();
10761        if (codeFile.isDirectory()) {
10762            return name;
10763        } else if (name.endsWith(".apk") || name.endsWith(".tmp")) {
10764            final int lastDot = name.lastIndexOf('.');
10765            return name.substring(0, lastDot);
10766        } else {
10767            Slog.w(TAG, "Odd, " + codePath + " doesn't look like an APK");
10768            return null;
10769        }
10770    }
10771
10772    class PackageInstalledInfo {
10773        String name;
10774        int uid;
10775        // The set of users that originally had this package installed.
10776        int[] origUsers;
10777        // The set of users that now have this package installed.
10778        int[] newUsers;
10779        PackageParser.Package pkg;
10780        int returnCode;
10781        String returnMsg;
10782        PackageRemovedInfo removedInfo;
10783
10784        public void setError(int code, String msg) {
10785            returnCode = code;
10786            returnMsg = msg;
10787            Slog.w(TAG, msg);
10788        }
10789
10790        public void setError(String msg, PackageParserException e) {
10791            returnCode = e.error;
10792            returnMsg = ExceptionUtils.getCompleteMessage(msg, e);
10793            Slog.w(TAG, msg, e);
10794        }
10795
10796        public void setError(String msg, PackageManagerException e) {
10797            returnCode = e.error;
10798            returnMsg = ExceptionUtils.getCompleteMessage(msg, e);
10799            Slog.w(TAG, msg, e);
10800        }
10801
10802        // In some error cases we want to convey more info back to the observer
10803        String origPackage;
10804        String origPermission;
10805    }
10806
10807    /*
10808     * Install a non-existing package.
10809     */
10810    private void installNewPackageLI(PackageParser.Package pkg, int parseFlags, int scanFlags,
10811            UserHandle user, String installerPackageName, String volumeUuid,
10812            PackageInstalledInfo res) {
10813        // Remember this for later, in case we need to rollback this install
10814        String pkgName = pkg.packageName;
10815
10816        if (DEBUG_INSTALL) Slog.d(TAG, "installNewPackageLI: " + pkg);
10817        final boolean dataDirExists = PackageManager.getDataDirForUser(volumeUuid, pkgName,
10818                UserHandle.USER_OWNER).exists();
10819        synchronized(mPackages) {
10820            if (mSettings.mRenamedPackages.containsKey(pkgName)) {
10821                // A package with the same name is already installed, though
10822                // it has been renamed to an older name.  The package we
10823                // are trying to install should be installed as an update to
10824                // the existing one, but that has not been requested, so bail.
10825                res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName
10826                        + " without first uninstalling package running as "
10827                        + mSettings.mRenamedPackages.get(pkgName));
10828                return;
10829            }
10830            if (mPackages.containsKey(pkgName)) {
10831                // Don't allow installation over an existing package with the same name.
10832                res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName
10833                        + " without first uninstalling.");
10834                return;
10835            }
10836        }
10837
10838        try {
10839            PackageParser.Package newPackage = scanPackageLI(pkg, parseFlags, scanFlags,
10840                    System.currentTimeMillis(), user);
10841
10842            updateSettingsLI(newPackage, installerPackageName, volumeUuid, null, null, res, user);
10843            // delete the partially installed application. the data directory will have to be
10844            // restored if it was already existing
10845            if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
10846                // remove package from internal structures.  Note that we want deletePackageX to
10847                // delete the package data and cache directories that it created in
10848                // scanPackageLocked, unless those directories existed before we even tried to
10849                // install.
10850                deletePackageLI(pkgName, UserHandle.ALL, false, null, null,
10851                        dataDirExists ? PackageManager.DELETE_KEEP_DATA : 0,
10852                                res.removedInfo, true);
10853            }
10854
10855        } catch (PackageManagerException e) {
10856            res.setError("Package couldn't be installed in " + pkg.codePath, e);
10857        }
10858    }
10859
10860    private boolean checkUpgradeKeySetLP(PackageSetting oldPS, PackageParser.Package newPkg) {
10861        // Upgrade keysets are being used.  Determine if new package has a superset of the
10862        // required keys.
10863        long[] upgradeKeySets = oldPS.keySetData.getUpgradeKeySets();
10864        KeySetManagerService ksms = mSettings.mKeySetManagerService;
10865        for (int i = 0; i < upgradeKeySets.length; i++) {
10866            Set<PublicKey> upgradeSet = ksms.getPublicKeysFromKeySetLPr(upgradeKeySets[i]);
10867            if (newPkg.mSigningKeys.containsAll(upgradeSet)) {
10868                return true;
10869            }
10870        }
10871        return false;
10872    }
10873
10874    private void replacePackageLI(PackageParser.Package pkg, int parseFlags, int scanFlags,
10875            UserHandle user, String installerPackageName, String volumeUuid,
10876            PackageInstalledInfo res) {
10877        final PackageParser.Package oldPackage;
10878        final String pkgName = pkg.packageName;
10879        final int[] allUsers;
10880        final boolean[] perUserInstalled;
10881        final boolean weFroze;
10882
10883        // First find the old package info and check signatures
10884        synchronized(mPackages) {
10885            oldPackage = mPackages.get(pkgName);
10886            if (DEBUG_INSTALL) Slog.d(TAG, "replacePackageLI: new=" + pkg + ", old=" + oldPackage);
10887            final PackageSetting ps = mSettings.mPackages.get(pkgName);
10888            if (ps == null || !ps.keySetData.isUsingUpgradeKeySets() || ps.sharedUser != null) {
10889                // default to original signature matching
10890                if (compareSignatures(oldPackage.mSignatures, pkg.mSignatures)
10891                    != PackageManager.SIGNATURE_MATCH) {
10892                    res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
10893                            "New package has a different signature: " + pkgName);
10894                    return;
10895                }
10896            } else {
10897                if(!checkUpgradeKeySetLP(ps, pkg)) {
10898                    res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
10899                            "New package not signed by keys specified by upgrade-keysets: "
10900                            + pkgName);
10901                    return;
10902                }
10903            }
10904
10905            // In case of rollback, remember per-user/profile install state
10906            allUsers = sUserManager.getUserIds();
10907            perUserInstalled = new boolean[allUsers.length];
10908            for (int i = 0; i < allUsers.length; i++) {
10909                perUserInstalled[i] = ps != null ? ps.getInstalled(allUsers[i]) : false;
10910            }
10911
10912            // Mark the app as frozen to prevent launching during the upgrade
10913            // process, and then kill all running instances
10914            if (!ps.frozen) {
10915                ps.frozen = true;
10916                weFroze = true;
10917            } else {
10918                weFroze = false;
10919            }
10920        }
10921
10922        // Now that we're guarded by frozen state, kill app during upgrade
10923        killApplication(pkgName, oldPackage.applicationInfo.uid, "replace pkg");
10924
10925        try {
10926            boolean sysPkg = (isSystemApp(oldPackage));
10927            if (sysPkg) {
10928                replaceSystemPackageLI(oldPackage, pkg, parseFlags, scanFlags,
10929                        user, allUsers, perUserInstalled, installerPackageName, volumeUuid, res);
10930            } else {
10931                replaceNonSystemPackageLI(oldPackage, pkg, parseFlags, scanFlags,
10932                        user, allUsers, perUserInstalled, installerPackageName, volumeUuid, res);
10933            }
10934        } finally {
10935            // Regardless of success or failure of upgrade steps above, always
10936            // unfreeze the package if we froze it
10937            if (weFroze) {
10938                unfreezePackage(pkgName);
10939            }
10940        }
10941    }
10942
10943    private void replaceNonSystemPackageLI(PackageParser.Package deletedPackage,
10944            PackageParser.Package pkg, int parseFlags, int scanFlags, UserHandle user,
10945            int[] allUsers, boolean[] perUserInstalled, String installerPackageName,
10946            String volumeUuid, PackageInstalledInfo res) {
10947        String pkgName = deletedPackage.packageName;
10948        boolean deletedPkg = true;
10949        boolean updatedSettings = false;
10950
10951        if (DEBUG_INSTALL) Slog.d(TAG, "replaceNonSystemPackageLI: new=" + pkg + ", old="
10952                + deletedPackage);
10953        long origUpdateTime;
10954        if (pkg.mExtras != null) {
10955            origUpdateTime = ((PackageSetting)pkg.mExtras).lastUpdateTime;
10956        } else {
10957            origUpdateTime = 0;
10958        }
10959
10960        // First delete the existing package while retaining the data directory
10961        if (!deletePackageLI(pkgName, null, true, null, null, PackageManager.DELETE_KEEP_DATA,
10962                res.removedInfo, true)) {
10963            // If the existing package wasn't successfully deleted
10964            res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE, "replaceNonSystemPackageLI");
10965            deletedPkg = false;
10966        } else {
10967            // Successfully deleted the old package; proceed with replace.
10968
10969            // If deleted package lived in a container, give users a chance to
10970            // relinquish resources before killing.
10971            if (deletedPackage.isForwardLocked() || isExternal(deletedPackage)) {
10972                if (DEBUG_INSTALL) {
10973                    Slog.i(TAG, "upgrading pkg " + deletedPackage + " is ASEC-hosted -> UNAVAILABLE");
10974                }
10975                final int[] uidArray = new int[] { deletedPackage.applicationInfo.uid };
10976                final ArrayList<String> pkgList = new ArrayList<String>(1);
10977                pkgList.add(deletedPackage.applicationInfo.packageName);
10978                sendResourcesChangedBroadcast(false, true, pkgList, uidArray, null);
10979            }
10980
10981            deleteCodeCacheDirsLI(pkg.volumeUuid, pkgName);
10982            try {
10983                final PackageParser.Package newPackage = scanPackageLI(pkg, parseFlags,
10984                        scanFlags | SCAN_UPDATE_TIME, System.currentTimeMillis(), user);
10985                updateSettingsLI(newPackage, installerPackageName, volumeUuid, allUsers,
10986                        perUserInstalled, res, user);
10987                updatedSettings = true;
10988            } catch (PackageManagerException e) {
10989                res.setError("Package couldn't be installed in " + pkg.codePath, e);
10990            }
10991        }
10992
10993        if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
10994            // remove package from internal structures.  Note that we want deletePackageX to
10995            // delete the package data and cache directories that it created in
10996            // scanPackageLocked, unless those directories existed before we even tried to
10997            // install.
10998            if(updatedSettings) {
10999                if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, rolling pack: " + pkgName);
11000                deletePackageLI(
11001                        pkgName, null, true, allUsers, perUserInstalled,
11002                        PackageManager.DELETE_KEEP_DATA,
11003                                res.removedInfo, true);
11004            }
11005            // Since we failed to install the new package we need to restore the old
11006            // package that we deleted.
11007            if (deletedPkg) {
11008                if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, reinstalling: " + deletedPackage);
11009                File restoreFile = new File(deletedPackage.codePath);
11010                // Parse old package
11011                boolean oldExternal = isExternal(deletedPackage);
11012                int oldParseFlags  = mDefParseFlags | PackageParser.PARSE_CHATTY |
11013                        (deletedPackage.isForwardLocked() ? PackageParser.PARSE_FORWARD_LOCK : 0) |
11014                        (oldExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0);
11015                int oldScanFlags = SCAN_UPDATE_SIGNATURE | SCAN_UPDATE_TIME;
11016                try {
11017                    scanPackageLI(restoreFile, oldParseFlags, oldScanFlags, origUpdateTime, null);
11018                } catch (PackageManagerException e) {
11019                    Slog.e(TAG, "Failed to restore package : " + pkgName + " after failed upgrade: "
11020                            + e.getMessage());
11021                    return;
11022                }
11023                // Restore of old package succeeded. Update permissions.
11024                // writer
11025                synchronized (mPackages) {
11026                    updatePermissionsLPw(deletedPackage.packageName, deletedPackage,
11027                            UPDATE_PERMISSIONS_ALL);
11028                    // can downgrade to reader
11029                    mSettings.writeLPr();
11030                }
11031                Slog.i(TAG, "Successfully restored package : " + pkgName + " after failed upgrade");
11032            }
11033        }
11034    }
11035
11036    private void replaceSystemPackageLI(PackageParser.Package deletedPackage,
11037            PackageParser.Package pkg, int parseFlags, int scanFlags, UserHandle user,
11038            int[] allUsers, boolean[] perUserInstalled, String installerPackageName,
11039            String volumeUuid, PackageInstalledInfo res) {
11040        if (DEBUG_INSTALL) Slog.d(TAG, "replaceSystemPackageLI: new=" + pkg
11041                + ", old=" + deletedPackage);
11042        boolean disabledSystem = false;
11043        boolean updatedSettings = false;
11044        parseFlags |= PackageParser.PARSE_IS_SYSTEM;
11045        if ((deletedPackage.applicationInfo.privateFlags&ApplicationInfo.PRIVATE_FLAG_PRIVILEGED)
11046                != 0) {
11047            parseFlags |= PackageParser.PARSE_IS_PRIVILEGED;
11048        }
11049        String packageName = deletedPackage.packageName;
11050        if (packageName == null) {
11051            res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE,
11052                    "Attempt to delete null packageName.");
11053            return;
11054        }
11055        PackageParser.Package oldPkg;
11056        PackageSetting oldPkgSetting;
11057        // reader
11058        synchronized (mPackages) {
11059            oldPkg = mPackages.get(packageName);
11060            oldPkgSetting = mSettings.mPackages.get(packageName);
11061            if((oldPkg == null) || (oldPkg.applicationInfo == null) ||
11062                    (oldPkgSetting == null)) {
11063                res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE,
11064                        "Couldn't find package:" + packageName + " information");
11065                return;
11066            }
11067        }
11068
11069        res.removedInfo.uid = oldPkg.applicationInfo.uid;
11070        res.removedInfo.removedPackage = packageName;
11071        // Remove existing system package
11072        removePackageLI(oldPkgSetting, true);
11073        // writer
11074        synchronized (mPackages) {
11075            disabledSystem = mSettings.disableSystemPackageLPw(packageName);
11076            if (!disabledSystem && deletedPackage != null) {
11077                // We didn't need to disable the .apk as a current system package,
11078                // which means we are replacing another update that is already
11079                // installed.  We need to make sure to delete the older one's .apk.
11080                res.removedInfo.args = createInstallArgsForExisting(0,
11081                        deletedPackage.applicationInfo.getCodePath(),
11082                        deletedPackage.applicationInfo.getResourcePath(),
11083                        getAppDexInstructionSets(deletedPackage.applicationInfo));
11084            } else {
11085                res.removedInfo.args = null;
11086            }
11087        }
11088
11089        // Successfully disabled the old package. Now proceed with re-installation
11090        deleteCodeCacheDirsLI(pkg.volumeUuid, packageName);
11091
11092        res.returnCode = PackageManager.INSTALL_SUCCEEDED;
11093        pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
11094
11095        PackageParser.Package newPackage = null;
11096        try {
11097            newPackage = scanPackageLI(pkg, parseFlags, scanFlags, 0, user);
11098            if (newPackage.mExtras != null) {
11099                final PackageSetting newPkgSetting = (PackageSetting) newPackage.mExtras;
11100                newPkgSetting.firstInstallTime = oldPkgSetting.firstInstallTime;
11101                newPkgSetting.lastUpdateTime = System.currentTimeMillis();
11102
11103                // is the update attempting to change shared user? that isn't going to work...
11104                if (oldPkgSetting.sharedUser != newPkgSetting.sharedUser) {
11105                    res.setError(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
11106                            "Forbidding shared user change from " + oldPkgSetting.sharedUser
11107                            + " to " + newPkgSetting.sharedUser);
11108                    updatedSettings = true;
11109                }
11110            }
11111
11112            if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
11113                updateSettingsLI(newPackage, installerPackageName, volumeUuid, allUsers,
11114                        perUserInstalled, res, user);
11115                updatedSettings = true;
11116            }
11117
11118        } catch (PackageManagerException e) {
11119            res.setError("Package couldn't be installed in " + pkg.codePath, e);
11120        }
11121
11122        if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
11123            // Re installation failed. Restore old information
11124            // Remove new pkg information
11125            if (newPackage != null) {
11126                removeInstalledPackageLI(newPackage, true);
11127            }
11128            // Add back the old system package
11129            try {
11130                scanPackageLI(oldPkg, parseFlags, SCAN_UPDATE_SIGNATURE, 0, user);
11131            } catch (PackageManagerException e) {
11132                Slog.e(TAG, "Failed to restore original package: " + e.getMessage());
11133            }
11134            // Restore the old system information in Settings
11135            synchronized (mPackages) {
11136                if (disabledSystem) {
11137                    mSettings.enableSystemPackageLPw(packageName);
11138                }
11139                if (updatedSettings) {
11140                    mSettings.setInstallerPackageName(packageName,
11141                            oldPkgSetting.installerPackageName);
11142                }
11143                mSettings.writeLPr();
11144            }
11145        }
11146    }
11147
11148    private void updateSettingsLI(PackageParser.Package newPackage, String installerPackageName,
11149            String volumeUuid, int[] allUsers, boolean[] perUserInstalled, PackageInstalledInfo res,
11150            UserHandle user) {
11151        String pkgName = newPackage.packageName;
11152        synchronized (mPackages) {
11153            //write settings. the installStatus will be incomplete at this stage.
11154            //note that the new package setting would have already been
11155            //added to mPackages. It hasn't been persisted yet.
11156            mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_INCOMPLETE);
11157            mSettings.writeLPr();
11158        }
11159
11160        if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + newPackage.codePath);
11161
11162        synchronized (mPackages) {
11163            updatePermissionsLPw(newPackage.packageName, newPackage,
11164                    UPDATE_PERMISSIONS_REPLACE_PKG | (newPackage.permissions.size() > 0
11165                            ? UPDATE_PERMISSIONS_ALL : 0));
11166            // For system-bundled packages, we assume that installing an upgraded version
11167            // of the package implies that the user actually wants to run that new code,
11168            // so we enable the package.
11169            PackageSetting ps = mSettings.mPackages.get(pkgName);
11170            if (ps != null) {
11171                if (isSystemApp(newPackage)) {
11172                    // NB: implicit assumption that system package upgrades apply to all users
11173                    if (DEBUG_INSTALL) {
11174                        Slog.d(TAG, "Implicitly enabling system package on upgrade: " + pkgName);
11175                    }
11176                    if (res.origUsers != null) {
11177                        for (int userHandle : res.origUsers) {
11178                            ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT,
11179                                    userHandle, installerPackageName);
11180                        }
11181                    }
11182                    // Also convey the prior install/uninstall state
11183                    if (allUsers != null && perUserInstalled != null) {
11184                        for (int i = 0; i < allUsers.length; i++) {
11185                            if (DEBUG_INSTALL) {
11186                                Slog.d(TAG, "    user " + allUsers[i]
11187                                        + " => " + perUserInstalled[i]);
11188                            }
11189                            ps.setInstalled(perUserInstalled[i], allUsers[i]);
11190                        }
11191                        // these install state changes will be persisted in the
11192                        // upcoming call to mSettings.writeLPr().
11193                    }
11194                }
11195                // It's implied that when a user requests installation, they want the app to be
11196                // installed and enabled.
11197                int userId = user.getIdentifier();
11198                if (userId != UserHandle.USER_ALL) {
11199                    ps.setInstalled(true, userId);
11200                    ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, userId, installerPackageName);
11201                }
11202            }
11203            res.name = pkgName;
11204            res.uid = newPackage.applicationInfo.uid;
11205            res.pkg = newPackage;
11206            mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_COMPLETE);
11207            mSettings.setInstallerPackageName(pkgName, installerPackageName);
11208            res.returnCode = PackageManager.INSTALL_SUCCEEDED;
11209            //to update install status
11210            mSettings.writeLPr();
11211        }
11212    }
11213
11214    private void installPackageLI(InstallArgs args, PackageInstalledInfo res) {
11215        final int installFlags = args.installFlags;
11216        final String installerPackageName = args.installerPackageName;
11217        final String volumeUuid = args.volumeUuid;
11218        final File tmpPackageFile = new File(args.getCodePath());
11219        final boolean forwardLocked = ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0);
11220        final boolean onExternal = (((installFlags & PackageManager.INSTALL_EXTERNAL) != 0)
11221                || (args.volumeUuid != null));
11222        boolean replace = false;
11223        int scanFlags = SCAN_NEW_INSTALL | SCAN_FORCE_DEX | SCAN_UPDATE_SIGNATURE;
11224        // Result object to be returned
11225        res.returnCode = PackageManager.INSTALL_SUCCEEDED;
11226
11227        if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile);
11228        // Retrieve PackageSettings and parse package
11229        final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY
11230                | (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0)
11231                | (onExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0);
11232        PackageParser pp = new PackageParser();
11233        pp.setSeparateProcesses(mSeparateProcesses);
11234        pp.setDisplayMetrics(mMetrics);
11235
11236        final PackageParser.Package pkg;
11237        try {
11238            pkg = pp.parsePackage(tmpPackageFile, parseFlags);
11239        } catch (PackageParserException e) {
11240            res.setError("Failed parse during installPackageLI", e);
11241            return;
11242        }
11243
11244        // Mark that we have an install time CPU ABI override.
11245        pkg.cpuAbiOverride = args.abiOverride;
11246
11247        String pkgName = res.name = pkg.packageName;
11248        if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_TEST_ONLY) != 0) {
11249            if ((installFlags & PackageManager.INSTALL_ALLOW_TEST) == 0) {
11250                res.setError(INSTALL_FAILED_TEST_ONLY, "installPackageLI");
11251                return;
11252            }
11253        }
11254
11255        try {
11256            pp.collectCertificates(pkg, parseFlags);
11257            pp.collectManifestDigest(pkg);
11258        } catch (PackageParserException e) {
11259            res.setError("Failed collect during installPackageLI", e);
11260            return;
11261        }
11262
11263        /* If the installer passed in a manifest digest, compare it now. */
11264        if (args.manifestDigest != null) {
11265            if (DEBUG_INSTALL) {
11266                final String parsedManifest = pkg.manifestDigest == null ? "null"
11267                        : pkg.manifestDigest.toString();
11268                Slog.d(TAG, "Comparing manifests: " + args.manifestDigest.toString() + " vs. "
11269                        + parsedManifest);
11270            }
11271
11272            if (!args.manifestDigest.equals(pkg.manifestDigest)) {
11273                res.setError(INSTALL_FAILED_PACKAGE_CHANGED, "Manifest digest changed");
11274                return;
11275            }
11276        } else if (DEBUG_INSTALL) {
11277            final String parsedManifest = pkg.manifestDigest == null
11278                    ? "null" : pkg.manifestDigest.toString();
11279            Slog.d(TAG, "manifestDigest was not present, but parser got: " + parsedManifest);
11280        }
11281
11282        // Get rid of all references to package scan path via parser.
11283        pp = null;
11284        String oldCodePath = null;
11285        boolean systemApp = false;
11286        synchronized (mPackages) {
11287            // Check if installing already existing package
11288            if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
11289                String oldName = mSettings.mRenamedPackages.get(pkgName);
11290                if (pkg.mOriginalPackages != null
11291                        && pkg.mOriginalPackages.contains(oldName)
11292                        && mPackages.containsKey(oldName)) {
11293                    // This package is derived from an original package,
11294                    // and this device has been updating from that original
11295                    // name.  We must continue using the original name, so
11296                    // rename the new package here.
11297                    pkg.setPackageName(oldName);
11298                    pkgName = pkg.packageName;
11299                    replace = true;
11300                    if (DEBUG_INSTALL) Slog.d(TAG, "Replacing existing renamed package: oldName="
11301                            + oldName + " pkgName=" + pkgName);
11302                } else if (mPackages.containsKey(pkgName)) {
11303                    // This package, under its official name, already exists
11304                    // on the device; we should replace it.
11305                    replace = true;
11306                    if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing pacakge: " + pkgName);
11307                }
11308            }
11309
11310            PackageSetting ps = mSettings.mPackages.get(pkgName);
11311            if (ps != null) {
11312                if (DEBUG_INSTALL) Slog.d(TAG, "Existing package: " + ps);
11313
11314                // Quick sanity check that we're signed correctly if updating;
11315                // we'll check this again later when scanning, but we want to
11316                // bail early here before tripping over redefined permissions.
11317                if (!ps.keySetData.isUsingUpgradeKeySets() || ps.sharedUser != null) {
11318                    try {
11319                        verifySignaturesLP(ps, pkg);
11320                    } catch (PackageManagerException e) {
11321                        res.setError(e.error, e.getMessage());
11322                        return;
11323                    }
11324                } else {
11325                    if (!checkUpgradeKeySetLP(ps, pkg)) {
11326                        res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
11327                                + pkg.packageName + " upgrade keys do not match the "
11328                                + "previously installed version");
11329                        return;
11330                    }
11331                }
11332
11333                oldCodePath = mSettings.mPackages.get(pkgName).codePathString;
11334                if (ps.pkg != null && ps.pkg.applicationInfo != null) {
11335                    systemApp = (ps.pkg.applicationInfo.flags &
11336                            ApplicationInfo.FLAG_SYSTEM) != 0;
11337                }
11338                res.origUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
11339            }
11340
11341            // Check whether the newly-scanned package wants to define an already-defined perm
11342            int N = pkg.permissions.size();
11343            for (int i = N-1; i >= 0; i--) {
11344                PackageParser.Permission perm = pkg.permissions.get(i);
11345                BasePermission bp = mSettings.mPermissions.get(perm.info.name);
11346                if (bp != null) {
11347                    // If the defining package is signed with our cert, it's okay.  This
11348                    // also includes the "updating the same package" case, of course.
11349                    // "updating same package" could also involve key-rotation.
11350                    final boolean sigsOk;
11351                    if (!bp.sourcePackage.equals(pkg.packageName)
11352                            || !(bp.packageSetting instanceof PackageSetting)
11353                            || !bp.packageSetting.keySetData.isUsingUpgradeKeySets()
11354                            || ((PackageSetting) bp.packageSetting).sharedUser != null) {
11355                        sigsOk = compareSignatures(bp.packageSetting.signatures.mSignatures,
11356                                pkg.mSignatures) == PackageManager.SIGNATURE_MATCH;
11357                    } else {
11358                        sigsOk = checkUpgradeKeySetLP((PackageSetting) bp.packageSetting, pkg);
11359                    }
11360                    if (!sigsOk) {
11361                        // If the owning package is the system itself, we log but allow
11362                        // install to proceed; we fail the install on all other permission
11363                        // redefinitions.
11364                        if (!bp.sourcePackage.equals("android")) {
11365                            res.setError(INSTALL_FAILED_DUPLICATE_PERMISSION, "Package "
11366                                    + pkg.packageName + " attempting to redeclare permission "
11367                                    + perm.info.name + " already owned by " + bp.sourcePackage);
11368                            res.origPermission = perm.info.name;
11369                            res.origPackage = bp.sourcePackage;
11370                            return;
11371                        } else {
11372                            Slog.w(TAG, "Package " + pkg.packageName
11373                                    + " attempting to redeclare system permission "
11374                                    + perm.info.name + "; ignoring new declaration");
11375                            pkg.permissions.remove(i);
11376                        }
11377                    }
11378                }
11379            }
11380
11381        }
11382
11383        if (systemApp && onExternal) {
11384            // Disable updates to system apps on sdcard
11385            res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
11386                    "Cannot install updates to system apps on sdcard");
11387            return;
11388        }
11389
11390        if (args.move != null) {
11391            // We did an in-place move, so dex is ready to roll
11392            scanFlags |= SCAN_NO_DEX;
11393        } else if (!forwardLocked && !pkg.applicationInfo.isExternalAsec()) {
11394            // Enable SCAN_NO_DEX flag to skip dexopt at a later stage
11395            scanFlags |= SCAN_NO_DEX;
11396            // Run dexopt before old package gets removed, to minimize time when app is unavailable
11397            int result = mPackageDexOptimizer
11398                    .performDexOpt(pkg, null /* instruction sets */, true /* forceDex */,
11399                            false /* defer */, false /* inclDependencies */);
11400            if (result == PackageDexOptimizer.DEX_OPT_FAILED) {
11401                res.setError(INSTALL_FAILED_DEXOPT, "Dexopt failed for " + pkg.codePath);
11402                return;
11403            }
11404        }
11405
11406        if (!args.doRename(res.returnCode, pkg, oldCodePath)) {
11407            res.setError(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename");
11408            return;
11409        }
11410
11411        startIntentFilterVerifications(args.user.getIdentifier(), pkg);
11412
11413        if (replace) {
11414            replacePackageLI(pkg, parseFlags, scanFlags, args.user,
11415                    installerPackageName, volumeUuid, res);
11416        } else {
11417            installNewPackageLI(pkg, parseFlags, scanFlags | SCAN_DELETE_DATA_ON_FAILURES,
11418                    args.user, installerPackageName, volumeUuid, res);
11419        }
11420        synchronized (mPackages) {
11421            final PackageSetting ps = mSettings.mPackages.get(pkgName);
11422            if (ps != null) {
11423                res.newUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
11424            }
11425        }
11426    }
11427
11428    private void startIntentFilterVerifications(int userId, PackageParser.Package pkg) {
11429        if (mIntentFilterVerifierComponent == null) {
11430            Slog.d(TAG, "No IntentFilter verification will not be done as "
11431                    + "there is no IntentFilterVerifier available!");
11432            return;
11433        }
11434
11435        final int verifierUid = getPackageUid(
11436                mIntentFilterVerifierComponent.getPackageName(),
11437                (userId == UserHandle.USER_ALL) ? UserHandle.USER_OWNER : userId);
11438
11439        mHandler.removeMessages(START_INTENT_FILTER_VERIFICATIONS);
11440        final Message msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS);
11441        msg.obj = pkg;
11442        msg.arg1 = userId;
11443        msg.arg2 = verifierUid;
11444
11445        mHandler.sendMessage(msg);
11446    }
11447
11448    private void verifyIntentFiltersIfNeeded(int userId, int verifierUid,
11449            PackageParser.Package pkg) {
11450        int size = pkg.activities.size();
11451        if (size == 0) {
11452            Slog.d(TAG, "No activity, so no need to verify any IntentFilter!");
11453            return;
11454        }
11455
11456        final boolean hasDomainURLs = hasDomainURLs(pkg);
11457        if (!hasDomainURLs) {
11458            Slog.d(TAG, "No domain URLs, so no need to verify any IntentFilter!");
11459            return;
11460        }
11461
11462        Slog.d(TAG, "Checking for userId:" + userId + " if any IntentFilter from the " + size
11463                + " Activities needs verification ...");
11464
11465        final int verificationId = mIntentFilterVerificationToken++;
11466        int count = 0;
11467        final String packageName = pkg.packageName;
11468        ArrayList<String> allHosts = new ArrayList<>();
11469
11470        synchronized (mPackages) {
11471            for (PackageParser.Activity a : pkg.activities) {
11472                for (ActivityIntentInfo filter : a.intents) {
11473                    boolean needsFilterVerification = filter.needsVerification();
11474                    if (needsFilterVerification && needsNetworkVerificationLPr(filter)) {
11475                        Slog.d(TAG, "Verification needed for IntentFilter:" + filter.toString());
11476                        mIntentFilterVerifier.addOneIntentFilterVerification(
11477                                verifierUid, userId, verificationId, filter, packageName);
11478                        count++;
11479                    } else if (!needsFilterVerification) {
11480                        Slog.d(TAG, "No verification needed for IntentFilter:" + filter.toString());
11481                        if (hasValidDomains(filter)) {
11482                            ArrayList<String> hosts = filter.getHostsList();
11483                            if (hosts.size() > 0) {
11484                                allHosts.addAll(hosts);
11485                            } else {
11486                                if (allHosts.isEmpty()) {
11487                                    allHosts.add("*");
11488                                }
11489                            }
11490                        }
11491                    } else {
11492                        Slog.d(TAG, "Verification already done for IntentFilter:"
11493                                + filter.toString());
11494                    }
11495                }
11496            }
11497        }
11498
11499        if (count > 0) {
11500            mIntentFilterVerifier.startVerifications(userId);
11501            Slog.d(TAG, "Started " + count + " IntentFilter verification"
11502                    + (count > 1 ? "s" : "") +  " for userId:" + userId + "!");
11503        } else {
11504            Slog.d(TAG, "No need to start any IntentFilter verification!");
11505            if (allHosts.size() > 0 && mSettings.createIntentFilterVerificationIfNeededLPw(
11506                    packageName, allHosts) != null) {
11507                scheduleWriteSettingsLocked();
11508            }
11509        }
11510    }
11511
11512    private boolean needsNetworkVerificationLPr(ActivityIntentInfo filter) {
11513        final ComponentName cn  = filter.activity.getComponentName();
11514        final String packageName = cn.getPackageName();
11515
11516        IntentFilterVerificationInfo ivi = mSettings.getIntentFilterVerificationLPr(
11517                packageName);
11518        if (ivi == null) {
11519            return true;
11520        }
11521        int status = ivi.getStatus();
11522        switch (status) {
11523            case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED:
11524            case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK:
11525                return true;
11526
11527            default:
11528                // Nothing to do
11529                return false;
11530        }
11531    }
11532
11533    private static boolean isMultiArch(PackageSetting ps) {
11534        return (ps.pkgFlags & ApplicationInfo.FLAG_MULTIARCH) != 0;
11535    }
11536
11537    private static boolean isMultiArch(ApplicationInfo info) {
11538        return (info.flags & ApplicationInfo.FLAG_MULTIARCH) != 0;
11539    }
11540
11541    private static boolean isExternal(PackageParser.Package pkg) {
11542        return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
11543    }
11544
11545    private static boolean isExternal(PackageSetting ps) {
11546        return (ps.pkgFlags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
11547    }
11548
11549    private static boolean isExternal(ApplicationInfo info) {
11550        return (info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
11551    }
11552
11553    private static boolean isSystemApp(PackageParser.Package pkg) {
11554        return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
11555    }
11556
11557    private static boolean isPrivilegedApp(PackageParser.Package pkg) {
11558        return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0;
11559    }
11560
11561    private static boolean hasDomainURLs(PackageParser.Package pkg) {
11562        return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) != 0;
11563    }
11564
11565    private static boolean isSystemApp(PackageSetting ps) {
11566        return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0;
11567    }
11568
11569    private static boolean isUpdatedSystemApp(PackageSetting ps) {
11570        return (ps.pkgFlags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
11571    }
11572
11573    private int packageFlagsToInstallFlags(PackageSetting ps) {
11574        int installFlags = 0;
11575        if (isExternal(ps) && TextUtils.isEmpty(ps.volumeUuid)) {
11576            // This existing package was an external ASEC install when we have
11577            // the external flag without a UUID
11578            installFlags |= PackageManager.INSTALL_EXTERNAL;
11579        }
11580        if (ps.isForwardLocked()) {
11581            installFlags |= PackageManager.INSTALL_FORWARD_LOCK;
11582        }
11583        return installFlags;
11584    }
11585
11586    private void deleteTempPackageFiles() {
11587        final FilenameFilter filter = new FilenameFilter() {
11588            public boolean accept(File dir, String name) {
11589                return name.startsWith("vmdl") && name.endsWith(".tmp");
11590            }
11591        };
11592        for (File file : mDrmAppPrivateInstallDir.listFiles(filter)) {
11593            file.delete();
11594        }
11595    }
11596
11597    @Override
11598    public void deletePackageAsUser(String packageName, IPackageDeleteObserver observer, int userId,
11599            int flags) {
11600        deletePackage(packageName, new LegacyPackageDeleteObserver(observer).getBinder(), userId,
11601                flags);
11602    }
11603
11604    @Override
11605    public void deletePackage(final String packageName,
11606            final IPackageDeleteObserver2 observer, final int userId, final int flags) {
11607        mContext.enforceCallingOrSelfPermission(
11608                android.Manifest.permission.DELETE_PACKAGES, null);
11609        final int uid = Binder.getCallingUid();
11610        if (UserHandle.getUserId(uid) != userId) {
11611            mContext.enforceCallingPermission(
11612                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
11613                    "deletePackage for user " + userId);
11614        }
11615        if (isUserRestricted(userId, UserManager.DISALLOW_UNINSTALL_APPS)) {
11616            try {
11617                observer.onPackageDeleted(packageName,
11618                        PackageManager.DELETE_FAILED_USER_RESTRICTED, null);
11619            } catch (RemoteException re) {
11620            }
11621            return;
11622        }
11623
11624        boolean uninstallBlocked = false;
11625        if ((flags & PackageManager.DELETE_ALL_USERS) != 0) {
11626            int[] users = sUserManager.getUserIds();
11627            for (int i = 0; i < users.length; ++i) {
11628                if (getBlockUninstallForUser(packageName, users[i])) {
11629                    uninstallBlocked = true;
11630                    break;
11631                }
11632            }
11633        } else {
11634            uninstallBlocked = getBlockUninstallForUser(packageName, userId);
11635        }
11636        if (uninstallBlocked) {
11637            try {
11638                observer.onPackageDeleted(packageName, PackageManager.DELETE_FAILED_OWNER_BLOCKED,
11639                        null);
11640            } catch (RemoteException re) {
11641            }
11642            return;
11643        }
11644
11645        if (DEBUG_REMOVE) {
11646            Slog.d(TAG, "deletePackageAsUser: pkg=" + packageName + " user=" + userId);
11647        }
11648        // Queue up an async operation since the package deletion may take a little while.
11649        mHandler.post(new Runnable() {
11650            public void run() {
11651                mHandler.removeCallbacks(this);
11652                final int returnCode = deletePackageX(packageName, userId, flags);
11653                if (observer != null) {
11654                    try {
11655                        observer.onPackageDeleted(packageName, returnCode, null);
11656                    } catch (RemoteException e) {
11657                        Log.i(TAG, "Observer no longer exists.");
11658                    } //end catch
11659                } //end if
11660            } //end run
11661        });
11662    }
11663
11664    private boolean isPackageDeviceAdmin(String packageName, int userId) {
11665        IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
11666                ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
11667        try {
11668            if (dpm != null) {
11669                if (dpm.isDeviceOwner(packageName)) {
11670                    return true;
11671                }
11672                int[] users;
11673                if (userId == UserHandle.USER_ALL) {
11674                    users = sUserManager.getUserIds();
11675                } else {
11676                    users = new int[]{userId};
11677                }
11678                for (int i = 0; i < users.length; ++i) {
11679                    if (dpm.packageHasActiveAdmins(packageName, users[i])) {
11680                        return true;
11681                    }
11682                }
11683            }
11684        } catch (RemoteException e) {
11685        }
11686        return false;
11687    }
11688
11689    /**
11690     *  This method is an internal method that could be get invoked either
11691     *  to delete an installed package or to clean up a failed installation.
11692     *  After deleting an installed package, a broadcast is sent to notify any
11693     *  listeners that the package has been installed. For cleaning up a failed
11694     *  installation, the broadcast is not necessary since the package's
11695     *  installation wouldn't have sent the initial broadcast either
11696     *  The key steps in deleting a package are
11697     *  deleting the package information in internal structures like mPackages,
11698     *  deleting the packages base directories through installd
11699     *  updating mSettings to reflect current status
11700     *  persisting settings for later use
11701     *  sending a broadcast if necessary
11702     */
11703    private int deletePackageX(String packageName, int userId, int flags) {
11704        final PackageRemovedInfo info = new PackageRemovedInfo();
11705        final boolean res;
11706
11707        final UserHandle removeForUser = (flags & PackageManager.DELETE_ALL_USERS) != 0
11708                ? UserHandle.ALL : new UserHandle(userId);
11709
11710        if (isPackageDeviceAdmin(packageName, removeForUser.getIdentifier())) {
11711            Slog.w(TAG, "Not removing package " + packageName + ": has active device admin");
11712            return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER;
11713        }
11714
11715        boolean removedForAllUsers = false;
11716        boolean systemUpdate = false;
11717
11718        // for the uninstall-updates case and restricted profiles, remember the per-
11719        // userhandle installed state
11720        int[] allUsers;
11721        boolean[] perUserInstalled;
11722        synchronized (mPackages) {
11723            PackageSetting ps = mSettings.mPackages.get(packageName);
11724            allUsers = sUserManager.getUserIds();
11725            perUserInstalled = new boolean[allUsers.length];
11726            for (int i = 0; i < allUsers.length; i++) {
11727                perUserInstalled[i] = ps != null ? ps.getInstalled(allUsers[i]) : false;
11728            }
11729        }
11730
11731        synchronized (mInstallLock) {
11732            if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageX: pkg=" + packageName + " user=" + userId);
11733            res = deletePackageLI(packageName, removeForUser,
11734                    true, allUsers, perUserInstalled,
11735                    flags | REMOVE_CHATTY, info, true);
11736            systemUpdate = info.isRemovedPackageSystemUpdate;
11737            if (res && !systemUpdate && mPackages.get(packageName) == null) {
11738                removedForAllUsers = true;
11739            }
11740            if (DEBUG_REMOVE) Slog.d(TAG, "delete res: systemUpdate=" + systemUpdate
11741                    + " removedForAllUsers=" + removedForAllUsers);
11742        }
11743
11744        if (res) {
11745            info.sendBroadcast(true, systemUpdate, removedForAllUsers);
11746
11747            // If the removed package was a system update, the old system package
11748            // was re-enabled; we need to broadcast this information
11749            if (systemUpdate) {
11750                Bundle extras = new Bundle(1);
11751                extras.putInt(Intent.EXTRA_UID, info.removedAppId >= 0
11752                        ? info.removedAppId : info.uid);
11753                extras.putBoolean(Intent.EXTRA_REPLACING, true);
11754
11755                sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
11756                        extras, null, null, null);
11757                sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, packageName,
11758                        extras, null, null, null);
11759                sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, null,
11760                        null, packageName, null, null);
11761            }
11762        }
11763        // Force a gc here.
11764        Runtime.getRuntime().gc();
11765        // Delete the resources here after sending the broadcast to let
11766        // other processes clean up before deleting resources.
11767        if (info.args != null) {
11768            synchronized (mInstallLock) {
11769                info.args.doPostDeleteLI(true);
11770            }
11771        }
11772
11773        return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR;
11774    }
11775
11776    class PackageRemovedInfo {
11777        String removedPackage;
11778        int uid = -1;
11779        int removedAppId = -1;
11780        int[] removedUsers = null;
11781        boolean isRemovedPackageSystemUpdate = false;
11782        // Clean up resources deleted packages.
11783        InstallArgs args = null;
11784
11785        void sendBroadcast(boolean fullRemove, boolean replacing, boolean removedForAllUsers) {
11786            Bundle extras = new Bundle(1);
11787            extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid);
11788            extras.putBoolean(Intent.EXTRA_DATA_REMOVED, fullRemove);
11789            if (replacing) {
11790                extras.putBoolean(Intent.EXTRA_REPLACING, true);
11791            }
11792            extras.putBoolean(Intent.EXTRA_REMOVED_FOR_ALL_USERS, removedForAllUsers);
11793            if (removedPackage != null) {
11794                sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED, removedPackage,
11795                        extras, null, null, removedUsers);
11796                if (fullRemove && !replacing) {
11797                    sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED, removedPackage,
11798                            extras, null, null, removedUsers);
11799                }
11800            }
11801            if (removedAppId >= 0) {
11802                sendPackageBroadcast(Intent.ACTION_UID_REMOVED, null, extras, null, null,
11803                        removedUsers);
11804            }
11805        }
11806    }
11807
11808    /*
11809     * This method deletes the package from internal data structures. If the DONT_DELETE_DATA
11810     * flag is not set, the data directory is removed as well.
11811     * make sure this flag is set for partially installed apps. If not its meaningless to
11812     * delete a partially installed application.
11813     */
11814    private void removePackageDataLI(PackageSetting ps,
11815            int[] allUserHandles, boolean[] perUserInstalled,
11816            PackageRemovedInfo outInfo, int flags, boolean writeSettings) {
11817        String packageName = ps.name;
11818        if (DEBUG_REMOVE) Slog.d(TAG, "removePackageDataLI: " + ps);
11819        removePackageLI(ps, (flags&REMOVE_CHATTY) != 0);
11820        // Retrieve object to delete permissions for shared user later on
11821        final PackageSetting deletedPs;
11822        // reader
11823        synchronized (mPackages) {
11824            deletedPs = mSettings.mPackages.get(packageName);
11825            if (outInfo != null) {
11826                outInfo.removedPackage = packageName;
11827                outInfo.removedUsers = deletedPs != null
11828                        ? deletedPs.queryInstalledUsers(sUserManager.getUserIds(), true)
11829                        : null;
11830            }
11831        }
11832        if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) {
11833            removeDataDirsLI(ps.volumeUuid, packageName);
11834            schedulePackageCleaning(packageName, UserHandle.USER_ALL, true);
11835        }
11836        // writer
11837        synchronized (mPackages) {
11838            if (deletedPs != null) {
11839                if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) {
11840                    if (outInfo != null) {
11841                        mSettings.mKeySetManagerService.removeAppKeySetDataLPw(packageName);
11842                        outInfo.removedAppId = mSettings.removePackageLPw(packageName);
11843                    }
11844                    updatePermissionsLPw(deletedPs.name, null, 0);
11845                    if (deletedPs.sharedUser != null) {
11846                        // Remove permissions associated with package. Since runtime
11847                        // permissions are per user we have to kill the removed package
11848                        // or packages running under the shared user of the removed
11849                        // package if revoking the permissions requested only by the removed
11850                        // package is successful and this causes a change in gids.
11851                        for (int userId : UserManagerService.getInstance().getUserIds()) {
11852                            final int userIdToKill = mSettings.updateSharedUserPermsLPw(deletedPs,
11853                                    userId);
11854                            if (userIdToKill == UserHandle.USER_ALL
11855                                    || userIdToKill >= UserHandle.USER_OWNER) {
11856                                // If gids changed for this user, kill all affected packages.
11857                                mHandler.post(new Runnable() {
11858                                    @Override
11859                                    public void run() {
11860                                        // This has to happen with no lock held.
11861                                        killSettingPackagesForUser(deletedPs, userIdToKill,
11862                                                KILL_APP_REASON_GIDS_CHANGED);
11863                                    }
11864                                });
11865                            break;
11866                            }
11867                        }
11868                    }
11869                    clearPackagePreferredActivitiesLPw(deletedPs.name, UserHandle.USER_ALL);
11870                    clearIntentFilterVerificationsLPw(deletedPs.name, UserHandle.USER_ALL);
11871                }
11872                // make sure to preserve per-user disabled state if this removal was just
11873                // a downgrade of a system app to the factory package
11874                if (allUserHandles != null && perUserInstalled != null) {
11875                    if (DEBUG_REMOVE) {
11876                        Slog.d(TAG, "Propagating install state across downgrade");
11877                    }
11878                    for (int i = 0; i < allUserHandles.length; i++) {
11879                        if (DEBUG_REMOVE) {
11880                            Slog.d(TAG, "    user " + allUserHandles[i]
11881                                    + " => " + perUserInstalled[i]);
11882                        }
11883                        ps.setInstalled(perUserInstalled[i], allUserHandles[i]);
11884                    }
11885                }
11886            }
11887            // can downgrade to reader
11888            if (writeSettings) {
11889                // Save settings now
11890                mSettings.writeLPr();
11891            }
11892        }
11893        if (outInfo != null) {
11894            // A user ID was deleted here. Go through all users and remove it
11895            // from KeyStore.
11896            removeKeystoreDataIfNeeded(UserHandle.USER_ALL, outInfo.removedAppId);
11897        }
11898    }
11899
11900    static boolean locationIsPrivileged(File path) {
11901        try {
11902            final String privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app")
11903                    .getCanonicalPath();
11904            return path.getCanonicalPath().startsWith(privilegedAppDir);
11905        } catch (IOException e) {
11906            Slog.e(TAG, "Unable to access code path " + path);
11907        }
11908        return false;
11909    }
11910
11911    /*
11912     * Tries to delete system package.
11913     */
11914    private boolean deleteSystemPackageLI(PackageSetting newPs,
11915            int[] allUserHandles, boolean[] perUserInstalled,
11916            int flags, PackageRemovedInfo outInfo, boolean writeSettings) {
11917        final boolean applyUserRestrictions
11918                = (allUserHandles != null) && (perUserInstalled != null);
11919        PackageSetting disabledPs = null;
11920        // Confirm if the system package has been updated
11921        // An updated system app can be deleted. This will also have to restore
11922        // the system pkg from system partition
11923        // reader
11924        synchronized (mPackages) {
11925            disabledPs = mSettings.getDisabledSystemPkgLPr(newPs.name);
11926        }
11927        if (DEBUG_REMOVE) Slog.d(TAG, "deleteSystemPackageLI: newPs=" + newPs
11928                + " disabledPs=" + disabledPs);
11929        if (disabledPs == null) {
11930            Slog.w(TAG, "Attempt to delete unknown system package "+ newPs.name);
11931            return false;
11932        } else if (DEBUG_REMOVE) {
11933            Slog.d(TAG, "Deleting system pkg from data partition");
11934        }
11935        if (DEBUG_REMOVE) {
11936            if (applyUserRestrictions) {
11937                Slog.d(TAG, "Remembering install states:");
11938                for (int i = 0; i < allUserHandles.length; i++) {
11939                    Slog.d(TAG, "   u=" + allUserHandles[i] + " inst=" + perUserInstalled[i]);
11940                }
11941            }
11942        }
11943        // Delete the updated package
11944        outInfo.isRemovedPackageSystemUpdate = true;
11945        if (disabledPs.versionCode < newPs.versionCode) {
11946            // Delete data for downgrades
11947            flags &= ~PackageManager.DELETE_KEEP_DATA;
11948        } else {
11949            // Preserve data by setting flag
11950            flags |= PackageManager.DELETE_KEEP_DATA;
11951        }
11952        boolean ret = deleteInstalledPackageLI(newPs, true, flags,
11953                allUserHandles, perUserInstalled, outInfo, writeSettings);
11954        if (!ret) {
11955            return false;
11956        }
11957        // writer
11958        synchronized (mPackages) {
11959            // Reinstate the old system package
11960            mSettings.enableSystemPackageLPw(newPs.name);
11961            // Remove any native libraries from the upgraded package.
11962            NativeLibraryHelper.removeNativeBinariesLI(newPs.legacyNativeLibraryPathString);
11963        }
11964        // Install the system package
11965        if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs);
11966        int parseFlags = PackageParser.PARSE_MUST_BE_APK | PackageParser.PARSE_IS_SYSTEM;
11967        if (locationIsPrivileged(disabledPs.codePath)) {
11968            parseFlags |= PackageParser.PARSE_IS_PRIVILEGED;
11969        }
11970
11971        final PackageParser.Package newPkg;
11972        try {
11973            newPkg = scanPackageLI(disabledPs.codePath, parseFlags, SCAN_NO_PATHS, 0, null);
11974        } catch (PackageManagerException e) {
11975            Slog.w(TAG, "Failed to restore system package:" + newPs.name + ": " + e.getMessage());
11976            return false;
11977        }
11978
11979        // writer
11980        synchronized (mPackages) {
11981            PackageSetting ps = mSettings.mPackages.get(newPkg.packageName);
11982            updatePermissionsLPw(newPkg.packageName, newPkg,
11983                    UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG);
11984            if (applyUserRestrictions) {
11985                if (DEBUG_REMOVE) {
11986                    Slog.d(TAG, "Propagating install state across reinstall");
11987                }
11988                for (int i = 0; i < allUserHandles.length; i++) {
11989                    if (DEBUG_REMOVE) {
11990                        Slog.d(TAG, "    user " + allUserHandles[i]
11991                                + " => " + perUserInstalled[i]);
11992                    }
11993                    ps.setInstalled(perUserInstalled[i], allUserHandles[i]);
11994                }
11995                // Regardless of writeSettings we need to ensure that this restriction
11996                // state propagation is persisted
11997                mSettings.writeAllUsersPackageRestrictionsLPr();
11998            }
11999            // can downgrade to reader here
12000            if (writeSettings) {
12001                mSettings.writeLPr();
12002            }
12003        }
12004        return true;
12005    }
12006
12007    private boolean deleteInstalledPackageLI(PackageSetting ps,
12008            boolean deleteCodeAndResources, int flags,
12009            int[] allUserHandles, boolean[] perUserInstalled,
12010            PackageRemovedInfo outInfo, boolean writeSettings) {
12011        if (outInfo != null) {
12012            outInfo.uid = ps.appId;
12013        }
12014
12015        // Delete package data from internal structures and also remove data if flag is set
12016        removePackageDataLI(ps, allUserHandles, perUserInstalled, outInfo, flags, writeSettings);
12017
12018        // Delete application code and resources
12019        if (deleteCodeAndResources && (outInfo != null)) {
12020            outInfo.args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
12021                    ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
12022            if (DEBUG_SD_INSTALL) Slog.i(TAG, "args=" + outInfo.args);
12023        }
12024        return true;
12025    }
12026
12027    @Override
12028    public boolean setBlockUninstallForUser(String packageName, boolean blockUninstall,
12029            int userId) {
12030        mContext.enforceCallingOrSelfPermission(
12031                android.Manifest.permission.DELETE_PACKAGES, null);
12032        synchronized (mPackages) {
12033            PackageSetting ps = mSettings.mPackages.get(packageName);
12034            if (ps == null) {
12035                Log.i(TAG, "Package doesn't exist in set block uninstall " + packageName);
12036                return false;
12037            }
12038            if (!ps.getInstalled(userId)) {
12039                // Can't block uninstall for an app that is not installed or enabled.
12040                Log.i(TAG, "Package not installed in set block uninstall " + packageName);
12041                return false;
12042            }
12043            ps.setBlockUninstall(blockUninstall, userId);
12044            mSettings.writePackageRestrictionsLPr(userId);
12045        }
12046        return true;
12047    }
12048
12049    @Override
12050    public boolean getBlockUninstallForUser(String packageName, int userId) {
12051        synchronized (mPackages) {
12052            PackageSetting ps = mSettings.mPackages.get(packageName);
12053            if (ps == null) {
12054                Log.i(TAG, "Package doesn't exist in get block uninstall " + packageName);
12055                return false;
12056            }
12057            return ps.getBlockUninstall(userId);
12058        }
12059    }
12060
12061    /*
12062     * This method handles package deletion in general
12063     */
12064    private boolean deletePackageLI(String packageName, UserHandle user,
12065            boolean deleteCodeAndResources, int[] allUserHandles, boolean[] perUserInstalled,
12066            int flags, PackageRemovedInfo outInfo,
12067            boolean writeSettings) {
12068        if (packageName == null) {
12069            Slog.w(TAG, "Attempt to delete null packageName.");
12070            return false;
12071        }
12072        if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: " + packageName + " user " + user);
12073        PackageSetting ps;
12074        boolean dataOnly = false;
12075        int removeUser = -1;
12076        int appId = -1;
12077        synchronized (mPackages) {
12078            ps = mSettings.mPackages.get(packageName);
12079            if (ps == null) {
12080                Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
12081                return false;
12082            }
12083            if ((!isSystemApp(ps) || (flags&PackageManager.DELETE_SYSTEM_APP) != 0) && user != null
12084                    && user.getIdentifier() != UserHandle.USER_ALL) {
12085                // The caller is asking that the package only be deleted for a single
12086                // user.  To do this, we just mark its uninstalled state and delete
12087                // its data.  If this is a system app, we only allow this to happen if
12088                // they have set the special DELETE_SYSTEM_APP which requests different
12089                // semantics than normal for uninstalling system apps.
12090                if (DEBUG_REMOVE) Slog.d(TAG, "Only deleting for single user");
12091                ps.setUserState(user.getIdentifier(),
12092                        COMPONENT_ENABLED_STATE_DEFAULT,
12093                        false, //installed
12094                        true,  //stopped
12095                        true,  //notLaunched
12096                        false, //hidden
12097                        null, null, null,
12098                        false, // blockUninstall
12099                        INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED);
12100                if (!isSystemApp(ps)) {
12101                    if (ps.isAnyInstalled(sUserManager.getUserIds())) {
12102                        // Other user still have this package installed, so all
12103                        // we need to do is clear this user's data and save that
12104                        // it is uninstalled.
12105                        if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users");
12106                        removeUser = user.getIdentifier();
12107                        appId = ps.appId;
12108                        scheduleWritePackageRestrictionsLocked(removeUser);
12109                    } else {
12110                        // We need to set it back to 'installed' so the uninstall
12111                        // broadcasts will be sent correctly.
12112                        if (DEBUG_REMOVE) Slog.d(TAG, "Not installed by other users, full delete");
12113                        ps.setInstalled(true, user.getIdentifier());
12114                    }
12115                } else {
12116                    // This is a system app, so we assume that the
12117                    // other users still have this package installed, so all
12118                    // we need to do is clear this user's data and save that
12119                    // it is uninstalled.
12120                    if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app");
12121                    removeUser = user.getIdentifier();
12122                    appId = ps.appId;
12123                    scheduleWritePackageRestrictionsLocked(removeUser);
12124                }
12125            }
12126        }
12127
12128        if (removeUser >= 0) {
12129            // From above, we determined that we are deleting this only
12130            // for a single user.  Continue the work here.
12131            if (DEBUG_REMOVE) Slog.d(TAG, "Updating install state for user: " + removeUser);
12132            if (outInfo != null) {
12133                outInfo.removedPackage = packageName;
12134                outInfo.removedAppId = appId;
12135                outInfo.removedUsers = new int[] {removeUser};
12136            }
12137            mInstaller.clearUserData(ps.volumeUuid, packageName, removeUser);
12138            removeKeystoreDataIfNeeded(removeUser, appId);
12139            schedulePackageCleaning(packageName, removeUser, false);
12140            synchronized (mPackages) {
12141                if (clearPackagePreferredActivitiesLPw(packageName, removeUser)) {
12142                    scheduleWritePackageRestrictionsLocked(removeUser);
12143                }
12144            }
12145            return true;
12146        }
12147
12148        if (dataOnly) {
12149            // Delete application data first
12150            if (DEBUG_REMOVE) Slog.d(TAG, "Removing package data only");
12151            removePackageDataLI(ps, null, null, outInfo, flags, writeSettings);
12152            return true;
12153        }
12154
12155        boolean ret = false;
12156        if (isSystemApp(ps)) {
12157            if (DEBUG_REMOVE) Slog.d(TAG, "Removing system package:" + ps.name);
12158            // When an updated system application is deleted we delete the existing resources as well and
12159            // fall back to existing code in system partition
12160            ret = deleteSystemPackageLI(ps, allUserHandles, perUserInstalled,
12161                    flags, outInfo, writeSettings);
12162        } else {
12163            if (DEBUG_REMOVE) Slog.d(TAG, "Removing non-system package:" + ps.name);
12164            // Kill application pre-emptively especially for apps on sd.
12165            killApplication(packageName, ps.appId, "uninstall pkg");
12166            ret = deleteInstalledPackageLI(ps, deleteCodeAndResources, flags,
12167                    allUserHandles, perUserInstalled,
12168                    outInfo, writeSettings);
12169        }
12170
12171        return ret;
12172    }
12173
12174    private final class ClearStorageConnection implements ServiceConnection {
12175        IMediaContainerService mContainerService;
12176
12177        @Override
12178        public void onServiceConnected(ComponentName name, IBinder service) {
12179            synchronized (this) {
12180                mContainerService = IMediaContainerService.Stub.asInterface(service);
12181                notifyAll();
12182            }
12183        }
12184
12185        @Override
12186        public void onServiceDisconnected(ComponentName name) {
12187        }
12188    }
12189
12190    private void clearExternalStorageDataSync(String packageName, int userId, boolean allData) {
12191        final boolean mounted;
12192        if (Environment.isExternalStorageEmulated()) {
12193            mounted = true;
12194        } else {
12195            final String status = Environment.getExternalStorageState();
12196
12197            mounted = status.equals(Environment.MEDIA_MOUNTED)
12198                    || status.equals(Environment.MEDIA_MOUNTED_READ_ONLY);
12199        }
12200
12201        if (!mounted) {
12202            return;
12203        }
12204
12205        final Intent containerIntent = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
12206        int[] users;
12207        if (userId == UserHandle.USER_ALL) {
12208            users = sUserManager.getUserIds();
12209        } else {
12210            users = new int[] { userId };
12211        }
12212        final ClearStorageConnection conn = new ClearStorageConnection();
12213        if (mContext.bindServiceAsUser(
12214                containerIntent, conn, Context.BIND_AUTO_CREATE, UserHandle.OWNER)) {
12215            try {
12216                for (int curUser : users) {
12217                    long timeout = SystemClock.uptimeMillis() + 5000;
12218                    synchronized (conn) {
12219                        long now = SystemClock.uptimeMillis();
12220                        while (conn.mContainerService == null && now < timeout) {
12221                            try {
12222                                conn.wait(timeout - now);
12223                            } catch (InterruptedException e) {
12224                            }
12225                        }
12226                    }
12227                    if (conn.mContainerService == null) {
12228                        return;
12229                    }
12230
12231                    final UserEnvironment userEnv = new UserEnvironment(curUser);
12232                    clearDirectory(conn.mContainerService,
12233                            userEnv.buildExternalStorageAppCacheDirs(packageName));
12234                    if (allData) {
12235                        clearDirectory(conn.mContainerService,
12236                                userEnv.buildExternalStorageAppDataDirs(packageName));
12237                        clearDirectory(conn.mContainerService,
12238                                userEnv.buildExternalStorageAppMediaDirs(packageName));
12239                    }
12240                }
12241            } finally {
12242                mContext.unbindService(conn);
12243            }
12244        }
12245    }
12246
12247    @Override
12248    public void clearApplicationUserData(final String packageName,
12249            final IPackageDataObserver observer, final int userId) {
12250        mContext.enforceCallingOrSelfPermission(
12251                android.Manifest.permission.CLEAR_APP_USER_DATA, null);
12252        enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, "clear application data");
12253        // Queue up an async operation since the package deletion may take a little while.
12254        mHandler.post(new Runnable() {
12255            public void run() {
12256                mHandler.removeCallbacks(this);
12257                final boolean succeeded;
12258                synchronized (mInstallLock) {
12259                    succeeded = clearApplicationUserDataLI(packageName, userId);
12260                }
12261                clearExternalStorageDataSync(packageName, userId, true);
12262                if (succeeded) {
12263                    // invoke DeviceStorageMonitor's update method to clear any notifications
12264                    DeviceStorageMonitorInternal
12265                            dsm = LocalServices.getService(DeviceStorageMonitorInternal.class);
12266                    if (dsm != null) {
12267                        dsm.checkMemory();
12268                    }
12269                }
12270                if(observer != null) {
12271                    try {
12272                        observer.onRemoveCompleted(packageName, succeeded);
12273                    } catch (RemoteException e) {
12274                        Log.i(TAG, "Observer no longer exists.");
12275                    }
12276                } //end if observer
12277            } //end run
12278        });
12279    }
12280
12281    private boolean clearApplicationUserDataLI(String packageName, int userId) {
12282        if (packageName == null) {
12283            Slog.w(TAG, "Attempt to delete null packageName.");
12284            return false;
12285        }
12286
12287        // Try finding details about the requested package
12288        PackageParser.Package pkg;
12289        synchronized (mPackages) {
12290            pkg = mPackages.get(packageName);
12291            if (pkg == null) {
12292                final PackageSetting ps = mSettings.mPackages.get(packageName);
12293                if (ps != null) {
12294                    pkg = ps.pkg;
12295                }
12296            }
12297        }
12298
12299        if (pkg == null) {
12300            Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
12301        }
12302
12303        // Always delete data directories for package, even if we found no other
12304        // record of app. This helps users recover from UID mismatches without
12305        // resorting to a full data wipe.
12306        int retCode = mInstaller.clearUserData(pkg.volumeUuid, packageName, userId);
12307        if (retCode < 0) {
12308            Slog.w(TAG, "Couldn't remove cache files for package: " + packageName);
12309            return false;
12310        }
12311
12312        if (pkg == null) {
12313            return false;
12314        }
12315
12316        if (pkg != null && pkg.applicationInfo != null) {
12317            final int appId = pkg.applicationInfo.uid;
12318            removeKeystoreDataIfNeeded(userId, appId);
12319        }
12320
12321        // Create a native library symlink only if we have native libraries
12322        // and if the native libraries are 32 bit libraries. We do not provide
12323        // this symlink for 64 bit libraries.
12324        if (pkg != null && pkg.applicationInfo.primaryCpuAbi != null &&
12325                !VMRuntime.is64BitAbi(pkg.applicationInfo.primaryCpuAbi)) {
12326            final String nativeLibPath = pkg.applicationInfo.nativeLibraryDir;
12327            if (mInstaller.linkNativeLibraryDirectory(pkg.volumeUuid, pkg.packageName,
12328                    nativeLibPath, userId) < 0) {
12329                Slog.w(TAG, "Failed linking native library dir");
12330                return false;
12331            }
12332        }
12333
12334        return true;
12335    }
12336
12337    /**
12338     * Remove entries from the keystore daemon. Will only remove it if the
12339     * {@code appId} is valid.
12340     */
12341    private static void removeKeystoreDataIfNeeded(int userId, int appId) {
12342        if (appId < 0) {
12343            return;
12344        }
12345
12346        final KeyStore keyStore = KeyStore.getInstance();
12347        if (keyStore != null) {
12348            if (userId == UserHandle.USER_ALL) {
12349                for (final int individual : sUserManager.getUserIds()) {
12350                    keyStore.clearUid(UserHandle.getUid(individual, appId));
12351                }
12352            } else {
12353                keyStore.clearUid(UserHandle.getUid(userId, appId));
12354            }
12355        } else {
12356            Slog.w(TAG, "Could not contact keystore to clear entries for app id " + appId);
12357        }
12358    }
12359
12360    @Override
12361    public void deleteApplicationCacheFiles(final String packageName,
12362            final IPackageDataObserver observer) {
12363        mContext.enforceCallingOrSelfPermission(
12364                android.Manifest.permission.DELETE_CACHE_FILES, null);
12365        // Queue up an async operation since the package deletion may take a little while.
12366        final int userId = UserHandle.getCallingUserId();
12367        mHandler.post(new Runnable() {
12368            public void run() {
12369                mHandler.removeCallbacks(this);
12370                final boolean succeded;
12371                synchronized (mInstallLock) {
12372                    succeded = deleteApplicationCacheFilesLI(packageName, userId);
12373                }
12374                clearExternalStorageDataSync(packageName, userId, false);
12375                if(observer != null) {
12376                    try {
12377                        observer.onRemoveCompleted(packageName, succeded);
12378                    } catch (RemoteException e) {
12379                        Log.i(TAG, "Observer no longer exists.");
12380                    }
12381                } //end if observer
12382            } //end run
12383        });
12384    }
12385
12386    private boolean deleteApplicationCacheFilesLI(String packageName, int userId) {
12387        if (packageName == null) {
12388            Slog.w(TAG, "Attempt to delete null packageName.");
12389            return false;
12390        }
12391        PackageParser.Package p;
12392        synchronized (mPackages) {
12393            p = mPackages.get(packageName);
12394        }
12395        if (p == null) {
12396            Slog.w(TAG, "Package named '" + packageName +"' doesn't exist.");
12397            return false;
12398        }
12399        final ApplicationInfo applicationInfo = p.applicationInfo;
12400        if (applicationInfo == null) {
12401            Slog.w(TAG, "Package " + packageName + " has no applicationInfo.");
12402            return false;
12403        }
12404        int retCode = mInstaller.deleteCacheFiles(p.volumeUuid, packageName, userId);
12405        if (retCode < 0) {
12406            Slog.w(TAG, "Couldn't remove cache files for package: "
12407                       + packageName + " u" + userId);
12408            return false;
12409        }
12410        return true;
12411    }
12412
12413    @Override
12414    public void getPackageSizeInfo(final String packageName, int userHandle,
12415            final IPackageStatsObserver observer) {
12416        mContext.enforceCallingOrSelfPermission(
12417                android.Manifest.permission.GET_PACKAGE_SIZE, null);
12418        if (packageName == null) {
12419            throw new IllegalArgumentException("Attempt to get size of null packageName");
12420        }
12421
12422        PackageStats stats = new PackageStats(packageName, userHandle);
12423
12424        /*
12425         * Queue up an async operation since the package measurement may take a
12426         * little while.
12427         */
12428        Message msg = mHandler.obtainMessage(INIT_COPY);
12429        msg.obj = new MeasureParams(stats, observer);
12430        mHandler.sendMessage(msg);
12431    }
12432
12433    private boolean getPackageSizeInfoLI(String packageName, int userHandle,
12434            PackageStats pStats) {
12435        if (packageName == null) {
12436            Slog.w(TAG, "Attempt to get size of null packageName.");
12437            return false;
12438        }
12439        PackageParser.Package p;
12440        boolean dataOnly = false;
12441        String libDirRoot = null;
12442        String asecPath = null;
12443        PackageSetting ps = null;
12444        synchronized (mPackages) {
12445            p = mPackages.get(packageName);
12446            ps = mSettings.mPackages.get(packageName);
12447            if(p == null) {
12448                dataOnly = true;
12449                if((ps == null) || (ps.pkg == null)) {
12450                    Slog.w(TAG, "Package named '" + packageName +"' doesn't exist.");
12451                    return false;
12452                }
12453                p = ps.pkg;
12454            }
12455            if (ps != null) {
12456                libDirRoot = ps.legacyNativeLibraryPathString;
12457            }
12458            if (p != null && (isExternal(p) || p.isForwardLocked())) {
12459                String secureContainerId = cidFromCodePath(p.applicationInfo.getBaseCodePath());
12460                if (secureContainerId != null) {
12461                    asecPath = PackageHelper.getSdFilesystem(secureContainerId);
12462                }
12463            }
12464        }
12465        String publicSrcDir = null;
12466        if(!dataOnly) {
12467            final ApplicationInfo applicationInfo = p.applicationInfo;
12468            if (applicationInfo == null) {
12469                Slog.w(TAG, "Package " + packageName + " has no applicationInfo.");
12470                return false;
12471            }
12472            if (p.isForwardLocked()) {
12473                publicSrcDir = applicationInfo.getBaseResourcePath();
12474            }
12475        }
12476        // TODO: extend to measure size of split APKs
12477        // TODO(multiArch): Extend getSizeInfo to look at the full subdirectory tree,
12478        // not just the first level.
12479        // TODO(multiArch): Extend getSizeInfo to look at *all* instruction sets, not
12480        // just the primary.
12481        String[] dexCodeInstructionSets = getDexCodeInstructionSets(getAppDexInstructionSets(ps));
12482        int res = mInstaller.getSizeInfo(p.volumeUuid, packageName, userHandle, p.baseCodePath,
12483                libDirRoot, publicSrcDir, asecPath, dexCodeInstructionSets, pStats);
12484        if (res < 0) {
12485            return false;
12486        }
12487
12488        // Fix-up for forward-locked applications in ASEC containers.
12489        if (!isExternal(p)) {
12490            pStats.codeSize += pStats.externalCodeSize;
12491            pStats.externalCodeSize = 0L;
12492        }
12493
12494        return true;
12495    }
12496
12497
12498    @Override
12499    public void addPackageToPreferred(String packageName) {
12500        Slog.w(TAG, "addPackageToPreferred: this is now a no-op");
12501    }
12502
12503    @Override
12504    public void removePackageFromPreferred(String packageName) {
12505        Slog.w(TAG, "removePackageFromPreferred: this is now a no-op");
12506    }
12507
12508    @Override
12509    public List<PackageInfo> getPreferredPackages(int flags) {
12510        return new ArrayList<PackageInfo>();
12511    }
12512
12513    private int getUidTargetSdkVersionLockedLPr(int uid) {
12514        Object obj = mSettings.getUserIdLPr(uid);
12515        if (obj instanceof SharedUserSetting) {
12516            final SharedUserSetting sus = (SharedUserSetting) obj;
12517            int vers = Build.VERSION_CODES.CUR_DEVELOPMENT;
12518            final Iterator<PackageSetting> it = sus.packages.iterator();
12519            while (it.hasNext()) {
12520                final PackageSetting ps = it.next();
12521                if (ps.pkg != null) {
12522                    int v = ps.pkg.applicationInfo.targetSdkVersion;
12523                    if (v < vers) vers = v;
12524                }
12525            }
12526            return vers;
12527        } else if (obj instanceof PackageSetting) {
12528            final PackageSetting ps = (PackageSetting) obj;
12529            if (ps.pkg != null) {
12530                return ps.pkg.applicationInfo.targetSdkVersion;
12531            }
12532        }
12533        return Build.VERSION_CODES.CUR_DEVELOPMENT;
12534    }
12535
12536    @Override
12537    public void addPreferredActivity(IntentFilter filter, int match,
12538            ComponentName[] set, ComponentName activity, int userId) {
12539        addPreferredActivityInternal(filter, match, set, activity, true, userId,
12540                "Adding preferred");
12541    }
12542
12543    private void addPreferredActivityInternal(IntentFilter filter, int match,
12544            ComponentName[] set, ComponentName activity, boolean always, int userId,
12545            String opname) {
12546        // writer
12547        int callingUid = Binder.getCallingUid();
12548        enforceCrossUserPermission(callingUid, userId, true, false, "add preferred activity");
12549        if (filter.countActions() == 0) {
12550            Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
12551            return;
12552        }
12553        synchronized (mPackages) {
12554            if (mContext.checkCallingOrSelfPermission(
12555                    android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
12556                    != PackageManager.PERMISSION_GRANTED) {
12557                if (getUidTargetSdkVersionLockedLPr(callingUid)
12558                        < Build.VERSION_CODES.FROYO) {
12559                    Slog.w(TAG, "Ignoring addPreferredActivity() from uid "
12560                            + callingUid);
12561                    return;
12562                }
12563                mContext.enforceCallingOrSelfPermission(
12564                        android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
12565            }
12566
12567            PreferredIntentResolver pir = mSettings.editPreferredActivitiesLPw(userId);
12568            Slog.i(TAG, opname + " activity " + activity.flattenToShortString() + " for user "
12569                    + userId + ":");
12570            filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
12571            pir.addFilter(new PreferredActivity(filter, match, set, activity, always));
12572            scheduleWritePackageRestrictionsLocked(userId);
12573        }
12574    }
12575
12576    @Override
12577    public void replacePreferredActivity(IntentFilter filter, int match,
12578            ComponentName[] set, ComponentName activity, int userId) {
12579        if (filter.countActions() != 1) {
12580            throw new IllegalArgumentException(
12581                    "replacePreferredActivity expects filter to have only 1 action.");
12582        }
12583        if (filter.countDataAuthorities() != 0
12584                || filter.countDataPaths() != 0
12585                || filter.countDataSchemes() > 1
12586                || filter.countDataTypes() != 0) {
12587            throw new IllegalArgumentException(
12588                    "replacePreferredActivity expects filter to have no data authorities, " +
12589                    "paths, or types; and at most one scheme.");
12590        }
12591
12592        final int callingUid = Binder.getCallingUid();
12593        enforceCrossUserPermission(callingUid, userId, true, false, "replace preferred activity");
12594        synchronized (mPackages) {
12595            if (mContext.checkCallingOrSelfPermission(
12596                    android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
12597                    != PackageManager.PERMISSION_GRANTED) {
12598                if (getUidTargetSdkVersionLockedLPr(callingUid)
12599                        < Build.VERSION_CODES.FROYO) {
12600                    Slog.w(TAG, "Ignoring replacePreferredActivity() from uid "
12601                            + Binder.getCallingUid());
12602                    return;
12603                }
12604                mContext.enforceCallingOrSelfPermission(
12605                        android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
12606            }
12607
12608            PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
12609            if (pir != null) {
12610                // Get all of the existing entries that exactly match this filter.
12611                ArrayList<PreferredActivity> existing = pir.findFilters(filter);
12612                if (existing != null && existing.size() == 1) {
12613                    PreferredActivity cur = existing.get(0);
12614                    if (DEBUG_PREFERRED) {
12615                        Slog.i(TAG, "Checking replace of preferred:");
12616                        filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
12617                        if (!cur.mPref.mAlways) {
12618                            Slog.i(TAG, "  -- CUR; not mAlways!");
12619                        } else {
12620                            Slog.i(TAG, "  -- CUR: mMatch=" + cur.mPref.mMatch);
12621                            Slog.i(TAG, "  -- CUR: mSet="
12622                                    + Arrays.toString(cur.mPref.mSetComponents));
12623                            Slog.i(TAG, "  -- CUR: mComponent=" + cur.mPref.mShortComponent);
12624                            Slog.i(TAG, "  -- NEW: mMatch="
12625                                    + (match&IntentFilter.MATCH_CATEGORY_MASK));
12626                            Slog.i(TAG, "  -- CUR: mSet=" + Arrays.toString(set));
12627                            Slog.i(TAG, "  -- CUR: mComponent=" + activity.flattenToShortString());
12628                        }
12629                    }
12630                    if (cur.mPref.mAlways && cur.mPref.mComponent.equals(activity)
12631                            && cur.mPref.mMatch == (match&IntentFilter.MATCH_CATEGORY_MASK)
12632                            && cur.mPref.sameSet(set)) {
12633                        // Setting the preferred activity to what it happens to be already
12634                        if (DEBUG_PREFERRED) {
12635                            Slog.i(TAG, "Replacing with same preferred activity "
12636                                    + cur.mPref.mShortComponent + " for user "
12637                                    + userId + ":");
12638                            filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
12639                        }
12640                        return;
12641                    }
12642                }
12643
12644                if (existing != null) {
12645                    if (DEBUG_PREFERRED) {
12646                        Slog.i(TAG, existing.size() + " existing preferred matches for:");
12647                        filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
12648                    }
12649                    for (int i = 0; i < existing.size(); i++) {
12650                        PreferredActivity pa = existing.get(i);
12651                        if (DEBUG_PREFERRED) {
12652                            Slog.i(TAG, "Removing existing preferred activity "
12653                                    + pa.mPref.mComponent + ":");
12654                            pa.dump(new LogPrinter(Log.INFO, TAG), "  ");
12655                        }
12656                        pir.removeFilter(pa);
12657                    }
12658                }
12659            }
12660            addPreferredActivityInternal(filter, match, set, activity, true, userId,
12661                    "Replacing preferred");
12662        }
12663    }
12664
12665    @Override
12666    public void clearPackagePreferredActivities(String packageName) {
12667        final int uid = Binder.getCallingUid();
12668        // writer
12669        synchronized (mPackages) {
12670            PackageParser.Package pkg = mPackages.get(packageName);
12671            if (pkg == null || pkg.applicationInfo.uid != uid) {
12672                if (mContext.checkCallingOrSelfPermission(
12673                        android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
12674                        != PackageManager.PERMISSION_GRANTED) {
12675                    if (getUidTargetSdkVersionLockedLPr(Binder.getCallingUid())
12676                            < Build.VERSION_CODES.FROYO) {
12677                        Slog.w(TAG, "Ignoring clearPackagePreferredActivities() from uid "
12678                                + Binder.getCallingUid());
12679                        return;
12680                    }
12681                    mContext.enforceCallingOrSelfPermission(
12682                            android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
12683                }
12684            }
12685
12686            int user = UserHandle.getCallingUserId();
12687            if (clearPackagePreferredActivitiesLPw(packageName, user)) {
12688                scheduleWritePackageRestrictionsLocked(user);
12689            }
12690        }
12691    }
12692
12693    /** This method takes a specific user id as well as UserHandle.USER_ALL. */
12694    boolean clearPackagePreferredActivitiesLPw(String packageName, int userId) {
12695        ArrayList<PreferredActivity> removed = null;
12696        boolean changed = false;
12697        for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
12698            final int thisUserId = mSettings.mPreferredActivities.keyAt(i);
12699            PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
12700            if (userId != UserHandle.USER_ALL && userId != thisUserId) {
12701                continue;
12702            }
12703            Iterator<PreferredActivity> it = pir.filterIterator();
12704            while (it.hasNext()) {
12705                PreferredActivity pa = it.next();
12706                // Mark entry for removal only if it matches the package name
12707                // and the entry is of type "always".
12708                if (packageName == null ||
12709                        (pa.mPref.mComponent.getPackageName().equals(packageName)
12710                                && pa.mPref.mAlways)) {
12711                    if (removed == null) {
12712                        removed = new ArrayList<PreferredActivity>();
12713                    }
12714                    removed.add(pa);
12715                }
12716            }
12717            if (removed != null) {
12718                for (int j=0; j<removed.size(); j++) {
12719                    PreferredActivity pa = removed.get(j);
12720                    pir.removeFilter(pa);
12721                }
12722                changed = true;
12723            }
12724        }
12725        return changed;
12726    }
12727
12728    /** This method takes a specific user id as well as UserHandle.USER_ALL. */
12729    void clearIntentFilterVerificationsLPw(String packageName, int userId) {
12730        if (userId == UserHandle.USER_ALL) {
12731            mSettings.removeIntentFilterVerificationLPw(packageName, sUserManager.getUserIds());
12732            for (int oneUserId : sUserManager.getUserIds()) {
12733                scheduleWritePackageRestrictionsLocked(oneUserId);
12734            }
12735        } else {
12736            mSettings.removeIntentFilterVerificationLPw(packageName, userId);
12737            scheduleWritePackageRestrictionsLocked(userId);
12738        }
12739    }
12740
12741    @Override
12742    public void resetPreferredActivities(int userId) {
12743        /* TODO: Actually use userId. Why is it being passed in? */
12744        mContext.enforceCallingOrSelfPermission(
12745                android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
12746        // writer
12747        synchronized (mPackages) {
12748            int user = UserHandle.getCallingUserId();
12749            clearPackagePreferredActivitiesLPw(null, user);
12750            mSettings.readDefaultPreferredAppsLPw(this, user);
12751            scheduleWritePackageRestrictionsLocked(user);
12752        }
12753    }
12754
12755    @Override
12756    public int getPreferredActivities(List<IntentFilter> outFilters,
12757            List<ComponentName> outActivities, String packageName) {
12758
12759        int num = 0;
12760        final int userId = UserHandle.getCallingUserId();
12761        // reader
12762        synchronized (mPackages) {
12763            PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
12764            if (pir != null) {
12765                final Iterator<PreferredActivity> it = pir.filterIterator();
12766                while (it.hasNext()) {
12767                    final PreferredActivity pa = it.next();
12768                    if (packageName == null
12769                            || (pa.mPref.mComponent.getPackageName().equals(packageName)
12770                                    && pa.mPref.mAlways)) {
12771                        if (outFilters != null) {
12772                            outFilters.add(new IntentFilter(pa));
12773                        }
12774                        if (outActivities != null) {
12775                            outActivities.add(pa.mPref.mComponent);
12776                        }
12777                    }
12778                }
12779            }
12780        }
12781
12782        return num;
12783    }
12784
12785    @Override
12786    public void addPersistentPreferredActivity(IntentFilter filter, ComponentName activity,
12787            int userId) {
12788        int callingUid = Binder.getCallingUid();
12789        if (callingUid != Process.SYSTEM_UID) {
12790            throw new SecurityException(
12791                    "addPersistentPreferredActivity can only be run by the system");
12792        }
12793        if (filter.countActions() == 0) {
12794            Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
12795            return;
12796        }
12797        synchronized (mPackages) {
12798            Slog.i(TAG, "Adding persistent preferred activity " + activity + " for user " + userId +
12799                    " :");
12800            filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
12801            mSettings.editPersistentPreferredActivitiesLPw(userId).addFilter(
12802                    new PersistentPreferredActivity(filter, activity));
12803            scheduleWritePackageRestrictionsLocked(userId);
12804        }
12805    }
12806
12807    @Override
12808    public void clearPackagePersistentPreferredActivities(String packageName, int userId) {
12809        int callingUid = Binder.getCallingUid();
12810        if (callingUid != Process.SYSTEM_UID) {
12811            throw new SecurityException(
12812                    "clearPackagePersistentPreferredActivities can only be run by the system");
12813        }
12814        ArrayList<PersistentPreferredActivity> removed = null;
12815        boolean changed = false;
12816        synchronized (mPackages) {
12817            for (int i=0; i<mSettings.mPersistentPreferredActivities.size(); i++) {
12818                final int thisUserId = mSettings.mPersistentPreferredActivities.keyAt(i);
12819                PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
12820                        .valueAt(i);
12821                if (userId != thisUserId) {
12822                    continue;
12823                }
12824                Iterator<PersistentPreferredActivity> it = ppir.filterIterator();
12825                while (it.hasNext()) {
12826                    PersistentPreferredActivity ppa = it.next();
12827                    // Mark entry for removal only if it matches the package name.
12828                    if (ppa.mComponent.getPackageName().equals(packageName)) {
12829                        if (removed == null) {
12830                            removed = new ArrayList<PersistentPreferredActivity>();
12831                        }
12832                        removed.add(ppa);
12833                    }
12834                }
12835                if (removed != null) {
12836                    for (int j=0; j<removed.size(); j++) {
12837                        PersistentPreferredActivity ppa = removed.get(j);
12838                        ppir.removeFilter(ppa);
12839                    }
12840                    changed = true;
12841                }
12842            }
12843
12844            if (changed) {
12845                scheduleWritePackageRestrictionsLocked(userId);
12846            }
12847        }
12848    }
12849
12850    /**
12851     * Non-Binder method, support for the backup/restore mechanism: write the
12852     * full set of preferred activities in its canonical XML format.  Returns true
12853     * on success; false otherwise.
12854     */
12855    @Override
12856    public byte[] getPreferredActivityBackup(int userId) {
12857        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12858            throw new SecurityException("Only the system may call getPreferredActivityBackup()");
12859        }
12860
12861        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
12862        try {
12863            final XmlSerializer serializer = new FastXmlSerializer();
12864            serializer.setOutput(dataStream, "utf-8");
12865            serializer.startDocument(null, true);
12866            serializer.startTag(null, TAG_PREFERRED_BACKUP);
12867
12868            synchronized (mPackages) {
12869                mSettings.writePreferredActivitiesLPr(serializer, userId, true);
12870            }
12871
12872            serializer.endTag(null, TAG_PREFERRED_BACKUP);
12873            serializer.endDocument();
12874            serializer.flush();
12875        } catch (Exception e) {
12876            if (DEBUG_BACKUP) {
12877                Slog.e(TAG, "Unable to write preferred activities for backup", e);
12878            }
12879            return null;
12880        }
12881
12882        return dataStream.toByteArray();
12883    }
12884
12885    @Override
12886    public void restorePreferredActivities(byte[] backup, int userId) {
12887        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12888            throw new SecurityException("Only the system may call restorePreferredActivities()");
12889        }
12890
12891        try {
12892            final XmlPullParser parser = Xml.newPullParser();
12893            parser.setInput(new ByteArrayInputStream(backup), null);
12894
12895            int type;
12896            while ((type = parser.next()) != XmlPullParser.START_TAG
12897                    && type != XmlPullParser.END_DOCUMENT) {
12898            }
12899            if (type != XmlPullParser.START_TAG) {
12900                // oops didn't find a start tag?!
12901                if (DEBUG_BACKUP) {
12902                    Slog.e(TAG, "Didn't find start tag during restore");
12903                }
12904                return;
12905            }
12906
12907            // this is supposed to be TAG_PREFERRED_BACKUP
12908            if (!TAG_PREFERRED_BACKUP.equals(parser.getName())) {
12909                if (DEBUG_BACKUP) {
12910                    Slog.e(TAG, "Found unexpected tag " + parser.getName());
12911                }
12912                return;
12913            }
12914
12915            // skip interfering stuff, then we're aligned with the backing implementation
12916            while ((type = parser.next()) == XmlPullParser.TEXT) { }
12917            synchronized (mPackages) {
12918                mSettings.readPreferredActivitiesLPw(parser, userId);
12919            }
12920        } catch (Exception e) {
12921            if (DEBUG_BACKUP) {
12922                Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
12923            }
12924        }
12925    }
12926
12927    @Override
12928    public void addCrossProfileIntentFilter(IntentFilter intentFilter, String ownerPackage,
12929            int sourceUserId, int targetUserId, int flags) {
12930        mContext.enforceCallingOrSelfPermission(
12931                        android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
12932        int callingUid = Binder.getCallingUid();
12933        enforceOwnerRights(ownerPackage, callingUid);
12934        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
12935        if (intentFilter.countActions() == 0) {
12936            Slog.w(TAG, "Cannot set a crossProfile intent filter with no filter actions");
12937            return;
12938        }
12939        synchronized (mPackages) {
12940            CrossProfileIntentFilter newFilter = new CrossProfileIntentFilter(intentFilter,
12941                    ownerPackage, targetUserId, flags);
12942            CrossProfileIntentResolver resolver =
12943                    mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
12944            ArrayList<CrossProfileIntentFilter> existing = resolver.findFilters(intentFilter);
12945            // We have all those whose filter is equal. Now checking if the rest is equal as well.
12946            if (existing != null) {
12947                int size = existing.size();
12948                for (int i = 0; i < size; i++) {
12949                    if (newFilter.equalsIgnoreFilter(existing.get(i))) {
12950                        return;
12951                    }
12952                }
12953            }
12954            resolver.addFilter(newFilter);
12955            scheduleWritePackageRestrictionsLocked(sourceUserId);
12956        }
12957    }
12958
12959    @Override
12960    public void clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage) {
12961        mContext.enforceCallingOrSelfPermission(
12962                        android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
12963        int callingUid = Binder.getCallingUid();
12964        enforceOwnerRights(ownerPackage, callingUid);
12965        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
12966        synchronized (mPackages) {
12967            CrossProfileIntentResolver resolver =
12968                    mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
12969            ArraySet<CrossProfileIntentFilter> set =
12970                    new ArraySet<CrossProfileIntentFilter>(resolver.filterSet());
12971            for (CrossProfileIntentFilter filter : set) {
12972                if (filter.getOwnerPackage().equals(ownerPackage)) {
12973                    resolver.removeFilter(filter);
12974                }
12975            }
12976            scheduleWritePackageRestrictionsLocked(sourceUserId);
12977        }
12978    }
12979
12980    // Enforcing that callingUid is owning pkg on userId
12981    private void enforceOwnerRights(String pkg, int callingUid) {
12982        // The system owns everything.
12983        if (UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) {
12984            return;
12985        }
12986        int callingUserId = UserHandle.getUserId(callingUid);
12987        PackageInfo pi = getPackageInfo(pkg, 0, callingUserId);
12988        if (pi == null) {
12989            throw new IllegalArgumentException("Unknown package " + pkg + " on user "
12990                    + callingUserId);
12991        }
12992        if (!UserHandle.isSameApp(pi.applicationInfo.uid, callingUid)) {
12993            throw new SecurityException("Calling uid " + callingUid
12994                    + " does not own package " + pkg);
12995        }
12996    }
12997
12998    @Override
12999    public ComponentName getHomeActivities(List<ResolveInfo> allHomeCandidates) {
13000        Intent intent = new Intent(Intent.ACTION_MAIN);
13001        intent.addCategory(Intent.CATEGORY_HOME);
13002
13003        final int callingUserId = UserHandle.getCallingUserId();
13004        List<ResolveInfo> list = queryIntentActivities(intent, null,
13005                PackageManager.GET_META_DATA, callingUserId);
13006        ResolveInfo preferred = findPreferredActivity(intent, null, 0, list, 0,
13007                true, false, false, callingUserId);
13008
13009        allHomeCandidates.clear();
13010        if (list != null) {
13011            for (ResolveInfo ri : list) {
13012                allHomeCandidates.add(ri);
13013            }
13014        }
13015        return (preferred == null || preferred.activityInfo == null)
13016                ? null
13017                : new ComponentName(preferred.activityInfo.packageName,
13018                        preferred.activityInfo.name);
13019    }
13020
13021    @Override
13022    public void setApplicationEnabledSetting(String appPackageName,
13023            int newState, int flags, int userId, String callingPackage) {
13024        if (!sUserManager.exists(userId)) return;
13025        if (callingPackage == null) {
13026            callingPackage = Integer.toString(Binder.getCallingUid());
13027        }
13028        setEnabledSetting(appPackageName, null, newState, flags, userId, callingPackage);
13029    }
13030
13031    @Override
13032    public void setComponentEnabledSetting(ComponentName componentName,
13033            int newState, int flags, int userId) {
13034        if (!sUserManager.exists(userId)) return;
13035        setEnabledSetting(componentName.getPackageName(),
13036                componentName.getClassName(), newState, flags, userId, null);
13037    }
13038
13039    private void setEnabledSetting(final String packageName, String className, int newState,
13040            final int flags, int userId, String callingPackage) {
13041        if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT
13042              || newState == COMPONENT_ENABLED_STATE_ENABLED
13043              || newState == COMPONENT_ENABLED_STATE_DISABLED
13044              || newState == COMPONENT_ENABLED_STATE_DISABLED_USER
13045              || newState == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED)) {
13046            throw new IllegalArgumentException("Invalid new component state: "
13047                    + newState);
13048        }
13049        PackageSetting pkgSetting;
13050        final int uid = Binder.getCallingUid();
13051        final int permission = mContext.checkCallingOrSelfPermission(
13052                android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
13053        enforceCrossUserPermission(uid, userId, false, true, "set enabled");
13054        final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
13055        boolean sendNow = false;
13056        boolean isApp = (className == null);
13057        String componentName = isApp ? packageName : className;
13058        int packageUid = -1;
13059        ArrayList<String> components;
13060
13061        // writer
13062        synchronized (mPackages) {
13063            pkgSetting = mSettings.mPackages.get(packageName);
13064            if (pkgSetting == null) {
13065                if (className == null) {
13066                    throw new IllegalArgumentException(
13067                            "Unknown package: " + packageName);
13068                }
13069                throw new IllegalArgumentException(
13070                        "Unknown component: " + packageName
13071                        + "/" + className);
13072            }
13073            // Allow root and verify that userId is not being specified by a different user
13074            if (!allowedByPermission && !UserHandle.isSameApp(uid, pkgSetting.appId)) {
13075                throw new SecurityException(
13076                        "Permission Denial: attempt to change component state from pid="
13077                        + Binder.getCallingPid()
13078                        + ", uid=" + uid + ", package uid=" + pkgSetting.appId);
13079            }
13080            if (className == null) {
13081                // We're dealing with an application/package level state change
13082                if (pkgSetting.getEnabled(userId) == newState) {
13083                    // Nothing to do
13084                    return;
13085                }
13086                if (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
13087                    || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {
13088                    // Don't care about who enables an app.
13089                    callingPackage = null;
13090                }
13091                pkgSetting.setEnabled(newState, userId, callingPackage);
13092                // pkgSetting.pkg.mSetEnabled = newState;
13093            } else {
13094                // We're dealing with a component level state change
13095                // First, verify that this is a valid class name.
13096                PackageParser.Package pkg = pkgSetting.pkg;
13097                if (pkg == null || !pkg.hasComponentClassName(className)) {
13098                    if (pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.JELLY_BEAN) {
13099                        throw new IllegalArgumentException("Component class " + className
13100                                + " does not exist in " + packageName);
13101                    } else {
13102                        Slog.w(TAG, "Failed setComponentEnabledSetting: component class "
13103                                + className + " does not exist in " + packageName);
13104                    }
13105                }
13106                switch (newState) {
13107                case COMPONENT_ENABLED_STATE_ENABLED:
13108                    if (!pkgSetting.enableComponentLPw(className, userId)) {
13109                        return;
13110                    }
13111                    break;
13112                case COMPONENT_ENABLED_STATE_DISABLED:
13113                    if (!pkgSetting.disableComponentLPw(className, userId)) {
13114                        return;
13115                    }
13116                    break;
13117                case COMPONENT_ENABLED_STATE_DEFAULT:
13118                    if (!pkgSetting.restoreComponentLPw(className, userId)) {
13119                        return;
13120                    }
13121                    break;
13122                default:
13123                    Slog.e(TAG, "Invalid new component state: " + newState);
13124                    return;
13125                }
13126            }
13127            scheduleWritePackageRestrictionsLocked(userId);
13128            components = mPendingBroadcasts.get(userId, packageName);
13129            final boolean newPackage = components == null;
13130            if (newPackage) {
13131                components = new ArrayList<String>();
13132            }
13133            if (!components.contains(componentName)) {
13134                components.add(componentName);
13135            }
13136            if ((flags&PackageManager.DONT_KILL_APP) == 0) {
13137                sendNow = true;
13138                // Purge entry from pending broadcast list if another one exists already
13139                // since we are sending one right away.
13140                mPendingBroadcasts.remove(userId, packageName);
13141            } else {
13142                if (newPackage) {
13143                    mPendingBroadcasts.put(userId, packageName, components);
13144                }
13145                if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) {
13146                    // Schedule a message
13147                    mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, BROADCAST_DELAY);
13148                }
13149            }
13150        }
13151
13152        long callingId = Binder.clearCallingIdentity();
13153        try {
13154            if (sendNow) {
13155                packageUid = UserHandle.getUid(userId, pkgSetting.appId);
13156                sendPackageChangedBroadcast(packageName,
13157                        (flags&PackageManager.DONT_KILL_APP) != 0, components, packageUid);
13158            }
13159        } finally {
13160            Binder.restoreCallingIdentity(callingId);
13161        }
13162    }
13163
13164    private void sendPackageChangedBroadcast(String packageName,
13165            boolean killFlag, ArrayList<String> componentNames, int packageUid) {
13166        if (DEBUG_INSTALL)
13167            Log.v(TAG, "Sending package changed: package=" + packageName + " components="
13168                    + componentNames);
13169        Bundle extras = new Bundle(4);
13170        extras.putString(Intent.EXTRA_CHANGED_COMPONENT_NAME, componentNames.get(0));
13171        String nameList[] = new String[componentNames.size()];
13172        componentNames.toArray(nameList);
13173        extras.putStringArray(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST, nameList);
13174        extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, killFlag);
13175        extras.putInt(Intent.EXTRA_UID, packageUid);
13176        sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED,  packageName, extras, null, null,
13177                new int[] {UserHandle.getUserId(packageUid)});
13178    }
13179
13180    @Override
13181    public void setPackageStoppedState(String packageName, boolean stopped, int userId) {
13182        if (!sUserManager.exists(userId)) return;
13183        final int uid = Binder.getCallingUid();
13184        final int permission = mContext.checkCallingOrSelfPermission(
13185                android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
13186        final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
13187        enforceCrossUserPermission(uid, userId, true, true, "stop package");
13188        // writer
13189        synchronized (mPackages) {
13190            if (mSettings.setPackageStoppedStateLPw(this, packageName, stopped,
13191                    allowedByPermission, uid, userId)) {
13192                scheduleWritePackageRestrictionsLocked(userId);
13193            }
13194        }
13195    }
13196
13197    @Override
13198    public String getInstallerPackageName(String packageName) {
13199        // reader
13200        synchronized (mPackages) {
13201            return mSettings.getInstallerPackageNameLPr(packageName);
13202        }
13203    }
13204
13205    @Override
13206    public int getApplicationEnabledSetting(String packageName, int userId) {
13207        if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
13208        int uid = Binder.getCallingUid();
13209        enforceCrossUserPermission(uid, userId, false, false, "get enabled");
13210        // reader
13211        synchronized (mPackages) {
13212            return mSettings.getApplicationEnabledSettingLPr(packageName, userId);
13213        }
13214    }
13215
13216    @Override
13217    public int getComponentEnabledSetting(ComponentName componentName, int userId) {
13218        if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
13219        int uid = Binder.getCallingUid();
13220        enforceCrossUserPermission(uid, userId, false, false, "get component enabled");
13221        // reader
13222        synchronized (mPackages) {
13223            return mSettings.getComponentEnabledSettingLPr(componentName, userId);
13224        }
13225    }
13226
13227    @Override
13228    public void enterSafeMode() {
13229        enforceSystemOrRoot("Only the system can request entering safe mode");
13230
13231        if (!mSystemReady) {
13232            mSafeMode = true;
13233        }
13234    }
13235
13236    @Override
13237    public void systemReady() {
13238        mSystemReady = true;
13239
13240        // Read the compatibilty setting when the system is ready.
13241        boolean compatibilityModeEnabled = android.provider.Settings.Global.getInt(
13242                mContext.getContentResolver(),
13243                android.provider.Settings.Global.COMPATIBILITY_MODE, 1) == 1;
13244        PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled);
13245        if (DEBUG_SETTINGS) {
13246            Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled);
13247        }
13248
13249        synchronized (mPackages) {
13250            // Verify that all of the preferred activity components actually
13251            // exist.  It is possible for applications to be updated and at
13252            // that point remove a previously declared activity component that
13253            // had been set as a preferred activity.  We try to clean this up
13254            // the next time we encounter that preferred activity, but it is
13255            // possible for the user flow to never be able to return to that
13256            // situation so here we do a sanity check to make sure we haven't
13257            // left any junk around.
13258            ArrayList<PreferredActivity> removed = new ArrayList<PreferredActivity>();
13259            for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
13260                PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
13261                removed.clear();
13262                for (PreferredActivity pa : pir.filterSet()) {
13263                    if (mActivities.mActivities.get(pa.mPref.mComponent) == null) {
13264                        removed.add(pa);
13265                    }
13266                }
13267                if (removed.size() > 0) {
13268                    for (int r=0; r<removed.size(); r++) {
13269                        PreferredActivity pa = removed.get(r);
13270                        Slog.w(TAG, "Removing dangling preferred activity: "
13271                                + pa.mPref.mComponent);
13272                        pir.removeFilter(pa);
13273                    }
13274                    mSettings.writePackageRestrictionsLPr(
13275                            mSettings.mPreferredActivities.keyAt(i));
13276                }
13277            }
13278        }
13279        sUserManager.systemReady();
13280
13281        // Kick off any messages waiting for system ready
13282        if (mPostSystemReadyMessages != null) {
13283            for (Message msg : mPostSystemReadyMessages) {
13284                msg.sendToTarget();
13285            }
13286            mPostSystemReadyMessages = null;
13287        }
13288
13289        // Watch for external volumes that come and go over time
13290        final StorageManager storage = mContext.getSystemService(StorageManager.class);
13291        storage.registerListener(mStorageListener);
13292
13293        mInstallerService.systemReady();
13294    }
13295
13296    @Override
13297    public boolean isSafeMode() {
13298        return mSafeMode;
13299    }
13300
13301    @Override
13302    public boolean hasSystemUidErrors() {
13303        return mHasSystemUidErrors;
13304    }
13305
13306    static String arrayToString(int[] array) {
13307        StringBuffer buf = new StringBuffer(128);
13308        buf.append('[');
13309        if (array != null) {
13310            for (int i=0; i<array.length; i++) {
13311                if (i > 0) buf.append(", ");
13312                buf.append(array[i]);
13313            }
13314        }
13315        buf.append(']');
13316        return buf.toString();
13317    }
13318
13319    static class DumpState {
13320        public static final int DUMP_LIBS = 1 << 0;
13321        public static final int DUMP_FEATURES = 1 << 1;
13322        public static final int DUMP_RESOLVERS = 1 << 2;
13323        public static final int DUMP_PERMISSIONS = 1 << 3;
13324        public static final int DUMP_PACKAGES = 1 << 4;
13325        public static final int DUMP_SHARED_USERS = 1 << 5;
13326        public static final int DUMP_MESSAGES = 1 << 6;
13327        public static final int DUMP_PROVIDERS = 1 << 7;
13328        public static final int DUMP_VERIFIERS = 1 << 8;
13329        public static final int DUMP_PREFERRED = 1 << 9;
13330        public static final int DUMP_PREFERRED_XML = 1 << 10;
13331        public static final int DUMP_KEYSETS = 1 << 11;
13332        public static final int DUMP_VERSION = 1 << 12;
13333        public static final int DUMP_INSTALLS = 1 << 13;
13334        public static final int DUMP_INTENT_FILTER_VERIFIERS = 1 << 14;
13335        public static final int DUMP_DOMAIN_PREFERRED = 1 << 15;
13336
13337        public static final int OPTION_SHOW_FILTERS = 1 << 0;
13338
13339        private int mTypes;
13340
13341        private int mOptions;
13342
13343        private boolean mTitlePrinted;
13344
13345        private SharedUserSetting mSharedUser;
13346
13347        public boolean isDumping(int type) {
13348            if (mTypes == 0 && type != DUMP_PREFERRED_XML) {
13349                return true;
13350            }
13351
13352            return (mTypes & type) != 0;
13353        }
13354
13355        public void setDump(int type) {
13356            mTypes |= type;
13357        }
13358
13359        public boolean isOptionEnabled(int option) {
13360            return (mOptions & option) != 0;
13361        }
13362
13363        public void setOptionEnabled(int option) {
13364            mOptions |= option;
13365        }
13366
13367        public boolean onTitlePrinted() {
13368            final boolean printed = mTitlePrinted;
13369            mTitlePrinted = true;
13370            return printed;
13371        }
13372
13373        public boolean getTitlePrinted() {
13374            return mTitlePrinted;
13375        }
13376
13377        public void setTitlePrinted(boolean enabled) {
13378            mTitlePrinted = enabled;
13379        }
13380
13381        public SharedUserSetting getSharedUser() {
13382            return mSharedUser;
13383        }
13384
13385        public void setSharedUser(SharedUserSetting user) {
13386            mSharedUser = user;
13387        }
13388    }
13389
13390    @Override
13391    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
13392        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
13393                != PackageManager.PERMISSION_GRANTED) {
13394            pw.println("Permission Denial: can't dump ActivityManager from from pid="
13395                    + Binder.getCallingPid()
13396                    + ", uid=" + Binder.getCallingUid()
13397                    + " without permission "
13398                    + android.Manifest.permission.DUMP);
13399            return;
13400        }
13401
13402        DumpState dumpState = new DumpState();
13403        boolean fullPreferred = false;
13404        boolean checkin = false;
13405
13406        String packageName = null;
13407
13408        int opti = 0;
13409        while (opti < args.length) {
13410            String opt = args[opti];
13411            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13412                break;
13413            }
13414            opti++;
13415
13416            if ("-a".equals(opt)) {
13417                // Right now we only know how to print all.
13418            } else if ("-h".equals(opt)) {
13419                pw.println("Package manager dump options:");
13420                pw.println("  [-h] [-f] [--checkin] [cmd] ...");
13421                pw.println("    --checkin: dump for a checkin");
13422                pw.println("    -f: print details of intent filters");
13423                pw.println("    -h: print this help");
13424                pw.println("  cmd may be one of:");
13425                pw.println("    l[ibraries]: list known shared libraries");
13426                pw.println("    f[ibraries]: list device features");
13427                pw.println("    k[eysets]: print known keysets");
13428                pw.println("    r[esolvers]: dump intent resolvers");
13429                pw.println("    perm[issions]: dump permissions");
13430                pw.println("    pref[erred]: print preferred package settings");
13431                pw.println("    preferred-xml [--full]: print preferred package settings as xml");
13432                pw.println("    prov[iders]: dump content providers");
13433                pw.println("    p[ackages]: dump installed packages");
13434                pw.println("    s[hared-users]: dump shared user IDs");
13435                pw.println("    m[essages]: print collected runtime messages");
13436                pw.println("    v[erifiers]: print package verifier info");
13437                pw.println("    version: print database version info");
13438                pw.println("    write: write current settings now");
13439                pw.println("    <package.name>: info about given package");
13440                pw.println("    installs: details about install sessions");
13441                pw.println("    d[omain-preferred-apps]: print domains preferred apps");
13442                pw.println("    i[ntent-filter-verifiers]|ifv: print intent filter verifier info");
13443                return;
13444            } else if ("--checkin".equals(opt)) {
13445                checkin = true;
13446            } else if ("-f".equals(opt)) {
13447                dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
13448            } else {
13449                pw.println("Unknown argument: " + opt + "; use -h for help");
13450            }
13451        }
13452
13453        // Is the caller requesting to dump a particular piece of data?
13454        if (opti < args.length) {
13455            String cmd = args[opti];
13456            opti++;
13457            // Is this a package name?
13458            if ("android".equals(cmd) || cmd.contains(".")) {
13459                packageName = cmd;
13460                // When dumping a single package, we always dump all of its
13461                // filter information since the amount of data will be reasonable.
13462                dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
13463            } else if ("l".equals(cmd) || "libraries".equals(cmd)) {
13464                dumpState.setDump(DumpState.DUMP_LIBS);
13465            } else if ("f".equals(cmd) || "features".equals(cmd)) {
13466                dumpState.setDump(DumpState.DUMP_FEATURES);
13467            } else if ("r".equals(cmd) || "resolvers".equals(cmd)) {
13468                dumpState.setDump(DumpState.DUMP_RESOLVERS);
13469            } else if ("perm".equals(cmd) || "permissions".equals(cmd)) {
13470                dumpState.setDump(DumpState.DUMP_PERMISSIONS);
13471            } else if ("pref".equals(cmd) || "preferred".equals(cmd)) {
13472                dumpState.setDump(DumpState.DUMP_PREFERRED);
13473            } else if ("preferred-xml".equals(cmd)) {
13474                dumpState.setDump(DumpState.DUMP_PREFERRED_XML);
13475                if (opti < args.length && "--full".equals(args[opti])) {
13476                    fullPreferred = true;
13477                    opti++;
13478                }
13479            } else if ("d".equals(cmd) || "domain-preferred-apps".equals(cmd)) {
13480                dumpState.setDump(DumpState.DUMP_DOMAIN_PREFERRED);
13481            } else if ("p".equals(cmd) || "packages".equals(cmd)) {
13482                dumpState.setDump(DumpState.DUMP_PACKAGES);
13483            } else if ("s".equals(cmd) || "shared-users".equals(cmd)) {
13484                dumpState.setDump(DumpState.DUMP_SHARED_USERS);
13485            } else if ("prov".equals(cmd) || "providers".equals(cmd)) {
13486                dumpState.setDump(DumpState.DUMP_PROVIDERS);
13487            } else if ("m".equals(cmd) || "messages".equals(cmd)) {
13488                dumpState.setDump(DumpState.DUMP_MESSAGES);
13489            } else if ("v".equals(cmd) || "verifiers".equals(cmd)) {
13490                dumpState.setDump(DumpState.DUMP_VERIFIERS);
13491            } else if ("i".equals(cmd) || "ifv".equals(cmd)
13492                    || "intent-filter-verifiers".equals(cmd)) {
13493                dumpState.setDump(DumpState.DUMP_INTENT_FILTER_VERIFIERS);
13494            } else if ("version".equals(cmd)) {
13495                dumpState.setDump(DumpState.DUMP_VERSION);
13496            } else if ("k".equals(cmd) || "keysets".equals(cmd)) {
13497                dumpState.setDump(DumpState.DUMP_KEYSETS);
13498            } else if ("installs".equals(cmd)) {
13499                dumpState.setDump(DumpState.DUMP_INSTALLS);
13500            } else if ("write".equals(cmd)) {
13501                synchronized (mPackages) {
13502                    mSettings.writeLPr();
13503                    pw.println("Settings written.");
13504                    return;
13505                }
13506            }
13507        }
13508
13509        if (checkin) {
13510            pw.println("vers,1");
13511        }
13512
13513        // reader
13514        synchronized (mPackages) {
13515            if (dumpState.isDumping(DumpState.DUMP_VERSION) && packageName == null) {
13516                if (!checkin) {
13517                    if (dumpState.onTitlePrinted())
13518                        pw.println();
13519                    pw.println("Database versions:");
13520                    pw.print("  SDK Version:");
13521                    pw.print(" internal=");
13522                    pw.print(mSettings.mInternalSdkPlatform);
13523                    pw.print(" external=");
13524                    pw.println(mSettings.mExternalSdkPlatform);
13525                    pw.print("  DB Version:");
13526                    pw.print(" internal=");
13527                    pw.print(mSettings.mInternalDatabaseVersion);
13528                    pw.print(" external=");
13529                    pw.println(mSettings.mExternalDatabaseVersion);
13530                }
13531            }
13532
13533            if (dumpState.isDumping(DumpState.DUMP_VERIFIERS) && packageName == null) {
13534                if (!checkin) {
13535                    if (dumpState.onTitlePrinted())
13536                        pw.println();
13537                    pw.println("Verifiers:");
13538                    pw.print("  Required: ");
13539                    pw.print(mRequiredVerifierPackage);
13540                    pw.print(" (uid=");
13541                    pw.print(getPackageUid(mRequiredVerifierPackage, 0));
13542                    pw.println(")");
13543                } else if (mRequiredVerifierPackage != null) {
13544                    pw.print("vrfy,"); pw.print(mRequiredVerifierPackage);
13545                    pw.print(","); pw.println(getPackageUid(mRequiredVerifierPackage, 0));
13546                }
13547            }
13548
13549            if (dumpState.isDumping(DumpState.DUMP_INTENT_FILTER_VERIFIERS) &&
13550                    packageName == null) {
13551                if (mIntentFilterVerifierComponent != null) {
13552                    String verifierPackageName = mIntentFilterVerifierComponent.getPackageName();
13553                    if (!checkin) {
13554                        if (dumpState.onTitlePrinted())
13555                            pw.println();
13556                        pw.println("Intent Filter Verifier:");
13557                        pw.print("  Using: ");
13558                        pw.print(verifierPackageName);
13559                        pw.print(" (uid=");
13560                        pw.print(getPackageUid(verifierPackageName, 0));
13561                        pw.println(")");
13562                    } else if (verifierPackageName != null) {
13563                        pw.print("ifv,"); pw.print(verifierPackageName);
13564                        pw.print(","); pw.println(getPackageUid(verifierPackageName, 0));
13565                    }
13566                } else {
13567                    pw.println();
13568                    pw.println("No Intent Filter Verifier available!");
13569                }
13570            }
13571
13572            if (dumpState.isDumping(DumpState.DUMP_LIBS) && packageName == null) {
13573                boolean printedHeader = false;
13574                final Iterator<String> it = mSharedLibraries.keySet().iterator();
13575                while (it.hasNext()) {
13576                    String name = it.next();
13577                    SharedLibraryEntry ent = mSharedLibraries.get(name);
13578                    if (!checkin) {
13579                        if (!printedHeader) {
13580                            if (dumpState.onTitlePrinted())
13581                                pw.println();
13582                            pw.println("Libraries:");
13583                            printedHeader = true;
13584                        }
13585                        pw.print("  ");
13586                    } else {
13587                        pw.print("lib,");
13588                    }
13589                    pw.print(name);
13590                    if (!checkin) {
13591                        pw.print(" -> ");
13592                    }
13593                    if (ent.path != null) {
13594                        if (!checkin) {
13595                            pw.print("(jar) ");
13596                            pw.print(ent.path);
13597                        } else {
13598                            pw.print(",jar,");
13599                            pw.print(ent.path);
13600                        }
13601                    } else {
13602                        if (!checkin) {
13603                            pw.print("(apk) ");
13604                            pw.print(ent.apk);
13605                        } else {
13606                            pw.print(",apk,");
13607                            pw.print(ent.apk);
13608                        }
13609                    }
13610                    pw.println();
13611                }
13612            }
13613
13614            if (dumpState.isDumping(DumpState.DUMP_FEATURES) && packageName == null) {
13615                if (dumpState.onTitlePrinted())
13616                    pw.println();
13617                if (!checkin) {
13618                    pw.println("Features:");
13619                }
13620                Iterator<String> it = mAvailableFeatures.keySet().iterator();
13621                while (it.hasNext()) {
13622                    String name = it.next();
13623                    if (!checkin) {
13624                        pw.print("  ");
13625                    } else {
13626                        pw.print("feat,");
13627                    }
13628                    pw.println(name);
13629                }
13630            }
13631
13632            if (!checkin && dumpState.isDumping(DumpState.DUMP_RESOLVERS)) {
13633                if (mActivities.dump(pw, dumpState.getTitlePrinted() ? "\nActivity Resolver Table:"
13634                        : "Activity Resolver Table:", "  ", packageName,
13635                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
13636                    dumpState.setTitlePrinted(true);
13637                }
13638                if (mReceivers.dump(pw, dumpState.getTitlePrinted() ? "\nReceiver Resolver Table:"
13639                        : "Receiver Resolver Table:", "  ", packageName,
13640                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
13641                    dumpState.setTitlePrinted(true);
13642                }
13643                if (mServices.dump(pw, dumpState.getTitlePrinted() ? "\nService Resolver Table:"
13644                        : "Service Resolver Table:", "  ", packageName,
13645                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
13646                    dumpState.setTitlePrinted(true);
13647                }
13648                if (mProviders.dump(pw, dumpState.getTitlePrinted() ? "\nProvider Resolver Table:"
13649                        : "Provider Resolver Table:", "  ", packageName,
13650                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
13651                    dumpState.setTitlePrinted(true);
13652                }
13653            }
13654
13655            if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED)) {
13656                for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
13657                    PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
13658                    int user = mSettings.mPreferredActivities.keyAt(i);
13659                    if (pir.dump(pw,
13660                            dumpState.getTitlePrinted()
13661                                ? "\nPreferred Activities User " + user + ":"
13662                                : "Preferred Activities User " + user + ":", "  ",
13663                            packageName, true, false)) {
13664                        dumpState.setTitlePrinted(true);
13665                    }
13666                }
13667            }
13668
13669            if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED_XML)) {
13670                pw.flush();
13671                FileOutputStream fout = new FileOutputStream(fd);
13672                BufferedOutputStream str = new BufferedOutputStream(fout);
13673                XmlSerializer serializer = new FastXmlSerializer();
13674                try {
13675                    serializer.setOutput(str, "utf-8");
13676                    serializer.startDocument(null, true);
13677                    serializer.setFeature(
13678                            "http://xmlpull.org/v1/doc/features.html#indent-output", true);
13679                    mSettings.writePreferredActivitiesLPr(serializer, 0, fullPreferred);
13680                    serializer.endDocument();
13681                    serializer.flush();
13682                } catch (IllegalArgumentException e) {
13683                    pw.println("Failed writing: " + e);
13684                } catch (IllegalStateException e) {
13685                    pw.println("Failed writing: " + e);
13686                } catch (IOException e) {
13687                    pw.println("Failed writing: " + e);
13688                }
13689            }
13690
13691            if (!checkin && dumpState.isDumping(DumpState.DUMP_DOMAIN_PREFERRED)) {
13692                pw.println();
13693                int count = mSettings.mPackages.size();
13694                if (count == 0) {
13695                    pw.println("No domain preferred apps!");
13696                    pw.println();
13697                } else {
13698                    final String prefix = "  ";
13699                    Collection<PackageSetting> allPackageSettings = mSettings.mPackages.values();
13700                    if (allPackageSettings.size() == 0) {
13701                        pw.println("No domain preferred apps!");
13702                        pw.println();
13703                    } else {
13704                        pw.println("Domain preferred apps status:");
13705                        pw.println();
13706                        count = 0;
13707                        for (PackageSetting ps : allPackageSettings) {
13708                            IntentFilterVerificationInfo ivi = ps.getIntentFilterVerificationInfo();
13709                            if (ivi == null || ivi.getPackageName() == null) continue;
13710                            pw.println(prefix + "Package Name: " + ivi.getPackageName());
13711                            pw.println(prefix + "Domains: " + ivi.getDomainsString());
13712                            pw.println(prefix + "Status: " + ivi.getStatusString());
13713                            pw.println();
13714                            count++;
13715                        }
13716                        if (count == 0) {
13717                            pw.println(prefix + "No domain preferred app status!");
13718                            pw.println();
13719                        }
13720                        for (int userId : sUserManager.getUserIds()) {
13721                            pw.println("Domain preferred apps for User " + userId + ":");
13722                            pw.println();
13723                            count = 0;
13724                            for (PackageSetting ps : allPackageSettings) {
13725                                IntentFilterVerificationInfo ivi = ps.getIntentFilterVerificationInfo();
13726                                if (ivi == null || ivi.getPackageName() == null) {
13727                                    continue;
13728                                }
13729                                final int status = ps.getDomainVerificationStatusForUser(userId);
13730                                if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) {
13731                                    continue;
13732                                }
13733                                pw.println(prefix + "Package Name: " + ivi.getPackageName());
13734                                pw.println(prefix + "Domains: " + ivi.getDomainsString());
13735                                String statusStr = IntentFilterVerificationInfo.
13736                                        getStatusStringFromValue(status);
13737                                pw.println(prefix + "Status: " + statusStr);
13738                                pw.println();
13739                                count++;
13740                            }
13741                            if (count == 0) {
13742                                pw.println(prefix + "No domain preferred apps!");
13743                                pw.println();
13744                            }
13745                        }
13746                    }
13747                }
13748            }
13749
13750            if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) {
13751                mSettings.dumpPermissionsLPr(pw, packageName, dumpState);
13752                if (packageName == null) {
13753                    for (int iperm=0; iperm<mAppOpPermissionPackages.size(); iperm++) {
13754                        if (iperm == 0) {
13755                            if (dumpState.onTitlePrinted())
13756                                pw.println();
13757                            pw.println("AppOp Permissions:");
13758                        }
13759                        pw.print("  AppOp Permission ");
13760                        pw.print(mAppOpPermissionPackages.keyAt(iperm));
13761                        pw.println(":");
13762                        ArraySet<String> pkgs = mAppOpPermissionPackages.valueAt(iperm);
13763                        for (int ipkg=0; ipkg<pkgs.size(); ipkg++) {
13764                            pw.print("    "); pw.println(pkgs.valueAt(ipkg));
13765                        }
13766                    }
13767                }
13768            }
13769
13770            if (!checkin && dumpState.isDumping(DumpState.DUMP_PROVIDERS)) {
13771                boolean printedSomething = false;
13772                for (PackageParser.Provider p : mProviders.mProviders.values()) {
13773                    if (packageName != null && !packageName.equals(p.info.packageName)) {
13774                        continue;
13775                    }
13776                    if (!printedSomething) {
13777                        if (dumpState.onTitlePrinted())
13778                            pw.println();
13779                        pw.println("Registered ContentProviders:");
13780                        printedSomething = true;
13781                    }
13782                    pw.print("  "); p.printComponentShortName(pw); pw.println(":");
13783                    pw.print("    "); pw.println(p.toString());
13784                }
13785                printedSomething = false;
13786                for (Map.Entry<String, PackageParser.Provider> entry :
13787                        mProvidersByAuthority.entrySet()) {
13788                    PackageParser.Provider p = entry.getValue();
13789                    if (packageName != null && !packageName.equals(p.info.packageName)) {
13790                        continue;
13791                    }
13792                    if (!printedSomething) {
13793                        if (dumpState.onTitlePrinted())
13794                            pw.println();
13795                        pw.println("ContentProvider Authorities:");
13796                        printedSomething = true;
13797                    }
13798                    pw.print("  ["); pw.print(entry.getKey()); pw.println("]:");
13799                    pw.print("    "); pw.println(p.toString());
13800                    if (p.info != null && p.info.applicationInfo != null) {
13801                        final String appInfo = p.info.applicationInfo.toString();
13802                        pw.print("      applicationInfo="); pw.println(appInfo);
13803                    }
13804                }
13805            }
13806
13807            if (!checkin && dumpState.isDumping(DumpState.DUMP_KEYSETS)) {
13808                mSettings.mKeySetManagerService.dumpLPr(pw, packageName, dumpState);
13809            }
13810
13811            if (dumpState.isDumping(DumpState.DUMP_PACKAGES)) {
13812                mSettings.dumpPackagesLPr(pw, packageName, dumpState, checkin);
13813            }
13814
13815            if (dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) {
13816                mSettings.dumpSharedUsersLPr(pw, packageName, dumpState, checkin);
13817            }
13818
13819            if (!checkin && dumpState.isDumping(DumpState.DUMP_INSTALLS) && packageName == null) {
13820                // XXX should handle packageName != null by dumping only install data that
13821                // the given package is involved with.
13822                if (dumpState.onTitlePrinted()) pw.println();
13823                mInstallerService.dump(new IndentingPrintWriter(pw, "  ", 120));
13824            }
13825
13826            if (!checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES) && packageName == null) {
13827                if (dumpState.onTitlePrinted()) pw.println();
13828                mSettings.dumpReadMessagesLPr(pw, dumpState);
13829
13830                pw.println();
13831                pw.println("Package warning messages:");
13832                BufferedReader in = null;
13833                String line = null;
13834                try {
13835                    in = new BufferedReader(new FileReader(getSettingsProblemFile()));
13836                    while ((line = in.readLine()) != null) {
13837                        if (line.contains("ignored: updated version")) continue;
13838                        pw.println(line);
13839                    }
13840                } catch (IOException ignored) {
13841                } finally {
13842                    IoUtils.closeQuietly(in);
13843                }
13844            }
13845
13846            if (checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES)) {
13847                BufferedReader in = null;
13848                String line = null;
13849                try {
13850                    in = new BufferedReader(new FileReader(getSettingsProblemFile()));
13851                    while ((line = in.readLine()) != null) {
13852                        if (line.contains("ignored: updated version")) continue;
13853                        pw.print("msg,");
13854                        pw.println(line);
13855                    }
13856                } catch (IOException ignored) {
13857                } finally {
13858                    IoUtils.closeQuietly(in);
13859                }
13860            }
13861        }
13862    }
13863
13864    // ------- apps on sdcard specific code -------
13865    static final boolean DEBUG_SD_INSTALL = false;
13866
13867    private static final String SD_ENCRYPTION_KEYSTORE_NAME = "AppsOnSD";
13868
13869    private static final String SD_ENCRYPTION_ALGORITHM = "AES";
13870
13871    private boolean mMediaMounted = false;
13872
13873    static String getEncryptKey() {
13874        try {
13875            String sdEncKey = SystemKeyStore.getInstance().retrieveKeyHexString(
13876                    SD_ENCRYPTION_KEYSTORE_NAME);
13877            if (sdEncKey == null) {
13878                sdEncKey = SystemKeyStore.getInstance().generateNewKeyHexString(128,
13879                        SD_ENCRYPTION_ALGORITHM, SD_ENCRYPTION_KEYSTORE_NAME);
13880                if (sdEncKey == null) {
13881                    Slog.e(TAG, "Failed to create encryption keys");
13882                    return null;
13883                }
13884            }
13885            return sdEncKey;
13886        } catch (NoSuchAlgorithmException nsae) {
13887            Slog.e(TAG, "Failed to create encryption keys with exception: " + nsae);
13888            return null;
13889        } catch (IOException ioe) {
13890            Slog.e(TAG, "Failed to retrieve encryption keys with exception: " + ioe);
13891            return null;
13892        }
13893    }
13894
13895    /*
13896     * Update media status on PackageManager.
13897     */
13898    @Override
13899    public void updateExternalMediaStatus(final boolean mediaStatus, final boolean reportStatus) {
13900        int callingUid = Binder.getCallingUid();
13901        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
13902            throw new SecurityException("Media status can only be updated by the system");
13903        }
13904        // reader; this apparently protects mMediaMounted, but should probably
13905        // be a different lock in that case.
13906        synchronized (mPackages) {
13907            Log.i(TAG, "Updating external media status from "
13908                    + (mMediaMounted ? "mounted" : "unmounted") + " to "
13909                    + (mediaStatus ? "mounted" : "unmounted"));
13910            if (DEBUG_SD_INSTALL)
13911                Log.i(TAG, "updateExternalMediaStatus:: mediaStatus=" + mediaStatus
13912                        + ", mMediaMounted=" + mMediaMounted);
13913            if (mediaStatus == mMediaMounted) {
13914                final Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1
13915                        : 0, -1);
13916                mHandler.sendMessage(msg);
13917                return;
13918            }
13919            mMediaMounted = mediaStatus;
13920        }
13921        // Queue up an async operation since the package installation may take a
13922        // little while.
13923        mHandler.post(new Runnable() {
13924            public void run() {
13925                updateExternalMediaStatusInner(mediaStatus, reportStatus, true);
13926            }
13927        });
13928    }
13929
13930    /**
13931     * Called by MountService when the initial ASECs to scan are available.
13932     * Should block until all the ASEC containers are finished being scanned.
13933     */
13934    public void scanAvailableAsecs() {
13935        updateExternalMediaStatusInner(true, false, false);
13936        if (mShouldRestoreconData) {
13937            SELinuxMMAC.setRestoreconDone();
13938            mShouldRestoreconData = false;
13939        }
13940    }
13941
13942    /*
13943     * Collect information of applications on external media, map them against
13944     * existing containers and update information based on current mount status.
13945     * Please note that we always have to report status if reportStatus has been
13946     * set to true especially when unloading packages.
13947     */
13948    private void updateExternalMediaStatusInner(boolean isMounted, boolean reportStatus,
13949            boolean externalStorage) {
13950        ArrayMap<AsecInstallArgs, String> processCids = new ArrayMap<>();
13951        int[] uidArr = EmptyArray.INT;
13952
13953        final String[] list = PackageHelper.getSecureContainerList();
13954        if (ArrayUtils.isEmpty(list)) {
13955            Log.i(TAG, "No secure containers found");
13956        } else {
13957            // Process list of secure containers and categorize them
13958            // as active or stale based on their package internal state.
13959
13960            // reader
13961            synchronized (mPackages) {
13962                for (String cid : list) {
13963                    // Leave stages untouched for now; installer service owns them
13964                    if (PackageInstallerService.isStageName(cid)) continue;
13965
13966                    if (DEBUG_SD_INSTALL)
13967                        Log.i(TAG, "Processing container " + cid);
13968                    String pkgName = getAsecPackageName(cid);
13969                    if (pkgName == null) {
13970                        Slog.i(TAG, "Found stale container " + cid + " with no package name");
13971                        continue;
13972                    }
13973                    if (DEBUG_SD_INSTALL)
13974                        Log.i(TAG, "Looking for pkg : " + pkgName);
13975
13976                    final PackageSetting ps = mSettings.mPackages.get(pkgName);
13977                    if (ps == null) {
13978                        Slog.i(TAG, "Found stale container " + cid + " with no matching settings");
13979                        continue;
13980                    }
13981
13982                    /*
13983                     * Skip packages that are not external if we're unmounting
13984                     * external storage.
13985                     */
13986                    if (externalStorage && !isMounted && !isExternal(ps)) {
13987                        continue;
13988                    }
13989
13990                    final AsecInstallArgs args = new AsecInstallArgs(cid,
13991                            getAppDexInstructionSets(ps), ps.isForwardLocked());
13992                    // The package status is changed only if the code path
13993                    // matches between settings and the container id.
13994                    if (ps.codePathString != null
13995                            && ps.codePathString.startsWith(args.getCodePath())) {
13996                        if (DEBUG_SD_INSTALL) {
13997                            Log.i(TAG, "Container : " + cid + " corresponds to pkg : " + pkgName
13998                                    + " at code path: " + ps.codePathString);
13999                        }
14000
14001                        // We do have a valid package installed on sdcard
14002                        processCids.put(args, ps.codePathString);
14003                        final int uid = ps.appId;
14004                        if (uid != -1) {
14005                            uidArr = ArrayUtils.appendInt(uidArr, uid);
14006                        }
14007                    } else {
14008                        Slog.i(TAG, "Found stale container " + cid + ": expected codePath="
14009                                + ps.codePathString);
14010                    }
14011                }
14012            }
14013
14014            Arrays.sort(uidArr);
14015        }
14016
14017        // Process packages with valid entries.
14018        if (isMounted) {
14019            if (DEBUG_SD_INSTALL)
14020                Log.i(TAG, "Loading packages");
14021            loadMediaPackages(processCids, uidArr);
14022            startCleaningPackages();
14023            mInstallerService.onSecureContainersAvailable();
14024        } else {
14025            if (DEBUG_SD_INSTALL)
14026                Log.i(TAG, "Unloading packages");
14027            unloadMediaPackages(processCids, uidArr, reportStatus);
14028        }
14029    }
14030
14031    private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
14032            ArrayList<ApplicationInfo> infos, IIntentReceiver finishedReceiver) {
14033        final int size = infos.size();
14034        final String[] packageNames = new String[size];
14035        final int[] packageUids = new int[size];
14036        for (int i = 0; i < size; i++) {
14037            final ApplicationInfo info = infos.get(i);
14038            packageNames[i] = info.packageName;
14039            packageUids[i] = info.uid;
14040        }
14041        sendResourcesChangedBroadcast(mediaStatus, replacing, packageNames, packageUids,
14042                finishedReceiver);
14043    }
14044
14045    private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
14046            ArrayList<String> pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
14047        sendResourcesChangedBroadcast(mediaStatus, replacing,
14048                pkgList.toArray(new String[pkgList.size()]), uidArr, finishedReceiver);
14049    }
14050
14051    private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
14052            String[] pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
14053        int size = pkgList.length;
14054        if (size > 0) {
14055            // Send broadcasts here
14056            Bundle extras = new Bundle();
14057            extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
14058            if (uidArr != null) {
14059                extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidArr);
14060            }
14061            if (replacing) {
14062                extras.putBoolean(Intent.EXTRA_REPLACING, replacing);
14063            }
14064            String action = mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE
14065                    : Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE;
14066            sendPackageBroadcast(action, null, extras, null, finishedReceiver, null);
14067        }
14068    }
14069
14070   /*
14071     * Look at potentially valid container ids from processCids If package
14072     * information doesn't match the one on record or package scanning fails,
14073     * the cid is added to list of removeCids. We currently don't delete stale
14074     * containers.
14075     */
14076    private void loadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int[] uidArr) {
14077        ArrayList<String> pkgList = new ArrayList<String>();
14078        Set<AsecInstallArgs> keys = processCids.keySet();
14079
14080        for (AsecInstallArgs args : keys) {
14081            String codePath = processCids.get(args);
14082            if (DEBUG_SD_INSTALL)
14083                Log.i(TAG, "Loading container : " + args.cid);
14084            int retCode = PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
14085            try {
14086                // Make sure there are no container errors first.
14087                if (args.doPreInstall(PackageManager.INSTALL_SUCCEEDED) != PackageManager.INSTALL_SUCCEEDED) {
14088                    Slog.e(TAG, "Failed to mount cid : " + args.cid
14089                            + " when installing from sdcard");
14090                    continue;
14091                }
14092                // Check code path here.
14093                if (codePath == null || !codePath.startsWith(args.getCodePath())) {
14094                    Slog.e(TAG, "Container " + args.cid + " cachepath " + args.getCodePath()
14095                            + " does not match one in settings " + codePath);
14096                    continue;
14097                }
14098                // Parse package
14099                int parseFlags = mDefParseFlags;
14100                if (args.isExternalAsec()) {
14101                    parseFlags |= PackageParser.PARSE_EXTERNAL_STORAGE;
14102                }
14103                if (args.isFwdLocked()) {
14104                    parseFlags |= PackageParser.PARSE_FORWARD_LOCK;
14105                }
14106
14107                synchronized (mInstallLock) {
14108                    PackageParser.Package pkg = null;
14109                    try {
14110                        pkg = scanPackageLI(new File(codePath), parseFlags, 0, 0, null);
14111                    } catch (PackageManagerException e) {
14112                        Slog.w(TAG, "Failed to scan " + codePath + ": " + e.getMessage());
14113                    }
14114                    // Scan the package
14115                    if (pkg != null) {
14116                        /*
14117                         * TODO why is the lock being held? doPostInstall is
14118                         * called in other places without the lock. This needs
14119                         * to be straightened out.
14120                         */
14121                        // writer
14122                        synchronized (mPackages) {
14123                            retCode = PackageManager.INSTALL_SUCCEEDED;
14124                            pkgList.add(pkg.packageName);
14125                            // Post process args
14126                            args.doPostInstall(PackageManager.INSTALL_SUCCEEDED,
14127                                    pkg.applicationInfo.uid);
14128                        }
14129                    } else {
14130                        Slog.i(TAG, "Failed to install pkg from  " + codePath + " from sdcard");
14131                    }
14132                }
14133
14134            } finally {
14135                if (retCode != PackageManager.INSTALL_SUCCEEDED) {
14136                    Log.w(TAG, "Container " + args.cid + " is stale, retCode=" + retCode);
14137                }
14138            }
14139        }
14140        // writer
14141        synchronized (mPackages) {
14142            // If the platform SDK has changed since the last time we booted,
14143            // we need to re-grant app permission to catch any new ones that
14144            // appear. This is really a hack, and means that apps can in some
14145            // cases get permissions that the user didn't initially explicitly
14146            // allow... it would be nice to have some better way to handle
14147            // this situation.
14148            final boolean regrantPermissions = mSettings.mExternalSdkPlatform != mSdkVersion;
14149            if (regrantPermissions)
14150                Slog.i(TAG, "Platform changed from " + mSettings.mExternalSdkPlatform + " to "
14151                        + mSdkVersion + "; regranting permissions for external storage");
14152            mSettings.mExternalSdkPlatform = mSdkVersion;
14153
14154            // Make sure group IDs have been assigned, and any permission
14155            // changes in other apps are accounted for
14156            updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL
14157                    | (regrantPermissions
14158                            ? (UPDATE_PERMISSIONS_REPLACE_PKG|UPDATE_PERMISSIONS_REPLACE_ALL)
14159                            : 0));
14160
14161            mSettings.updateExternalDatabaseVersion();
14162
14163            // can downgrade to reader
14164            // Persist settings
14165            mSettings.writeLPr();
14166        }
14167        // Send a broadcast to let everyone know we are done processing
14168        if (pkgList.size() > 0) {
14169            sendResourcesChangedBroadcast(true, false, pkgList, uidArr, null);
14170        }
14171    }
14172
14173   /*
14174     * Utility method to unload a list of specified containers
14175     */
14176    private void unloadAllContainers(Set<AsecInstallArgs> cidArgs) {
14177        // Just unmount all valid containers.
14178        for (AsecInstallArgs arg : cidArgs) {
14179            synchronized (mInstallLock) {
14180                arg.doPostDeleteLI(false);
14181           }
14182       }
14183   }
14184
14185    /*
14186     * Unload packages mounted on external media. This involves deleting package
14187     * data from internal structures, sending broadcasts about diabled packages,
14188     * gc'ing to free up references, unmounting all secure containers
14189     * corresponding to packages on external media, and posting a
14190     * UPDATED_MEDIA_STATUS message if status has been requested. Please note
14191     * that we always have to post this message if status has been requested no
14192     * matter what.
14193     */
14194    private void unloadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int uidArr[],
14195            final boolean reportStatus) {
14196        if (DEBUG_SD_INSTALL)
14197            Log.i(TAG, "unloading media packages");
14198        ArrayList<String> pkgList = new ArrayList<String>();
14199        ArrayList<AsecInstallArgs> failedList = new ArrayList<AsecInstallArgs>();
14200        final Set<AsecInstallArgs> keys = processCids.keySet();
14201        for (AsecInstallArgs args : keys) {
14202            String pkgName = args.getPackageName();
14203            if (DEBUG_SD_INSTALL)
14204                Log.i(TAG, "Trying to unload pkg : " + pkgName);
14205            // Delete package internally
14206            PackageRemovedInfo outInfo = new PackageRemovedInfo();
14207            synchronized (mInstallLock) {
14208                boolean res = deletePackageLI(pkgName, null, false, null, null,
14209                        PackageManager.DELETE_KEEP_DATA, outInfo, false);
14210                if (res) {
14211                    pkgList.add(pkgName);
14212                } else {
14213                    Slog.e(TAG, "Failed to delete pkg from sdcard : " + pkgName);
14214                    failedList.add(args);
14215                }
14216            }
14217        }
14218
14219        // reader
14220        synchronized (mPackages) {
14221            // We didn't update the settings after removing each package;
14222            // write them now for all packages.
14223            mSettings.writeLPr();
14224        }
14225
14226        // We have to absolutely send UPDATED_MEDIA_STATUS only
14227        // after confirming that all the receivers processed the ordered
14228        // broadcast when packages get disabled, force a gc to clean things up.
14229        // and unload all the containers.
14230        if (pkgList.size() > 0) {
14231            sendResourcesChangedBroadcast(false, false, pkgList, uidArr,
14232                    new IIntentReceiver.Stub() {
14233                public void performReceive(Intent intent, int resultCode, String data,
14234                        Bundle extras, boolean ordered, boolean sticky,
14235                        int sendingUser) throws RemoteException {
14236                    Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS,
14237                            reportStatus ? 1 : 0, 1, keys);
14238                    mHandler.sendMessage(msg);
14239                }
14240            });
14241        } else {
14242            Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1 : 0, -1,
14243                    keys);
14244            mHandler.sendMessage(msg);
14245        }
14246    }
14247
14248    private void loadPrivatePackages(VolumeInfo vol) {
14249        final ArrayList<ApplicationInfo> loaded = new ArrayList<>();
14250        final int parseFlags = mDefParseFlags | PackageParser.PARSE_EXTERNAL_STORAGE;
14251        synchronized (mInstallLock) {
14252        synchronized (mPackages) {
14253            final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(vol.fsUuid);
14254            for (PackageSetting ps : packages) {
14255                final PackageParser.Package pkg;
14256                try {
14257                    pkg = scanPackageLI(ps.codePath, parseFlags, 0, 0, null);
14258                    loaded.add(pkg.applicationInfo);
14259                } catch (PackageManagerException e) {
14260                    Slog.w(TAG, "Failed to scan " + ps.codePath + ": " + e.getMessage());
14261                }
14262            }
14263
14264            // TODO: regrant any permissions that changed based since original install
14265
14266            mSettings.writeLPr();
14267        }
14268        }
14269
14270        Slog.d(TAG, "Loaded packages " + loaded);
14271        sendResourcesChangedBroadcast(true, false, loaded, null);
14272    }
14273
14274    private void unloadPrivatePackages(VolumeInfo vol) {
14275        final ArrayList<ApplicationInfo> unloaded = new ArrayList<>();
14276        synchronized (mInstallLock) {
14277        synchronized (mPackages) {
14278            final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(vol.fsUuid);
14279            for (PackageSetting ps : packages) {
14280                if (ps.pkg == null) continue;
14281
14282                final ApplicationInfo info = ps.pkg.applicationInfo;
14283                final PackageRemovedInfo outInfo = new PackageRemovedInfo();
14284                if (deletePackageLI(ps.name, null, false, null, null,
14285                        PackageManager.DELETE_KEEP_DATA, outInfo, false)) {
14286                    unloaded.add(info);
14287                } else {
14288                    Slog.w(TAG, "Failed to unload " + ps.codePath);
14289                }
14290            }
14291
14292            mSettings.writeLPr();
14293        }
14294        }
14295
14296        Slog.d(TAG, "Unloaded packages " + unloaded);
14297        sendResourcesChangedBroadcast(false, false, unloaded, null);
14298    }
14299
14300    private void unfreezePackage(String packageName) {
14301        synchronized (mPackages) {
14302            final PackageSetting ps = mSettings.mPackages.get(packageName);
14303            if (ps != null) {
14304                ps.frozen = false;
14305            }
14306        }
14307    }
14308
14309    @Override
14310    public int movePackage(final String packageName, final String volumeUuid) {
14311        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
14312
14313        final int moveId = mNextMoveId.getAndIncrement();
14314        try {
14315            movePackageInternal(packageName, volumeUuid, moveId);
14316        } catch (PackageManagerException e) {
14317            Slog.d(TAG, "Failed to move " + packageName, e);
14318            mMoveCallbacks.notifyStatusChanged(moveId,
14319                    PackageManager.MOVE_FAILED_INTERNAL_ERROR);
14320        }
14321        return moveId;
14322    }
14323
14324    private void movePackageInternal(final String packageName, final String volumeUuid,
14325            final int moveId) throws PackageManagerException {
14326        final UserHandle user = new UserHandle(UserHandle.getCallingUserId());
14327        final StorageManager storage = mContext.getSystemService(StorageManager.class);
14328        final PackageManager pm = mContext.getPackageManager();
14329
14330        final boolean currentAsec;
14331        final String currentVolumeUuid;
14332        final File codeFile;
14333        final String installerPackageName;
14334        final String packageAbiOverride;
14335        final int appId;
14336        final String seinfo;
14337        final String label;
14338
14339        // reader
14340        synchronized (mPackages) {
14341            final PackageParser.Package pkg = mPackages.get(packageName);
14342            final PackageSetting ps = mSettings.mPackages.get(packageName);
14343            if (pkg == null || ps == null) {
14344                throw new PackageManagerException(MOVE_FAILED_DOESNT_EXIST, "Missing package");
14345            }
14346
14347            if (pkg.applicationInfo.isSystemApp()) {
14348                throw new PackageManagerException(MOVE_FAILED_SYSTEM_PACKAGE,
14349                        "Cannot move system application");
14350            }
14351
14352            if (Objects.equals(ps.volumeUuid, volumeUuid)) {
14353                throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
14354                        "Package already moved to " + volumeUuid);
14355            }
14356
14357            final File probe = new File(pkg.codePath);
14358            final File probeOat = new File(probe, "oat");
14359            if (!probe.isDirectory() || !probeOat.isDirectory()) {
14360                throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
14361                        "Move only supported for modern cluster style installs");
14362            }
14363
14364            if (ps.frozen) {
14365                throw new PackageManagerException(MOVE_FAILED_OPERATION_PENDING,
14366                        "Failed to move already frozen package");
14367            }
14368            ps.frozen = true;
14369
14370            currentAsec = pkg.applicationInfo.isForwardLocked()
14371                    || pkg.applicationInfo.isExternalAsec();
14372            currentVolumeUuid = ps.volumeUuid;
14373            codeFile = new File(pkg.codePath);
14374            installerPackageName = ps.installerPackageName;
14375            packageAbiOverride = ps.cpuAbiOverrideString;
14376            appId = UserHandle.getAppId(pkg.applicationInfo.uid);
14377            seinfo = pkg.applicationInfo.seinfo;
14378            label = String.valueOf(pm.getApplicationLabel(pkg.applicationInfo));
14379        }
14380
14381        // Now that we're guarded by frozen state, kill app during move
14382        killApplication(packageName, appId, "move pkg");
14383
14384        final Bundle extras = new Bundle();
14385        extras.putString(Intent.EXTRA_PACKAGE_NAME, packageName);
14386        extras.putString(Intent.EXTRA_TITLE, label);
14387        mMoveCallbacks.notifyCreated(moveId, extras);
14388
14389        int installFlags;
14390        final boolean moveCompleteApp;
14391        final File measurePath;
14392
14393        if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, volumeUuid)) {
14394            installFlags = INSTALL_INTERNAL;
14395            moveCompleteApp = !currentAsec;
14396            measurePath = Environment.getDataAppDirectory(volumeUuid);
14397        } else if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, volumeUuid)) {
14398            installFlags = INSTALL_EXTERNAL;
14399            moveCompleteApp = false;
14400            measurePath = storage.getPrimaryPhysicalVolume().getPath();
14401        } else {
14402            final VolumeInfo volume = storage.findVolumeByUuid(volumeUuid);
14403            if (volume == null || volume.getType() != VolumeInfo.TYPE_PRIVATE
14404                    || !volume.isMountedWritable()) {
14405                unfreezePackage(packageName);
14406                throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
14407                        "Move location not mounted private volume");
14408            }
14409
14410            Preconditions.checkState(!currentAsec);
14411
14412            installFlags = INSTALL_INTERNAL;
14413            moveCompleteApp = true;
14414            measurePath = Environment.getDataAppDirectory(volumeUuid);
14415        }
14416
14417        final PackageStats stats = new PackageStats(null, -1);
14418        synchronized (mInstaller) {
14419            if (!getPackageSizeInfoLI(packageName, -1, stats)) {
14420                unfreezePackage(packageName);
14421                throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
14422                        "Failed to measure package size");
14423            }
14424        }
14425
14426        Slog.d(TAG, "Measured code size " + stats.codeSize + ", data size " + stats.dataSize);
14427
14428        final long startFreeBytes = measurePath.getFreeSpace();
14429        final long sizeBytes;
14430        if (moveCompleteApp) {
14431            sizeBytes = stats.codeSize + stats.dataSize;
14432        } else {
14433            sizeBytes = stats.codeSize;
14434        }
14435
14436        if (sizeBytes > storage.getStorageBytesUntilLow(measurePath)) {
14437            unfreezePackage(packageName);
14438            throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
14439                    "Not enough free space to move");
14440        }
14441
14442        mMoveCallbacks.notifyStatusChanged(moveId, 10);
14443
14444        final CountDownLatch installedLatch = new CountDownLatch(1);
14445        final IPackageInstallObserver2 installObserver = new IPackageInstallObserver2.Stub() {
14446            @Override
14447            public void onUserActionRequired(Intent intent) throws RemoteException {
14448                throw new IllegalStateException();
14449            }
14450
14451            @Override
14452            public void onPackageInstalled(String basePackageName, int returnCode, String msg,
14453                    Bundle extras) throws RemoteException {
14454                Slog.d(TAG, "Install result for move: "
14455                        + PackageManager.installStatusToString(returnCode, msg));
14456
14457                installedLatch.countDown();
14458
14459                // Regardless of success or failure of the move operation,
14460                // always unfreeze the package
14461                unfreezePackage(packageName);
14462
14463                final int status = PackageManager.installStatusToPublicStatus(returnCode);
14464                switch (status) {
14465                    case PackageInstaller.STATUS_SUCCESS:
14466                        mMoveCallbacks.notifyStatusChanged(moveId,
14467                                PackageManager.MOVE_SUCCEEDED);
14468                        break;
14469                    case PackageInstaller.STATUS_FAILURE_STORAGE:
14470                        mMoveCallbacks.notifyStatusChanged(moveId,
14471                                PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE);
14472                        break;
14473                    default:
14474                        mMoveCallbacks.notifyStatusChanged(moveId,
14475                                PackageManager.MOVE_FAILED_INTERNAL_ERROR);
14476                        break;
14477                }
14478            }
14479        };
14480
14481        final MoveInfo move;
14482        if (moveCompleteApp) {
14483            // Kick off a thread to report progress estimates
14484            new Thread() {
14485                @Override
14486                public void run() {
14487                    while (true) {
14488                        try {
14489                            if (installedLatch.await(1, TimeUnit.SECONDS)) {
14490                                break;
14491                            }
14492                        } catch (InterruptedException ignored) {
14493                        }
14494
14495                        final long deltaFreeBytes = startFreeBytes - measurePath.getFreeSpace();
14496                        final int progress = 10 + (int) MathUtils.constrain(
14497                                ((deltaFreeBytes * 80) / sizeBytes), 0, 80);
14498                        mMoveCallbacks.notifyStatusChanged(moveId, progress);
14499                    }
14500                }
14501            }.start();
14502
14503            final String dataAppName = codeFile.getName();
14504            move = new MoveInfo(moveId, currentVolumeUuid, volumeUuid, packageName,
14505                    dataAppName, appId, seinfo);
14506        } else {
14507            move = null;
14508        }
14509
14510        installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
14511
14512        final Message msg = mHandler.obtainMessage(INIT_COPY);
14513        final OriginInfo origin = OriginInfo.fromExistingFile(codeFile);
14514        msg.obj = new InstallParams(origin, move, installObserver, installFlags,
14515                installerPackageName, volumeUuid, null, user, packageAbiOverride);
14516        mHandler.sendMessage(msg);
14517    }
14518
14519    @Override
14520    public int movePrimaryStorage(String volumeUuid) throws RemoteException {
14521        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
14522
14523        final int realMoveId = mNextMoveId.getAndIncrement();
14524        final Bundle extras = new Bundle();
14525        extras.putString(VolumeRecord.EXTRA_FS_UUID, volumeUuid);
14526        mMoveCallbacks.notifyCreated(realMoveId, extras);
14527
14528        final IPackageMoveObserver callback = new IPackageMoveObserver.Stub() {
14529            @Override
14530            public void onCreated(int moveId, Bundle extras) {
14531                // Ignored
14532            }
14533
14534            @Override
14535            public void onStatusChanged(int moveId, int status, long estMillis) {
14536                mMoveCallbacks.notifyStatusChanged(realMoveId, status, estMillis);
14537            }
14538        };
14539
14540        final StorageManager storage = mContext.getSystemService(StorageManager.class);
14541        storage.setPrimaryStorageUuid(volumeUuid, callback);
14542        return realMoveId;
14543    }
14544
14545    @Override
14546    public int getMoveStatus(int moveId) {
14547        mContext.enforceCallingOrSelfPermission(
14548                android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
14549        return mMoveCallbacks.mLastStatus.get(moveId);
14550    }
14551
14552    @Override
14553    public void registerMoveCallback(IPackageMoveObserver callback) {
14554        mContext.enforceCallingOrSelfPermission(
14555                android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
14556        mMoveCallbacks.register(callback);
14557    }
14558
14559    @Override
14560    public void unregisterMoveCallback(IPackageMoveObserver callback) {
14561        mContext.enforceCallingOrSelfPermission(
14562                android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
14563        mMoveCallbacks.unregister(callback);
14564    }
14565
14566    @Override
14567    public boolean setInstallLocation(int loc) {
14568        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS,
14569                null);
14570        if (getInstallLocation() == loc) {
14571            return true;
14572        }
14573        if (loc == PackageHelper.APP_INSTALL_AUTO || loc == PackageHelper.APP_INSTALL_INTERNAL
14574                || loc == PackageHelper.APP_INSTALL_EXTERNAL) {
14575            android.provider.Settings.Global.putInt(mContext.getContentResolver(),
14576                    android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, loc);
14577            return true;
14578        }
14579        return false;
14580   }
14581
14582    @Override
14583    public int getInstallLocation() {
14584        return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
14585                android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION,
14586                PackageHelper.APP_INSTALL_AUTO);
14587    }
14588
14589    /** Called by UserManagerService */
14590    void cleanUpUserLILPw(UserManagerService userManager, int userHandle) {
14591        mDirtyUsers.remove(userHandle);
14592        mSettings.removeUserLPw(userHandle);
14593        mPendingBroadcasts.remove(userHandle);
14594        if (mInstaller != null) {
14595            // Technically, we shouldn't be doing this with the package lock
14596            // held.  However, this is very rare, and there is already so much
14597            // other disk I/O going on, that we'll let it slide for now.
14598            final StorageManager storage = StorageManager.from(mContext);
14599            final List<VolumeInfo> vols = storage.getVolumes();
14600            for (VolumeInfo vol : vols) {
14601                if (vol.getType() == VolumeInfo.TYPE_PRIVATE && vol.isMountedWritable()) {
14602                    final String volumeUuid = vol.getFsUuid();
14603                    Slog.d(TAG, "Removing user data on volume " + volumeUuid);
14604                    mInstaller.removeUserDataDirs(volumeUuid, userHandle);
14605                }
14606            }
14607        }
14608        mUserNeedsBadging.delete(userHandle);
14609        removeUnusedPackagesLILPw(userManager, userHandle);
14610    }
14611
14612    /**
14613     * We're removing userHandle and would like to remove any downloaded packages
14614     * that are no longer in use by any other user.
14615     * @param userHandle the user being removed
14616     */
14617    private void removeUnusedPackagesLILPw(UserManagerService userManager, final int userHandle) {
14618        final boolean DEBUG_CLEAN_APKS = false;
14619        int [] users = userManager.getUserIdsLPr();
14620        Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
14621        while (psit.hasNext()) {
14622            PackageSetting ps = psit.next();
14623            if (ps.pkg == null) {
14624                continue;
14625            }
14626            final String packageName = ps.pkg.packageName;
14627            // Skip over if system app
14628            if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) {
14629                continue;
14630            }
14631            if (DEBUG_CLEAN_APKS) {
14632                Slog.i(TAG, "Checking package " + packageName);
14633            }
14634            boolean keep = false;
14635            for (int i = 0; i < users.length; i++) {
14636                if (users[i] != userHandle && ps.getInstalled(users[i])) {
14637                    keep = true;
14638                    if (DEBUG_CLEAN_APKS) {
14639                        Slog.i(TAG, "  Keeping package " + packageName + " for user "
14640                                + users[i]);
14641                    }
14642                    break;
14643                }
14644            }
14645            if (!keep) {
14646                if (DEBUG_CLEAN_APKS) {
14647                    Slog.i(TAG, "  Removing package " + packageName);
14648                }
14649                mHandler.post(new Runnable() {
14650                    public void run() {
14651                        deletePackageX(packageName, userHandle, 0);
14652                    } //end run
14653                });
14654            }
14655        }
14656    }
14657
14658    /** Called by UserManagerService */
14659    void createNewUserLILPw(int userHandle, File path) {
14660        if (mInstaller != null) {
14661            mInstaller.createUserConfig(userHandle);
14662            mSettings.createNewUserLILPw(this, mInstaller, userHandle, path);
14663        }
14664    }
14665
14666    void newUserCreatedLILPw(int userHandle) {
14667        // Adding a user requires updating runtime permissions for system apps.
14668        updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL);
14669    }
14670
14671    @Override
14672    public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException {
14673        mContext.enforceCallingOrSelfPermission(
14674                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
14675                "Only package verification agents can read the verifier device identity");
14676
14677        synchronized (mPackages) {
14678            return mSettings.getVerifierDeviceIdentityLPw();
14679        }
14680    }
14681
14682    @Override
14683    public void setPermissionEnforced(String permission, boolean enforced) {
14684        mContext.enforceCallingOrSelfPermission(GRANT_REVOKE_PERMISSIONS, null);
14685        if (READ_EXTERNAL_STORAGE.equals(permission)) {
14686            synchronized (mPackages) {
14687                if (mSettings.mReadExternalStorageEnforced == null
14688                        || mSettings.mReadExternalStorageEnforced != enforced) {
14689                    mSettings.mReadExternalStorageEnforced = enforced;
14690                    mSettings.writeLPr();
14691                }
14692            }
14693            // kill any non-foreground processes so we restart them and
14694            // grant/revoke the GID.
14695            final IActivityManager am = ActivityManagerNative.getDefault();
14696            if (am != null) {
14697                final long token = Binder.clearCallingIdentity();
14698                try {
14699                    am.killProcessesBelowForeground("setPermissionEnforcement");
14700                } catch (RemoteException e) {
14701                } finally {
14702                    Binder.restoreCallingIdentity(token);
14703                }
14704            }
14705        } else {
14706            throw new IllegalArgumentException("No selective enforcement for " + permission);
14707        }
14708    }
14709
14710    @Override
14711    @Deprecated
14712    public boolean isPermissionEnforced(String permission) {
14713        return true;
14714    }
14715
14716    @Override
14717    public boolean isStorageLow() {
14718        final long token = Binder.clearCallingIdentity();
14719        try {
14720            final DeviceStorageMonitorInternal
14721                    dsm = LocalServices.getService(DeviceStorageMonitorInternal.class);
14722            if (dsm != null) {
14723                return dsm.isMemoryLow();
14724            } else {
14725                return false;
14726            }
14727        } finally {
14728            Binder.restoreCallingIdentity(token);
14729        }
14730    }
14731
14732    @Override
14733    public IPackageInstaller getPackageInstaller() {
14734        return mInstallerService;
14735    }
14736
14737    private boolean userNeedsBadging(int userId) {
14738        int index = mUserNeedsBadging.indexOfKey(userId);
14739        if (index < 0) {
14740            final UserInfo userInfo;
14741            final long token = Binder.clearCallingIdentity();
14742            try {
14743                userInfo = sUserManager.getUserInfo(userId);
14744            } finally {
14745                Binder.restoreCallingIdentity(token);
14746            }
14747            final boolean b;
14748            if (userInfo != null && userInfo.isManagedProfile()) {
14749                b = true;
14750            } else {
14751                b = false;
14752            }
14753            mUserNeedsBadging.put(userId, b);
14754            return b;
14755        }
14756        return mUserNeedsBadging.valueAt(index);
14757    }
14758
14759    @Override
14760    public KeySet getKeySetByAlias(String packageName, String alias) {
14761        if (packageName == null || alias == null) {
14762            return null;
14763        }
14764        synchronized(mPackages) {
14765            final PackageParser.Package pkg = mPackages.get(packageName);
14766            if (pkg == null) {
14767                Slog.w(TAG, "KeySet requested for unknown package:" + packageName);
14768                throw new IllegalArgumentException("Unknown package: " + packageName);
14769            }
14770            KeySetManagerService ksms = mSettings.mKeySetManagerService;
14771            return new KeySet(ksms.getKeySetByAliasAndPackageNameLPr(packageName, alias));
14772        }
14773    }
14774
14775    @Override
14776    public KeySet getSigningKeySet(String packageName) {
14777        if (packageName == null) {
14778            return null;
14779        }
14780        synchronized(mPackages) {
14781            final PackageParser.Package pkg = mPackages.get(packageName);
14782            if (pkg == null) {
14783                Slog.w(TAG, "KeySet requested for unknown package:" + packageName);
14784                throw new IllegalArgumentException("Unknown package: " + packageName);
14785            }
14786            if (pkg.applicationInfo.uid != Binder.getCallingUid()
14787                    && Process.SYSTEM_UID != Binder.getCallingUid()) {
14788                throw new SecurityException("May not access signing KeySet of other apps.");
14789            }
14790            KeySetManagerService ksms = mSettings.mKeySetManagerService;
14791            return new KeySet(ksms.getSigningKeySetByPackageNameLPr(packageName));
14792        }
14793    }
14794
14795    @Override
14796    public boolean isPackageSignedByKeySet(String packageName, KeySet ks) {
14797        if (packageName == null || ks == null) {
14798            return false;
14799        }
14800        synchronized(mPackages) {
14801            final PackageParser.Package pkg = mPackages.get(packageName);
14802            if (pkg == null) {
14803                Slog.w(TAG, "KeySet requested for unknown package:" + packageName);
14804                throw new IllegalArgumentException("Unknown package: " + packageName);
14805            }
14806            IBinder ksh = ks.getToken();
14807            if (ksh instanceof KeySetHandle) {
14808                KeySetManagerService ksms = mSettings.mKeySetManagerService;
14809                return ksms.packageIsSignedByLPr(packageName, (KeySetHandle) ksh);
14810            }
14811            return false;
14812        }
14813    }
14814
14815    @Override
14816    public boolean isPackageSignedByKeySetExactly(String packageName, KeySet ks) {
14817        if (packageName == null || ks == null) {
14818            return false;
14819        }
14820        synchronized(mPackages) {
14821            final PackageParser.Package pkg = mPackages.get(packageName);
14822            if (pkg == null) {
14823                Slog.w(TAG, "KeySet requested for unknown package:" + packageName);
14824                throw new IllegalArgumentException("Unknown package: " + packageName);
14825            }
14826            IBinder ksh = ks.getToken();
14827            if (ksh instanceof KeySetHandle) {
14828                KeySetManagerService ksms = mSettings.mKeySetManagerService;
14829                return ksms.packageIsSignedByExactlyLPr(packageName, (KeySetHandle) ksh);
14830            }
14831            return false;
14832        }
14833    }
14834
14835    public void getUsageStatsIfNoPackageUsageInfo() {
14836        if (!mPackageUsage.isHistoricalPackageUsageAvailable()) {
14837            UsageStatsManager usm = (UsageStatsManager) mContext.getSystemService(Context.USAGE_STATS_SERVICE);
14838            if (usm == null) {
14839                throw new IllegalStateException("UsageStatsManager must be initialized");
14840            }
14841            long now = System.currentTimeMillis();
14842            Map<String, UsageStats> stats = usm.queryAndAggregateUsageStats(now - mDexOptLRUThresholdInMills, now);
14843            for (Map.Entry<String, UsageStats> entry : stats.entrySet()) {
14844                String packageName = entry.getKey();
14845                PackageParser.Package pkg = mPackages.get(packageName);
14846                if (pkg == null) {
14847                    continue;
14848                }
14849                UsageStats usage = entry.getValue();
14850                pkg.mLastPackageUsageTimeInMills = usage.getLastTimeUsed();
14851                mPackageUsage.mIsHistoricalPackageUsageAvailable = true;
14852            }
14853        }
14854    }
14855
14856    /**
14857     * Check and throw if the given before/after packages would be considered a
14858     * downgrade.
14859     */
14860    private static void checkDowngrade(PackageParser.Package before, PackageInfoLite after)
14861            throws PackageManagerException {
14862        if (after.versionCode < before.mVersionCode) {
14863            throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
14864                    "Update version code " + after.versionCode + " is older than current "
14865                    + before.mVersionCode);
14866        } else if (after.versionCode == before.mVersionCode) {
14867            if (after.baseRevisionCode < before.baseRevisionCode) {
14868                throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
14869                        "Update base revision code " + after.baseRevisionCode
14870                        + " is older than current " + before.baseRevisionCode);
14871            }
14872
14873            if (!ArrayUtils.isEmpty(after.splitNames)) {
14874                for (int i = 0; i < after.splitNames.length; i++) {
14875                    final String splitName = after.splitNames[i];
14876                    final int j = ArrayUtils.indexOf(before.splitNames, splitName);
14877                    if (j != -1) {
14878                        if (after.splitRevisionCodes[i] < before.splitRevisionCodes[j]) {
14879                            throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
14880                                    "Update split " + splitName + " revision code "
14881                                    + after.splitRevisionCodes[i] + " is older than current "
14882                                    + before.splitRevisionCodes[j]);
14883                        }
14884                    }
14885                }
14886            }
14887        }
14888    }
14889
14890    private static class MoveCallbacks extends Handler {
14891        private static final int MSG_CREATED = 1;
14892        private static final int MSG_STATUS_CHANGED = 2;
14893
14894        private final RemoteCallbackList<IPackageMoveObserver>
14895                mCallbacks = new RemoteCallbackList<>();
14896
14897        private final SparseIntArray mLastStatus = new SparseIntArray();
14898
14899        public MoveCallbacks(Looper looper) {
14900            super(looper);
14901        }
14902
14903        public void register(IPackageMoveObserver callback) {
14904            mCallbacks.register(callback);
14905        }
14906
14907        public void unregister(IPackageMoveObserver callback) {
14908            mCallbacks.unregister(callback);
14909        }
14910
14911        @Override
14912        public void handleMessage(Message msg) {
14913            final SomeArgs args = (SomeArgs) msg.obj;
14914            final int n = mCallbacks.beginBroadcast();
14915            for (int i = 0; i < n; i++) {
14916                final IPackageMoveObserver callback = mCallbacks.getBroadcastItem(i);
14917                try {
14918                    invokeCallback(callback, msg.what, args);
14919                } catch (RemoteException ignored) {
14920                }
14921            }
14922            mCallbacks.finishBroadcast();
14923            args.recycle();
14924        }
14925
14926        private void invokeCallback(IPackageMoveObserver callback, int what, SomeArgs args)
14927                throws RemoteException {
14928            switch (what) {
14929                case MSG_CREATED: {
14930                    callback.onCreated(args.argi1, (Bundle) args.arg2);
14931                    break;
14932                }
14933                case MSG_STATUS_CHANGED: {
14934                    callback.onStatusChanged(args.argi1, args.argi2, (long) args.arg3);
14935                    break;
14936                }
14937            }
14938        }
14939
14940        private void notifyCreated(int moveId, Bundle extras) {
14941            Slog.v(TAG, "Move " + moveId + " created " + extras.toString());
14942
14943            final SomeArgs args = SomeArgs.obtain();
14944            args.argi1 = moveId;
14945            args.arg2 = extras;
14946            obtainMessage(MSG_CREATED, args).sendToTarget();
14947        }
14948
14949        private void notifyStatusChanged(int moveId, int status) {
14950            notifyStatusChanged(moveId, status, -1);
14951        }
14952
14953        private void notifyStatusChanged(int moveId, int status, long estMillis) {
14954            Slog.v(TAG, "Move " + moveId + " status " + status);
14955
14956            final SomeArgs args = SomeArgs.obtain();
14957            args.argi1 = moveId;
14958            args.argi2 = status;
14959            args.arg3 = estMillis;
14960            obtainMessage(MSG_STATUS_CHANGED, args).sendToTarget();
14961
14962            synchronized (mLastStatus) {
14963                mLastStatus.put(moveId, status);
14964            }
14965        }
14966    }
14967}
14968