OSDN Git Service

am 3011e1be: am 8db769dd: am df878bd3: am ced2f74a: am e8c1a97f: am 3b92fc04: am...
[android-x86/frameworks-base.git] / services / core / java / com / android / server / pm / PackageManagerService.java
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
17 package com.android.server.pm;
18
19 import static android.Manifest.permission.GRANT_REVOKE_PERMISSIONS;
20 import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
21 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
22 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
23 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED;
24 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER;
25 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
26 import static android.content.pm.PackageManager.INSTALL_EXTERNAL;
27 import static android.content.pm.PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
28 import static android.content.pm.PackageManager.INSTALL_FAILED_CONFLICTING_PROVIDER;
29 import static android.content.pm.PackageManager.INSTALL_FAILED_DEXOPT;
30 import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE;
31 import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION;
32 import static android.content.pm.PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
33 import static android.content.pm.PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
34 import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_APK;
35 import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
36 import static android.content.pm.PackageManager.INSTALL_FAILED_MISSING_SHARED_LIBRARY;
37 import static android.content.pm.PackageManager.INSTALL_FAILED_PACKAGE_CHANGED;
38 import static android.content.pm.PackageManager.INSTALL_FAILED_REPLACE_COULDNT_DELETE;
39 import static android.content.pm.PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE;
40 import static android.content.pm.PackageManager.INSTALL_FAILED_TEST_ONLY;
41 import static android.content.pm.PackageManager.INSTALL_FAILED_UID_CHANGED;
42 import static android.content.pm.PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE;
43 import static android.content.pm.PackageManager.INSTALL_FAILED_USER_RESTRICTED;
44 import static android.content.pm.PackageManager.INSTALL_FORWARD_LOCK;
45 import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
46 import static android.content.pm.PackageParser.isApkFile;
47 import static android.os.Process.PACKAGE_INFO_GID;
48 import static android.os.Process.SYSTEM_UID;
49 import static android.system.OsConstants.O_CREAT;
50 import static android.system.OsConstants.O_RDWR;
51 import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE;
52 import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_USER_OWNER;
53 import static com.android.internal.content.NativeLibraryHelper.LIB64_DIR_NAME;
54 import static com.android.internal.content.NativeLibraryHelper.LIB_DIR_NAME;
55 import static com.android.internal.util.ArrayUtils.appendInt;
56 import static com.android.internal.util.ArrayUtils.removeInt;
57
58 import android.util.ArrayMap;
59
60 import com.android.internal.R;
61 import com.android.internal.app.IMediaContainerService;
62 import com.android.internal.app.ResolverActivity;
63 import com.android.internal.content.NativeLibraryHelper;
64 import com.android.internal.content.PackageHelper;
65 import com.android.internal.os.IParcelFileDescriptorFactory;
66 import com.android.internal.util.ArrayUtils;
67 import com.android.internal.util.FastPrintWriter;
68 import com.android.internal.util.FastXmlSerializer;
69 import com.android.internal.util.IndentingPrintWriter;
70 import com.android.server.EventLogTags;
71 import com.android.server.IntentResolver;
72 import com.android.server.LocalServices;
73 import com.android.server.ServiceThread;
74 import com.android.server.SystemConfig;
75 import com.android.server.Watchdog;
76 import com.android.server.pm.Settings.DatabaseVersion;
77 import com.android.server.storage.DeviceStorageMonitorInternal;
78
79 import org.xmlpull.v1.XmlSerializer;
80
81 import android.app.ActivityManager;
82 import android.app.ActivityManagerNative;
83 import android.app.AppGlobals;
84 import android.app.IActivityManager;
85 import android.app.admin.IDevicePolicyManager;
86 import android.app.backup.IBackupManager;
87 import android.content.BroadcastReceiver;
88 import android.content.ComponentName;
89 import android.content.Context;
90 import android.content.IIntentReceiver;
91 import android.content.Intent;
92 import android.content.IntentFilter;
93 import android.content.IntentSender;
94 import android.content.IntentSender.SendIntentException;
95 import android.content.ServiceConnection;
96 import android.content.pm.ActivityInfo;
97 import android.content.pm.ApplicationInfo;
98 import android.content.pm.FeatureInfo;
99 import android.content.pm.IPackageDataObserver;
100 import android.content.pm.IPackageDeleteObserver;
101 import android.content.pm.IPackageDeleteObserver2;
102 import android.content.pm.IPackageInstallObserver2;
103 import android.content.pm.IPackageInstaller;
104 import android.content.pm.IPackageManager;
105 import android.content.pm.IPackageMoveObserver;
106 import android.content.pm.IPackageStatsObserver;
107 import android.content.pm.InstrumentationInfo;
108 import android.content.pm.KeySet;
109 import android.content.pm.ManifestDigest;
110 import android.content.pm.PackageCleanItem;
111 import android.content.pm.PackageInfo;
112 import android.content.pm.PackageInfoLite;
113 import android.content.pm.PackageInstaller;
114 import android.content.pm.PackageManager;
115 import android.content.pm.PackageManager.LegacyPackageDeleteObserver;
116 import android.content.pm.PackageParser.ActivityIntentInfo;
117 import android.content.pm.PackageParser.PackageLite;
118 import android.content.pm.PackageParser.PackageParserException;
119 import android.content.pm.PackageParser;
120 import android.content.pm.PackageStats;
121 import android.content.pm.PackageUserState;
122 import android.content.pm.ParceledListSlice;
123 import android.content.pm.PermissionGroupInfo;
124 import android.content.pm.PermissionInfo;
125 import android.content.pm.ProviderInfo;
126 import android.content.pm.ResolveInfo;
127 import android.content.pm.ServiceInfo;
128 import android.content.pm.Signature;
129 import android.content.pm.UserInfo;
130 import android.content.pm.VerificationParams;
131 import android.content.pm.VerifierDeviceIdentity;
132 import android.content.pm.VerifierInfo;
133 import android.content.res.Resources;
134 import android.hardware.display.DisplayManager;
135 import android.net.Uri;
136 import android.os.Binder;
137 import android.os.Build;
138 import android.os.Bundle;
139 import android.os.Environment;
140 import android.os.Environment.UserEnvironment;
141 import android.os.storage.StorageManager;
142 import android.os.Debug;
143 import android.os.FileUtils;
144 import android.os.Handler;
145 import android.os.IBinder;
146 import android.os.Looper;
147 import android.os.Message;
148 import android.os.Parcel;
149 import android.os.ParcelFileDescriptor;
150 import android.os.Process;
151 import android.os.RemoteException;
152 import android.os.SELinux;
153 import android.os.ServiceManager;
154 import android.os.SystemClock;
155 import android.os.SystemProperties;
156 import android.os.UserHandle;
157 import android.os.UserManager;
158 import android.security.KeyStore;
159 import android.security.SystemKeyStore;
160 import android.system.ErrnoException;
161 import android.system.Os;
162 import android.system.StructStat;
163 import android.text.TextUtils;
164 import android.util.ArraySet;
165 import android.util.AtomicFile;
166 import android.util.DisplayMetrics;
167 import android.util.EventLog;
168 import android.util.ExceptionUtils;
169 import android.util.Log;
170 import android.util.LogPrinter;
171 import android.util.PrintStreamPrinter;
172 import android.util.Slog;
173 import android.util.SparseArray;
174 import android.util.SparseBooleanArray;
175 import android.view.Display;
176
177 import java.io.BufferedInputStream;
178 import java.io.BufferedOutputStream;
179 import java.io.BufferedReader;
180 import java.io.File;
181 import java.io.FileDescriptor;
182 import java.io.FileInputStream;
183 import java.io.FileNotFoundException;
184 import java.io.FileOutputStream;
185 import java.io.FileReader;
186 import java.io.FilenameFilter;
187 import java.io.IOException;
188 import java.io.InputStream;
189 import java.io.PrintWriter;
190 import java.nio.charset.StandardCharsets;
191 import java.security.NoSuchAlgorithmException;
192 import java.security.PublicKey;
193 import java.security.cert.CertificateEncodingException;
194 import java.security.cert.CertificateException;
195 import java.text.SimpleDateFormat;
196 import java.util.ArrayList;
197 import java.util.Arrays;
198 import java.util.Collection;
199 import java.util.Collections;
200 import java.util.Comparator;
201 import java.util.Date;
202 import java.util.HashMap;
203 import java.util.HashSet;
204 import java.util.Iterator;
205 import java.util.List;
206 import java.util.Map;
207 import java.util.Objects;
208 import java.util.Set;
209 import java.util.concurrent.atomic.AtomicBoolean;
210 import java.util.concurrent.atomic.AtomicLong;
211
212 import dalvik.system.DexFile;
213 import dalvik.system.StaleDexCacheError;
214 import dalvik.system.VMRuntime;
215
216 import libcore.io.IoUtils;
217 import libcore.util.EmptyArray;
218
219 /**
220  * Keep track of all those .apks everywhere.
221  * 
222  * This is very central to the platform's security; please run the unit
223  * tests whenever making modifications here:
224  * 
225 mmm frameworks/base/tests/AndroidTests
226 adb install -r -f out/target/product/passion/data/app/AndroidTests.apk
227 adb shell am instrument -w -e class com.android.unit_tests.PackageManagerTests com.android.unit_tests/android.test.InstrumentationTestRunner
228  * 
229  * {@hide}
230  */
231 public class PackageManagerService extends IPackageManager.Stub {
232     static final String TAG = "PackageManager";
233     static final boolean DEBUG_SETTINGS = false;
234     static final boolean DEBUG_PREFERRED = false;
235     static final boolean DEBUG_UPGRADE = false;
236     private static final boolean DEBUG_INSTALL = false;
237     private static final boolean DEBUG_REMOVE = false;
238     private static final boolean DEBUG_BROADCASTS = false;
239     private static final boolean DEBUG_SHOW_INFO = false;
240     private static final boolean DEBUG_PACKAGE_INFO = false;
241     private static final boolean DEBUG_INTENT_MATCHING = false;
242     private static final boolean DEBUG_PACKAGE_SCANNING = false;
243     private static final boolean DEBUG_VERIFY = false;
244     private static final boolean DEBUG_DEXOPT = false;
245     private static final boolean DEBUG_ABI_SELECTION = false;
246
247     private static final int RADIO_UID = Process.PHONE_UID;
248     private static final int LOG_UID = Process.LOG_UID;
249     private static final int NFC_UID = Process.NFC_UID;
250     private static final int BLUETOOTH_UID = Process.BLUETOOTH_UID;
251     private static final int SHELL_UID = Process.SHELL_UID;
252
253     // Cap the size of permission trees that 3rd party apps can define
254     private static final int MAX_PERMISSION_TREE_FOOTPRINT = 32768;     // characters of text
255
256     // Suffix used during package installation when copying/moving
257     // package apks to install directory.
258     private static final String INSTALL_PACKAGE_SUFFIX = "-";
259
260     static final int SCAN_NO_DEX = 1<<1;
261     static final int SCAN_FORCE_DEX = 1<<2;
262     static final int SCAN_UPDATE_SIGNATURE = 1<<3;
263     static final int SCAN_NEW_INSTALL = 1<<4;
264     static final int SCAN_NO_PATHS = 1<<5;
265     static final int SCAN_UPDATE_TIME = 1<<6;
266     static final int SCAN_DEFER_DEX = 1<<7;
267     static final int SCAN_BOOTING = 1<<8;
268     static final int SCAN_TRUSTED_OVERLAY = 1<<9;
269     static final int SCAN_DELETE_DATA_ON_FAILURES = 1<<10;
270     static final int SCAN_REPLACING = 1<<11;
271
272     static final int REMOVE_CHATTY = 1<<16;
273
274     /**
275      * Timeout (in milliseconds) after which the watchdog should declare that
276      * our handler thread is wedged.  The usual default for such things is one
277      * minute but we sometimes do very lengthy I/O operations on this thread,
278      * such as installing multi-gigabyte applications, so ours needs to be longer.
279      */
280     private static final long WATCHDOG_TIMEOUT = 1000*60*10;     // ten minutes
281
282     /**
283      * Whether verification is enabled by default.
284      */
285     private static final boolean DEFAULT_VERIFY_ENABLE = true;
286
287     /**
288      * The default maximum time to wait for the verification agent to return in
289      * milliseconds.
290      */
291     private static final long DEFAULT_VERIFICATION_TIMEOUT = 10 * 1000;
292
293     /**
294      * The default response for package verification timeout.
295      *
296      * This can be either PackageManager.VERIFICATION_ALLOW or
297      * PackageManager.VERIFICATION_REJECT.
298      */
299     private static final int DEFAULT_VERIFICATION_RESPONSE = PackageManager.VERIFICATION_ALLOW;
300
301     static final String DEFAULT_CONTAINER_PACKAGE = "com.android.defcontainer";
302
303     static final ComponentName DEFAULT_CONTAINER_COMPONENT = new ComponentName(
304             DEFAULT_CONTAINER_PACKAGE,
305             "com.android.defcontainer.DefaultContainerService");
306
307     private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive";
308
309     private static final String VENDOR_OVERLAY_DIR = "/vendor/overlay";
310
311     private static String sPreferredInstructionSet;
312
313     final ServiceThread mHandlerThread;
314
315     private static final String IDMAP_PREFIX = "/data/resource-cache/";
316     private static final String IDMAP_SUFFIX = "@idmap";
317
318     final PackageHandler mHandler;
319
320     /**
321      * Messages for {@link #mHandler} that need to wait for system ready before
322      * being dispatched.
323      */
324     private ArrayList<Message> mPostSystemReadyMessages;
325
326     final int mSdkVersion = Build.VERSION.SDK_INT;
327
328     final Context mContext;
329     final boolean mFactoryTest;
330     final boolean mOnlyCore;
331     final boolean mLazyDexOpt;
332     final DisplayMetrics mMetrics;
333     final int mDefParseFlags;
334     final String[] mSeparateProcesses;
335     final boolean mIsUpgrade;
336
337     // This is where all application persistent data goes.
338     final File mAppDataDir;
339
340     // This is where all application persistent data goes for secondary users.
341     final File mUserAppDataDir;
342
343     /** The location for ASEC container files on internal storage. */
344     final String mAsecInternalPath;
345
346     // Used for privilege escalation. MUST NOT BE CALLED WITH mPackages
347     // LOCK HELD.  Can be called with mInstallLock held.
348     final Installer mInstaller;
349
350     /** Directory where installed third-party apps stored */
351     final File mAppInstallDir;
352
353     /**
354      * Directory to which applications installed internally have their
355      * 32 bit native libraries copied.
356      */
357     private File mAppLib32InstallDir;
358
359     // Directory containing the private parts (e.g. code and non-resource assets) of forward-locked
360     // apps.
361     final File mDrmAppPrivateInstallDir;
362
363     // ----------------------------------------------------------------
364
365     // Lock for state used when installing and doing other long running
366     // operations.  Methods that must be called with this lock held have
367     // the suffix "LI".
368     final Object mInstallLock = new Object();
369
370     // ----------------------------------------------------------------
371
372     // Keys are String (package name), values are Package.  This also serves
373     // as the lock for the global state.  Methods that must be called with
374     // this lock held have the prefix "LP".
375     final HashMap<String, PackageParser.Package> mPackages =
376             new HashMap<String, PackageParser.Package>();
377
378     // Tracks available target package names -> overlay package paths.
379     final HashMap<String, HashMap<String, PackageParser.Package>> mOverlays =
380         new HashMap<String, HashMap<String, PackageParser.Package>>();
381
382     final Settings mSettings;
383     boolean mRestoredSettings;
384
385     // System configuration read by SystemConfig.
386     final int[] mGlobalGids;
387     final SparseArray<HashSet<String>> mSystemPermissions;
388     final HashMap<String, FeatureInfo> mAvailableFeatures;
389
390     // If mac_permissions.xml was found for seinfo labeling.
391     boolean mFoundPolicyFile;
392
393     // If a recursive restorecon of /data/data/<pkg> is needed.
394     private boolean mShouldRestoreconData = SELinuxMMAC.shouldRestorecon();
395
396     public static final class SharedLibraryEntry {
397         public final String path;
398         public final String apk;
399
400         SharedLibraryEntry(String _path, String _apk) {
401             path = _path;
402             apk = _apk;
403         }
404     }
405
406     // Currently known shared libraries.
407     final HashMap<String, SharedLibraryEntry> mSharedLibraries =
408             new HashMap<String, SharedLibraryEntry>();
409
410     // All available activities, for your resolving pleasure.
411     final ActivityIntentResolver mActivities =
412             new ActivityIntentResolver();
413
414     // All available receivers, for your resolving pleasure.
415     final ActivityIntentResolver mReceivers =
416             new ActivityIntentResolver();
417
418     // All available services, for your resolving pleasure.
419     final ServiceIntentResolver mServices = new ServiceIntentResolver();
420
421     // All available providers, for your resolving pleasure.
422     final ProviderIntentResolver mProviders = new ProviderIntentResolver();
423
424     // Mapping from provider base names (first directory in content URI codePath)
425     // to the provider information.
426     final HashMap<String, PackageParser.Provider> mProvidersByAuthority =
427             new HashMap<String, PackageParser.Provider>();
428
429     // Mapping from instrumentation class names to info about them.
430     final HashMap<ComponentName, PackageParser.Instrumentation> mInstrumentation =
431             new HashMap<ComponentName, PackageParser.Instrumentation>();
432
433     // Mapping from permission names to info about them.
434     final HashMap<String, PackageParser.PermissionGroup> mPermissionGroups =
435             new HashMap<String, PackageParser.PermissionGroup>();
436
437     // Packages whose data we have transfered into another package, thus
438     // should no longer exist.
439     final HashSet<String> mTransferedPackages = new HashSet<String>();
440     
441     // Broadcast actions that are only available to the system.
442     final HashSet<String> mProtectedBroadcasts = new HashSet<String>();
443
444     /** List of packages waiting for verification. */
445     final SparseArray<PackageVerificationState> mPendingVerification
446             = new SparseArray<PackageVerificationState>();
447
448     /** Set of packages associated with each app op permission. */
449     final ArrayMap<String, ArraySet<String>> mAppOpPermissionPackages = new ArrayMap<>();
450
451     final PackageInstallerService mInstallerService;
452
453     HashSet<PackageParser.Package> mDeferredDexOpt = null;
454
455     // Cache of users who need badging.
456     SparseBooleanArray mUserNeedsBadging = new SparseBooleanArray();
457
458     /** Token for keys in mPendingVerification. */
459     private int mPendingVerificationToken = 0;
460
461     volatile boolean mSystemReady;
462     volatile boolean mSafeMode;
463     volatile boolean mHasSystemUidErrors;
464
465     ApplicationInfo mAndroidApplication;
466     final ActivityInfo mResolveActivity = new ActivityInfo();
467     final ResolveInfo mResolveInfo = new ResolveInfo();
468     ComponentName mResolveComponentName;
469     PackageParser.Package mPlatformPackage;
470     ComponentName mCustomResolverComponentName;
471
472     boolean mResolverReplaced = false;
473
474     // Set of pending broadcasts for aggregating enable/disable of components.
475     static class PendingPackageBroadcasts {
476         // for each user id, a map of <package name -> components within that package>
477         final SparseArray<HashMap<String, ArrayList<String>>> mUidMap;
478
479         public PendingPackageBroadcasts() {
480             mUidMap = new SparseArray<HashMap<String, ArrayList<String>>>(2);
481         }
482
483         public ArrayList<String> get(int userId, String packageName) {
484             HashMap<String, ArrayList<String>> packages = getOrAllocate(userId);
485             return packages.get(packageName);
486         }
487
488         public void put(int userId, String packageName, ArrayList<String> components) {
489             HashMap<String, ArrayList<String>> packages = getOrAllocate(userId);
490             packages.put(packageName, components);
491         }
492
493         public void remove(int userId, String packageName) {
494             HashMap<String, ArrayList<String>> packages = mUidMap.get(userId);
495             if (packages != null) {
496                 packages.remove(packageName);
497             }
498         }
499
500         public void remove(int userId) {
501             mUidMap.remove(userId);
502         }
503
504         public int userIdCount() {
505             return mUidMap.size();
506         }
507
508         public int userIdAt(int n) {
509             return mUidMap.keyAt(n);
510         }
511
512         public HashMap<String, ArrayList<String>> packagesForUserId(int userId) {
513             return mUidMap.get(userId);
514         }
515
516         public int size() {
517             // total number of pending broadcast entries across all userIds
518             int num = 0;
519             for (int i = 0; i< mUidMap.size(); i++) {
520                 num += mUidMap.valueAt(i).size();
521             }
522             return num;
523         }
524
525         public void clear() {
526             mUidMap.clear();
527         }
528
529         private HashMap<String, ArrayList<String>> getOrAllocate(int userId) {
530             HashMap<String, ArrayList<String>> map = mUidMap.get(userId);
531             if (map == null) {
532                 map = new HashMap<String, ArrayList<String>>();
533                 mUidMap.put(userId, map);
534             }
535             return map;
536         }
537     }
538     final PendingPackageBroadcasts mPendingBroadcasts = new PendingPackageBroadcasts();
539
540     // Service Connection to remote media container service to copy
541     // package uri's from external media onto secure containers
542     // or internal storage.
543     private IMediaContainerService mContainerService = null;
544
545     static final int SEND_PENDING_BROADCAST = 1;
546     static final int MCS_BOUND = 3;
547     static final int END_COPY = 4;
548     static final int INIT_COPY = 5;
549     static final int MCS_UNBIND = 6;
550     static final int START_CLEANING_PACKAGE = 7;
551     static final int FIND_INSTALL_LOC = 8;
552     static final int POST_INSTALL = 9;
553     static final int MCS_RECONNECT = 10;
554     static final int MCS_GIVE_UP = 11;
555     static final int UPDATED_MEDIA_STATUS = 12;
556     static final int WRITE_SETTINGS = 13;
557     static final int WRITE_PACKAGE_RESTRICTIONS = 14;
558     static final int PACKAGE_VERIFIED = 15;
559     static final int CHECK_PENDING_VERIFICATION = 16;
560
561     static final int WRITE_SETTINGS_DELAY = 10*1000;  // 10 seconds
562
563     // Delay time in millisecs
564     static final int BROADCAST_DELAY = 10 * 1000;
565
566     static UserManagerService sUserManager;
567
568     // Stores a list of users whose package restrictions file needs to be updated
569     private HashSet<Integer> mDirtyUsers = new HashSet<Integer>();
570
571     final private DefaultContainerConnection mDefContainerConn =
572             new DefaultContainerConnection();
573     class DefaultContainerConnection implements ServiceConnection {
574         public void onServiceConnected(ComponentName name, IBinder service) {
575             if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceConnected");
576             IMediaContainerService imcs =
577                 IMediaContainerService.Stub.asInterface(service);
578             mHandler.sendMessage(mHandler.obtainMessage(MCS_BOUND, imcs));
579         }
580
581         public void onServiceDisconnected(ComponentName name) {
582             if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceDisconnected");
583         }
584     };
585
586     // Recordkeeping of restore-after-install operations that are currently in flight
587     // between the Package Manager and the Backup Manager
588     class PostInstallData {
589         public InstallArgs args;
590         public PackageInstalledInfo res;
591
592         PostInstallData(InstallArgs _a, PackageInstalledInfo _r) {
593             args = _a;
594             res = _r;
595         }
596     };
597     final SparseArray<PostInstallData> mRunningInstalls = new SparseArray<PostInstallData>();
598     int mNextInstallToken = 1;  // nonzero; will be wrapped back to 1 when ++ overflows
599
600     private final String mRequiredVerifierPackage;
601
602     private final PackageUsage mPackageUsage = new PackageUsage();
603
604     private class PackageUsage {
605         private static final int WRITE_INTERVAL
606             = (DEBUG_DEXOPT) ? 0 : 30*60*1000; // 30m in ms
607
608         private final Object mFileLock = new Object();
609         private final AtomicLong mLastWritten = new AtomicLong(0);
610         private final AtomicBoolean mBackgroundWriteRunning = new AtomicBoolean(false);
611
612         private boolean mIsHistoricalPackageUsageAvailable = true;
613
614         boolean isHistoricalPackageUsageAvailable() {
615             return mIsHistoricalPackageUsageAvailable;
616         }
617
618         void write(boolean force) {
619             if (force) {
620                 writeInternal();
621                 return;
622             }
623             if (SystemClock.elapsedRealtime() - mLastWritten.get() < WRITE_INTERVAL
624                 && !DEBUG_DEXOPT) {
625                 return;
626             }
627             if (mBackgroundWriteRunning.compareAndSet(false, true)) {
628                 new Thread("PackageUsage_DiskWriter") {
629                     @Override
630                     public void run() {
631                         try {
632                             writeInternal();
633                         } finally {
634                             mBackgroundWriteRunning.set(false);
635                         }
636                     }
637                 }.start();
638             }
639         }
640
641         private void writeInternal() {
642             synchronized (mPackages) {
643                 synchronized (mFileLock) {
644                     AtomicFile file = getFile();
645                     FileOutputStream f = null;
646                     try {
647                         f = file.startWrite();
648                         BufferedOutputStream out = new BufferedOutputStream(f);
649                         FileUtils.setPermissions(file.getBaseFile().getPath(), 0660, SYSTEM_UID, PACKAGE_INFO_GID);
650                         StringBuilder sb = new StringBuilder();
651                         for (PackageParser.Package pkg : mPackages.values()) {
652                             if (pkg.mLastPackageUsageTimeInMills == 0) {
653                                 continue;
654                             }
655                             sb.setLength(0);
656                             sb.append(pkg.packageName);
657                             sb.append(' ');
658                             sb.append((long)pkg.mLastPackageUsageTimeInMills);
659                             sb.append('\n');
660                             out.write(sb.toString().getBytes(StandardCharsets.US_ASCII));
661                         }
662                         out.flush();
663                         file.finishWrite(f);
664                     } catch (IOException e) {
665                         if (f != null) {
666                             file.failWrite(f);
667                         }
668                         Log.e(TAG, "Failed to write package usage times", e);
669                     }
670                 }
671             }
672             mLastWritten.set(SystemClock.elapsedRealtime());
673         }
674
675         void readLP() {
676             synchronized (mFileLock) {
677                 AtomicFile file = getFile();
678                 BufferedInputStream in = null;
679                 try {
680                     in = new BufferedInputStream(file.openRead());
681                     StringBuffer sb = new StringBuffer();
682                     while (true) {
683                         String packageName = readToken(in, sb, ' ');
684                         if (packageName == null) {
685                             break;
686                         }
687                         String timeInMillisString = readToken(in, sb, '\n');
688                         if (timeInMillisString == null) {
689                             throw new IOException("Failed to find last usage time for package "
690                                                   + packageName);
691                         }
692                         PackageParser.Package pkg = mPackages.get(packageName);
693                         if (pkg == null) {
694                             continue;
695                         }
696                         long timeInMillis;
697                         try {
698                             timeInMillis = Long.parseLong(timeInMillisString.toString());
699                         } catch (NumberFormatException e) {
700                             throw new IOException("Failed to parse " + timeInMillisString
701                                                   + " as a long.", e);
702                         }
703                         pkg.mLastPackageUsageTimeInMills = timeInMillis;
704                     }
705                 } catch (FileNotFoundException expected) {
706                     mIsHistoricalPackageUsageAvailable = false;
707                 } catch (IOException e) {
708                     Log.w(TAG, "Failed to read package usage times", e);
709                 } finally {
710                     IoUtils.closeQuietly(in);
711                 }
712             }
713             mLastWritten.set(SystemClock.elapsedRealtime());
714         }
715
716         private String readToken(InputStream in, StringBuffer sb, char endOfToken)
717                 throws IOException {
718             sb.setLength(0);
719             while (true) {
720                 int ch = in.read();
721                 if (ch == -1) {
722                     if (sb.length() == 0) {
723                         return null;
724                     }
725                     throw new IOException("Unexpected EOF");
726                 }
727                 if (ch == endOfToken) {
728                     return sb.toString();
729                 }
730                 sb.append((char)ch);
731             }
732         }
733
734         private AtomicFile getFile() {
735             File dataDir = Environment.getDataDirectory();
736             File systemDir = new File(dataDir, "system");
737             File fname = new File(systemDir, "package-usage.list");
738             return new AtomicFile(fname);
739         }
740     }
741
742     class PackageHandler extends Handler {
743         private boolean mBound = false;
744         final ArrayList<HandlerParams> mPendingInstalls =
745             new ArrayList<HandlerParams>();
746
747         private boolean connectToService() {
748             if (DEBUG_SD_INSTALL) Log.i(TAG, "Trying to bind to" +
749                     " DefaultContainerService");
750             Intent service = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
751             Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
752             if (mContext.bindServiceAsUser(service, mDefContainerConn,
753                     Context.BIND_AUTO_CREATE, UserHandle.OWNER)) {
754                 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
755                 mBound = true;
756                 return true;
757             }
758             Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
759             return false;
760         }
761
762         private void disconnectService() {
763             mContainerService = null;
764             mBound = false;
765             Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
766             mContext.unbindService(mDefContainerConn);
767             Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
768         }
769
770         PackageHandler(Looper looper) {
771             super(looper);
772         }
773
774         public void handleMessage(Message msg) {
775             try {
776                 doHandleMessage(msg);
777             } finally {
778                 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
779             }
780         }
781         
782         void doHandleMessage(Message msg) {
783             switch (msg.what) {
784                 case INIT_COPY: {
785                     HandlerParams params = (HandlerParams) msg.obj;
786                     int idx = mPendingInstalls.size();
787                     if (DEBUG_INSTALL) Slog.i(TAG, "init_copy idx=" + idx + ": " + params);
788                     // If a bind was already initiated we dont really
789                     // need to do anything. The pending install
790                     // will be processed later on.
791                     if (!mBound) {
792                         // If this is the only one pending we might
793                         // have to bind to the service again.
794                         if (!connectToService()) {
795                             Slog.e(TAG, "Failed to bind to media container service");
796                             params.serviceError();
797                             return;
798                         } else {
799                             // Once we bind to the service, the first
800                             // pending request will be processed.
801                             mPendingInstalls.add(idx, params);
802                         }
803                     } else {
804                         mPendingInstalls.add(idx, params);
805                         // Already bound to the service. Just make
806                         // sure we trigger off processing the first request.
807                         if (idx == 0) {
808                             mHandler.sendEmptyMessage(MCS_BOUND);
809                         }
810                     }
811                     break;
812                 }
813                 case MCS_BOUND: {
814                     if (DEBUG_INSTALL) Slog.i(TAG, "mcs_bound");
815                     if (msg.obj != null) {
816                         mContainerService = (IMediaContainerService) msg.obj;
817                     }
818                     if (mContainerService == null) {
819                         // Something seriously wrong. Bail out
820                         Slog.e(TAG, "Cannot bind to media container service");
821                         for (HandlerParams params : mPendingInstalls) {
822                             // Indicate service bind error
823                             params.serviceError();
824                         }
825                         mPendingInstalls.clear();
826                     } else if (mPendingInstalls.size() > 0) {
827                         HandlerParams params = mPendingInstalls.get(0);
828                         if (params != null) {
829                             if (params.startCopy()) {
830                                 // We are done...  look for more work or to
831                                 // go idle.
832                                 if (DEBUG_SD_INSTALL) Log.i(TAG,
833                                         "Checking for more work or unbind...");
834                                 // Delete pending install
835                                 if (mPendingInstalls.size() > 0) {
836                                     mPendingInstalls.remove(0);
837                                 }
838                                 if (mPendingInstalls.size() == 0) {
839                                     if (mBound) {
840                                         if (DEBUG_SD_INSTALL) Log.i(TAG,
841                                                 "Posting delayed MCS_UNBIND");
842                                         removeMessages(MCS_UNBIND);
843                                         Message ubmsg = obtainMessage(MCS_UNBIND);
844                                         // Unbind after a little delay, to avoid
845                                         // continual thrashing.
846                                         sendMessageDelayed(ubmsg, 10000);
847                                     }
848                                 } else {
849                                     // There are more pending requests in queue.
850                                     // Just post MCS_BOUND message to trigger processing
851                                     // of next pending install.
852                                     if (DEBUG_SD_INSTALL) Log.i(TAG,
853                                             "Posting MCS_BOUND for next work");
854                                     mHandler.sendEmptyMessage(MCS_BOUND);
855                                 }
856                             }
857                         }
858                     } else {
859                         // Should never happen ideally.
860                         Slog.w(TAG, "Empty queue");
861                     }
862                     break;
863                 }
864                 case MCS_RECONNECT: {
865                     if (DEBUG_INSTALL) Slog.i(TAG, "mcs_reconnect");
866                     if (mPendingInstalls.size() > 0) {
867                         if (mBound) {
868                             disconnectService();
869                         }
870                         if (!connectToService()) {
871                             Slog.e(TAG, "Failed to bind to media container service");
872                             for (HandlerParams params : mPendingInstalls) {
873                                 // Indicate service bind error
874                                 params.serviceError();
875                             }
876                             mPendingInstalls.clear();
877                         }
878                     }
879                     break;
880                 }
881                 case MCS_UNBIND: {
882                     // If there is no actual work left, then time to unbind.
883                     if (DEBUG_INSTALL) Slog.i(TAG, "mcs_unbind");
884
885                     if (mPendingInstalls.size() == 0 && mPendingVerification.size() == 0) {
886                         if (mBound) {
887                             if (DEBUG_INSTALL) Slog.i(TAG, "calling disconnectService()");
888
889                             disconnectService();
890                         }
891                     } else if (mPendingInstalls.size() > 0) {
892                         // There are more pending requests in queue.
893                         // Just post MCS_BOUND message to trigger processing
894                         // of next pending install.
895                         mHandler.sendEmptyMessage(MCS_BOUND);
896                     }
897
898                     break;
899                 }
900                 case MCS_GIVE_UP: {
901                     if (DEBUG_INSTALL) Slog.i(TAG, "mcs_giveup too many retries");
902                     mPendingInstalls.remove(0);
903                     break;
904                 }
905                 case SEND_PENDING_BROADCAST: {
906                     String packages[];
907                     ArrayList<String> components[];
908                     int size = 0;
909                     int uids[];
910                     Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
911                     synchronized (mPackages) {
912                         if (mPendingBroadcasts == null) {
913                             return;
914                         }
915                         size = mPendingBroadcasts.size();
916                         if (size <= 0) {
917                             // Nothing to be done. Just return
918                             return;
919                         }
920                         packages = new String[size];
921                         components = new ArrayList[size];
922                         uids = new int[size];
923                         int i = 0;  // filling out the above arrays
924
925                         for (int n = 0; n < mPendingBroadcasts.userIdCount(); n++) {
926                             int packageUserId = mPendingBroadcasts.userIdAt(n);
927                             Iterator<Map.Entry<String, ArrayList<String>>> it
928                                     = mPendingBroadcasts.packagesForUserId(packageUserId)
929                                             .entrySet().iterator();
930                             while (it.hasNext() && i < size) {
931                                 Map.Entry<String, ArrayList<String>> ent = it.next();
932                                 packages[i] = ent.getKey();
933                                 components[i] = ent.getValue();
934                                 PackageSetting ps = mSettings.mPackages.get(ent.getKey());
935                                 uids[i] = (ps != null)
936                                         ? UserHandle.getUid(packageUserId, ps.appId)
937                                         : -1;
938                                 i++;
939                             }
940                         }
941                         size = i;
942                         mPendingBroadcasts.clear();
943                     }
944                     // Send broadcasts
945                     for (int i = 0; i < size; i++) {
946                         sendPackageChangedBroadcast(packages[i], true, components[i], uids[i]);
947                     }
948                     Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
949                     break;
950                 }
951                 case START_CLEANING_PACKAGE: {
952                     Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
953                     final String packageName = (String)msg.obj;
954                     final int userId = msg.arg1;
955                     final boolean andCode = msg.arg2 != 0;
956                     synchronized (mPackages) {
957                         if (userId == UserHandle.USER_ALL) {
958                             int[] users = sUserManager.getUserIds();
959                             for (int user : users) {
960                                 mSettings.addPackageToCleanLPw(
961                                         new PackageCleanItem(user, packageName, andCode));
962                             }
963                         } else {
964                             mSettings.addPackageToCleanLPw(
965                                     new PackageCleanItem(userId, packageName, andCode));
966                         }
967                     }
968                     Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
969                     startCleaningPackages();
970                 } break;
971                 case POST_INSTALL: {
972                     if (DEBUG_INSTALL) Log.v(TAG, "Handling post-install for " + msg.arg1);
973                     PostInstallData data = mRunningInstalls.get(msg.arg1);
974                     mRunningInstalls.delete(msg.arg1);
975                     boolean deleteOld = false;
976
977                     if (data != null) {
978                         InstallArgs args = data.args;
979                         PackageInstalledInfo res = data.res;
980
981                         if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
982                             res.removedInfo.sendBroadcast(false, true, false);
983                             Bundle extras = new Bundle(1);
984                             extras.putInt(Intent.EXTRA_UID, res.uid);
985                             // Determine the set of users who are adding this
986                             // package for the first time vs. those who are seeing
987                             // an update.
988                             int[] firstUsers;
989                             int[] updateUsers = new int[0];
990                             if (res.origUsers == null || res.origUsers.length == 0) {
991                                 firstUsers = res.newUsers;
992                             } else {
993                                 firstUsers = new int[0];
994                                 for (int i=0; i<res.newUsers.length; i++) {
995                                     int user = res.newUsers[i];
996                                     boolean isNew = true;
997                                     for (int j=0; j<res.origUsers.length; j++) {
998                                         if (res.origUsers[j] == user) {
999                                             isNew = false;
1000                                             break;
1001                                         }
1002                                     }
1003                                     if (isNew) {
1004                                         int[] newFirst = new int[firstUsers.length+1];
1005                                         System.arraycopy(firstUsers, 0, newFirst, 0,
1006                                                 firstUsers.length);
1007                                         newFirst[firstUsers.length] = user;
1008                                         firstUsers = newFirst;
1009                                     } else {
1010                                         int[] newUpdate = new int[updateUsers.length+1];
1011                                         System.arraycopy(updateUsers, 0, newUpdate, 0,
1012                                                 updateUsers.length);
1013                                         newUpdate[updateUsers.length] = user;
1014                                         updateUsers = newUpdate;
1015                                     }
1016                                 }
1017                             }
1018                             sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
1019                                     res.pkg.applicationInfo.packageName,
1020                                     extras, null, null, firstUsers);
1021                             final boolean update = res.removedInfo.removedPackage != null;
1022                             if (update) {
1023                                 extras.putBoolean(Intent.EXTRA_REPLACING, true);
1024                             }
1025                             sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
1026                                     res.pkg.applicationInfo.packageName,
1027                                     extras, null, null, updateUsers);
1028                             if (update) {
1029                                 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
1030                                         res.pkg.applicationInfo.packageName,
1031                                         extras, null, null, updateUsers);
1032                                 sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
1033                                         null, null,
1034                                         res.pkg.applicationInfo.packageName, null, updateUsers);
1035
1036                                 // treat asec-hosted packages like removable media on upgrade
1037                                 if (isForwardLocked(res.pkg) || isExternal(res.pkg)) {
1038                                     if (DEBUG_INSTALL) {
1039                                         Slog.i(TAG, "upgrading pkg " + res.pkg
1040                                                 + " is ASEC-hosted -> AVAILABLE");
1041                                     }
1042                                     int[] uidArray = new int[] { res.pkg.applicationInfo.uid };
1043                                     ArrayList<String> pkgList = new ArrayList<String>(1);
1044                                     pkgList.add(res.pkg.applicationInfo.packageName);
1045                                     sendResourcesChangedBroadcast(true, true,
1046                                             pkgList,uidArray, null);
1047                                 }
1048                             }
1049                             if (res.removedInfo.args != null) {
1050                                 // Remove the replaced package's older resources safely now
1051                                 deleteOld = true;
1052                             }
1053
1054                             // Log current value of "unknown sources" setting
1055                             EventLog.writeEvent(EventLogTags.UNKNOWN_SOURCES_ENABLED,
1056                                 getUnknownSourcesSettings());
1057                         }
1058                         // Force a gc to clear up things
1059                         Runtime.getRuntime().gc();
1060                         // We delete after a gc for applications  on sdcard.
1061                         if (deleteOld) {
1062                             synchronized (mInstallLock) {
1063                                 res.removedInfo.args.doPostDeleteLI(true);
1064                             }
1065                         }
1066                         if (args.observer != null) {
1067                             try {
1068                                 Bundle extras = extrasForInstallResult(res);
1069                                 args.observer.onPackageInstalled(res.name, res.returnCode,
1070                                         res.returnMsg, extras);
1071                             } catch (RemoteException e) {
1072                                 Slog.i(TAG, "Observer no longer exists.");
1073                             }
1074                         }
1075                     } else {
1076                         Slog.e(TAG, "Bogus post-install token " + msg.arg1);
1077                     }
1078                 } break;
1079                 case UPDATED_MEDIA_STATUS: {
1080                     if (DEBUG_SD_INSTALL) Log.i(TAG, "Got message UPDATED_MEDIA_STATUS");
1081                     boolean reportStatus = msg.arg1 == 1;
1082                     boolean doGc = msg.arg2 == 1;
1083                     if (DEBUG_SD_INSTALL) Log.i(TAG, "reportStatus=" + reportStatus + ", doGc = " + doGc);
1084                     if (doGc) {
1085                         // Force a gc to clear up stale containers.
1086                         Runtime.getRuntime().gc();
1087                     }
1088                     if (msg.obj != null) {
1089                         @SuppressWarnings("unchecked")
1090                         Set<AsecInstallArgs> args = (Set<AsecInstallArgs>) msg.obj;
1091                         if (DEBUG_SD_INSTALL) Log.i(TAG, "Unloading all containers");
1092                         // Unload containers
1093                         unloadAllContainers(args);
1094                     }
1095                     if (reportStatus) {
1096                         try {
1097                             if (DEBUG_SD_INSTALL) Log.i(TAG, "Invoking MountService call back");
1098                             PackageHelper.getMountService().finishMediaUpdate();
1099                         } catch (RemoteException e) {
1100                             Log.e(TAG, "MountService not running?");
1101                         }
1102                     }
1103                 } break;
1104                 case WRITE_SETTINGS: {
1105                     Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1106                     synchronized (mPackages) {
1107                         removeMessages(WRITE_SETTINGS);
1108                         removeMessages(WRITE_PACKAGE_RESTRICTIONS);
1109                         mSettings.writeLPr();
1110                         mDirtyUsers.clear();
1111                     }
1112                     Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1113                 } break;
1114                 case WRITE_PACKAGE_RESTRICTIONS: {
1115                     Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1116                     synchronized (mPackages) {
1117                         removeMessages(WRITE_PACKAGE_RESTRICTIONS);
1118                         for (int userId : mDirtyUsers) {
1119                             mSettings.writePackageRestrictionsLPr(userId);
1120                         }
1121                         mDirtyUsers.clear();
1122                     }
1123                     Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1124                 } break;
1125                 case CHECK_PENDING_VERIFICATION: {
1126                     final int verificationId = msg.arg1;
1127                     final PackageVerificationState state = mPendingVerification.get(verificationId);
1128
1129                     if ((state != null) && !state.timeoutExtended()) {
1130                         final InstallArgs args = state.getInstallArgs();
1131                         final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
1132
1133                         Slog.i(TAG, "Verification timed out for " + originUri);
1134                         mPendingVerification.remove(verificationId);
1135
1136                         int ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
1137
1138                         if (getDefaultVerificationResponse() == PackageManager.VERIFICATION_ALLOW) {
1139                             Slog.i(TAG, "Continuing with installation of " + originUri);
1140                             state.setVerifierResponse(Binder.getCallingUid(),
1141                                     PackageManager.VERIFICATION_ALLOW_WITHOUT_SUFFICIENT);
1142                             broadcastPackageVerified(verificationId, originUri,
1143                                     PackageManager.VERIFICATION_ALLOW,
1144                                     state.getInstallArgs().getUser());
1145                             try {
1146                                 ret = args.copyApk(mContainerService, true);
1147                             } catch (RemoteException e) {
1148                                 Slog.e(TAG, "Could not contact the ContainerService");
1149                             }
1150                         } else {
1151                             broadcastPackageVerified(verificationId, originUri,
1152                                     PackageManager.VERIFICATION_REJECT,
1153                                     state.getInstallArgs().getUser());
1154                         }
1155
1156                         processPendingInstall(args, ret);
1157                         mHandler.sendEmptyMessage(MCS_UNBIND);
1158                     }
1159                     break;
1160                 }
1161                 case PACKAGE_VERIFIED: {
1162                     final int verificationId = msg.arg1;
1163
1164                     final PackageVerificationState state = mPendingVerification.get(verificationId);
1165                     if (state == null) {
1166                         Slog.w(TAG, "Invalid verification token " + verificationId + " received");
1167                         break;
1168                     }
1169
1170                     final PackageVerificationResponse response = (PackageVerificationResponse) msg.obj;
1171
1172                     state.setVerifierResponse(response.callerUid, response.code);
1173
1174                     if (state.isVerificationComplete()) {
1175                         mPendingVerification.remove(verificationId);
1176
1177                         final InstallArgs args = state.getInstallArgs();
1178                         final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
1179
1180                         int ret;
1181                         if (state.isInstallAllowed()) {
1182                             ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
1183                             broadcastPackageVerified(verificationId, originUri,
1184                                     response.code, state.getInstallArgs().getUser());
1185                             try {
1186                                 ret = args.copyApk(mContainerService, true);
1187                             } catch (RemoteException e) {
1188                                 Slog.e(TAG, "Could not contact the ContainerService");
1189                             }
1190                         } else {
1191                             ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
1192                         }
1193
1194                         processPendingInstall(args, ret);
1195
1196                         mHandler.sendEmptyMessage(MCS_UNBIND);
1197                     }
1198
1199                     break;
1200                 }
1201             }
1202         }
1203     }
1204
1205     Bundle extrasForInstallResult(PackageInstalledInfo res) {
1206         Bundle extras = null;
1207         switch (res.returnCode) {
1208             case PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION: {
1209                 extras = new Bundle();
1210                 extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PERMISSION,
1211                         res.origPermission);
1212                 extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PACKAGE,
1213                         res.origPackage);
1214                 break;
1215             }
1216         }
1217         return extras;
1218     }
1219
1220     void scheduleWriteSettingsLocked() {
1221         if (!mHandler.hasMessages(WRITE_SETTINGS)) {
1222             mHandler.sendEmptyMessageDelayed(WRITE_SETTINGS, WRITE_SETTINGS_DELAY);
1223         }
1224     }
1225
1226     void scheduleWritePackageRestrictionsLocked(int userId) {
1227         if (!sUserManager.exists(userId)) return;
1228         mDirtyUsers.add(userId);
1229         if (!mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) {
1230             mHandler.sendEmptyMessageDelayed(WRITE_PACKAGE_RESTRICTIONS, WRITE_SETTINGS_DELAY);
1231         }
1232     }
1233
1234     public static final PackageManagerService main(Context context, Installer installer,
1235             boolean factoryTest, boolean onlyCore) {
1236         PackageManagerService m = new PackageManagerService(context, installer,
1237                 factoryTest, onlyCore);
1238         ServiceManager.addService("package", m);
1239         return m;
1240     }
1241
1242     static String[] splitString(String str, char sep) {
1243         int count = 1;
1244         int i = 0;
1245         while ((i=str.indexOf(sep, i)) >= 0) {
1246             count++;
1247             i++;
1248         }
1249
1250         String[] res = new String[count];
1251         i=0;
1252         count = 0;
1253         int lastI=0;
1254         while ((i=str.indexOf(sep, i)) >= 0) {
1255             res[count] = str.substring(lastI, i);
1256             count++;
1257             i++;
1258             lastI = i;
1259         }
1260         res[count] = str.substring(lastI, str.length());
1261         return res;
1262     }
1263
1264     private static void getDefaultDisplayMetrics(Context context, DisplayMetrics metrics) {
1265         DisplayManager displayManager = (DisplayManager) context.getSystemService(
1266                 Context.DISPLAY_SERVICE);
1267         displayManager.getDisplay(Display.DEFAULT_DISPLAY).getMetrics(metrics);
1268     }
1269
1270     public PackageManagerService(Context context, Installer installer,
1271             boolean factoryTest, boolean onlyCore) {
1272         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START,
1273                 SystemClock.uptimeMillis());
1274
1275         if (mSdkVersion <= 0) {
1276             Slog.w(TAG, "**** ro.build.version.sdk not set!");
1277         }
1278
1279         mContext = context;
1280         mFactoryTest = factoryTest;
1281         mOnlyCore = onlyCore;
1282         mLazyDexOpt = "eng".equals(SystemProperties.get("ro.build.type"));
1283         mMetrics = new DisplayMetrics();
1284         mSettings = new Settings(context);
1285         mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID,
1286                 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PRIVILEGED);
1287         mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID,
1288                 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PRIVILEGED);
1289         mSettings.addSharedUserLPw("android.uid.log", LOG_UID,
1290                 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PRIVILEGED);
1291         mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID,
1292                 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PRIVILEGED);
1293         mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID,
1294                 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PRIVILEGED);
1295         mSettings.addSharedUserLPw("android.uid.shell", SHELL_UID,
1296                 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PRIVILEGED);
1297
1298         String separateProcesses = SystemProperties.get("debug.separate_processes");
1299         if (separateProcesses != null && separateProcesses.length() > 0) {
1300             if ("*".equals(separateProcesses)) {
1301                 mDefParseFlags = PackageParser.PARSE_IGNORE_PROCESSES;
1302                 mSeparateProcesses = null;
1303                 Slog.w(TAG, "Running with debug.separate_processes: * (ALL)");
1304             } else {
1305                 mDefParseFlags = 0;
1306                 mSeparateProcesses = separateProcesses.split(",");
1307                 Slog.w(TAG, "Running with debug.separate_processes: "
1308                         + separateProcesses);
1309             }
1310         } else {
1311             mDefParseFlags = 0;
1312             mSeparateProcesses = null;
1313         }
1314
1315         mInstaller = installer;
1316
1317         getDefaultDisplayMetrics(context, mMetrics);
1318
1319         SystemConfig systemConfig = SystemConfig.getInstance();
1320         mGlobalGids = systemConfig.getGlobalGids();
1321         mSystemPermissions = systemConfig.getSystemPermissions();
1322         mAvailableFeatures = systemConfig.getAvailableFeatures();
1323
1324         synchronized (mInstallLock) {
1325         // writer
1326         synchronized (mPackages) {
1327             mHandlerThread = new ServiceThread(TAG,
1328                     Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
1329             mHandlerThread.start();
1330             mHandler = new PackageHandler(mHandlerThread.getLooper());
1331             Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT);
1332
1333             File dataDir = Environment.getDataDirectory();
1334             mAppDataDir = new File(dataDir, "data");
1335             mAppInstallDir = new File(dataDir, "app");
1336             mAppLib32InstallDir = new File(dataDir, "app-lib");
1337             mAsecInternalPath = new File(dataDir, "app-asec").getPath();
1338             mUserAppDataDir = new File(dataDir, "user");
1339             mDrmAppPrivateInstallDir = new File(dataDir, "app-private");
1340
1341             sUserManager = new UserManagerService(context, this,
1342                     mInstallLock, mPackages);
1343
1344             // Propagate permission configuration in to package manager.
1345             ArrayMap<String, SystemConfig.PermissionEntry> permConfig
1346                     = systemConfig.getPermissions();
1347             for (int i=0; i<permConfig.size(); i++) {
1348                 SystemConfig.PermissionEntry perm = permConfig.valueAt(i);
1349                 BasePermission bp = mSettings.mPermissions.get(perm.name);
1350                 if (bp == null) {
1351                     bp = new BasePermission(perm.name, "android", BasePermission.TYPE_BUILTIN);
1352                     mSettings.mPermissions.put(perm.name, bp);
1353                 }
1354                 if (perm.gids != null) {
1355                     bp.gids = appendInts(bp.gids, perm.gids);
1356                 }
1357             }
1358
1359             ArrayMap<String, String> libConfig = systemConfig.getSharedLibraries();
1360             for (int i=0; i<libConfig.size(); i++) {
1361                 mSharedLibraries.put(libConfig.keyAt(i),
1362                         new SharedLibraryEntry(libConfig.valueAt(i), null));
1363             }
1364
1365             mFoundPolicyFile = SELinuxMMAC.readInstallPolicy();
1366
1367             mRestoredSettings = mSettings.readLPw(this, sUserManager.getUsers(false),
1368                     mSdkVersion, mOnlyCore);
1369
1370             String customResolverActivity = Resources.getSystem().getString(
1371                     R.string.config_customResolverActivity);
1372             if (TextUtils.isEmpty(customResolverActivity)) {
1373                 customResolverActivity = null;
1374             } else {
1375                 mCustomResolverComponentName = ComponentName.unflattenFromString(
1376                         customResolverActivity);
1377             }
1378
1379             long startTime = SystemClock.uptimeMillis();
1380
1381             EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START,
1382                     startTime);
1383
1384             // Set flag to monitor and not change apk file paths when
1385             // scanning install directories.
1386             final int scanFlags = SCAN_NO_PATHS | SCAN_DEFER_DEX | SCAN_BOOTING;
1387
1388             final HashSet<String> alreadyDexOpted = new HashSet<String>();
1389
1390             /**
1391              * Add everything in the in the boot class path to the
1392              * list of process files because dexopt will have been run
1393              * if necessary during zygote startup.
1394              */
1395             final String bootClassPath = System.getenv("BOOTCLASSPATH");
1396             final String systemServerClassPath = System.getenv("SYSTEMSERVERCLASSPATH");
1397
1398             if (bootClassPath != null) {
1399                 String[] bootClassPathElements = splitString(bootClassPath, ':');
1400                 for (String element : bootClassPathElements) {
1401                     alreadyDexOpted.add(element);
1402                 }
1403             } else {
1404                 Slog.w(TAG, "No BOOTCLASSPATH found!");
1405             }
1406
1407             if (systemServerClassPath != null) {
1408                 String[] systemServerClassPathElements = splitString(systemServerClassPath, ':');
1409                 for (String element : systemServerClassPathElements) {
1410                     alreadyDexOpted.add(element);
1411                 }
1412             } else {
1413                 Slog.w(TAG, "No SYSTEMSERVERCLASSPATH found!");
1414             }
1415
1416             boolean didDexOptLibraryOrTool = false;
1417
1418             final List<String> allInstructionSets = getAllInstructionSets();
1419             final String[] dexCodeInstructionSets =
1420                 getDexCodeInstructionSets(allInstructionSets.toArray(new String[allInstructionSets.size()]));
1421
1422             /**
1423              * Ensure all external libraries have had dexopt run on them.
1424              */
1425             if (mSharedLibraries.size() > 0) {
1426                 // NOTE: For now, we're compiling these system "shared libraries"
1427                 // (and framework jars) into all available architectures. It's possible
1428                 // to compile them only when we come across an app that uses them (there's
1429                 // already logic for that in scanPackageLI) but that adds some complexity.
1430                 for (String dexCodeInstructionSet : dexCodeInstructionSets) {
1431                     for (SharedLibraryEntry libEntry : mSharedLibraries.values()) {
1432                         final String lib = libEntry.path;
1433                         if (lib == null) {
1434                             continue;
1435                         }
1436
1437                         try {
1438                             byte dexoptRequired = DexFile.isDexOptNeededInternal(lib, null,
1439                                                                                  dexCodeInstructionSet,
1440                                                                                  false);
1441                             if (dexoptRequired != DexFile.UP_TO_DATE) {
1442                                 alreadyDexOpted.add(lib);
1443
1444                                 // The list of "shared libraries" we have at this point is
1445                                 if (dexoptRequired == DexFile.DEXOPT_NEEDED) {
1446                                     mInstaller.dexopt(lib, Process.SYSTEM_UID, true, dexCodeInstructionSet);
1447                                 } else {
1448                                     mInstaller.patchoat(lib, Process.SYSTEM_UID, true, dexCodeInstructionSet);
1449                                 }
1450                                 didDexOptLibraryOrTool = true;
1451                             }
1452                         } catch (FileNotFoundException e) {
1453                             Slog.w(TAG, "Library not found: " + lib);
1454                         } catch (IOException e) {
1455                             Slog.w(TAG, "Cannot dexopt " + lib + "; is it an APK or JAR? "
1456                                     + e.getMessage());
1457                         }
1458                     }
1459                 }
1460             }
1461
1462             File frameworkDir = new File(Environment.getRootDirectory(), "framework");
1463
1464             // Gross hack for now: we know this file doesn't contain any
1465             // code, so don't dexopt it to avoid the resulting log spew.
1466             alreadyDexOpted.add(frameworkDir.getPath() + "/framework-res.apk");
1467
1468             // Gross hack for now: we know this file is only part of
1469             // the boot class path for art, so don't dexopt it to
1470             // avoid the resulting log spew.
1471             alreadyDexOpted.add(frameworkDir.getPath() + "/core-libart.jar");
1472
1473             /**
1474              * And there are a number of commands implemented in Java, which
1475              * we currently need to do the dexopt on so that they can be
1476              * run from a non-root shell.
1477              */
1478             String[] frameworkFiles = frameworkDir.list();
1479             if (frameworkFiles != null) {
1480                 // TODO: We could compile these only for the most preferred ABI. We should
1481                 // first double check that the dex files for these commands are not referenced
1482                 // by other system apps.
1483                 for (String dexCodeInstructionSet : dexCodeInstructionSets) {
1484                     for (int i=0; i<frameworkFiles.length; i++) {
1485                         File libPath = new File(frameworkDir, frameworkFiles[i]);
1486                         String path = libPath.getPath();
1487                         // Skip the file if we already did it.
1488                         if (alreadyDexOpted.contains(path)) {
1489                             continue;
1490                         }
1491                         // Skip the file if it is not a type we want to dexopt.
1492                         if (!path.endsWith(".apk") && !path.endsWith(".jar")) {
1493                             continue;
1494                         }
1495                         try {
1496                             byte dexoptRequired = DexFile.isDexOptNeededInternal(path, null,
1497                                                                                  dexCodeInstructionSet,
1498                                                                                  false);
1499                             if (dexoptRequired == DexFile.DEXOPT_NEEDED) {
1500                                 mInstaller.dexopt(path, Process.SYSTEM_UID, true, dexCodeInstructionSet);
1501                                 didDexOptLibraryOrTool = true;
1502                             } else if (dexoptRequired == DexFile.PATCHOAT_NEEDED) {
1503                                 mInstaller.patchoat(path, Process.SYSTEM_UID, true, dexCodeInstructionSet);
1504                                 didDexOptLibraryOrTool = true;
1505                             }
1506                         } catch (FileNotFoundException e) {
1507                             Slog.w(TAG, "Jar not found: " + path);
1508                         } catch (IOException e) {
1509                             Slog.w(TAG, "Exception reading jar: " + path, e);
1510                         }
1511                     }
1512                 }
1513             }
1514
1515             // Collect vendor overlay packages.
1516             // (Do this before scanning any apps.)
1517             // For security and version matching reason, only consider
1518             // overlay packages if they reside in VENDOR_OVERLAY_DIR.
1519             File vendorOverlayDir = new File(VENDOR_OVERLAY_DIR);
1520             scanDirLI(vendorOverlayDir, PackageParser.PARSE_IS_SYSTEM
1521                     | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags | SCAN_TRUSTED_OVERLAY, 0);
1522
1523             // Find base frameworks (resource packages without code).
1524             scanDirLI(frameworkDir, PackageParser.PARSE_IS_SYSTEM
1525                     | PackageParser.PARSE_IS_SYSTEM_DIR
1526                     | PackageParser.PARSE_IS_PRIVILEGED,
1527                     scanFlags | SCAN_NO_DEX, 0);
1528
1529             // Collected privileged system packages.
1530             final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app");
1531             scanDirLI(privilegedAppDir, PackageParser.PARSE_IS_SYSTEM
1532                     | PackageParser.PARSE_IS_SYSTEM_DIR
1533                     | PackageParser.PARSE_IS_PRIVILEGED, scanFlags, 0);
1534
1535             // Collect ordinary system packages.
1536             final File systemAppDir = new File(Environment.getRootDirectory(), "app");
1537             scanDirLI(systemAppDir, PackageParser.PARSE_IS_SYSTEM
1538                     | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
1539
1540             // Collect all vendor packages.
1541             File vendorAppDir = new File("/vendor/app");
1542             try {
1543                 vendorAppDir = vendorAppDir.getCanonicalFile();
1544             } catch (IOException e) {
1545                 // failed to look up canonical path, continue with original one
1546             }
1547             scanDirLI(vendorAppDir, PackageParser.PARSE_IS_SYSTEM
1548                     | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
1549
1550             // Collect all OEM packages.
1551             final File oemAppDir = new File(Environment.getOemDirectory(), "app");
1552             scanDirLI(oemAppDir, PackageParser.PARSE_IS_SYSTEM
1553                     | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
1554
1555             if (DEBUG_UPGRADE) Log.v(TAG, "Running installd update commands");
1556             mInstaller.moveFiles();
1557
1558             // Prune any system packages that no longer exist.
1559             final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<String>();
1560             final ArrayMap<String, File> expectingBetter = new ArrayMap<>();
1561             if (!mOnlyCore) {
1562                 Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
1563                 while (psit.hasNext()) {
1564                     PackageSetting ps = psit.next();
1565
1566                     /*
1567                      * If this is not a system app, it can't be a
1568                      * disable system app.
1569                      */
1570                     if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
1571                         continue;
1572                     }
1573
1574                     /*
1575                      * If the package is scanned, it's not erased.
1576                      */
1577                     final PackageParser.Package scannedPkg = mPackages.get(ps.name);
1578                     if (scannedPkg != null) {
1579                         /*
1580                          * If the system app is both scanned and in the
1581                          * disabled packages list, then it must have been
1582                          * added via OTA. Remove it from the currently
1583                          * scanned package so the previously user-installed
1584                          * application can be scanned.
1585                          */
1586                         if (mSettings.isDisabledSystemPackageLPr(ps.name)) {
1587                             logCriticalInfo(Log.WARN, "Expecting better updated system app for "
1588                                     + ps.name + "; removing system app.  Last known codePath="
1589                                     + ps.codePathString + ", installStatus=" + ps.installStatus
1590                                     + ", versionCode=" + ps.versionCode + "; scanned versionCode="
1591                                     + scannedPkg.mVersionCode);
1592                             removePackageLI(ps, true);
1593                             expectingBetter.put(ps.name, ps.codePath);
1594                         }
1595
1596                         continue;
1597                     }
1598
1599                     if (!mSettings.isDisabledSystemPackageLPr(ps.name)) {
1600                         psit.remove();
1601                         logCriticalInfo(Log.WARN, "System package " + ps.name
1602                                 + " no longer exists; wiping its data");
1603                         removeDataDirsLI(ps.name);
1604                     } else {
1605                         final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(ps.name);
1606                         if (disabledPs.codePath == null || !disabledPs.codePath.exists()) {
1607                             possiblyDeletedUpdatedSystemApps.add(ps.name);
1608                         }
1609                     }
1610                 }
1611             }
1612
1613             //look for any incomplete package installations
1614             ArrayList<PackageSetting> deletePkgsList = mSettings.getListOfIncompleteInstallPackagesLPr();
1615             //clean up list
1616             for(int i = 0; i < deletePkgsList.size(); i++) {
1617                 //clean up here
1618                 cleanupInstallFailedPackage(deletePkgsList.get(i));
1619             }
1620             //delete tmp files
1621             deleteTempPackageFiles();
1622
1623             // Remove any shared userIDs that have no associated packages
1624             mSettings.pruneSharedUsersLPw();
1625
1626             if (!mOnlyCore) {
1627                 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,
1628                         SystemClock.uptimeMillis());
1629                 scanDirLI(mAppInstallDir, 0, scanFlags, 0);
1630
1631                 scanDirLI(mDrmAppPrivateInstallDir, PackageParser.PARSE_FORWARD_LOCK,
1632                         scanFlags, 0);
1633
1634                 /**
1635                  * Remove disable package settings for any updated system
1636                  * apps that were removed via an OTA. If they're not a
1637                  * previously-updated app, remove them completely.
1638                  * Otherwise, just revoke their system-level permissions.
1639                  */
1640                 for (String deletedAppName : possiblyDeletedUpdatedSystemApps) {
1641                     PackageParser.Package deletedPkg = mPackages.get(deletedAppName);
1642                     mSettings.removeDisabledSystemPackageLPw(deletedAppName);
1643
1644                     String msg;
1645                     if (deletedPkg == null) {
1646                         msg = "Updated system package " + deletedAppName
1647                                 + " no longer exists; wiping its data";
1648                         removeDataDirsLI(deletedAppName);
1649                     } else {
1650                         msg = "Updated system app + " + deletedAppName
1651                                 + " no longer present; removing system privileges for "
1652                                 + deletedAppName;
1653
1654                         deletedPkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM;
1655
1656                         PackageSetting deletedPs = mSettings.mPackages.get(deletedAppName);
1657                         deletedPs.pkgFlags &= ~ApplicationInfo.FLAG_SYSTEM;
1658                     }
1659                     logCriticalInfo(Log.WARN, msg);
1660                 }
1661
1662                 /**
1663                  * Make sure all system apps that we expected to appear on
1664                  * the userdata partition actually showed up. If they never
1665                  * appeared, crawl back and revive the system version.
1666                  */
1667                 for (int i = 0; i < expectingBetter.size(); i++) {
1668                     final String packageName = expectingBetter.keyAt(i);
1669                     if (!mPackages.containsKey(packageName)) {
1670                         final File scanFile = expectingBetter.valueAt(i);
1671
1672                         logCriticalInfo(Log.WARN, "Expected better " + packageName
1673                                 + " but never showed up; reverting to system");
1674
1675                         final int reparseFlags;
1676                         if (FileUtils.contains(privilegedAppDir, scanFile)) {
1677                             reparseFlags = PackageParser.PARSE_IS_SYSTEM
1678                                     | PackageParser.PARSE_IS_SYSTEM_DIR
1679                                     | PackageParser.PARSE_IS_PRIVILEGED;
1680                         } else if (FileUtils.contains(systemAppDir, scanFile)) {
1681                             reparseFlags = PackageParser.PARSE_IS_SYSTEM
1682                                     | PackageParser.PARSE_IS_SYSTEM_DIR;
1683                         } else if (FileUtils.contains(vendorAppDir, scanFile)) {
1684                             reparseFlags = PackageParser.PARSE_IS_SYSTEM
1685                                     | PackageParser.PARSE_IS_SYSTEM_DIR;
1686                         } else if (FileUtils.contains(oemAppDir, scanFile)) {
1687                             reparseFlags = PackageParser.PARSE_IS_SYSTEM
1688                                     | PackageParser.PARSE_IS_SYSTEM_DIR;
1689                         } else {
1690                             Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile);
1691                             continue;
1692                         }
1693
1694                         mSettings.enableSystemPackageLPw(packageName);
1695
1696                         try {
1697                             scanPackageLI(scanFile, reparseFlags, scanFlags, 0, null);
1698                         } catch (PackageManagerException e) {
1699                             Slog.e(TAG, "Failed to parse original system package: "
1700                                     + e.getMessage());
1701                         }
1702                     }
1703                 }
1704             }
1705
1706             // Now that we know all of the shared libraries, update all clients to have
1707             // the correct library paths.
1708             updateAllSharedLibrariesLPw();
1709
1710             for (SharedUserSetting setting : mSettings.getAllSharedUsersLPw()) {
1711                 // NOTE: We ignore potential failures here during a system scan (like
1712                 // the rest of the commands above) because there's precious little we
1713                 // can do about it. A settings error is reported, though.
1714                 adjustCpuAbisForSharedUserLPw(setting.packages, null /* scanned package */,
1715                         false /* force dexopt */, false /* defer dexopt */);
1716             }
1717
1718             // Now that we know all the packages we are keeping,
1719             // read and update their last usage times.
1720             mPackageUsage.readLP();
1721
1722             EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END,
1723                     SystemClock.uptimeMillis());
1724             Slog.i(TAG, "Time to scan packages: "
1725                     + ((SystemClock.uptimeMillis()-startTime)/1000f)
1726                     + " seconds");
1727
1728             // If the platform SDK has changed since the last time we booted,
1729             // we need to re-grant app permission to catch any new ones that
1730             // appear.  This is really a hack, and means that apps can in some
1731             // cases get permissions that the user didn't initially explicitly
1732             // allow...  it would be nice to have some better way to handle
1733             // this situation.
1734             final boolean regrantPermissions = mSettings.mInternalSdkPlatform
1735                     != mSdkVersion;
1736             if (regrantPermissions) Slog.i(TAG, "Platform changed from "
1737                     + mSettings.mInternalSdkPlatform + " to " + mSdkVersion
1738                     + "; regranting permissions for internal storage");
1739             mSettings.mInternalSdkPlatform = mSdkVersion;
1740             
1741             updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL
1742                     | (regrantPermissions
1743                             ? (UPDATE_PERMISSIONS_REPLACE_PKG|UPDATE_PERMISSIONS_REPLACE_ALL)
1744                             : 0));
1745
1746             // If this is the first boot, and it is a normal boot, then
1747             // we need to initialize the default preferred apps.
1748             if (!mRestoredSettings && !onlyCore) {
1749                 mSettings.readDefaultPreferredAppsLPw(this, 0);
1750             }
1751
1752             // If this is first boot after an OTA, and a normal boot, then
1753             // we need to clear code cache directories.
1754             mIsUpgrade = !Build.FINGERPRINT.equals(mSettings.mFingerprint);
1755             if (mIsUpgrade && !onlyCore) {
1756                 Slog.i(TAG, "Build fingerprint changed; clearing code caches");
1757                 for (String pkgName : mSettings.mPackages.keySet()) {
1758                     deleteCodeCacheDirsLI(pkgName);
1759                 }
1760                 mSettings.mFingerprint = Build.FINGERPRINT;
1761             }
1762
1763             // All the changes are done during package scanning.
1764             mSettings.updateInternalDatabaseVersion();
1765
1766             // can downgrade to reader
1767             mSettings.writeLPr();
1768
1769             EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY,
1770                     SystemClock.uptimeMillis());
1771
1772
1773             mRequiredVerifierPackage = getRequiredVerifierLPr();
1774         } // synchronized (mPackages)
1775         } // synchronized (mInstallLock)
1776
1777         mInstallerService = new PackageInstallerService(context, this, mAppInstallDir);
1778
1779         // Now after opening every single application zip, make sure they
1780         // are all flushed.  Not really needed, but keeps things nice and
1781         // tidy.
1782         Runtime.getRuntime().gc();
1783     }
1784
1785     @Override
1786     public boolean isFirstBoot() {
1787         return !mRestoredSettings;
1788     }
1789
1790     @Override
1791     public boolean isOnlyCoreApps() {
1792         return mOnlyCore;
1793     }
1794
1795     @Override
1796     public boolean isUpgrade() {
1797         return mIsUpgrade;
1798     }
1799
1800     private String getRequiredVerifierLPr() {
1801         final Intent verification = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
1802         final List<ResolveInfo> receivers = queryIntentReceivers(verification, PACKAGE_MIME_TYPE,
1803                 PackageManager.GET_DISABLED_COMPONENTS, 0 /* TODO: Which userId? */);
1804
1805         String requiredVerifier = null;
1806
1807         final int N = receivers.size();
1808         for (int i = 0; i < N; i++) {
1809             final ResolveInfo info = receivers.get(i);
1810
1811             if (info.activityInfo == null) {
1812                 continue;
1813             }
1814
1815             final String packageName = info.activityInfo.packageName;
1816
1817             final PackageSetting ps = mSettings.mPackages.get(packageName);
1818             if (ps == null) {
1819                 continue;
1820             }
1821
1822             final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps;
1823             if (!gp.grantedPermissions
1824                     .contains(android.Manifest.permission.PACKAGE_VERIFICATION_AGENT)) {
1825                 continue;
1826             }
1827
1828             if (requiredVerifier != null) {
1829                 throw new RuntimeException("There can be only one required verifier");
1830             }
1831
1832             requiredVerifier = packageName;
1833         }
1834
1835         return requiredVerifier;
1836     }
1837
1838     @Override
1839     public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1840             throws RemoteException {
1841         try {
1842             return super.onTransact(code, data, reply, flags);
1843         } catch (RuntimeException e) {
1844             if (!(e instanceof SecurityException) && !(e instanceof IllegalArgumentException)) {
1845                 Slog.wtf(TAG, "Package Manager Crash", e);
1846             }
1847             throw e;
1848         }
1849     }
1850
1851     void cleanupInstallFailedPackage(PackageSetting ps) {
1852         logCriticalInfo(Log.WARN, "Cleaning up incompletely installed app: " + ps.name);
1853
1854         removeDataDirsLI(ps.name);
1855         if (ps.codePath != null) {
1856             if (ps.codePath.isDirectory()) {
1857                 FileUtils.deleteContents(ps.codePath);
1858             }
1859             ps.codePath.delete();
1860         }
1861         if (ps.resourcePath != null && !ps.resourcePath.equals(ps.codePath)) {
1862             if (ps.resourcePath.isDirectory()) {
1863                 FileUtils.deleteContents(ps.resourcePath);
1864             }
1865             ps.resourcePath.delete();
1866         }
1867         mSettings.removePackageLPw(ps.name);
1868     }
1869
1870     static int[] appendInts(int[] cur, int[] add) {
1871         if (add == null) return cur;
1872         if (cur == null) return add;
1873         final int N = add.length;
1874         for (int i=0; i<N; i++) {
1875             cur = appendInt(cur, add[i]);
1876         }
1877         return cur;
1878     }
1879
1880     static int[] removeInts(int[] cur, int[] rem) {
1881         if (rem == null) return cur;
1882         if (cur == null) return cur;
1883         final int N = rem.length;
1884         for (int i=0; i<N; i++) {
1885             cur = removeInt(cur, rem[i]);
1886         }
1887         return cur;
1888     }
1889
1890     PackageInfo generatePackageInfo(PackageParser.Package p, int flags, int userId) {
1891         if (!sUserManager.exists(userId)) return null;
1892         final PackageSetting ps = (PackageSetting) p.mExtras;
1893         if (ps == null) {
1894             return null;
1895         }
1896         final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps;
1897         final PackageUserState state = ps.readUserState(userId);
1898         return PackageParser.generatePackageInfo(p, gp.gids, flags,
1899                 ps.firstInstallTime, ps.lastUpdateTime, gp.grantedPermissions,
1900                 state, userId);
1901     }
1902
1903     @Override
1904     public boolean isPackageAvailable(String packageName, int userId) {
1905         if (!sUserManager.exists(userId)) return false;
1906         enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "is package available");
1907         synchronized (mPackages) {
1908             PackageParser.Package p = mPackages.get(packageName);
1909             if (p != null) {
1910                 final PackageSetting ps = (PackageSetting) p.mExtras;
1911                 if (ps != null) {
1912                     final PackageUserState state = ps.readUserState(userId);
1913                     if (state != null) {
1914                         return PackageParser.isAvailable(state);
1915                     }
1916                 }
1917             }
1918         }
1919         return false;
1920     }
1921
1922     @Override
1923     public PackageInfo getPackageInfo(String packageName, int flags, int userId) {
1924         if (!sUserManager.exists(userId)) return null;
1925         enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get package info");
1926         // reader
1927         synchronized (mPackages) {
1928             PackageParser.Package p = mPackages.get(packageName);
1929             if (DEBUG_PACKAGE_INFO)
1930                 Log.v(TAG, "getPackageInfo " + packageName + ": " + p);
1931             if (p != null) {
1932                 return generatePackageInfo(p, flags, userId);
1933             }
1934             if((flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0) {
1935                 return generatePackageInfoFromSettingsLPw(packageName, flags, userId);
1936             }
1937         }
1938         return null;
1939     }
1940
1941     @Override
1942     public String[] currentToCanonicalPackageNames(String[] names) {
1943         String[] out = new String[names.length];
1944         // reader
1945         synchronized (mPackages) {
1946             for (int i=names.length-1; i>=0; i--) {
1947                 PackageSetting ps = mSettings.mPackages.get(names[i]);
1948                 out[i] = ps != null && ps.realName != null ? ps.realName : names[i];
1949             }
1950         }
1951         return out;
1952     }
1953     
1954     @Override
1955     public String[] canonicalToCurrentPackageNames(String[] names) {
1956         String[] out = new String[names.length];
1957         // reader
1958         synchronized (mPackages) {
1959             for (int i=names.length-1; i>=0; i--) {
1960                 String cur = mSettings.mRenamedPackages.get(names[i]);
1961                 out[i] = cur != null ? cur : names[i];
1962             }
1963         }
1964         return out;
1965     }
1966
1967     @Override
1968     public int getPackageUid(String packageName, int userId) {
1969         if (!sUserManager.exists(userId)) return -1;
1970         enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get package uid");
1971         // reader
1972         synchronized (mPackages) {
1973             PackageParser.Package p = mPackages.get(packageName);
1974             if(p != null) {
1975                 return UserHandle.getUid(userId, p.applicationInfo.uid);
1976             }
1977             PackageSetting ps = mSettings.mPackages.get(packageName);
1978             if((ps == null) || (ps.pkg == null) || (ps.pkg.applicationInfo == null)) {
1979                 return -1;
1980             }
1981             p = ps.pkg;
1982             return p != null ? UserHandle.getUid(userId, p.applicationInfo.uid) : -1;
1983         }
1984     }
1985
1986     @Override
1987     public int[] getPackageGids(String packageName) {
1988         // reader
1989         synchronized (mPackages) {
1990             PackageParser.Package p = mPackages.get(packageName);
1991             if (DEBUG_PACKAGE_INFO)
1992                 Log.v(TAG, "getPackageGids" + packageName + ": " + p);
1993             if (p != null) {
1994                 final PackageSetting ps = (PackageSetting)p.mExtras;
1995                 return ps.getGids();
1996             }
1997         }
1998         // stupid thing to indicate an error.
1999         return new int[0];
2000     }
2001
2002     static final PermissionInfo generatePermissionInfo(
2003             BasePermission bp, int flags) {
2004         if (bp.perm != null) {
2005             return PackageParser.generatePermissionInfo(bp.perm, flags);
2006         }
2007         PermissionInfo pi = new PermissionInfo();
2008         pi.name = bp.name;
2009         pi.packageName = bp.sourcePackage;
2010         pi.nonLocalizedLabel = bp.name;
2011         pi.protectionLevel = bp.protectionLevel;
2012         return pi;
2013     }
2014     
2015     @Override
2016     public PermissionInfo getPermissionInfo(String name, int flags) {
2017         // reader
2018         synchronized (mPackages) {
2019             final BasePermission p = mSettings.mPermissions.get(name);
2020             if (p != null) {
2021                 return generatePermissionInfo(p, flags);
2022             }
2023             return null;
2024         }
2025     }
2026
2027     @Override
2028     public List<PermissionInfo> queryPermissionsByGroup(String group, int flags) {
2029         // reader
2030         synchronized (mPackages) {
2031             ArrayList<PermissionInfo> out = new ArrayList<PermissionInfo>(10);
2032             for (BasePermission p : mSettings.mPermissions.values()) {
2033                 if (group == null) {
2034                     if (p.perm == null || p.perm.info.group == null) {
2035                         out.add(generatePermissionInfo(p, flags));
2036                     }
2037                 } else {
2038                     if (p.perm != null && group.equals(p.perm.info.group)) {
2039                         out.add(PackageParser.generatePermissionInfo(p.perm, flags));
2040                     }
2041                 }
2042             }
2043
2044             if (out.size() > 0) {
2045                 return out;
2046             }
2047             return mPermissionGroups.containsKey(group) ? out : null;
2048         }
2049     }
2050
2051     @Override
2052     public PermissionGroupInfo getPermissionGroupInfo(String name, int flags) {
2053         // reader
2054         synchronized (mPackages) {
2055             return PackageParser.generatePermissionGroupInfo(
2056                     mPermissionGroups.get(name), flags);
2057         }
2058     }
2059
2060     @Override
2061     public List<PermissionGroupInfo> getAllPermissionGroups(int flags) {
2062         // reader
2063         synchronized (mPackages) {
2064             final int N = mPermissionGroups.size();
2065             ArrayList<PermissionGroupInfo> out
2066                     = new ArrayList<PermissionGroupInfo>(N);
2067             for (PackageParser.PermissionGroup pg : mPermissionGroups.values()) {
2068                 out.add(PackageParser.generatePermissionGroupInfo(pg, flags));
2069             }
2070             return out;
2071         }
2072     }
2073
2074     private ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName, int flags,
2075             int userId) {
2076         if (!sUserManager.exists(userId)) return null;
2077         PackageSetting ps = mSettings.mPackages.get(packageName);
2078         if (ps != null) {
2079             if (ps.pkg == null) {
2080                 PackageInfo pInfo = generatePackageInfoFromSettingsLPw(packageName,
2081                         flags, userId);
2082                 if (pInfo != null) {
2083                     return pInfo.applicationInfo;
2084                 }
2085                 return null;
2086             }
2087             return PackageParser.generateApplicationInfo(ps.pkg, flags,
2088                     ps.readUserState(userId), userId);
2089         }
2090         return null;
2091     }
2092
2093     private PackageInfo generatePackageInfoFromSettingsLPw(String packageName, int flags,
2094             int userId) {
2095         if (!sUserManager.exists(userId)) return null;
2096         PackageSetting ps = mSettings.mPackages.get(packageName);
2097         if (ps != null) {
2098             PackageParser.Package pkg = ps.pkg;
2099             if (pkg == null) {
2100                 if ((flags & PackageManager.GET_UNINSTALLED_PACKAGES) == 0) {
2101                     return null;
2102                 }
2103                 // Only data remains, so we aren't worried about code paths
2104                 pkg = new PackageParser.Package(packageName);
2105                 pkg.applicationInfo.packageName = packageName;
2106                 pkg.applicationInfo.flags = ps.pkgFlags | ApplicationInfo.FLAG_IS_DATA_ONLY;
2107                 pkg.applicationInfo.dataDir =
2108                         getDataPathForPackage(packageName, 0).getPath();
2109                 pkg.applicationInfo.primaryCpuAbi = ps.primaryCpuAbiString;
2110                 pkg.applicationInfo.secondaryCpuAbi = ps.secondaryCpuAbiString;
2111             }
2112             return generatePackageInfo(pkg, flags, userId);
2113         }
2114         return null;
2115     }
2116
2117     @Override
2118     public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) {
2119         if (!sUserManager.exists(userId)) return null;
2120         enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get application info");
2121         // writer
2122         synchronized (mPackages) {
2123             PackageParser.Package p = mPackages.get(packageName);
2124             if (DEBUG_PACKAGE_INFO) Log.v(
2125                     TAG, "getApplicationInfo " + packageName
2126                     + ": " + p);
2127             if (p != null) {
2128                 PackageSetting ps = mSettings.mPackages.get(packageName);
2129                 if (ps == null) return null;
2130                 // Note: isEnabledLP() does not apply here - always return info
2131                 return PackageParser.generateApplicationInfo(
2132                         p, flags, ps.readUserState(userId), userId);
2133             }
2134             if ("android".equals(packageName)||"system".equals(packageName)) {
2135                 return mAndroidApplication;
2136             }
2137             if ((flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0) {
2138                 return generateApplicationInfoFromSettingsLPw(packageName, flags, userId);
2139             }
2140         }
2141         return null;
2142     }
2143
2144
2145     @Override
2146     public void freeStorageAndNotify(final long freeStorageSize, final IPackageDataObserver observer) {
2147         mContext.enforceCallingOrSelfPermission(
2148                 android.Manifest.permission.CLEAR_APP_CACHE, null);
2149         // Queue up an async operation since clearing cache may take a little while.
2150         mHandler.post(new Runnable() {
2151             public void run() {
2152                 mHandler.removeCallbacks(this);
2153                 int retCode = -1;
2154                 synchronized (mInstallLock) {
2155                     retCode = mInstaller.freeCache(freeStorageSize);
2156                     if (retCode < 0) {
2157                         Slog.w(TAG, "Couldn't clear application caches");
2158                     }
2159                 }
2160                 if (observer != null) {
2161                     try {
2162                         observer.onRemoveCompleted(null, (retCode >= 0));
2163                     } catch (RemoteException e) {
2164                         Slog.w(TAG, "RemoveException when invoking call back");
2165                     }
2166                 }
2167             }
2168         });
2169     }
2170
2171     @Override
2172     public void freeStorage(final long freeStorageSize, final IntentSender pi) {
2173         mContext.enforceCallingOrSelfPermission(
2174                 android.Manifest.permission.CLEAR_APP_CACHE, null);
2175         // Queue up an async operation since clearing cache may take a little while.
2176         mHandler.post(new Runnable() {
2177             public void run() {
2178                 mHandler.removeCallbacks(this);
2179                 int retCode = -1;
2180                 synchronized (mInstallLock) {
2181                     retCode = mInstaller.freeCache(freeStorageSize);
2182                     if (retCode < 0) {
2183                         Slog.w(TAG, "Couldn't clear application caches");
2184                     }
2185                 }
2186                 if(pi != null) {
2187                     try {
2188                         // Callback via pending intent
2189                         int code = (retCode >= 0) ? 1 : 0;
2190                         pi.sendIntent(null, code, null,
2191                                 null, null);
2192                     } catch (SendIntentException e1) {
2193                         Slog.i(TAG, "Failed to send pending intent");
2194                     }
2195                 }
2196             }
2197         });
2198     }
2199
2200     void freeStorage(long freeStorageSize) throws IOException {
2201         synchronized (mInstallLock) {
2202             if (mInstaller.freeCache(freeStorageSize) < 0) {
2203                 throw new IOException("Failed to free enough space");
2204             }
2205         }
2206     }
2207
2208     @Override
2209     public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) {
2210         if (!sUserManager.exists(userId)) return null;
2211         enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get activity info");
2212         synchronized (mPackages) {
2213             PackageParser.Activity a = mActivities.mActivities.get(component);
2214
2215             if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a);
2216             if (a != null && mSettings.isEnabledLPr(a.info, flags, userId)) {
2217                 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
2218                 if (ps == null) return null;
2219                 return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId),
2220                         userId);
2221             }
2222             if (mResolveComponentName.equals(component)) {
2223                 return PackageParser.generateActivityInfo(mResolveActivity, flags,
2224                         new PackageUserState(), userId);
2225             }
2226         }
2227         return null;
2228     }
2229
2230     @Override
2231     public boolean activitySupportsIntent(ComponentName component, Intent intent,
2232             String resolvedType) {
2233         synchronized (mPackages) {
2234             PackageParser.Activity a = mActivities.mActivities.get(component);
2235             if (a == null) {
2236                 return false;
2237             }
2238             for (int i=0; i<a.intents.size(); i++) {
2239                 if (a.intents.get(i).match(intent.getAction(), resolvedType, intent.getScheme(),
2240                         intent.getData(), intent.getCategories(), TAG) >= 0) {
2241                     return true;
2242                 }
2243             }
2244             return false;
2245         }
2246     }
2247
2248     @Override
2249     public ActivityInfo getReceiverInfo(ComponentName component, int flags, int userId) {
2250         if (!sUserManager.exists(userId)) return null;
2251         enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get receiver info");
2252         synchronized (mPackages) {
2253             PackageParser.Activity a = mReceivers.mActivities.get(component);
2254             if (DEBUG_PACKAGE_INFO) Log.v(
2255                 TAG, "getReceiverInfo " + component + ": " + a);
2256             if (a != null && mSettings.isEnabledLPr(a.info, flags, userId)) {
2257                 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
2258                 if (ps == null) return null;
2259                 return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId),
2260                         userId);
2261             }
2262         }
2263         return null;
2264     }
2265
2266     @Override
2267     public ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) {
2268         if (!sUserManager.exists(userId)) return null;
2269         enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get service info");
2270         synchronized (mPackages) {
2271             PackageParser.Service s = mServices.mServices.get(component);
2272             if (DEBUG_PACKAGE_INFO) Log.v(
2273                 TAG, "getServiceInfo " + component + ": " + s);
2274             if (s != null && mSettings.isEnabledLPr(s.info, flags, userId)) {
2275                 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
2276                 if (ps == null) return null;
2277                 return PackageParser.generateServiceInfo(s, flags, ps.readUserState(userId),
2278                         userId);
2279             }
2280         }
2281         return null;
2282     }
2283
2284     @Override
2285     public ProviderInfo getProviderInfo(ComponentName component, int flags, int userId) {
2286         if (!sUserManager.exists(userId)) return null;
2287         enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get provider info");
2288         synchronized (mPackages) {
2289             PackageParser.Provider p = mProviders.mProviders.get(component);
2290             if (DEBUG_PACKAGE_INFO) Log.v(
2291                 TAG, "getProviderInfo " + component + ": " + p);
2292             if (p != null && mSettings.isEnabledLPr(p.info, flags, userId)) {
2293                 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
2294                 if (ps == null) return null;
2295                 return PackageParser.generateProviderInfo(p, flags, ps.readUserState(userId),
2296                         userId);
2297             }
2298         }
2299         return null;
2300     }
2301
2302     @Override
2303     public String[] getSystemSharedLibraryNames() {
2304         Set<String> libSet;
2305         synchronized (mPackages) {
2306             libSet = mSharedLibraries.keySet();
2307             int size = libSet.size();
2308             if (size > 0) {
2309                 String[] libs = new String[size];
2310                 libSet.toArray(libs);
2311                 return libs;
2312             }
2313         }
2314         return null;
2315     }
2316
2317     @Override
2318     public FeatureInfo[] getSystemAvailableFeatures() {
2319         Collection<FeatureInfo> featSet;
2320         synchronized (mPackages) {
2321             featSet = mAvailableFeatures.values();
2322             int size = featSet.size();
2323             if (size > 0) {
2324                 FeatureInfo[] features = new FeatureInfo[size+1];
2325                 featSet.toArray(features);
2326                 FeatureInfo fi = new FeatureInfo();
2327                 fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version",
2328                         FeatureInfo.GL_ES_VERSION_UNDEFINED);
2329                 features[size] = fi;
2330                 return features;
2331             }
2332         }
2333         return null;
2334     }
2335
2336     @Override
2337     public boolean hasSystemFeature(String name) {
2338         synchronized (mPackages) {
2339             return mAvailableFeatures.containsKey(name);
2340         }
2341     }
2342
2343     private void checkValidCaller(int uid, int userId) {
2344         if (UserHandle.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0)
2345             return;
2346
2347         throw new SecurityException("Caller uid=" + uid
2348                 + " is not privileged to communicate with user=" + userId);
2349     }
2350
2351     @Override
2352     public int checkPermission(String permName, String pkgName) {
2353         synchronized (mPackages) {
2354             PackageParser.Package p = mPackages.get(pkgName);
2355             if (p != null && p.mExtras != null) {
2356                 PackageSetting ps = (PackageSetting)p.mExtras;
2357                 if (ps.sharedUser != null) {
2358                     if (ps.sharedUser.grantedPermissions.contains(permName)) {
2359                         return PackageManager.PERMISSION_GRANTED;
2360                     }
2361                 } else if (ps.grantedPermissions.contains(permName)) {
2362                     return PackageManager.PERMISSION_GRANTED;
2363                 }
2364             }
2365         }
2366         return PackageManager.PERMISSION_DENIED;
2367     }
2368
2369     @Override
2370     public int checkUidPermission(String permName, int uid) {
2371         synchronized (mPackages) {
2372             Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
2373             if (obj != null) {
2374                 GrantedPermissions gp = (GrantedPermissions)obj;
2375                 if (gp.grantedPermissions.contains(permName)) {
2376                     return PackageManager.PERMISSION_GRANTED;
2377                 }
2378             } else {
2379                 HashSet<String> perms = mSystemPermissions.get(uid);
2380                 if (perms != null && perms.contains(permName)) {
2381                     return PackageManager.PERMISSION_GRANTED;
2382                 }
2383             }
2384         }
2385         return PackageManager.PERMISSION_DENIED;
2386     }
2387
2388     /**
2389      * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS
2390      * or INTERACT_ACROSS_USERS_FULL permissions, if the userid is not for the caller.
2391      * @param checkShell TODO(yamasani):
2392      * @param message the message to log on security exception
2393      */
2394     void enforceCrossUserPermission(int callingUid, int userId, boolean requireFullPermission,
2395             boolean checkShell, String message) {
2396         if (userId < 0) {
2397             throw new IllegalArgumentException("Invalid userId " + userId);
2398         }
2399         if (checkShell) {
2400             enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId);
2401         }
2402         if (userId == UserHandle.getUserId(callingUid)) return;
2403         if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
2404             if (requireFullPermission) {
2405                 mContext.enforceCallingOrSelfPermission(
2406                         android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
2407             } else {
2408                 try {
2409                     mContext.enforceCallingOrSelfPermission(
2410                             android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
2411                 } catch (SecurityException se) {
2412                     mContext.enforceCallingOrSelfPermission(
2413                             android.Manifest.permission.INTERACT_ACROSS_USERS, message);
2414                 }
2415             }
2416         }
2417     }
2418
2419     void enforceShellRestriction(String restriction, int callingUid, int userHandle) {
2420         if (callingUid == Process.SHELL_UID) {
2421             if (userHandle >= 0
2422                     && sUserManager.hasUserRestriction(restriction, userHandle)) {
2423                 throw new SecurityException("Shell does not have permission to access user "
2424                         + userHandle);
2425             } else if (userHandle < 0) {
2426                 Slog.e(TAG, "Unable to check shell permission for user " + userHandle + "\n\t"
2427                         + Debug.getCallers(3));
2428             }
2429         }
2430     }
2431
2432     private BasePermission findPermissionTreeLP(String permName) {
2433         for(BasePermission bp : mSettings.mPermissionTrees.values()) {
2434             if (permName.startsWith(bp.name) &&
2435                     permName.length() > bp.name.length() &&
2436                     permName.charAt(bp.name.length()) == '.') {
2437                 return bp;
2438             }
2439         }
2440         return null;
2441     }
2442
2443     private BasePermission checkPermissionTreeLP(String permName) {
2444         if (permName != null) {
2445             BasePermission bp = findPermissionTreeLP(permName);
2446             if (bp != null) {
2447                 if (bp.uid == UserHandle.getAppId(Binder.getCallingUid())) {
2448                     return bp;
2449                 }
2450                 throw new SecurityException("Calling uid "
2451                         + Binder.getCallingUid()
2452                         + " is not allowed to add to permission tree "
2453                         + bp.name + " owned by uid " + bp.uid);
2454             }
2455         }
2456         throw new SecurityException("No permission tree found for " + permName);
2457     }
2458
2459     static boolean compareStrings(CharSequence s1, CharSequence s2) {
2460         if (s1 == null) {
2461             return s2 == null;
2462         }
2463         if (s2 == null) {
2464             return false;
2465         }
2466         if (s1.getClass() != s2.getClass()) {
2467             return false;
2468         }
2469         return s1.equals(s2);
2470     }
2471     
2472     static boolean comparePermissionInfos(PermissionInfo pi1, PermissionInfo pi2) {
2473         if (pi1.icon != pi2.icon) return false;
2474         if (pi1.logo != pi2.logo) return false;
2475         if (pi1.protectionLevel != pi2.protectionLevel) return false;
2476         if (!compareStrings(pi1.name, pi2.name)) return false;
2477         if (!compareStrings(pi1.nonLocalizedLabel, pi2.nonLocalizedLabel)) return false;
2478         // We'll take care of setting this one.
2479         if (!compareStrings(pi1.packageName, pi2.packageName)) return false;
2480         // These are not currently stored in settings.
2481         //if (!compareStrings(pi1.group, pi2.group)) return false;
2482         //if (!compareStrings(pi1.nonLocalizedDescription, pi2.nonLocalizedDescription)) return false;
2483         //if (pi1.labelRes != pi2.labelRes) return false;
2484         //if (pi1.descriptionRes != pi2.descriptionRes) return false;
2485         return true;
2486     }
2487
2488     int permissionInfoFootprint(PermissionInfo info) {
2489         int size = info.name.length();
2490         if (info.nonLocalizedLabel != null) size += info.nonLocalizedLabel.length();
2491         if (info.nonLocalizedDescription != null) size += info.nonLocalizedDescription.length();
2492         return size;
2493     }
2494
2495     int calculateCurrentPermissionFootprintLocked(BasePermission tree) {
2496         int size = 0;
2497         for (BasePermission perm : mSettings.mPermissions.values()) {
2498             if (perm.uid == tree.uid) {
2499                 size += perm.name.length() + permissionInfoFootprint(perm.perm.info);
2500             }
2501         }
2502         return size;
2503     }
2504
2505     void enforcePermissionCapLocked(PermissionInfo info, BasePermission tree) {
2506         // We calculate the max size of permissions defined by this uid and throw
2507         // if that plus the size of 'info' would exceed our stated maximum.
2508         if (tree.uid != Process.SYSTEM_UID) {
2509             final int curTreeSize = calculateCurrentPermissionFootprintLocked(tree);
2510             if (curTreeSize + permissionInfoFootprint(info) > MAX_PERMISSION_TREE_FOOTPRINT) {
2511                 throw new SecurityException("Permission tree size cap exceeded");
2512             }
2513         }
2514     }
2515
2516     boolean addPermissionLocked(PermissionInfo info, boolean async) {
2517         if (info.labelRes == 0 && info.nonLocalizedLabel == null) {
2518             throw new SecurityException("Label must be specified in permission");
2519         }
2520         BasePermission tree = checkPermissionTreeLP(info.name);
2521         BasePermission bp = mSettings.mPermissions.get(info.name);
2522         boolean added = bp == null;
2523         boolean changed = true;
2524         int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel);
2525         if (added) {
2526             enforcePermissionCapLocked(info, tree);
2527             bp = new BasePermission(info.name, tree.sourcePackage,
2528                     BasePermission.TYPE_DYNAMIC);
2529         } else if (bp.type != BasePermission.TYPE_DYNAMIC) {
2530             throw new SecurityException(
2531                     "Not allowed to modify non-dynamic permission "
2532                     + info.name);
2533         } else {
2534             if (bp.protectionLevel == fixedLevel
2535                     && bp.perm.owner.equals(tree.perm.owner)
2536                     && bp.uid == tree.uid
2537                     && comparePermissionInfos(bp.perm.info, info)) {
2538                 changed = false;
2539             }
2540         }
2541         bp.protectionLevel = fixedLevel;
2542         info = new PermissionInfo(info);
2543         info.protectionLevel = fixedLevel;
2544         bp.perm = new PackageParser.Permission(tree.perm.owner, info);
2545         bp.perm.info.packageName = tree.perm.info.packageName;
2546         bp.uid = tree.uid;
2547         if (added) {
2548             mSettings.mPermissions.put(info.name, bp);
2549         }
2550         if (changed) {
2551             if (!async) {
2552                 mSettings.writeLPr();
2553             } else {
2554                 scheduleWriteSettingsLocked();
2555             }
2556         }
2557         return added;
2558     }
2559
2560     @Override
2561     public boolean addPermission(PermissionInfo info) {
2562         synchronized (mPackages) {
2563             return addPermissionLocked(info, false);
2564         }
2565     }
2566
2567     @Override
2568     public boolean addPermissionAsync(PermissionInfo info) {
2569         synchronized (mPackages) {
2570             return addPermissionLocked(info, true);
2571         }
2572     }
2573
2574     @Override
2575     public void removePermission(String name) {
2576         synchronized (mPackages) {
2577             checkPermissionTreeLP(name);
2578             BasePermission bp = mSettings.mPermissions.get(name);
2579             if (bp != null) {
2580                 if (bp.type != BasePermission.TYPE_DYNAMIC) {
2581                     throw new SecurityException(
2582                             "Not allowed to modify non-dynamic permission "
2583                             + name);
2584                 }
2585                 mSettings.mPermissions.remove(name);
2586                 mSettings.writeLPr();
2587             }
2588         }
2589     }
2590
2591     private static void checkGrantRevokePermissions(PackageParser.Package pkg, BasePermission bp) {
2592         int index = pkg.requestedPermissions.indexOf(bp.name);
2593         if (index == -1) {
2594             throw new SecurityException("Package " + pkg.packageName
2595                     + " has not requested permission " + bp.name);
2596         }
2597         boolean isNormal =
2598                 ((bp.protectionLevel&PermissionInfo.PROTECTION_MASK_BASE)
2599                         == PermissionInfo.PROTECTION_NORMAL);
2600         boolean isDangerous =
2601                 ((bp.protectionLevel&PermissionInfo.PROTECTION_MASK_BASE)
2602                         == PermissionInfo.PROTECTION_DANGEROUS);
2603         boolean isDevelopment =
2604                 ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0);
2605
2606         if (!isNormal && !isDangerous && !isDevelopment) {
2607             throw new SecurityException("Permission " + bp.name
2608                     + " is not a changeable permission type");
2609         }
2610
2611         if (isNormal || isDangerous) {
2612             if (pkg.requestedPermissionsRequired.get(index)) {
2613                 throw new SecurityException("Can't change " + bp.name
2614                         + ". It is required by the application");
2615             }
2616         }
2617     }
2618
2619     @Override
2620     public void grantPermission(String packageName, String permissionName) {
2621         mContext.enforceCallingOrSelfPermission(
2622                 android.Manifest.permission.GRANT_REVOKE_PERMISSIONS, null);
2623         synchronized (mPackages) {
2624             final PackageParser.Package pkg = mPackages.get(packageName);
2625             if (pkg == null) {
2626                 throw new IllegalArgumentException("Unknown package: " + packageName);
2627             }
2628             final BasePermission bp = mSettings.mPermissions.get(permissionName);
2629             if (bp == null) {
2630                 throw new IllegalArgumentException("Unknown permission: " + permissionName);
2631             }
2632
2633             checkGrantRevokePermissions(pkg, bp);
2634
2635             final PackageSetting ps = (PackageSetting) pkg.mExtras;
2636             if (ps == null) {
2637                 return;
2638             }
2639             final GrantedPermissions gp = (ps.sharedUser != null) ? ps.sharedUser : ps;
2640             if (gp.grantedPermissions.add(permissionName)) {
2641                 if (ps.haveGids) {
2642                     gp.gids = appendInts(gp.gids, bp.gids);
2643                 }
2644                 mSettings.writeLPr();
2645             }
2646         }
2647     }
2648
2649     @Override
2650     public void revokePermission(String packageName, String permissionName) {
2651         int changedAppId = -1;
2652
2653         synchronized (mPackages) {
2654             final PackageParser.Package pkg = mPackages.get(packageName);
2655             if (pkg == null) {
2656                 throw new IllegalArgumentException("Unknown package: " + packageName);
2657             }
2658             if (pkg.applicationInfo.uid != Binder.getCallingUid()) {
2659                 mContext.enforceCallingOrSelfPermission(
2660                         android.Manifest.permission.GRANT_REVOKE_PERMISSIONS, null);
2661             }
2662             final BasePermission bp = mSettings.mPermissions.get(permissionName);
2663             if (bp == null) {
2664                 throw new IllegalArgumentException("Unknown permission: " + permissionName);
2665             }
2666
2667             checkGrantRevokePermissions(pkg, bp);
2668
2669             final PackageSetting ps = (PackageSetting) pkg.mExtras;
2670             if (ps == null) {
2671                 return;
2672             }
2673             final GrantedPermissions gp = (ps.sharedUser != null) ? ps.sharedUser : ps;
2674             if (gp.grantedPermissions.remove(permissionName)) {
2675                 gp.grantedPermissions.remove(permissionName);
2676                 if (ps.haveGids) {
2677                     gp.gids = removeInts(gp.gids, bp.gids);
2678                 }
2679                 mSettings.writeLPr();
2680                 changedAppId = ps.appId;
2681             }
2682         }
2683
2684         if (changedAppId >= 0) {
2685             // We changed the perm on someone, kill its processes.
2686             IActivityManager am = ActivityManagerNative.getDefault();
2687             if (am != null) {
2688                 final int callingUserId = UserHandle.getCallingUserId();
2689                 final long ident = Binder.clearCallingIdentity();
2690                 try {
2691                     //XXX we should only revoke for the calling user's app permissions,
2692                     // but for now we impact all users.
2693                     //am.killUid(UserHandle.getUid(callingUserId, changedAppId),
2694                     //        "revoke " + permissionName);
2695                     int[] users = sUserManager.getUserIds();
2696                     for (int user : users) {
2697                         am.killUid(UserHandle.getUid(user, changedAppId),
2698                                 "revoke " + permissionName);
2699                     }
2700                 } catch (RemoteException e) {
2701                 } finally {
2702                     Binder.restoreCallingIdentity(ident);
2703                 }
2704             }
2705         }
2706     }
2707
2708     @Override
2709     public boolean isProtectedBroadcast(String actionName) {
2710         synchronized (mPackages) {
2711             return mProtectedBroadcasts.contains(actionName);
2712         }
2713     }
2714
2715     @Override
2716     public int checkSignatures(String pkg1, String pkg2) {
2717         synchronized (mPackages) {
2718             final PackageParser.Package p1 = mPackages.get(pkg1);
2719             final PackageParser.Package p2 = mPackages.get(pkg2);
2720             if (p1 == null || p1.mExtras == null
2721                     || p2 == null || p2.mExtras == null) {
2722                 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
2723             }
2724             return compareSignatures(p1.mSignatures, p2.mSignatures);
2725         }
2726     }
2727
2728     @Override
2729     public int checkUidSignatures(int uid1, int uid2) {
2730         // Map to base uids.
2731         uid1 = UserHandle.getAppId(uid1);
2732         uid2 = UserHandle.getAppId(uid2);
2733         // reader
2734         synchronized (mPackages) {
2735             Signature[] s1;
2736             Signature[] s2;
2737             Object obj = mSettings.getUserIdLPr(uid1);
2738             if (obj != null) {
2739                 if (obj instanceof SharedUserSetting) {
2740                     s1 = ((SharedUserSetting)obj).signatures.mSignatures;
2741                 } else if (obj instanceof PackageSetting) {
2742                     s1 = ((PackageSetting)obj).signatures.mSignatures;
2743                 } else {
2744                     return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
2745                 }
2746             } else {
2747                 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
2748             }
2749             obj = mSettings.getUserIdLPr(uid2);
2750             if (obj != null) {
2751                 if (obj instanceof SharedUserSetting) {
2752                     s2 = ((SharedUserSetting)obj).signatures.mSignatures;
2753                 } else if (obj instanceof PackageSetting) {
2754                     s2 = ((PackageSetting)obj).signatures.mSignatures;
2755                 } else {
2756                     return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
2757                 }
2758             } else {
2759                 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
2760             }
2761             return compareSignatures(s1, s2);
2762         }
2763     }
2764
2765     /**
2766      * Compares two sets of signatures. Returns:
2767      * <br />
2768      * {@link PackageManager#SIGNATURE_NEITHER_SIGNED}: if both signature sets are null,
2769      * <br />
2770      * {@link PackageManager#SIGNATURE_FIRST_NOT_SIGNED}: if the first signature set is null,
2771      * <br />
2772      * {@link PackageManager#SIGNATURE_SECOND_NOT_SIGNED}: if the second signature set is null,
2773      * <br />
2774      * {@link PackageManager#SIGNATURE_MATCH}: if the two signature sets are identical,
2775      * <br />
2776      * {@link PackageManager#SIGNATURE_NO_MATCH}: if the two signature sets differ.
2777      */
2778     static int compareSignatures(Signature[] s1, Signature[] s2) {
2779         if (s1 == null) {
2780             return s2 == null
2781                     ? PackageManager.SIGNATURE_NEITHER_SIGNED
2782                     : PackageManager.SIGNATURE_FIRST_NOT_SIGNED;
2783         }
2784
2785         if (s2 == null) {
2786             return PackageManager.SIGNATURE_SECOND_NOT_SIGNED;
2787         }
2788
2789         if (s1.length != s2.length) {
2790             return PackageManager.SIGNATURE_NO_MATCH;
2791         }
2792
2793         // Since both signature sets are of size 1, we can compare without HashSets.
2794         if (s1.length == 1) {
2795             return s1[0].equals(s2[0]) ?
2796                     PackageManager.SIGNATURE_MATCH :
2797                     PackageManager.SIGNATURE_NO_MATCH;
2798         }
2799
2800         HashSet<Signature> set1 = new HashSet<Signature>();
2801         for (Signature sig : s1) {
2802             set1.add(sig);
2803         }
2804         HashSet<Signature> set2 = new HashSet<Signature>();
2805         for (Signature sig : s2) {
2806             set2.add(sig);
2807         }
2808         // Make sure s2 contains all signatures in s1.
2809         if (set1.equals(set2)) {
2810             return PackageManager.SIGNATURE_MATCH;
2811         }
2812         return PackageManager.SIGNATURE_NO_MATCH;
2813     }
2814
2815     /**
2816      * If the database version for this type of package (internal storage or
2817      * external storage) is less than the version where package signatures
2818      * were updated, return true.
2819      */
2820     private boolean isCompatSignatureUpdateNeeded(PackageParser.Package scannedPkg) {
2821         return (isExternal(scannedPkg) && mSettings.isExternalDatabaseVersionOlderThan(
2822                 DatabaseVersion.SIGNATURE_END_ENTITY))
2823                 || (!isExternal(scannedPkg) && mSettings.isInternalDatabaseVersionOlderThan(
2824                         DatabaseVersion.SIGNATURE_END_ENTITY));
2825     }
2826
2827     /**
2828      * Used for backward compatibility to make sure any packages with
2829      * certificate chains get upgraded to the new style. {@code existingSigs}
2830      * will be in the old format (since they were stored on disk from before the
2831      * system upgrade) and {@code scannedSigs} will be in the newer format.
2832      */
2833     private int compareSignaturesCompat(PackageSignatures existingSigs,
2834             PackageParser.Package scannedPkg) {
2835         if (!isCompatSignatureUpdateNeeded(scannedPkg)) {
2836             return PackageManager.SIGNATURE_NO_MATCH;
2837         }
2838
2839         HashSet<Signature> existingSet = new HashSet<Signature>();
2840         for (Signature sig : existingSigs.mSignatures) {
2841             existingSet.add(sig);
2842         }
2843         HashSet<Signature> scannedCompatSet = new HashSet<Signature>();
2844         for (Signature sig : scannedPkg.mSignatures) {
2845             try {
2846                 Signature[] chainSignatures = sig.getChainSignatures();
2847                 for (Signature chainSig : chainSignatures) {
2848                     scannedCompatSet.add(chainSig);
2849                 }
2850             } catch (CertificateEncodingException e) {
2851                 scannedCompatSet.add(sig);
2852             }
2853         }
2854         /*
2855          * Make sure the expanded scanned set contains all signatures in the
2856          * existing one.
2857          */
2858         if (scannedCompatSet.equals(existingSet)) {
2859             // Migrate the old signatures to the new scheme.
2860             existingSigs.assignSignatures(scannedPkg.mSignatures);
2861             // The new KeySets will be re-added later in the scanning process.
2862             synchronized (mPackages) {
2863                 mSettings.mKeySetManagerService.removeAppKeySetDataLPw(scannedPkg.packageName);
2864             }
2865             return PackageManager.SIGNATURE_MATCH;
2866         }
2867         return PackageManager.SIGNATURE_NO_MATCH;
2868     }
2869
2870     @Override
2871     public String[] getPackagesForUid(int uid) {
2872         uid = UserHandle.getAppId(uid);
2873         // reader
2874         synchronized (mPackages) {
2875             Object obj = mSettings.getUserIdLPr(uid);
2876             if (obj instanceof SharedUserSetting) {
2877                 final SharedUserSetting sus = (SharedUserSetting) obj;
2878                 final int N = sus.packages.size();
2879                 final String[] res = new String[N];
2880                 final Iterator<PackageSetting> it = sus.packages.iterator();
2881                 int i = 0;
2882                 while (it.hasNext()) {
2883                     res[i++] = it.next().name;
2884                 }
2885                 return res;
2886             } else if (obj instanceof PackageSetting) {
2887                 final PackageSetting ps = (PackageSetting) obj;
2888                 return new String[] { ps.name };
2889             }
2890         }
2891         return null;
2892     }
2893
2894     @Override
2895     public String getNameForUid(int uid) {
2896         // reader
2897         synchronized (mPackages) {
2898             Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
2899             if (obj instanceof SharedUserSetting) {
2900                 final SharedUserSetting sus = (SharedUserSetting) obj;
2901                 return sus.name + ":" + sus.userId;
2902             } else if (obj instanceof PackageSetting) {
2903                 final PackageSetting ps = (PackageSetting) obj;
2904                 return ps.name;
2905             }
2906         }
2907         return null;
2908     }
2909
2910     @Override
2911     public int getUidForSharedUser(String sharedUserName) {
2912         if(sharedUserName == null) {
2913             return -1;
2914         }
2915         // reader
2916         synchronized (mPackages) {
2917             final SharedUserSetting suid = mSettings.getSharedUserLPw(sharedUserName, 0, false);
2918             if (suid == null) {
2919                 return -1;
2920             }
2921             return suid.userId;
2922         }
2923     }
2924
2925     @Override
2926     public int getFlagsForUid(int uid) {
2927         synchronized (mPackages) {
2928             Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
2929             if (obj instanceof SharedUserSetting) {
2930                 final SharedUserSetting sus = (SharedUserSetting) obj;
2931                 return sus.pkgFlags;
2932             } else if (obj instanceof PackageSetting) {
2933                 final PackageSetting ps = (PackageSetting) obj;
2934                 return ps.pkgFlags;
2935             }
2936         }
2937         return 0;
2938     }
2939
2940     @Override
2941     public boolean isUidPrivileged(int uid) {
2942         uid = UserHandle.getAppId(uid);
2943         // reader
2944         synchronized (mPackages) {
2945             Object obj = mSettings.getUserIdLPr(uid);
2946             if (obj instanceof SharedUserSetting) {
2947                 final SharedUserSetting sus = (SharedUserSetting) obj;
2948                 final Iterator<PackageSetting> it = sus.packages.iterator();
2949                 while (it.hasNext()) {
2950                     if (it.next().isPrivileged()) {
2951                         return true;
2952                     }
2953                 }
2954             } else if (obj instanceof PackageSetting) {
2955                 final PackageSetting ps = (PackageSetting) obj;
2956                 return ps.isPrivileged();
2957             }
2958         }
2959         return false;
2960     }
2961
2962     @Override
2963     public String[] getAppOpPermissionPackages(String permissionName) {
2964         synchronized (mPackages) {
2965             ArraySet<String> pkgs = mAppOpPermissionPackages.get(permissionName);
2966             if (pkgs == null) {
2967                 return null;
2968             }
2969             return pkgs.toArray(new String[pkgs.size()]);
2970         }
2971     }
2972
2973     @Override
2974     public ResolveInfo resolveIntent(Intent intent, String resolvedType,
2975             int flags, int userId) {
2976         if (!sUserManager.exists(userId)) return null;
2977         enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "resolve intent");
2978         List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId);
2979         return chooseBestActivity(intent, resolvedType, flags, query, userId);
2980     }
2981
2982     @Override
2983     public void setLastChosenActivity(Intent intent, String resolvedType, int flags,
2984             IntentFilter filter, int match, ComponentName activity) {
2985         final int userId = UserHandle.getCallingUserId();
2986         if (DEBUG_PREFERRED) {
2987             Log.v(TAG, "setLastChosenActivity intent=" + intent
2988                 + " resolvedType=" + resolvedType
2989                 + " flags=" + flags
2990                 + " filter=" + filter
2991                 + " match=" + match
2992                 + " activity=" + activity);
2993             filter.dump(new PrintStreamPrinter(System.out), "    ");
2994         }
2995         intent.setComponent(null);
2996         List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId);
2997         // Find any earlier preferred or last chosen entries and nuke them
2998         findPreferredActivity(intent, resolvedType,
2999                 flags, query, 0, false, true, false, userId);
3000         // Add the new activity as the last chosen for this filter
3001         addPreferredActivityInternal(filter, match, null, activity, false, userId,
3002                 "Setting last chosen");
3003     }
3004
3005     @Override
3006     public ResolveInfo getLastChosenActivity(Intent intent, String resolvedType, int flags) {
3007         final int userId = UserHandle.getCallingUserId();
3008         if (DEBUG_PREFERRED) Log.v(TAG, "Querying last chosen activity for " + intent);
3009         List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId);
3010         return findPreferredActivity(intent, resolvedType, flags, query, 0,
3011                 false, false, false, userId);
3012     }
3013
3014     private ResolveInfo chooseBestActivity(Intent intent, String resolvedType,
3015             int flags, List<ResolveInfo> query, int userId) {
3016         if (query != null) {
3017             final int N = query.size();
3018             if (N == 1) {
3019                 return query.get(0);
3020             } else if (N > 1) {
3021                 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3022                 // If there is more than one activity with the same priority,
3023                 // then let the user decide between them.
3024                 ResolveInfo r0 = query.get(0);
3025                 ResolveInfo r1 = query.get(1);
3026                 if (DEBUG_INTENT_MATCHING || debug) {
3027                     Slog.v(TAG, r0.activityInfo.name + "=" + r0.priority + " vs "
3028                             + r1.activityInfo.name + "=" + r1.priority);
3029                 }
3030                 // If the first activity has a higher priority, or a different
3031                 // default, then it is always desireable to pick it.
3032                 if (r0.priority != r1.priority
3033                         || r0.preferredOrder != r1.preferredOrder
3034                         || r0.isDefault != r1.isDefault) {
3035                     return query.get(0);
3036                 }
3037                 // If we have saved a preference for a preferred activity for
3038                 // this Intent, use that.
3039                 ResolveInfo ri = findPreferredActivity(intent, resolvedType,
3040                         flags, query, r0.priority, true, false, debug, userId);
3041                 if (ri != null) {
3042                     return ri;
3043                 }
3044                 if (userId != 0) {
3045                     ri = new ResolveInfo(mResolveInfo);
3046                     ri.activityInfo = new ActivityInfo(ri.activityInfo);
3047                     ri.activityInfo.applicationInfo = new ApplicationInfo(
3048                             ri.activityInfo.applicationInfo);
3049                     ri.activityInfo.applicationInfo.uid = UserHandle.getUid(userId,
3050                             UserHandle.getAppId(ri.activityInfo.applicationInfo.uid));
3051                     return ri;
3052                 }
3053                 return mResolveInfo;
3054             }
3055         }
3056         return null;
3057     }
3058
3059     private ResolveInfo findPersistentPreferredActivityLP(Intent intent, String resolvedType,
3060             int flags, List<ResolveInfo> query, boolean debug, int userId) {
3061         final int N = query.size();
3062         PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
3063                 .get(userId);
3064         // Get the list of persistent preferred activities that handle the intent
3065         if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for presistent preferred activities...");
3066         List<PersistentPreferredActivity> pprefs = ppir != null
3067                 ? ppir.queryIntent(intent, resolvedType,
3068                         (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId)
3069                 : null;
3070         if (pprefs != null && pprefs.size() > 0) {
3071             final int M = pprefs.size();
3072             for (int i=0; i<M; i++) {
3073                 final PersistentPreferredActivity ppa = pprefs.get(i);
3074                 if (DEBUG_PREFERRED || debug) {
3075                     Slog.v(TAG, "Checking PersistentPreferredActivity ds="
3076                             + (ppa.countDataSchemes() > 0 ? ppa.getDataScheme(0) : "<none>")
3077                             + "\n  component=" + ppa.mComponent);
3078                     ppa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
3079                 }
3080                 final ActivityInfo ai = getActivityInfo(ppa.mComponent,
3081                         flags | PackageManager.GET_DISABLED_COMPONENTS, userId);
3082                 if (DEBUG_PREFERRED || debug) {
3083                     Slog.v(TAG, "Found persistent preferred activity:");
3084                     if (ai != null) {
3085                         ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
3086                     } else {
3087                         Slog.v(TAG, "  null");
3088                     }
3089                 }
3090                 if (ai == null) {
3091                     // This previously registered persistent preferred activity
3092                     // component is no longer known. Ignore it and do NOT remove it.
3093                     continue;
3094                 }
3095                 for (int j=0; j<N; j++) {
3096                     final ResolveInfo ri = query.get(j);
3097                     if (!ri.activityInfo.applicationInfo.packageName
3098                             .equals(ai.applicationInfo.packageName)) {
3099                         continue;
3100                     }
3101                     if (!ri.activityInfo.name.equals(ai.name)) {
3102                         continue;
3103                     }
3104                     //  Found a persistent preference that can handle the intent.
3105                     if (DEBUG_PREFERRED || debug) {
3106                         Slog.v(TAG, "Returning persistent preferred activity: " +
3107                                 ri.activityInfo.packageName + "/" + ri.activityInfo.name);
3108                     }
3109                     return ri;
3110                 }
3111             }
3112         }
3113         return null;
3114     }
3115
3116     ResolveInfo findPreferredActivity(Intent intent, String resolvedType, int flags,
3117             List<ResolveInfo> query, int priority, boolean always,
3118             boolean removeMatches, boolean debug, int userId) {
3119         if (!sUserManager.exists(userId)) return null;
3120         // writer
3121         synchronized (mPackages) {
3122             if (intent.getSelector() != null) {
3123                 intent = intent.getSelector();
3124             }
3125             if (DEBUG_PREFERRED) intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION);
3126
3127             // Try to find a matching persistent preferred activity.
3128             ResolveInfo pri = findPersistentPreferredActivityLP(intent, resolvedType, flags, query,
3129                     debug, userId);
3130
3131             // If a persistent preferred activity matched, use it.
3132             if (pri != null) {
3133                 return pri;
3134             }
3135
3136             PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
3137             // Get the list of preferred activities that handle the intent
3138             if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for preferred activities...");
3139             List<PreferredActivity> prefs = pir != null
3140                     ? pir.queryIntent(intent, resolvedType,
3141                             (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId)
3142                     : null;
3143             if (prefs != null && prefs.size() > 0) {
3144                 boolean changed = false;
3145                 try {
3146                     // First figure out how good the original match set is.
3147                     // We will only allow preferred activities that came
3148                     // from the same match quality.
3149                     int match = 0;
3150
3151                     if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Figuring out best match...");
3152
3153                     final int N = query.size();
3154                     for (int j=0; j<N; j++) {
3155                         final ResolveInfo ri = query.get(j);
3156                         if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Match for " + ri.activityInfo
3157                                 + ": 0x" + Integer.toHexString(match));
3158                         if (ri.match > match) {
3159                             match = ri.match;
3160                         }
3161                     }
3162
3163                     if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Best match: 0x"
3164                             + Integer.toHexString(match));
3165
3166                     match &= IntentFilter.MATCH_CATEGORY_MASK;
3167                     final int M = prefs.size();
3168                     for (int i=0; i<M; i++) {
3169                         final PreferredActivity pa = prefs.get(i);
3170                         if (DEBUG_PREFERRED || debug) {
3171                             Slog.v(TAG, "Checking PreferredActivity ds="
3172                                     + (pa.countDataSchemes() > 0 ? pa.getDataScheme(0) : "<none>")
3173                                     + "\n  component=" + pa.mPref.mComponent);
3174                             pa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
3175                         }
3176                         if (pa.mPref.mMatch != match) {
3177                             if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping bad match "
3178                                     + Integer.toHexString(pa.mPref.mMatch));
3179                             continue;
3180                         }
3181                         // If it's not an "always" type preferred activity and that's what we're
3182                         // looking for, skip it.
3183                         if (always && !pa.mPref.mAlways) {
3184                             if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping mAlways=false entry");
3185                             continue;
3186                         }
3187                         final ActivityInfo ai = getActivityInfo(pa.mPref.mComponent,
3188                                 flags | PackageManager.GET_DISABLED_COMPONENTS, userId);
3189                         if (DEBUG_PREFERRED || debug) {
3190                             Slog.v(TAG, "Found preferred activity:");
3191                             if (ai != null) {
3192                                 ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
3193                             } else {
3194                                 Slog.v(TAG, "  null");
3195                             }
3196                         }
3197                         if (ai == null) {
3198                             // This previously registered preferred activity
3199                             // component is no longer known.  Most likely an update
3200                             // to the app was installed and in the new version this
3201                             // component no longer exists.  Clean it up by removing
3202                             // it from the preferred activities list, and skip it.
3203                             Slog.w(TAG, "Removing dangling preferred activity: "
3204                                     + pa.mPref.mComponent);
3205                             pir.removeFilter(pa);
3206                             changed = true;
3207                             continue;
3208                         }
3209                         for (int j=0; j<N; j++) {
3210                             final ResolveInfo ri = query.get(j);
3211                             if (!ri.activityInfo.applicationInfo.packageName
3212                                     .equals(ai.applicationInfo.packageName)) {
3213                                 continue;
3214                             }
3215                             if (!ri.activityInfo.name.equals(ai.name)) {
3216                                 continue;
3217                             }
3218
3219                             if (removeMatches) {
3220                                 pir.removeFilter(pa);
3221                                 changed = true;
3222                                 if (DEBUG_PREFERRED) {
3223                                     Slog.v(TAG, "Removing match " + pa.mPref.mComponent);
3224                                 }
3225                                 break;
3226                             }
3227
3228                             // Okay we found a previously set preferred or last chosen app.
3229                             // If the result set is different from when this
3230                             // was created, we need to clear it and re-ask the
3231                             // user their preference, if we're looking for an "always" type entry.
3232                             if (always && !pa.mPref.sameSet(query, priority)) {
3233                                 Slog.i(TAG, "Result set changed, dropping preferred activity for "
3234                                         + intent + " type " + resolvedType);
3235                                 if (DEBUG_PREFERRED) {
3236                                     Slog.v(TAG, "Removing preferred activity since set changed "
3237                                             + pa.mPref.mComponent);
3238                                 }
3239                                 pir.removeFilter(pa);
3240                                 // Re-add the filter as a "last chosen" entry (!always)
3241                                 PreferredActivity lastChosen = new PreferredActivity(
3242                                         pa, pa.mPref.mMatch, null, pa.mPref.mComponent, false);
3243                                 pir.addFilter(lastChosen);
3244                                 changed = true;
3245                                 return null;
3246                             }
3247
3248                             // Yay! Either the set matched or we're looking for the last chosen
3249                             if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Returning preferred activity: "
3250                                     + ri.activityInfo.packageName + "/" + ri.activityInfo.name);
3251                             return ri;
3252                         }
3253                     }
3254                 } finally {
3255                     if (changed) {
3256                         if (DEBUG_PREFERRED) {
3257                             Slog.v(TAG, "Preferred activity bookkeeping changed; writing restrictions");
3258                         }
3259                         mSettings.writePackageRestrictionsLPr(userId);
3260                     }
3261                 }
3262             }
3263         }
3264         if (DEBUG_PREFERRED || debug) Slog.v(TAG, "No preferred activity to return");
3265         return null;
3266     }
3267
3268     /*
3269      * Returns if intent can be forwarded from the sourceUserId to the targetUserId
3270      */
3271     @Override
3272     public boolean canForwardTo(Intent intent, String resolvedType, int sourceUserId,
3273             int targetUserId) {
3274         mContext.enforceCallingOrSelfPermission(
3275                 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
3276         List<CrossProfileIntentFilter> matches =
3277                 getMatchingCrossProfileIntentFilters(intent, resolvedType, sourceUserId);
3278         if (matches != null) {
3279             int size = matches.size();
3280             for (int i = 0; i < size; i++) {
3281                 if (matches.get(i).getTargetUserId() == targetUserId) return true;
3282             }
3283         }
3284         return false;
3285     }
3286
3287     private List<CrossProfileIntentFilter> getMatchingCrossProfileIntentFilters(Intent intent,
3288             String resolvedType, int userId) {
3289         CrossProfileIntentResolver resolver = mSettings.mCrossProfileIntentResolvers.get(userId);
3290         if (resolver != null) {
3291             return resolver.queryIntent(intent, resolvedType, false, userId);
3292         }
3293         return null;
3294     }
3295
3296     @Override
3297     public List<ResolveInfo> queryIntentActivities(Intent intent,
3298             String resolvedType, int flags, int userId) {
3299         if (!sUserManager.exists(userId)) return Collections.emptyList();
3300         enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "query intent activities");
3301         ComponentName comp = intent.getComponent();
3302         if (comp == null) {
3303             if (intent.getSelector() != null) {
3304                 intent = intent.getSelector(); 
3305                 comp = intent.getComponent();
3306             }
3307         }
3308
3309         if (comp != null) {
3310             final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
3311             final ActivityInfo ai = getActivityInfo(comp, flags, userId);
3312             if (ai != null) {
3313                 final ResolveInfo ri = new ResolveInfo();
3314                 ri.activityInfo = ai;
3315                 list.add(ri);
3316             }
3317             return list;
3318         }
3319
3320         // reader
3321         synchronized (mPackages) {
3322             final String pkgName = intent.getPackage();
3323             if (pkgName == null) {
3324                 List<CrossProfileIntentFilter> matchingFilters =
3325                         getMatchingCrossProfileIntentFilters(intent, resolvedType, userId);
3326                 // Check for results that need to skip the current profile.
3327                 ResolveInfo resolveInfo  = querySkipCurrentProfileIntents(matchingFilters, intent,
3328                         resolvedType, flags, userId);
3329                 if (resolveInfo != null) {
3330                     List<ResolveInfo> result = new ArrayList<ResolveInfo>(1);
3331                     result.add(resolveInfo);
3332                     return result;
3333                 }
3334                 // Check for cross profile results.
3335                 resolveInfo = queryCrossProfileIntents(
3336                         matchingFilters, intent, resolvedType, flags, userId);
3337
3338                 // Check for results in the current profile.
3339                 List<ResolveInfo> result = mActivities.queryIntent(
3340                         intent, resolvedType, flags, userId);
3341                 if (resolveInfo != null) {
3342                     result.add(resolveInfo);
3343                     Collections.sort(result, mResolvePrioritySorter);
3344                 }
3345                 return result;
3346             }
3347             final PackageParser.Package pkg = mPackages.get(pkgName);
3348             if (pkg != null) {
3349                 return mActivities.queryIntentForPackage(intent, resolvedType, flags,
3350                         pkg.activities, userId);
3351             }
3352             return new ArrayList<ResolveInfo>();
3353         }
3354     }
3355
3356     private ResolveInfo querySkipCurrentProfileIntents(
3357             List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
3358             int flags, int sourceUserId) {
3359         if (matchingFilters != null) {
3360             int size = matchingFilters.size();
3361             for (int i = 0; i < size; i ++) {
3362                 CrossProfileIntentFilter filter = matchingFilters.get(i);
3363                 if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0) {
3364                     // Checking if there are activities in the target user that can handle the
3365                     // intent.
3366                     ResolveInfo resolveInfo = checkTargetCanHandle(filter, intent, resolvedType,
3367                             flags, sourceUserId);
3368                     if (resolveInfo != null) {
3369                         return resolveInfo;
3370                     }
3371                 }
3372             }
3373         }
3374         return null;
3375     }
3376
3377     // Return matching ResolveInfo if any for skip current profile intent filters.
3378     private ResolveInfo queryCrossProfileIntents(
3379             List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
3380             int flags, int sourceUserId) {
3381         if (matchingFilters != null) {
3382             // Two {@link CrossProfileIntentFilter}s can have the same targetUserId and
3383             // match the same intent. For performance reasons, it is better not to
3384             // run queryIntent twice for the same userId
3385             SparseBooleanArray alreadyTriedUserIds = new SparseBooleanArray();
3386             int size = matchingFilters.size();
3387             for (int i = 0; i < size; i++) {
3388                 CrossProfileIntentFilter filter = matchingFilters.get(i);
3389                 int targetUserId = filter.getTargetUserId();
3390                 if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) == 0
3391                         && !alreadyTriedUserIds.get(targetUserId)) {
3392                     // Checking if there are activities in the target user that can handle the
3393                     // intent.
3394                     ResolveInfo resolveInfo = checkTargetCanHandle(filter, intent, resolvedType,
3395                             flags, sourceUserId);
3396                     if (resolveInfo != null) return resolveInfo;
3397                     alreadyTriedUserIds.put(targetUserId, true);
3398                 }
3399             }
3400         }
3401         return null;
3402     }
3403
3404     private ResolveInfo checkTargetCanHandle(CrossProfileIntentFilter filter, Intent intent,
3405             String resolvedType, int flags, int sourceUserId) {
3406         List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent,
3407                 resolvedType, flags, filter.getTargetUserId());
3408         if (resultTargetUser != null && !resultTargetUser.isEmpty()) {
3409             return createForwardingResolveInfo(filter, sourceUserId, filter.getTargetUserId());
3410         }
3411         return null;
3412     }
3413
3414     private ResolveInfo createForwardingResolveInfo(IntentFilter filter,
3415             int sourceUserId, int targetUserId) {
3416         ResolveInfo forwardingResolveInfo = new ResolveInfo();
3417         String className;
3418         if (targetUserId == UserHandle.USER_OWNER) {
3419             className = FORWARD_INTENT_TO_USER_OWNER;
3420         } else {
3421             className = FORWARD_INTENT_TO_MANAGED_PROFILE;
3422         }
3423         ComponentName forwardingActivityComponentName = new ComponentName(
3424                 mAndroidApplication.packageName, className);
3425         ActivityInfo forwardingActivityInfo = getActivityInfo(forwardingActivityComponentName, 0,
3426                 sourceUserId);
3427         if (targetUserId == UserHandle.USER_OWNER) {
3428             forwardingActivityInfo.showUserIcon = UserHandle.USER_OWNER;
3429             forwardingResolveInfo.noResourceId = true;
3430         }
3431         forwardingResolveInfo.activityInfo = forwardingActivityInfo;
3432         forwardingResolveInfo.priority = 0;
3433         forwardingResolveInfo.preferredOrder = 0;
3434         forwardingResolveInfo.match = 0;
3435         forwardingResolveInfo.isDefault = true;
3436         forwardingResolveInfo.filter = filter;
3437         forwardingResolveInfo.targetUserId = targetUserId;
3438         return forwardingResolveInfo;
3439     }
3440
3441     @Override
3442     public List<ResolveInfo> queryIntentActivityOptions(ComponentName caller,
3443             Intent[] specifics, String[] specificTypes, Intent intent,
3444             String resolvedType, int flags, int userId) {
3445         if (!sUserManager.exists(userId)) return Collections.emptyList();
3446         enforceCrossUserPermission(Binder.getCallingUid(), userId, false,
3447                 false, "query intent activity options");
3448         final String resultsAction = intent.getAction();
3449
3450         List<ResolveInfo> results = queryIntentActivities(intent, resolvedType, flags
3451                 | PackageManager.GET_RESOLVED_FILTER, userId);
3452
3453         if (DEBUG_INTENT_MATCHING) {
3454             Log.v(TAG, "Query " + intent + ": " + results);
3455         }
3456
3457         int specificsPos = 0;
3458         int N;
3459
3460         // todo: note that the algorithm used here is O(N^2).  This
3461         // isn't a problem in our current environment, but if we start running
3462         // into situations where we have more than 5 or 10 matches then this
3463         // should probably be changed to something smarter...
3464
3465         // First we go through and resolve each of the specific items
3466         // that were supplied, taking care of removing any corresponding
3467         // duplicate items in the generic resolve list.
3468         if (specifics != null) {
3469             for (int i=0; i<specifics.length; i++) {
3470                 final Intent sintent = specifics[i];
3471                 if (sintent == null) {
3472                     continue;
3473                 }
3474
3475                 if (DEBUG_INTENT_MATCHING) {
3476                     Log.v(TAG, "Specific #" + i + ": " + sintent);
3477                 }
3478
3479                 String action = sintent.getAction();
3480                 if (resultsAction != null && resultsAction.equals(action)) {
3481                     // If this action was explicitly requested, then don't
3482                     // remove things that have it.
3483                     action = null;
3484                 }
3485
3486                 ResolveInfo ri = null;
3487                 ActivityInfo ai = null;
3488
3489                 ComponentName comp = sintent.getComponent();
3490                 if (comp == null) {
3491                     ri = resolveIntent(
3492                         sintent,
3493                         specificTypes != null ? specificTypes[i] : null,
3494                             flags, userId);
3495                     if (ri == null) {
3496                         continue;
3497                     }
3498                     if (ri == mResolveInfo) {
3499                         // ACK!  Must do something better with this.
3500                     }
3501                     ai = ri.activityInfo;
3502                     comp = new ComponentName(ai.applicationInfo.packageName,
3503                             ai.name);
3504                 } else {
3505                     ai = getActivityInfo(comp, flags, userId);
3506                     if (ai == null) {
3507                         continue;
3508                     }
3509                 }
3510
3511                 // Look for any generic query activities that are duplicates
3512                 // of this specific one, and remove them from the results.
3513                 if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Specific #" + i + ": " + ai);
3514                 N = results.size();
3515                 int j;
3516                 for (j=specificsPos; j<N; j++) {
3517                     ResolveInfo sri = results.get(j);
3518                     if ((sri.activityInfo.name.equals(comp.getClassName())
3519                             && sri.activityInfo.applicationInfo.packageName.equals(
3520                                     comp.getPackageName()))
3521                         || (action != null && sri.filter.matchAction(action))) {
3522                         results.remove(j);
3523                         if (DEBUG_INTENT_MATCHING) Log.v(
3524                             TAG, "Removing duplicate item from " + j
3525                             + " due to specific " + specificsPos);
3526                         if (ri == null) {
3527                             ri = sri;
3528                         }
3529                         j--;
3530                         N--;
3531                     }
3532                 }
3533
3534                 // Add this specific item to its proper place.
3535                 if (ri == null) {
3536                     ri = new ResolveInfo();
3537                     ri.activityInfo = ai;
3538                 }
3539                 results.add(specificsPos, ri);
3540                 ri.specificIndex = i;
3541                 specificsPos++;
3542             }
3543         }
3544
3545         // Now we go through the remaining generic results and remove any
3546         // duplicate actions that are found here.
3547         N = results.size();
3548         for (int i=specificsPos; i<N-1; i++) {
3549             final ResolveInfo rii = results.get(i);
3550             if (rii.filter == null) {
3551                 continue;
3552             }
3553
3554             // Iterate over all of the actions of this result's intent
3555             // filter...  typically this should be just one.
3556             final Iterator<String> it = rii.filter.actionsIterator();
3557             if (it == null) {
3558                 continue;
3559             }
3560             while (it.hasNext()) {
3561                 final String action = it.next();
3562                 if (resultsAction != null && resultsAction.equals(action)) {
3563                     // If this action was explicitly requested, then don't
3564                     // remove things that have it.
3565                     continue;
3566                 }
3567                 for (int j=i+1; j<N; j++) {
3568                     final ResolveInfo rij = results.get(j);
3569                     if (rij.filter != null && rij.filter.hasAction(action)) {
3570                         results.remove(j);
3571                         if (DEBUG_INTENT_MATCHING) Log.v(
3572                             TAG, "Removing duplicate item from " + j
3573                             + " due to action " + action + " at " + i);
3574                         j--;
3575                         N--;
3576                     }
3577                 }
3578             }
3579
3580             // If the caller didn't request filter information, drop it now
3581             // so we don't have to marshall/unmarshall it.
3582             if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
3583                 rii.filter = null;
3584             }
3585         }
3586
3587         // Filter out the caller activity if so requested.
3588         if (caller != null) {
3589             N = results.size();
3590             for (int i=0; i<N; i++) {
3591                 ActivityInfo ainfo = results.get(i).activityInfo;
3592                 if (caller.getPackageName().equals(ainfo.applicationInfo.packageName)
3593                         && caller.getClassName().equals(ainfo.name)) {
3594                     results.remove(i);
3595                     break;
3596                 }
3597             }
3598         }
3599
3600         // If the caller didn't request filter information,
3601         // drop them now so we don't have to
3602         // marshall/unmarshall it.
3603         if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
3604             N = results.size();
3605             for (int i=0; i<N; i++) {
3606                 results.get(i).filter = null;
3607             }
3608         }
3609
3610         if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Result: " + results);
3611         return results;
3612     }
3613
3614     @Override
3615     public List<ResolveInfo> queryIntentReceivers(Intent intent, String resolvedType, int flags,
3616             int userId) {
3617         if (!sUserManager.exists(userId)) return Collections.emptyList();
3618         ComponentName comp = intent.getComponent();
3619         if (comp == null) {
3620             if (intent.getSelector() != null) {
3621                 intent = intent.getSelector(); 
3622                 comp = intent.getComponent();
3623             }
3624         }
3625         if (comp != null) {
3626             List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
3627             ActivityInfo ai = getReceiverInfo(comp, flags, userId);
3628             if (ai != null) {
3629                 ResolveInfo ri = new ResolveInfo();
3630                 ri.activityInfo = ai;
3631                 list.add(ri);
3632             }
3633             return list;
3634         }
3635
3636         // reader
3637         synchronized (mPackages) {
3638             String pkgName = intent.getPackage();
3639             if (pkgName == null) {
3640                 return mReceivers.queryIntent(intent, resolvedType, flags, userId);
3641             }
3642             final PackageParser.Package pkg = mPackages.get(pkgName);
3643             if (pkg != null) {
3644                 return mReceivers.queryIntentForPackage(intent, resolvedType, flags, pkg.receivers,
3645                         userId);
3646             }
3647             return null;
3648         }
3649     }
3650
3651     @Override
3652     public ResolveInfo resolveService(Intent intent, String resolvedType, int flags, int userId) {
3653         List<ResolveInfo> query = queryIntentServices(intent, resolvedType, flags, userId);
3654         if (!sUserManager.exists(userId)) return null;
3655         if (query != null) {
3656             if (query.size() >= 1) {
3657                 // If there is more than one service with the same priority,
3658                 // just arbitrarily pick the first one.
3659                 return query.get(0);
3660             }
3661         }
3662         return null;
3663     }
3664
3665     @Override
3666     public List<ResolveInfo> queryIntentServices(Intent intent, String resolvedType, int flags,
3667             int userId) {
3668         if (!sUserManager.exists(userId)) return Collections.emptyList();
3669         ComponentName comp = intent.getComponent();
3670         if (comp == null) {
3671             if (intent.getSelector() != null) {
3672                 intent = intent.getSelector(); 
3673                 comp = intent.getComponent();
3674             }
3675         }
3676         if (comp != null) {
3677             final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
3678             final ServiceInfo si = getServiceInfo(comp, flags, userId);
3679             if (si != null) {
3680                 final ResolveInfo ri = new ResolveInfo();
3681                 ri.serviceInfo = si;
3682                 list.add(ri);
3683             }
3684             return list;
3685         }
3686
3687         // reader
3688         synchronized (mPackages) {
3689             String pkgName = intent.getPackage();
3690             if (pkgName == null) {
3691                 return mServices.queryIntent(intent, resolvedType, flags, userId);
3692             }
3693             final PackageParser.Package pkg = mPackages.get(pkgName);
3694             if (pkg != null) {
3695                 return mServices.queryIntentForPackage(intent, resolvedType, flags, pkg.services,
3696                         userId);
3697             }
3698             return null;
3699         }
3700     }
3701
3702     @Override
3703     public List<ResolveInfo> queryIntentContentProviders(
3704             Intent intent, String resolvedType, int flags, int userId) {
3705         if (!sUserManager.exists(userId)) return Collections.emptyList();
3706         ComponentName comp = intent.getComponent();
3707         if (comp == null) {
3708             if (intent.getSelector() != null) {
3709                 intent = intent.getSelector();
3710                 comp = intent.getComponent();
3711             }
3712         }
3713         if (comp != null) {
3714             final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
3715             final ProviderInfo pi = getProviderInfo(comp, flags, userId);
3716             if (pi != null) {
3717                 final ResolveInfo ri = new ResolveInfo();
3718                 ri.providerInfo = pi;
3719                 list.add(ri);
3720             }
3721             return list;
3722         }
3723
3724         // reader
3725         synchronized (mPackages) {
3726             String pkgName = intent.getPackage();
3727             if (pkgName == null) {
3728                 return mProviders.queryIntent(intent, resolvedType, flags, userId);
3729             }
3730             final PackageParser.Package pkg = mPackages.get(pkgName);
3731             if (pkg != null) {
3732                 return mProviders.queryIntentForPackage(
3733                         intent, resolvedType, flags, pkg.providers, userId);
3734             }
3735             return null;
3736         }
3737     }
3738
3739     @Override
3740     public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) {
3741         final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0;
3742
3743         enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, "get installed packages");
3744
3745         // writer
3746         synchronized (mPackages) {
3747             ArrayList<PackageInfo> list;
3748             if (listUninstalled) {
3749                 list = new ArrayList<PackageInfo>(mSettings.mPackages.size());
3750                 for (PackageSetting ps : mSettings.mPackages.values()) {
3751                     PackageInfo pi;
3752                     if (ps.pkg != null) {
3753                         pi = generatePackageInfo(ps.pkg, flags, userId);
3754                     } else {
3755                         pi = generatePackageInfoFromSettingsLPw(ps.name, flags, userId);
3756                     }
3757                     if (pi != null) {
3758                         list.add(pi);
3759                     }
3760                 }
3761             } else {
3762                 list = new ArrayList<PackageInfo>(mPackages.size());
3763                 for (PackageParser.Package p : mPackages.values()) {
3764                     PackageInfo pi = generatePackageInfo(p, flags, userId);
3765                     if (pi != null) {
3766                         list.add(pi);
3767                     }
3768                 }
3769             }
3770
3771             return new ParceledListSlice<PackageInfo>(list);
3772         }
3773     }
3774
3775     private void addPackageHoldingPermissions(ArrayList<PackageInfo> list, PackageSetting ps,
3776             String[] permissions, boolean[] tmp, int flags, int userId) {
3777         int numMatch = 0;
3778         final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps;
3779         for (int i=0; i<permissions.length; i++) {
3780             if (gp.grantedPermissions.contains(permissions[i])) {
3781                 tmp[i] = true;
3782                 numMatch++;
3783             } else {
3784                 tmp[i] = false;
3785             }
3786         }
3787         if (numMatch == 0) {
3788             return;
3789         }
3790         PackageInfo pi;
3791         if (ps.pkg != null) {
3792             pi = generatePackageInfo(ps.pkg, flags, userId);
3793         } else {
3794             pi = generatePackageInfoFromSettingsLPw(ps.name, flags, userId);
3795         }
3796         // The above might return null in cases of uninstalled apps or install-state
3797         // skew across users/profiles.
3798         if (pi != null) {
3799             if ((flags&PackageManager.GET_PERMISSIONS) == 0) {
3800                 if (numMatch == permissions.length) {
3801                     pi.requestedPermissions = permissions;
3802                 } else {
3803                     pi.requestedPermissions = new String[numMatch];
3804                     numMatch = 0;
3805                     for (int i=0; i<permissions.length; i++) {
3806                         if (tmp[i]) {
3807                             pi.requestedPermissions[numMatch] = permissions[i];
3808                             numMatch++;
3809                         }
3810                     }
3811                 }
3812             }
3813             list.add(pi);
3814         }
3815     }
3816
3817     @Override
3818     public ParceledListSlice<PackageInfo> getPackagesHoldingPermissions(
3819             String[] permissions, int flags, int userId) {
3820         if (!sUserManager.exists(userId)) return null;
3821         final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0;
3822
3823         // writer
3824         synchronized (mPackages) {
3825             ArrayList<PackageInfo> list = new ArrayList<PackageInfo>();
3826             boolean[] tmpBools = new boolean[permissions.length];
3827             if (listUninstalled) {
3828                 for (PackageSetting ps : mSettings.mPackages.values()) {
3829                     addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags, userId);
3830                 }
3831             } else {
3832                 for (PackageParser.Package pkg : mPackages.values()) {
3833                     PackageSetting ps = (PackageSetting)pkg.mExtras;
3834                     if (ps != null) {
3835                         addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags,
3836                                 userId);
3837                     }
3838                 }
3839             }
3840
3841             return new ParceledListSlice<PackageInfo>(list);
3842         }
3843     }
3844
3845     @Override
3846     public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags, int userId) {
3847         if (!sUserManager.exists(userId)) return null;
3848         final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0;
3849
3850         // writer
3851         synchronized (mPackages) {
3852             ArrayList<ApplicationInfo> list;
3853             if (listUninstalled) {
3854                 list = new ArrayList<ApplicationInfo>(mSettings.mPackages.size());
3855                 for (PackageSetting ps : mSettings.mPackages.values()) {
3856                     ApplicationInfo ai;
3857                     if (ps.pkg != null) {
3858                         ai = PackageParser.generateApplicationInfo(ps.pkg, flags,
3859                                 ps.readUserState(userId), userId);
3860                     } else {
3861                         ai = generateApplicationInfoFromSettingsLPw(ps.name, flags, userId);
3862                     }
3863                     if (ai != null) {
3864                         list.add(ai);
3865                     }
3866                 }
3867             } else {
3868                 list = new ArrayList<ApplicationInfo>(mPackages.size());
3869                 for (PackageParser.Package p : mPackages.values()) {
3870                     if (p.mExtras != null) {
3871                         ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
3872                                 ((PackageSetting)p.mExtras).readUserState(userId), userId);
3873                         if (ai != null) {
3874                             list.add(ai);
3875                         }
3876                     }
3877                 }
3878             }
3879
3880             return new ParceledListSlice<ApplicationInfo>(list);
3881         }
3882     }
3883
3884     public List<ApplicationInfo> getPersistentApplications(int flags) {
3885         final ArrayList<ApplicationInfo> finalList = new ArrayList<ApplicationInfo>();
3886
3887         // reader
3888         synchronized (mPackages) {
3889             final Iterator<PackageParser.Package> i = mPackages.values().iterator();
3890             final int userId = UserHandle.getCallingUserId();
3891             while (i.hasNext()) {
3892                 final PackageParser.Package p = i.next();
3893                 if (p.applicationInfo != null
3894                         && (p.applicationInfo.flags&ApplicationInfo.FLAG_PERSISTENT) != 0
3895                         && (!mSafeMode || isSystemApp(p))) {
3896                     PackageSetting ps = mSettings.mPackages.get(p.packageName);
3897                     if (ps != null) {
3898                         ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
3899                                 ps.readUserState(userId), userId);
3900                         if (ai != null) {
3901                             finalList.add(ai);
3902                         }
3903                     }
3904                 }
3905             }
3906         }
3907
3908         return finalList;
3909     }
3910
3911     @Override
3912     public ProviderInfo resolveContentProvider(String name, int flags, int userId) {
3913         if (!sUserManager.exists(userId)) return null;
3914         // reader
3915         synchronized (mPackages) {
3916             final PackageParser.Provider provider = mProvidersByAuthority.get(name);
3917             PackageSetting ps = provider != null
3918                     ? mSettings.mPackages.get(provider.owner.packageName)
3919                     : null;
3920             return ps != null
3921                     && mSettings.isEnabledLPr(provider.info, flags, userId)
3922                     && (!mSafeMode || (provider.info.applicationInfo.flags
3923                             &ApplicationInfo.FLAG_SYSTEM) != 0)
3924                     ? PackageParser.generateProviderInfo(provider, flags,
3925                             ps.readUserState(userId), userId)
3926                     : null;
3927         }
3928     }
3929
3930     /**
3931      * @deprecated
3932      */
3933     @Deprecated
3934     public void querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo) {
3935         // reader
3936         synchronized (mPackages) {
3937             final Iterator<Map.Entry<String, PackageParser.Provider>> i = mProvidersByAuthority
3938                     .entrySet().iterator();
3939             final int userId = UserHandle.getCallingUserId();
3940             while (i.hasNext()) {
3941                 Map.Entry<String, PackageParser.Provider> entry = i.next();
3942                 PackageParser.Provider p = entry.getValue();
3943                 PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
3944
3945                 if (ps != null && p.syncable
3946                         && (!mSafeMode || (p.info.applicationInfo.flags
3947                                 &ApplicationInfo.FLAG_SYSTEM) != 0)) {
3948                     ProviderInfo info = PackageParser.generateProviderInfo(p, 0,
3949                             ps.readUserState(userId), userId);
3950                     if (info != null) {
3951                         outNames.add(entry.getKey());
3952                         outInfo.add(info);
3953                     }
3954                 }
3955             }
3956         }
3957     }
3958
3959     @Override
3960     public List<ProviderInfo> queryContentProviders(String processName,
3961             int uid, int flags) {
3962         ArrayList<ProviderInfo> finalList = null;
3963         // reader
3964         synchronized (mPackages) {
3965             final Iterator<PackageParser.Provider> i = mProviders.mProviders.values().iterator();
3966             final int userId = processName != null ?
3967                     UserHandle.getUserId(uid) : UserHandle.getCallingUserId();
3968             while (i.hasNext()) {
3969                 final PackageParser.Provider p = i.next();
3970                 PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
3971                 if (ps != null && p.info.authority != null
3972                         && (processName == null
3973                                 || (p.info.processName.equals(processName)
3974                                         && UserHandle.isSameApp(p.info.applicationInfo.uid, uid)))
3975                         && mSettings.isEnabledLPr(p.info, flags, userId)
3976                         && (!mSafeMode
3977                                 || (p.info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0)) {
3978                     if (finalList == null) {
3979                         finalList = new ArrayList<ProviderInfo>(3);
3980                     }
3981                     ProviderInfo info = PackageParser.generateProviderInfo(p, flags,
3982                             ps.readUserState(userId), userId);
3983                     if (info != null) {
3984                         finalList.add(info);
3985                     }
3986                 }
3987             }
3988         }
3989
3990         if (finalList != null) {
3991             Collections.sort(finalList, mProviderInitOrderSorter);
3992         }
3993
3994         return finalList;
3995     }
3996
3997     @Override
3998     public InstrumentationInfo getInstrumentationInfo(ComponentName name,
3999             int flags) {
4000         // reader
4001         synchronized (mPackages) {
4002             final PackageParser.Instrumentation i = mInstrumentation.get(name);
4003             return PackageParser.generateInstrumentationInfo(i, flags);
4004         }
4005     }
4006
4007     @Override
4008     public List<InstrumentationInfo> queryInstrumentation(String targetPackage,
4009             int flags) {
4010         ArrayList<InstrumentationInfo> finalList =
4011             new ArrayList<InstrumentationInfo>();
4012
4013         // reader
4014         synchronized (mPackages) {
4015             final Iterator<PackageParser.Instrumentation> i = mInstrumentation.values().iterator();
4016             while (i.hasNext()) {
4017                 final PackageParser.Instrumentation p = i.next();
4018                 if (targetPackage == null
4019                         || targetPackage.equals(p.info.targetPackage)) {
4020                     InstrumentationInfo ii = PackageParser.generateInstrumentationInfo(p,
4021                             flags);
4022                     if (ii != null) {
4023                         finalList.add(ii);
4024                     }
4025                 }
4026             }
4027         }
4028
4029         return finalList;
4030     }
4031
4032     private void createIdmapsForPackageLI(PackageParser.Package pkg) {
4033         HashMap<String, PackageParser.Package> overlays = mOverlays.get(pkg.packageName);
4034         if (overlays == null) {
4035             Slog.w(TAG, "Unable to create idmap for " + pkg.packageName + ": no overlay packages");
4036             return;
4037         }
4038         for (PackageParser.Package opkg : overlays.values()) {
4039             // Not much to do if idmap fails: we already logged the error
4040             // and we certainly don't want to abort installation of pkg simply
4041             // because an overlay didn't fit properly. For these reasons,
4042             // ignore the return value of createIdmapForPackagePairLI.
4043             createIdmapForPackagePairLI(pkg, opkg);
4044         }
4045     }
4046
4047     private boolean createIdmapForPackagePairLI(PackageParser.Package pkg,
4048             PackageParser.Package opkg) {
4049         if (!opkg.mTrustedOverlay) {
4050             Slog.w(TAG, "Skipping target and overlay pair " + pkg.baseCodePath + " and " +
4051                     opkg.baseCodePath + ": overlay not trusted");
4052             return false;
4053         }
4054         HashMap<String, PackageParser.Package> overlaySet = mOverlays.get(pkg.packageName);
4055         if (overlaySet == null) {
4056             Slog.e(TAG, "was about to create idmap for " + pkg.baseCodePath + " and " +
4057                     opkg.baseCodePath + " but target package has no known overlays");
4058             return false;
4059         }
4060         final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
4061         // TODO: generate idmap for split APKs
4062         if (mInstaller.idmap(pkg.baseCodePath, opkg.baseCodePath, sharedGid) != 0) {
4063             Slog.e(TAG, "Failed to generate idmap for " + pkg.baseCodePath + " and "
4064                     + opkg.baseCodePath);
4065             return false;
4066         }
4067         PackageParser.Package[] overlayArray =
4068             overlaySet.values().toArray(new PackageParser.Package[0]);
4069         Comparator<PackageParser.Package> cmp = new Comparator<PackageParser.Package>() {
4070             public int compare(PackageParser.Package p1, PackageParser.Package p2) {
4071                 return p1.mOverlayPriority - p2.mOverlayPriority;
4072             }
4073         };
4074         Arrays.sort(overlayArray, cmp);
4075
4076         pkg.applicationInfo.resourceDirs = new String[overlayArray.length];
4077         int i = 0;
4078         for (PackageParser.Package p : overlayArray) {
4079             pkg.applicationInfo.resourceDirs[i++] = p.baseCodePath;
4080         }
4081         return true;
4082     }
4083
4084     private void scanDirLI(File dir, int parseFlags, int scanFlags, long currentTime) {
4085         final File[] files = dir.listFiles();
4086         if (ArrayUtils.isEmpty(files)) {
4087             Log.d(TAG, "No files in app dir " + dir);
4088             return;
4089         }
4090
4091         if (DEBUG_PACKAGE_SCANNING) {
4092             Log.d(TAG, "Scanning app dir " + dir + " scanFlags=" + scanFlags
4093                     + " flags=0x" + Integer.toHexString(parseFlags));
4094         }
4095
4096         for (File file : files) {
4097             final boolean isPackage = (isApkFile(file) || file.isDirectory())
4098                     && !PackageInstallerService.isStageName(file.getName());
4099             if (!isPackage) {
4100                 // Ignore entries which are not packages
4101                 continue;
4102             }
4103             try {
4104                 scanPackageLI(file, parseFlags | PackageParser.PARSE_MUST_BE_APK,
4105                         scanFlags, currentTime, null);
4106             } catch (PackageManagerException e) {
4107                 Slog.w(TAG, "Failed to parse " + file + ": " + e.getMessage());
4108
4109                 // Delete invalid userdata apps
4110                 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM) == 0 &&
4111                         e.error == PackageManager.INSTALL_FAILED_INVALID_APK) {
4112                     logCriticalInfo(Log.WARN, "Deleting invalid package at " + file);
4113                     if (file.isDirectory()) {
4114                         FileUtils.deleteContents(file);
4115                     }
4116                     file.delete();
4117                 }
4118             }
4119         }
4120     }
4121
4122     private static File getSettingsProblemFile() {
4123         File dataDir = Environment.getDataDirectory();
4124         File systemDir = new File(dataDir, "system");
4125         File fname = new File(systemDir, "uiderrors.txt");
4126         return fname;
4127     }
4128
4129     static void reportSettingsProblem(int priority, String msg) {
4130         logCriticalInfo(priority, msg);
4131     }
4132
4133     static void logCriticalInfo(int priority, String msg) {
4134         Slog.println(priority, TAG, msg);
4135         EventLogTags.writePmCriticalInfo(msg);
4136         try {
4137             File fname = getSettingsProblemFile();
4138             FileOutputStream out = new FileOutputStream(fname, true);
4139             PrintWriter pw = new FastPrintWriter(out);
4140             SimpleDateFormat formatter = new SimpleDateFormat();
4141             String dateString = formatter.format(new Date(System.currentTimeMillis()));
4142             pw.println(dateString + ": " + msg);
4143             pw.close();
4144             FileUtils.setPermissions(
4145                     fname.toString(),
4146                     FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IROTH,
4147                     -1, -1);
4148         } catch (java.io.IOException e) {
4149         }
4150     }
4151
4152     private void collectCertificatesLI(PackageParser pp, PackageSetting ps,
4153             PackageParser.Package pkg, File srcFile, int parseFlags)
4154             throws PackageManagerException {
4155         if (ps != null
4156                 && ps.codePath.equals(srcFile)
4157                 && ps.timeStamp == srcFile.lastModified()
4158                 && !isCompatSignatureUpdateNeeded(pkg)) {
4159             long mSigningKeySetId = ps.keySetData.getProperSigningKeySet();
4160             if (ps.signatures.mSignatures != null
4161                     && ps.signatures.mSignatures.length != 0
4162                     && mSigningKeySetId != PackageKeySetData.KEYSET_UNASSIGNED) {
4163                 // Optimization: reuse the existing cached certificates
4164                 // if the package appears to be unchanged.
4165                 pkg.mSignatures = ps.signatures.mSignatures;
4166                 KeySetManagerService ksms = mSettings.mKeySetManagerService;
4167                 synchronized (mPackages) {
4168                     pkg.mSigningKeys = ksms.getPublicKeysFromKeySetLPr(mSigningKeySetId);
4169                 }
4170                 return;
4171             }
4172
4173             Slog.w(TAG, "PackageSetting for " + ps.name
4174                     + " is missing signatures.  Collecting certs again to recover them.");
4175         } else {
4176             Log.i(TAG, srcFile.toString() + " changed; collecting certs");
4177         }
4178
4179         try {
4180             pp.collectCertificates(pkg, parseFlags);
4181             pp.collectManifestDigest(pkg);
4182         } catch (PackageParserException e) {
4183             throw PackageManagerException.from(e);
4184         }
4185     }
4186
4187     /*
4188      *  Scan a package and return the newly parsed package.
4189      *  Returns null in case of errors and the error code is stored in mLastScanError
4190      */
4191     private PackageParser.Package scanPackageLI(File scanFile, int parseFlags, int scanFlags,
4192             long currentTime, UserHandle user) throws PackageManagerException {
4193         if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanFile);
4194         parseFlags |= mDefParseFlags;
4195         PackageParser pp = new PackageParser();
4196         pp.setSeparateProcesses(mSeparateProcesses);
4197         pp.setOnlyCoreApps(mOnlyCore);
4198         pp.setDisplayMetrics(mMetrics);
4199
4200         if ((scanFlags & SCAN_TRUSTED_OVERLAY) != 0) {
4201             parseFlags |= PackageParser.PARSE_TRUSTED_OVERLAY;
4202         }
4203
4204         final PackageParser.Package pkg;
4205         try {
4206             pkg = pp.parsePackage(scanFile, parseFlags);
4207         } catch (PackageParserException e) {
4208             throw PackageManagerException.from(e);
4209         }
4210
4211         PackageSetting ps = null;
4212         PackageSetting updatedPkg;
4213         // reader
4214         synchronized (mPackages) {
4215             // Look to see if we already know about this package.
4216             String oldName = mSettings.mRenamedPackages.get(pkg.packageName);
4217             if (pkg.mOriginalPackages != null && pkg.mOriginalPackages.contains(oldName)) {
4218                 // This package has been renamed to its original name.  Let's
4219                 // use that.
4220                 ps = mSettings.peekPackageLPr(oldName);
4221             }
4222             // If there was no original package, see one for the real package name.
4223             if (ps == null) {
4224                 ps = mSettings.peekPackageLPr(pkg.packageName);
4225             }
4226             // Check to see if this package could be hiding/updating a system
4227             // package.  Must look for it either under the original or real
4228             // package name depending on our state.
4229             updatedPkg = mSettings.getDisabledSystemPkgLPr(ps != null ? ps.name : pkg.packageName);
4230             if (DEBUG_INSTALL && updatedPkg != null) Slog.d(TAG, "updatedPkg = " + updatedPkg);
4231         }
4232         boolean updatedPkgBetter = false;
4233         // First check if this is a system package that may involve an update
4234         if (updatedPkg != null && (parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) {
4235             if (ps != null && !ps.codePath.equals(scanFile)) {
4236                 // The path has changed from what was last scanned...  check the
4237                 // version of the new path against what we have stored to determine
4238                 // what to do.
4239                 if (DEBUG_INSTALL) Slog.d(TAG, "Path changing from " + ps.codePath);
4240                 if (pkg.mVersionCode < ps.versionCode) {
4241                     // The system package has been updated and the code path does not match
4242                     // Ignore entry. Skip it.
4243                     logCriticalInfo(Log.INFO, "Package " + ps.name + " at " + scanFile
4244                             + " ignored: updated version " + ps.versionCode
4245                             + " better than this " + pkg.mVersionCode);
4246                     if (!updatedPkg.codePath.equals(scanFile)) {
4247                         Slog.w(PackageManagerService.TAG, "Code path for hidden system pkg : "
4248                                 + ps.name + " changing from " + updatedPkg.codePathString
4249                                 + " to " + scanFile);
4250                         updatedPkg.codePath = scanFile;
4251                         updatedPkg.codePathString = scanFile.toString();
4252                         // This is the point at which we know that the system-disk APK
4253                         // for this package has moved during a reboot (e.g. due to an OTA),
4254                         // so we need to reevaluate it for privilege policy.
4255                         if (locationIsPrivileged(scanFile)) {
4256                             updatedPkg.pkgFlags |= ApplicationInfo.FLAG_PRIVILEGED;
4257                         }
4258                     }
4259                     updatedPkg.pkg = pkg;
4260                     throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE, null);
4261                 } else {
4262                     // The current app on the system partition is better than
4263                     // what we have updated to on the data partition; switch
4264                     // back to the system partition version.
4265                     // At this point, its safely assumed that package installation for
4266                     // apps in system partition will go through. If not there won't be a working
4267                     // version of the app
4268                     // writer
4269                     synchronized (mPackages) {
4270                         // Just remove the loaded entries from package lists.
4271                         mPackages.remove(ps.name);
4272                     }
4273
4274                     logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile
4275                             + " reverting from " + ps.codePathString
4276                             + ": new version " + pkg.mVersionCode
4277                             + " better than installed " + ps.versionCode);
4278
4279                     InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
4280                             ps.codePathString, ps.resourcePathString, ps.legacyNativeLibraryPathString,
4281                             getAppDexInstructionSets(ps));
4282                     synchronized (mInstallLock) {
4283                         args.cleanUpResourcesLI();
4284                     }
4285                     synchronized (mPackages) {
4286                         mSettings.enableSystemPackageLPw(ps.name);
4287                     }
4288                     updatedPkgBetter = true;
4289                 }
4290             }
4291         }
4292
4293         if (updatedPkg != null) {
4294             // An updated system app will not have the PARSE_IS_SYSTEM flag set
4295             // initially
4296             parseFlags |= PackageParser.PARSE_IS_SYSTEM;
4297
4298             // An updated privileged app will not have the PARSE_IS_PRIVILEGED
4299             // flag set initially
4300             if ((updatedPkg.pkgFlags & ApplicationInfo.FLAG_PRIVILEGED) != 0) {
4301                 parseFlags |= PackageParser.PARSE_IS_PRIVILEGED;
4302             }
4303         }
4304
4305         // Verify certificates against what was last scanned
4306         collectCertificatesLI(pp, ps, pkg, scanFile, parseFlags);
4307
4308         /*
4309          * A new system app appeared, but we already had a non-system one of the
4310          * same name installed earlier.
4311          */
4312         boolean shouldHideSystemApp = false;
4313         if (updatedPkg == null && ps != null
4314                 && (parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0 && !isSystemApp(ps)) {
4315             /*
4316              * Check to make sure the signatures match first. If they don't,
4317              * wipe the installed application and its data.
4318              */
4319             if (compareSignatures(ps.signatures.mSignatures, pkg.mSignatures)
4320                     != PackageManager.SIGNATURE_MATCH) {
4321                 logCriticalInfo(Log.WARN, "Package " + ps.name + " appeared on system, but"
4322                         + " signatures don't match existing userdata copy; removing");
4323                 deletePackageLI(pkg.packageName, null, true, null, null, 0, null, false);
4324                 ps = null;
4325             } else {
4326                 /*
4327                  * If the newly-added system app is an older version than the
4328                  * already installed version, hide it. It will be scanned later
4329                  * and re-added like an update.
4330                  */
4331                 if (pkg.mVersionCode < ps.versionCode) {
4332                     shouldHideSystemApp = true;
4333                     logCriticalInfo(Log.INFO, "Package " + ps.name + " appeared at " + scanFile
4334                             + " but new version " + pkg.mVersionCode + " better than installed "
4335                             + ps.versionCode + "; hiding system");
4336                 } else {
4337                     /*
4338                      * The newly found system app is a newer version that the
4339                      * one previously installed. Simply remove the
4340                      * already-installed application and replace it with our own
4341                      * while keeping the application data.
4342                      */
4343                     logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile
4344                             + " reverting from " + ps.codePathString + ": new version "
4345                             + pkg.mVersionCode + " better than installed " + ps.versionCode);
4346                     InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
4347                             ps.codePathString, ps.resourcePathString, ps.legacyNativeLibraryPathString,
4348                             getAppDexInstructionSets(ps));
4349                     synchronized (mInstallLock) {
4350                         args.cleanUpResourcesLI();
4351                     }
4352                 }
4353             }
4354         }
4355
4356         // The apk is forward locked (not public) if its code and resources
4357         // are kept in different files. (except for app in either system or
4358         // vendor path).
4359         // TODO grab this value from PackageSettings
4360         if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
4361             if (ps != null && !ps.codePath.equals(ps.resourcePath)) {
4362                 parseFlags |= PackageParser.PARSE_FORWARD_LOCK;
4363             }
4364         }
4365
4366         // TODO: extend to support forward-locked splits
4367         String resourcePath = null;
4368         String baseResourcePath = null;
4369         if ((parseFlags & PackageParser.PARSE_FORWARD_LOCK) != 0 && !updatedPkgBetter) {
4370             if (ps != null && ps.resourcePathString != null) {
4371                 resourcePath = ps.resourcePathString;
4372                 baseResourcePath = ps.resourcePathString;
4373             } else {
4374                 // Should not happen at all. Just log an error.
4375                 Slog.e(TAG, "Resource path not set for pkg : " + pkg.packageName);
4376             }
4377         } else {
4378             resourcePath = pkg.codePath;
4379             baseResourcePath = pkg.baseCodePath;
4380         }
4381
4382         // Set application objects path explicitly.
4383         pkg.applicationInfo.setCodePath(pkg.codePath);
4384         pkg.applicationInfo.setBaseCodePath(pkg.baseCodePath);
4385         pkg.applicationInfo.setSplitCodePaths(pkg.splitCodePaths);
4386         pkg.applicationInfo.setResourcePath(resourcePath);
4387         pkg.applicationInfo.setBaseResourcePath(baseResourcePath);
4388         pkg.applicationInfo.setSplitResourcePaths(pkg.splitCodePaths);
4389
4390         // Note that we invoke the following method only if we are about to unpack an application
4391         PackageParser.Package scannedPkg = scanPackageLI(pkg, parseFlags, scanFlags
4392                 | SCAN_UPDATE_SIGNATURE, currentTime, user);
4393
4394         /*
4395          * If the system app should be overridden by a previously installed
4396          * data, hide the system app now and let the /data/app scan pick it up
4397          * again.
4398          */
4399         if (shouldHideSystemApp) {
4400             synchronized (mPackages) {
4401                 /*
4402                  * We have to grant systems permissions before we hide, because
4403                  * grantPermissions will assume the package update is trying to
4404                  * expand its permissions.
4405                  */
4406                 grantPermissionsLPw(pkg, true, pkg.packageName);
4407                 mSettings.disableSystemPackageLPw(pkg.packageName);
4408             }
4409         }
4410
4411         return scannedPkg;
4412     }
4413
4414     private static String fixProcessName(String defProcessName,
4415             String processName, int uid) {
4416         if (processName == null) {
4417             return defProcessName;
4418         }
4419         return processName;
4420     }
4421
4422     private void verifySignaturesLP(PackageSetting pkgSetting, PackageParser.Package pkg)
4423             throws PackageManagerException {
4424         if (pkgSetting.signatures.mSignatures != null) {
4425             // Already existing package. Make sure signatures match
4426             boolean match = compareSignatures(pkgSetting.signatures.mSignatures, pkg.mSignatures)
4427                     == PackageManager.SIGNATURE_MATCH;
4428             if (!match) {
4429                 match = compareSignaturesCompat(pkgSetting.signatures, pkg)
4430                         == PackageManager.SIGNATURE_MATCH;
4431             }
4432             if (!match) {
4433                 throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
4434                         + pkg.packageName + " signatures do not match the "
4435                         + "previously installed version; ignoring!");
4436             }
4437         }
4438
4439         // Check for shared user signatures
4440         if (pkgSetting.sharedUser != null && pkgSetting.sharedUser.signatures.mSignatures != null) {
4441             // Already existing package. Make sure signatures match
4442             boolean match = compareSignatures(pkgSetting.sharedUser.signatures.mSignatures,
4443                     pkg.mSignatures) == PackageManager.SIGNATURE_MATCH;
4444             if (!match) {
4445                 match = compareSignaturesCompat(pkgSetting.sharedUser.signatures, pkg)
4446                         == PackageManager.SIGNATURE_MATCH;
4447             }
4448             if (!match) {
4449                 throw new PackageManagerException(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
4450                         "Package " + pkg.packageName
4451                         + " has no signatures that match those in shared user "
4452                         + pkgSetting.sharedUser.name + "; ignoring!");
4453             }
4454         }
4455     }
4456
4457     /**
4458      * Enforces that only the system UID or root's UID can call a method exposed
4459      * via Binder.
4460      *
4461      * @param message used as message if SecurityException is thrown
4462      * @throws SecurityException if the caller is not system or root
4463      */
4464     private static final void enforceSystemOrRoot(String message) {
4465         final int uid = Binder.getCallingUid();
4466         if (uid != Process.SYSTEM_UID && uid != 0) {
4467             throw new SecurityException(message);
4468         }
4469     }
4470
4471     @Override
4472     public void performBootDexOpt() {
4473         enforceSystemOrRoot("Only the system can request dexopt be performed");
4474
4475         final HashSet<PackageParser.Package> pkgs;
4476         synchronized (mPackages) {
4477             pkgs = mDeferredDexOpt;
4478             mDeferredDexOpt = null;
4479         }
4480
4481         if (pkgs != null) {
4482             // Sort apps by importance for dexopt ordering. Important apps are given more priority
4483             // in case the device runs out of space.
4484             ArrayList<PackageParser.Package> sortedPkgs = new ArrayList<PackageParser.Package>();
4485             // Give priority to core apps.
4486             for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) {
4487                 PackageParser.Package pkg = it.next();
4488                 if (pkg.coreApp) {
4489                     if (DEBUG_DEXOPT) {
4490                         Log.i(TAG, "Adding core app " + sortedPkgs.size() + ": " + pkg.packageName);
4491                     }
4492                     sortedPkgs.add(pkg);
4493                     it.remove();
4494                 }
4495             }
4496             // Give priority to system apps that listen for pre boot complete.
4497             Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
4498             HashSet<String> pkgNames = getPackageNamesForIntent(intent);
4499             for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) {
4500                 PackageParser.Package pkg = it.next();
4501                 if (pkgNames.contains(pkg.packageName)) {
4502                     if (DEBUG_DEXOPT) {
4503                         Log.i(TAG, "Adding pre boot system app " + sortedPkgs.size() + ": " + pkg.packageName);
4504                     }
4505                     sortedPkgs.add(pkg);
4506                     it.remove();
4507                 }
4508             }
4509             // Give priority to system apps.
4510             for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) {
4511                 PackageParser.Package pkg = it.next();
4512                 if (isSystemApp(pkg) && !isUpdatedSystemApp(pkg)) {
4513                     if (DEBUG_DEXOPT) {
4514                         Log.i(TAG, "Adding system app " + sortedPkgs.size() + ": " + pkg.packageName);
4515                     }
4516                     sortedPkgs.add(pkg);
4517                     it.remove();
4518                 }
4519             }
4520             // Give priority to updated system apps.
4521             for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) {
4522                 PackageParser.Package pkg = it.next();
4523                 if (isUpdatedSystemApp(pkg)) {
4524                     if (DEBUG_DEXOPT) {
4525                         Log.i(TAG, "Adding updated system app " + sortedPkgs.size() + ": " + pkg.packageName);
4526                     }
4527                     sortedPkgs.add(pkg);
4528                     it.remove();
4529                 }
4530             }
4531             // Give priority to apps that listen for boot complete.
4532             intent = new Intent(Intent.ACTION_BOOT_COMPLETED);
4533             pkgNames = getPackageNamesForIntent(intent);
4534             for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) {
4535                 PackageParser.Package pkg = it.next();
4536                 if (pkgNames.contains(pkg.packageName)) {
4537                     if (DEBUG_DEXOPT) {
4538                         Log.i(TAG, "Adding boot app " + sortedPkgs.size() + ": " + pkg.packageName);
4539                     }
4540                     sortedPkgs.add(pkg);
4541                     it.remove();
4542                 }
4543             }
4544             // Filter out packages that aren't recently used.
4545             filterRecentlyUsedApps(pkgs);
4546             // Add all remaining apps.
4547             for (PackageParser.Package pkg : pkgs) {
4548                 if (DEBUG_DEXOPT) {
4549                     Log.i(TAG, "Adding app " + sortedPkgs.size() + ": " + pkg.packageName);
4550                 }
4551                 sortedPkgs.add(pkg);
4552             }
4553
4554             int i = 0;
4555             int total = sortedPkgs.size();
4556             File dataDir = Environment.getDataDirectory();
4557             long lowThreshold = StorageManager.from(mContext).getStorageLowBytes(dataDir);
4558             if (lowThreshold == 0) {
4559                 throw new IllegalStateException("Invalid low memory threshold");
4560             }
4561             for (PackageParser.Package pkg : sortedPkgs) {
4562                 long usableSpace = dataDir.getUsableSpace();
4563                 if (usableSpace < lowThreshold) {
4564                     Log.w(TAG, "Not running dexopt on remaining apps due to low memory: " + usableSpace);
4565                     break;
4566                 }
4567                 performBootDexOpt(pkg, ++i, total);
4568             }
4569         }
4570     }
4571
4572     private void filterRecentlyUsedApps(HashSet<PackageParser.Package> pkgs) {
4573         // Filter out packages that aren't recently used.
4574         //
4575         // The exception is first boot of a non-eng device (aka !mLazyDexOpt), which
4576         // should do a full dexopt.
4577         if (mLazyDexOpt || (!isFirstBoot() && mPackageUsage.isHistoricalPackageUsageAvailable())) {
4578             // TODO: add a property to control this?
4579             long dexOptLRUThresholdInMinutes;
4580             if (mLazyDexOpt) {
4581                 dexOptLRUThresholdInMinutes = 30; // only last 30 minutes of apps for eng builds.
4582             } else {
4583                 dexOptLRUThresholdInMinutes = 7 * 24 * 60; // apps used in the 7 days for users.
4584             }
4585             long dexOptLRUThresholdInMills = dexOptLRUThresholdInMinutes * 60 * 1000;
4586
4587             int total = pkgs.size();
4588             int skipped = 0;
4589             long now = System.currentTimeMillis();
4590             for (Iterator<PackageParser.Package> i = pkgs.iterator(); i.hasNext();) {
4591                 PackageParser.Package pkg = i.next();
4592                 long then = pkg.mLastPackageUsageTimeInMills;
4593                 if (then + dexOptLRUThresholdInMills < now) {
4594                     if (DEBUG_DEXOPT) {
4595                         Log.i(TAG, "Skipping dexopt of " + pkg.packageName + " last resumed: " +
4596                               ((then == 0) ? "never" : new Date(then)));
4597                     }
4598                     i.remove();
4599                     skipped++;
4600                 }
4601             }
4602             if (DEBUG_DEXOPT) {
4603                 Log.i(TAG, "Skipped optimizing " + skipped + " of " + total);
4604             }
4605         }
4606     }
4607
4608     private HashSet<String> getPackageNamesForIntent(Intent intent) {
4609         List<ResolveInfo> ris = null;
4610         try {
4611             ris = AppGlobals.getPackageManager().queryIntentReceivers(
4612                     intent, null, 0, UserHandle.USER_OWNER);
4613         } catch (RemoteException e) {
4614         }
4615         HashSet<String> pkgNames = new HashSet<String>();
4616         if (ris != null) {
4617             for (ResolveInfo ri : ris) {
4618                 pkgNames.add(ri.activityInfo.packageName);
4619             }
4620         }
4621         return pkgNames;
4622     }
4623
4624     private void performBootDexOpt(PackageParser.Package pkg, int curr, int total) {
4625         if (DEBUG_DEXOPT) {
4626             Log.i(TAG, "Optimizing app " + curr + " of " + total + ": " + pkg.packageName);
4627         }
4628         if (!isFirstBoot()) {
4629             try {
4630                 ActivityManagerNative.getDefault().showBootMessage(
4631                         mContext.getResources().getString(R.string.android_upgrading_apk,
4632                                 curr, total), true);
4633             } catch (RemoteException e) {
4634             }
4635         }
4636         PackageParser.Package p = pkg;
4637         synchronized (mInstallLock) {
4638             performDexOptLI(p, null /* instruction sets */, false /* force dex */,
4639                             false /* defer */, true /* include dependencies */);
4640         }
4641     }
4642
4643     @Override
4644     public boolean performDexOptIfNeeded(String packageName, String instructionSet) {
4645         return performDexOpt(packageName, instructionSet, false);
4646     }
4647
4648     private static String getPrimaryInstructionSet(ApplicationInfo info) {
4649         if (info.primaryCpuAbi == null) {
4650             return getPreferredInstructionSet();
4651         }
4652
4653         return VMRuntime.getInstructionSet(info.primaryCpuAbi);
4654     }
4655
4656     public boolean performDexOpt(String packageName, String instructionSet, boolean backgroundDexopt) {
4657         boolean dexopt = mLazyDexOpt || backgroundDexopt;
4658         boolean updateUsage = !backgroundDexopt;  // Don't update usage if this is just a backgroundDexopt
4659         if (!dexopt && !updateUsage) {
4660             // We aren't going to dexopt or update usage, so bail early.
4661             return false;
4662         }
4663         PackageParser.Package p;
4664         final String targetInstructionSet;
4665         synchronized (mPackages) {
4666             p = mPackages.get(packageName);
4667             if (p == null) {
4668                 return false;
4669             }
4670             if (updateUsage) {
4671                 p.mLastPackageUsageTimeInMills = System.currentTimeMillis();
4672             }
4673             mPackageUsage.write(false);
4674             if (!dexopt) {
4675                 // We aren't going to dexopt, so bail early.
4676                 return false;
4677             }
4678
4679             targetInstructionSet = instructionSet != null ? instructionSet :
4680                     getPrimaryInstructionSet(p.applicationInfo);
4681             if (p.mDexOptPerformed.contains(targetInstructionSet)) {
4682                 return false;
4683             }
4684         }
4685
4686         synchronized (mInstallLock) {
4687             final String[] instructionSets = new String[] { targetInstructionSet };
4688             return performDexOptLI(p, instructionSets, false /* force dex */, false /* defer */,
4689                     true /* include dependencies */) == DEX_OPT_PERFORMED;
4690         }
4691     }
4692
4693     public HashSet<String> getPackagesThatNeedDexOpt() {
4694         HashSet<String> pkgs = null;
4695         synchronized (mPackages) {
4696             for (PackageParser.Package p : mPackages.values()) {
4697                 if (DEBUG_DEXOPT) {
4698                     Log.i(TAG, p.packageName + " mDexOptPerformed=" + p.mDexOptPerformed.toArray());
4699                 }
4700                 if (!p.mDexOptPerformed.isEmpty()) {
4701                     continue;
4702                 }
4703                 if (pkgs == null) {
4704                     pkgs = new HashSet<String>();
4705                 }
4706                 pkgs.add(p.packageName);
4707             }
4708         }
4709         return pkgs;
4710     }
4711
4712     public void shutdown() {
4713         mPackageUsage.write(true);
4714     }
4715
4716     private void performDexOptLibsLI(ArrayList<String> libs, String[] instructionSets,
4717              boolean forceDex, boolean defer, HashSet<String> done) {
4718         for (int i=0; i<libs.size(); i++) {
4719             PackageParser.Package libPkg;
4720             String libName;
4721             synchronized (mPackages) {
4722                 libName = libs.get(i);
4723                 SharedLibraryEntry lib = mSharedLibraries.get(libName);
4724                 if (lib != null && lib.apk != null) {
4725                     libPkg = mPackages.get(lib.apk);
4726                 } else {
4727                     libPkg = null;
4728                 }
4729             }
4730             if (libPkg != null && !done.contains(libName)) {
4731                 performDexOptLI(libPkg, instructionSets, forceDex, defer, done);
4732             }
4733         }
4734     }
4735
4736     static final int DEX_OPT_SKIPPED = 0;
4737     static final int DEX_OPT_PERFORMED = 1;
4738     static final int DEX_OPT_DEFERRED = 2;
4739     static final int DEX_OPT_FAILED = -1;
4740
4741     private int performDexOptLI(PackageParser.Package pkg, String[] targetInstructionSets,
4742             boolean forceDex, boolean defer, HashSet<String> done) {
4743         final String[] instructionSets = targetInstructionSets != null ?
4744                 targetInstructionSets : getAppDexInstructionSets(pkg.applicationInfo);
4745
4746         if (done != null) {
4747             done.add(pkg.packageName);
4748             if (pkg.usesLibraries != null) {
4749                 performDexOptLibsLI(pkg.usesLibraries, instructionSets, forceDex, defer, done);
4750             }
4751             if (pkg.usesOptionalLibraries != null) {
4752                 performDexOptLibsLI(pkg.usesOptionalLibraries, instructionSets, forceDex, defer, done);
4753             }
4754         }
4755
4756         if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_HAS_CODE) == 0) {
4757             return DEX_OPT_SKIPPED;
4758         }
4759
4760         final boolean vmSafeMode = (pkg.applicationInfo.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0;
4761
4762         final List<String> paths = pkg.getAllCodePathsExcludingResourceOnly();
4763         boolean performedDexOpt = false;
4764         // There are three basic cases here:
4765         // 1.) we need to dexopt, either because we are forced or it is needed
4766         // 2.) we are defering a needed dexopt
4767         // 3.) we are skipping an unneeded dexopt
4768         final String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
4769         for (String dexCodeInstructionSet : dexCodeInstructionSets) {
4770             if (!forceDex && pkg.mDexOptPerformed.contains(dexCodeInstructionSet)) {
4771                 continue;
4772             }
4773
4774             for (String path : paths) {
4775                 try {
4776                     // This will return DEXOPT_NEEDED if we either cannot find any odex file for this
4777                     // patckage or the one we find does not match the image checksum (i.e. it was
4778                     // compiled against an old image). It will return PATCHOAT_NEEDED if we can find a
4779                     // odex file and it matches the checksum of the image but not its base address,
4780                     // meaning we need to move it.
4781                     final byte isDexOptNeeded = DexFile.isDexOptNeededInternal(path,
4782                             pkg.packageName, dexCodeInstructionSet, defer);
4783                     if (forceDex || (!defer && isDexOptNeeded == DexFile.DEXOPT_NEEDED)) {
4784                         Log.i(TAG, "Running dexopt on: " + path + " pkg="
4785                                 + pkg.applicationInfo.packageName + " isa=" + dexCodeInstructionSet
4786                                 + " vmSafeMode=" + vmSafeMode);
4787                         final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
4788                         final int ret = mInstaller.dexopt(path, sharedGid, !isForwardLocked(pkg),
4789                                 pkg.packageName, dexCodeInstructionSet, vmSafeMode);
4790
4791                         if (ret < 0) {
4792                             // Don't bother running dexopt again if we failed, it will probably
4793                             // just result in an error again. Also, don't bother dexopting for other
4794                             // paths & ISAs.
4795                             return DEX_OPT_FAILED;
4796                         }
4797
4798                         performedDexOpt = true;
4799                     } else if (!defer && isDexOptNeeded == DexFile.PATCHOAT_NEEDED) {
4800                         Log.i(TAG, "Running patchoat on: " + pkg.applicationInfo.packageName);
4801                         final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
4802                         final int ret = mInstaller.patchoat(path, sharedGid, !isForwardLocked(pkg),
4803                                 pkg.packageName, dexCodeInstructionSet);
4804
4805                         if (ret < 0) {
4806                             // Don't bother running patchoat again if we failed, it will probably
4807                             // just result in an error again. Also, don't bother dexopting for other
4808                             // paths & ISAs.
4809                             return DEX_OPT_FAILED;
4810                         }
4811
4812                         performedDexOpt = true;
4813                     }
4814
4815                     // We're deciding to defer a needed dexopt. Don't bother dexopting for other
4816                     // paths and instruction sets. We'll deal with them all together when we process
4817                     // our list of deferred dexopts.
4818                     if (defer && isDexOptNeeded != DexFile.UP_TO_DATE) {
4819                         if (mDeferredDexOpt == null) {
4820                             mDeferredDexOpt = new HashSet<PackageParser.Package>();
4821                         }
4822                         mDeferredDexOpt.add(pkg);
4823                         return DEX_OPT_DEFERRED;
4824                     }
4825                 } catch (FileNotFoundException e) {
4826                     Slog.w(TAG, "Apk not found for dexopt: " + path);
4827                     return DEX_OPT_FAILED;
4828                 } catch (IOException e) {
4829                     Slog.w(TAG, "IOException reading apk: " + path, e);
4830                     return DEX_OPT_FAILED;
4831                 } catch (StaleDexCacheError e) {
4832                     Slog.w(TAG, "StaleDexCacheError when reading apk: " + path, e);
4833                     return DEX_OPT_FAILED;
4834                 } catch (Exception e) {
4835                     Slog.w(TAG, "Exception when doing dexopt : ", e);
4836                     return DEX_OPT_FAILED;
4837                 }
4838             }
4839
4840             // At this point we haven't failed dexopt and we haven't deferred dexopt. We must
4841             // either have either succeeded dexopt, or have had isDexOptNeededInternal tell us
4842             // it isn't required. We therefore mark that this package doesn't need dexopt unless
4843             // it's forced. performedDexOpt will tell us whether we performed dex-opt or skipped
4844             // it.
4845             pkg.mDexOptPerformed.add(dexCodeInstructionSet);
4846         }
4847
4848         // If we've gotten here, we're sure that no error occurred and that we haven't
4849         // deferred dex-opt. We've either dex-opted one more paths or instruction sets or
4850         // we've skipped all of them because they are up to date. In both cases this
4851         // package doesn't need dexopt any longer.
4852         return performedDexOpt ? DEX_OPT_PERFORMED : DEX_OPT_SKIPPED;
4853     }
4854
4855     private static String[] getAppDexInstructionSets(ApplicationInfo info) {
4856         if (info.primaryCpuAbi != null) {
4857             if (info.secondaryCpuAbi != null) {
4858                 return new String[] {
4859                         VMRuntime.getInstructionSet(info.primaryCpuAbi),
4860                         VMRuntime.getInstructionSet(info.secondaryCpuAbi) };
4861             } else {
4862                 return new String[] {
4863                         VMRuntime.getInstructionSet(info.primaryCpuAbi) };
4864             }
4865         }
4866
4867         return new String[] { getPreferredInstructionSet() };
4868     }
4869
4870     private static String[] getAppDexInstructionSets(PackageSetting ps) {
4871         if (ps.primaryCpuAbiString != null) {
4872             if (ps.secondaryCpuAbiString != null) {
4873                 return new String[] {
4874                         VMRuntime.getInstructionSet(ps.primaryCpuAbiString),
4875                         VMRuntime.getInstructionSet(ps.secondaryCpuAbiString) };
4876             } else {
4877                 return new String[] {
4878                         VMRuntime.getInstructionSet(ps.primaryCpuAbiString) };
4879             }
4880         }
4881
4882         return new String[] { getPreferredInstructionSet() };
4883     }
4884
4885     private static String getPreferredInstructionSet() {
4886         if (sPreferredInstructionSet == null) {
4887             sPreferredInstructionSet = VMRuntime.getInstructionSet(Build.SUPPORTED_ABIS[0]);
4888         }
4889
4890         return sPreferredInstructionSet;
4891     }
4892
4893     private static List<String> getAllInstructionSets() {
4894         final String[] allAbis = Build.SUPPORTED_ABIS;
4895         final List<String> allInstructionSets = new ArrayList<String>(allAbis.length);
4896
4897         for (String abi : allAbis) {
4898             final String instructionSet = VMRuntime.getInstructionSet(abi);
4899             if (!allInstructionSets.contains(instructionSet)) {
4900                 allInstructionSets.add(instructionSet);
4901             }
4902         }
4903
4904         return allInstructionSets;
4905     }
4906
4907     /**
4908      * Returns the instruction set that should be used to compile dex code. In the presence of
4909      * a native bridge this might be different than the one shared libraries use.
4910      */
4911     private static String getDexCodeInstructionSet(String sharedLibraryIsa) {
4912         String dexCodeIsa = SystemProperties.get("ro.dalvik.vm.isa." + sharedLibraryIsa);
4913         return (dexCodeIsa.isEmpty() ? sharedLibraryIsa : dexCodeIsa);
4914     }
4915
4916     private static String[] getDexCodeInstructionSets(String[] instructionSets) {
4917         HashSet<String> dexCodeInstructionSets = new HashSet<String>(instructionSets.length);
4918         for (String instructionSet : instructionSets) {
4919             dexCodeInstructionSets.add(getDexCodeInstructionSet(instructionSet));
4920         }
4921         return dexCodeInstructionSets.toArray(new String[dexCodeInstructionSets.size()]);
4922     }
4923
4924     /**
4925      * Returns deduplicated list of supported instructions for dex code.
4926      */
4927     public static String[] getAllDexCodeInstructionSets() {
4928         String[] supportedInstructionSets = new String[Build.SUPPORTED_ABIS.length];
4929         for (int i = 0; i < supportedInstructionSets.length; i++) {
4930             String abi = Build.SUPPORTED_ABIS[i];
4931             supportedInstructionSets[i] = VMRuntime.getInstructionSet(abi);
4932         }
4933         return getDexCodeInstructionSets(supportedInstructionSets);
4934     }
4935
4936     @Override
4937     public void forceDexOpt(String packageName) {
4938         enforceSystemOrRoot("forceDexOpt");
4939
4940         PackageParser.Package pkg;
4941         synchronized (mPackages) {
4942             pkg = mPackages.get(packageName);
4943             if (pkg == null) {
4944                 throw new IllegalArgumentException("Missing package: " + packageName);
4945             }
4946         }
4947
4948         synchronized (mInstallLock) {
4949             final String[] instructionSets = new String[] {
4950                     getPrimaryInstructionSet(pkg.applicationInfo) };
4951             final int res = performDexOptLI(pkg, instructionSets, true, false, true);
4952             if (res != DEX_OPT_PERFORMED) {
4953                 throw new IllegalStateException("Failed to dexopt: " + res);
4954             }
4955         }
4956     }
4957
4958     private int performDexOptLI(PackageParser.Package pkg, String[] instructionSets,
4959                                 boolean forceDex, boolean defer, boolean inclDependencies) {
4960         HashSet<String> done;
4961         if (inclDependencies && (pkg.usesLibraries != null || pkg.usesOptionalLibraries != null)) {
4962             done = new HashSet<String>();
4963             done.add(pkg.packageName);
4964         } else {
4965             done = null;
4966         }
4967         return performDexOptLI(pkg, instructionSets,  forceDex, defer, done);
4968     }
4969
4970     private boolean verifyPackageUpdateLPr(PackageSetting oldPkg, PackageParser.Package newPkg) {
4971         if ((oldPkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) {
4972             Slog.w(TAG, "Unable to update from " + oldPkg.name
4973                     + " to " + newPkg.packageName
4974                     + ": old package not in system partition");
4975             return false;
4976         } else if (mPackages.get(oldPkg.name) != null) {
4977             Slog.w(TAG, "Unable to update from " + oldPkg.name
4978                     + " to " + newPkg.packageName
4979                     + ": old package still exists");
4980             return false;
4981         }
4982         return true;
4983     }
4984
4985     File getDataPathForUser(int userId) {
4986         return new File(mUserAppDataDir.getAbsolutePath() + File.separator + userId);
4987     }
4988
4989     private File getDataPathForPackage(String packageName, int userId) {
4990         /*
4991          * Until we fully support multiple users, return the directory we
4992          * previously would have. The PackageManagerTests will need to be
4993          * revised when this is changed back..
4994          */
4995         if (userId == 0) {
4996             return new File(mAppDataDir, packageName);
4997         } else {
4998             return new File(mUserAppDataDir.getAbsolutePath() + File.separator + userId
4999                 + File.separator + packageName);
5000         }
5001     }
5002
5003     private int createDataDirsLI(String packageName, int uid, String seinfo) {
5004         int[] users = sUserManager.getUserIds();
5005         int res = mInstaller.install(packageName, uid, uid, seinfo);
5006         if (res < 0) {
5007             return res;
5008         }
5009         for (int user : users) {
5010             if (user != 0) {
5011                 res = mInstaller.createUserData(packageName,
5012                         UserHandle.getUid(user, uid), user, seinfo);
5013                 if (res < 0) {
5014                     return res;
5015                 }
5016             }
5017         }
5018         return res;
5019     }
5020
5021     private int removeDataDirsLI(String packageName) {
5022         int[] users = sUserManager.getUserIds();
5023         int res = 0;
5024         for (int user : users) {
5025             int resInner = mInstaller.remove(packageName, user);
5026             if (resInner < 0) {
5027                 res = resInner;
5028             }
5029         }
5030
5031         return res;
5032     }
5033
5034     private int deleteCodeCacheDirsLI(String packageName) {
5035         int[] users = sUserManager.getUserIds();
5036         int res = 0;
5037         for (int user : users) {
5038             int resInner = mInstaller.deleteCodeCacheFiles(packageName, user);
5039             if (resInner < 0) {
5040                 res = resInner;
5041             }
5042         }
5043         return res;
5044     }
5045
5046     private void addSharedLibraryLPw(ArraySet<String> usesLibraryFiles, SharedLibraryEntry file,
5047             PackageParser.Package changingLib) {
5048         if (file.path != null) {
5049             usesLibraryFiles.add(file.path);
5050             return;
5051         }
5052         PackageParser.Package p = mPackages.get(file.apk);
5053         if (changingLib != null && changingLib.packageName.equals(file.apk)) {
5054             // If we are doing this while in the middle of updating a library apk,
5055             // then we need to make sure to use that new apk for determining the
5056             // dependencies here.  (We haven't yet finished committing the new apk
5057             // to the package manager state.)
5058             if (p == null || p.packageName.equals(changingLib.packageName)) {
5059                 p = changingLib;
5060             }
5061         }
5062         if (p != null) {
5063             usesLibraryFiles.addAll(p.getAllCodePaths());
5064         }
5065     }
5066
5067     private void updateSharedLibrariesLPw(PackageParser.Package pkg,
5068             PackageParser.Package changingLib) throws PackageManagerException {
5069         if (pkg.usesLibraries != null || pkg.usesOptionalLibraries != null) {
5070             final ArraySet<String> usesLibraryFiles = new ArraySet<>();
5071             int N = pkg.usesLibraries != null ? pkg.usesLibraries.size() : 0;
5072             for (int i=0; i<N; i++) {
5073                 final SharedLibraryEntry file = mSharedLibraries.get(pkg.usesLibraries.get(i));
5074                 if (file == null) {
5075                     throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
5076                             "Package " + pkg.packageName + " requires unavailable shared library "
5077                             + pkg.usesLibraries.get(i) + "; failing!");
5078                 }
5079                 addSharedLibraryLPw(usesLibraryFiles, file, changingLib);
5080             }
5081             N = pkg.usesOptionalLibraries != null ? pkg.usesOptionalLibraries.size() : 0;
5082             for (int i=0; i<N; i++) {
5083                 final SharedLibraryEntry file = mSharedLibraries.get(pkg.usesOptionalLibraries.get(i));
5084                 if (file == null) {
5085                     Slog.w(TAG, "Package " + pkg.packageName
5086                             + " desires unavailable shared library "
5087                             + pkg.usesOptionalLibraries.get(i) + "; ignoring!");
5088                 } else {
5089                     addSharedLibraryLPw(usesLibraryFiles, file, changingLib);
5090                 }
5091             }
5092             N = usesLibraryFiles.size();
5093             if (N > 0) {
5094                 pkg.usesLibraryFiles = usesLibraryFiles.toArray(new String[N]);
5095             } else {
5096                 pkg.usesLibraryFiles = null;
5097             }
5098         }
5099     }
5100
5101     private static boolean hasString(List<String> list, List<String> which) {
5102         if (list == null) {
5103             return false;
5104         }
5105         for (int i=list.size()-1; i>=0; i--) {
5106             for (int j=which.size()-1; j>=0; j--) {
5107                 if (which.get(j).equals(list.get(i))) {
5108                     return true;
5109                 }
5110             }
5111         }
5112         return false;
5113     }
5114
5115     private void updateAllSharedLibrariesLPw() {
5116         for (PackageParser.Package pkg : mPackages.values()) {
5117             try {
5118                 updateSharedLibrariesLPw(pkg, null);
5119             } catch (PackageManagerException e) {
5120                 Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
5121             }
5122         }
5123     }
5124
5125     private ArrayList<PackageParser.Package> updateAllSharedLibrariesLPw(
5126             PackageParser.Package changingPkg) {
5127         ArrayList<PackageParser.Package> res = null;
5128         for (PackageParser.Package pkg : mPackages.values()) {
5129             if (hasString(pkg.usesLibraries, changingPkg.libraryNames)
5130                     || hasString(pkg.usesOptionalLibraries, changingPkg.libraryNames)) {
5131                 if (res == null) {
5132                     res = new ArrayList<PackageParser.Package>();
5133                 }
5134                 res.add(pkg);
5135                 try {
5136                     updateSharedLibrariesLPw(pkg, changingPkg);
5137                 } catch (PackageManagerException e) {
5138                     Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
5139                 }
5140             }
5141         }
5142         return res;
5143     }
5144
5145     /**
5146      * Derive the value of the {@code cpuAbiOverride} based on the provided
5147      * value and an optional stored value from the package settings.
5148      */
5149     private static String deriveAbiOverride(String abiOverride, PackageSetting settings) {
5150         String cpuAbiOverride = null;
5151
5152         if (NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(abiOverride)) {
5153             cpuAbiOverride = null;
5154         } else if (abiOverride != null) {
5155             cpuAbiOverride = abiOverride;
5156         } else if (settings != null) {
5157             cpuAbiOverride = settings.cpuAbiOverrideString;
5158         }
5159
5160         return cpuAbiOverride;
5161     }
5162
5163     private PackageParser.Package scanPackageLI(PackageParser.Package pkg, int parseFlags,
5164             int scanFlags, long currentTime, UserHandle user) throws PackageManagerException {
5165         boolean success = false;
5166         try {
5167             final PackageParser.Package res = scanPackageDirtyLI(pkg, parseFlags, scanFlags,
5168                     currentTime, user);
5169             success = true;
5170             return res;
5171         } finally {
5172             if (!success && (scanFlags & SCAN_DELETE_DATA_ON_FAILURES) != 0) {
5173                 removeDataDirsLI(pkg.packageName);
5174             }
5175         }
5176     }
5177
5178     private PackageParser.Package scanPackageDirtyLI(PackageParser.Package pkg, int parseFlags,
5179             int scanFlags, long currentTime, UserHandle user) throws PackageManagerException {
5180         final File scanFile = new File(pkg.codePath);
5181         if (pkg.applicationInfo.getCodePath() == null ||
5182                 pkg.applicationInfo.getResourcePath() == null) {
5183             // Bail out. The resource and code paths haven't been set.
5184             throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
5185                     "Code and resource paths haven't been set correctly");
5186         }
5187
5188         if ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) {
5189             pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
5190         } else {
5191             // Only allow system apps to be flagged as core apps.
5192             pkg.coreApp = false;
5193         }
5194
5195         if ((parseFlags&PackageParser.PARSE_IS_PRIVILEGED) != 0) {
5196             pkg.applicationInfo.flags |= ApplicationInfo.FLAG_PRIVILEGED;
5197         }
5198
5199         if (mCustomResolverComponentName != null &&
5200                 mCustomResolverComponentName.getPackageName().equals(pkg.packageName)) {
5201             setUpCustomResolverActivity(pkg);
5202         }
5203
5204         if (pkg.packageName.equals("android")) {
5205             synchronized (mPackages) {
5206                 if (mAndroidApplication != null) {
5207                     Slog.w(TAG, "*************************************************");
5208                     Slog.w(TAG, "Core android package being redefined.  Skipping.");
5209                     Slog.w(TAG, " file=" + scanFile);
5210                     Slog.w(TAG, "*************************************************");
5211                     throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
5212                             "Core android package being redefined.  Skipping.");
5213                 }
5214
5215                 // Set up information for our fall-back user intent resolution activity.
5216                 mPlatformPackage = pkg;
5217                 pkg.mVersionCode = mSdkVersion;
5218                 mAndroidApplication = pkg.applicationInfo;
5219
5220                 if (!mResolverReplaced) {
5221                     mResolveActivity.applicationInfo = mAndroidApplication;
5222                     mResolveActivity.name = ResolverActivity.class.getName();
5223                     mResolveActivity.packageName = mAndroidApplication.packageName;
5224                     mResolveActivity.processName = "system:ui";
5225                     mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
5226                     mResolveActivity.documentLaunchMode = ActivityInfo.DOCUMENT_LAUNCH_NEVER;
5227                     mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS;
5228                     mResolveActivity.theme = R.style.Theme_Holo_Dialog_Alert;
5229                     mResolveActivity.exported = true;
5230                     mResolveActivity.enabled = true;
5231                     mResolveInfo.activityInfo = mResolveActivity;
5232                     mResolveInfo.priority = 0;
5233                     mResolveInfo.preferredOrder = 0;
5234                     mResolveInfo.match = 0;
5235                     mResolveComponentName = new ComponentName(
5236                             mAndroidApplication.packageName, mResolveActivity.name);
5237                 }
5238             }
5239         }
5240
5241         if (DEBUG_PACKAGE_SCANNING) {
5242             if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
5243                 Log.d(TAG, "Scanning package " + pkg.packageName);
5244         }
5245
5246         if (mPackages.containsKey(pkg.packageName)
5247                 || mSharedLibraries.containsKey(pkg.packageName)) {
5248             throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
5249                     "Application package " + pkg.packageName
5250                     + " already installed.  Skipping duplicate.");
5251         }
5252
5253         // Initialize package source and resource directories
5254         File destCodeFile = new File(pkg.applicationInfo.getCodePath());
5255         File destResourceFile = new File(pkg.applicationInfo.getResourcePath());
5256
5257         SharedUserSetting suid = null;
5258         PackageSetting pkgSetting = null;
5259
5260         if (!isSystemApp(pkg)) {
5261             // Only system apps can use these features.
5262             pkg.mOriginalPackages = null;
5263             pkg.mRealPackage = null;
5264             pkg.mAdoptPermissions = null;
5265         }
5266
5267         // writer
5268         synchronized (mPackages) {
5269             if (pkg.mSharedUserId != null) {
5270                 suid = mSettings.getSharedUserLPw(pkg.mSharedUserId, 0, true);
5271                 if (suid == null) {
5272                     throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE,
5273                             "Creating application package " + pkg.packageName
5274                             + " for shared user failed");
5275                 }
5276                 if (DEBUG_PACKAGE_SCANNING) {
5277                     if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
5278                         Log.d(TAG, "Shared UserID " + pkg.mSharedUserId + " (uid=" + suid.userId
5279                                 + "): packages=" + suid.packages);
5280                 }
5281             }
5282             
5283             // Check if we are renaming from an original package name.
5284             PackageSetting origPackage = null;
5285             String realName = null;
5286             if (pkg.mOriginalPackages != null) {
5287                 // This package may need to be renamed to a previously
5288                 // installed name.  Let's check on that...
5289                 final String renamed = mSettings.mRenamedPackages.get(pkg.mRealPackage);
5290                 if (pkg.mOriginalPackages.contains(renamed)) {
5291                     // This package had originally been installed as the
5292                     // original name, and we have already taken care of
5293                     // transitioning to the new one.  Just update the new
5294                     // one to continue using the old name.
5295                     realName = pkg.mRealPackage;
5296                     if (!pkg.packageName.equals(renamed)) {
5297                         // Callers into this function may have already taken
5298                         // care of renaming the package; only do it here if
5299                         // it is not already done.
5300                         pkg.setPackageName(renamed);
5301                     }
5302                     
5303                 } else {
5304                     for (int i=pkg.mOriginalPackages.size()-1; i>=0; i--) {
5305                         if ((origPackage = mSettings.peekPackageLPr(
5306                                 pkg.mOriginalPackages.get(i))) != null) {
5307                             // We do have the package already installed under its
5308                             // original name...  should we use it?
5309                             if (!verifyPackageUpdateLPr(origPackage, pkg)) {
5310                                 // New package is not compatible with original.
5311                                 origPackage = null;
5312                                 continue;
5313                             } else if (origPackage.sharedUser != null) {
5314                                 // Make sure uid is compatible between packages.
5315                                 if (!origPackage.sharedUser.name.equals(pkg.mSharedUserId)) {
5316                                     Slog.w(TAG, "Unable to migrate data from " + origPackage.name
5317                                             + " to " + pkg.packageName + ": old uid "
5318                                             + origPackage.sharedUser.name
5319                                             + " differs from " + pkg.mSharedUserId);
5320                                     origPackage = null;
5321                                     continue;
5322                                 }
5323                             } else {
5324                                 if (DEBUG_UPGRADE) Log.v(TAG, "Renaming new package "
5325                                         + pkg.packageName + " to old name " + origPackage.name);
5326                             }
5327                             break;
5328                         }
5329                     }
5330                 }
5331             }
5332             
5333             if (mTransferedPackages.contains(pkg.packageName)) {
5334                 Slog.w(TAG, "Package " + pkg.packageName
5335                         + " was transferred to another, but its .apk remains");
5336             }
5337
5338             // Just create the setting, don't add it yet. For already existing packages
5339             // the PkgSetting exists already and doesn't have to be created.
5340             pkgSetting = mSettings.getPackageLPw(pkg, origPackage, realName, suid, destCodeFile,
5341                     destResourceFile, pkg.applicationInfo.nativeLibraryRootDir,
5342                     pkg.applicationInfo.primaryCpuAbi,
5343                     pkg.applicationInfo.secondaryCpuAbi,
5344                     pkg.applicationInfo.flags, user, false);
5345             if (pkgSetting == null) {
5346                 throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE,
5347                         "Creating application package " + pkg.packageName + " failed");
5348             }
5349
5350             if (pkgSetting.origPackage != null) {
5351                 // If we are first transitioning from an original package,
5352                 // fix up the new package's name now.  We need to do this after
5353                 // looking up the package under its new name, so getPackageLP
5354                 // can take care of fiddling things correctly.
5355                 pkg.setPackageName(origPackage.name);
5356                 
5357                 // File a report about this.
5358                 String msg = "New package " + pkgSetting.realName
5359                         + " renamed to replace old package " + pkgSetting.name;
5360                 reportSettingsProblem(Log.WARN, msg);
5361                 
5362                 // Make a note of it.
5363                 mTransferedPackages.add(origPackage.name);
5364                 
5365                 // No longer need to retain this.
5366                 pkgSetting.origPackage = null;
5367             }
5368             
5369             if (realName != null) {
5370                 // Make a note of it.
5371                 mTransferedPackages.add(pkg.packageName);
5372             }
5373             
5374             if (mSettings.isDisabledSystemPackageLPr(pkg.packageName)) {
5375                 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
5376             }
5377
5378             if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
5379                 // Check all shared libraries and map to their actual file path.
5380                 // We only do this here for apps not on a system dir, because those
5381                 // are the only ones that can fail an install due to this.  We
5382                 // will take care of the system apps by updating all of their
5383                 // library paths after the scan is done.
5384                 updateSharedLibrariesLPw(pkg, null);
5385             }
5386
5387             if (mFoundPolicyFile) {
5388                 SELinuxMMAC.assignSeinfoValue(pkg);
5389             }
5390
5391             pkg.applicationInfo.uid = pkgSetting.appId;
5392             pkg.mExtras = pkgSetting;
5393             if (!pkgSetting.keySetData.isUsingUpgradeKeySets() || pkgSetting.sharedUser != null) {
5394                 try {
5395                     verifySignaturesLP(pkgSetting, pkg);
5396                 } catch (PackageManagerException e) {
5397                     if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
5398                         throw e;
5399                     }
5400                     // The signature has changed, but this package is in the system
5401                     // image...  let's recover!
5402                     pkgSetting.signatures.mSignatures = pkg.mSignatures;
5403                     // However...  if this package is part of a shared user, but it
5404                     // doesn't match the signature of the shared user, let's fail.
5405                     // What this means is that you can't change the signatures
5406                     // associated with an overall shared user, which doesn't seem all
5407                     // that unreasonable.
5408                     if (pkgSetting.sharedUser != null) {
5409                         if (compareSignatures(pkgSetting.sharedUser.signatures.mSignatures,
5410                                               pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) {
5411                             throw new PackageManagerException(
5412                                     INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES,
5413                                             "Signature mismatch for shared user : "
5414                                             + pkgSetting.sharedUser);
5415                         }
5416                     }
5417                     // File a report about this.
5418                     String msg = "System package " + pkg.packageName
5419                         + " signature changed; retaining data.";
5420                     reportSettingsProblem(Log.WARN, msg);
5421                 }
5422             } else {
5423                 if (!checkUpgradeKeySetLP(pkgSetting, pkg)) {
5424                     throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
5425                             + pkg.packageName + " upgrade keys do not match the "
5426                             + "previously installed version");
5427                 } else {
5428                     // signatures may have changed as result of upgrade
5429                     pkgSetting.signatures.mSignatures = pkg.mSignatures;
5430                 }
5431             }
5432             // Verify that this new package doesn't have any content providers
5433             // that conflict with existing packages.  Only do this if the
5434             // package isn't already installed, since we don't want to break
5435             // things that are installed.
5436             if ((scanFlags & SCAN_NEW_INSTALL) != 0) {
5437                 final int N = pkg.providers.size();
5438                 int i;
5439                 for (i=0; i<N; i++) {
5440                     PackageParser.Provider p = pkg.providers.get(i);
5441                     if (p.info.authority != null) {
5442                         String names[] = p.info.authority.split(";");
5443                         for (int j = 0; j < names.length; j++) {
5444                             if (mProvidersByAuthority.containsKey(names[j])) {
5445                                 PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
5446                                 final String otherPackageName =
5447                                         ((other != null && other.getComponentName() != null) ?
5448                                                 other.getComponentName().getPackageName() : "?");
5449                                 throw new PackageManagerException(
5450                                         INSTALL_FAILED_CONFLICTING_PROVIDER,
5451                                                 "Can't install because provider name " + names[j]
5452                                                 + " (in package " + pkg.applicationInfo.packageName
5453                                                 + ") is already used by " + otherPackageName);
5454                             }
5455                         }
5456                     }
5457                 }
5458             }
5459
5460             if (pkg.mAdoptPermissions != null) {
5461                 // This package wants to adopt ownership of permissions from
5462                 // another package.
5463                 for (int i = pkg.mAdoptPermissions.size() - 1; i >= 0; i--) {
5464                     final String origName = pkg.mAdoptPermissions.get(i);
5465                     final PackageSetting orig = mSettings.peekPackageLPr(origName);
5466                     if (orig != null) {
5467                         if (verifyPackageUpdateLPr(orig, pkg)) {
5468                             Slog.i(TAG, "Adopting permissions from " + origName + " to "
5469                                     + pkg.packageName);
5470                             mSettings.transferPermissionsLPw(origName, pkg.packageName);
5471                         }
5472                     }
5473                 }
5474             }
5475         }
5476
5477         final String pkgName = pkg.packageName;
5478         
5479         final long scanFileTime = scanFile.lastModified();
5480         final boolean forceDex = (scanFlags & SCAN_FORCE_DEX) != 0;
5481         pkg.applicationInfo.processName = fixProcessName(
5482                 pkg.applicationInfo.packageName,
5483                 pkg.applicationInfo.processName,
5484                 pkg.applicationInfo.uid);
5485
5486         File dataPath;
5487         if (mPlatformPackage == pkg) {
5488             // The system package is special.
5489             dataPath = new File(Environment.getDataDirectory(), "system");
5490
5491             pkg.applicationInfo.dataDir = dataPath.getPath();
5492
5493         } else {
5494             // This is a normal package, need to make its data directory.
5495             dataPath = getDataPathForPackage(pkg.packageName, 0);
5496
5497             boolean uidError = false;
5498             if (dataPath.exists()) {
5499                 int currentUid = 0;
5500                 try {
5501                     StructStat stat = Os.stat(dataPath.getPath());
5502                     currentUid = stat.st_uid;
5503                 } catch (ErrnoException e) {
5504                     Slog.e(TAG, "Couldn't stat path " + dataPath.getPath(), e);
5505                 }
5506
5507                 // If we have mismatched owners for the data path, we have a problem.
5508                 if (currentUid != pkg.applicationInfo.uid) {
5509                     boolean recovered = false;
5510                     if (currentUid == 0) {
5511                         // The directory somehow became owned by root.  Wow.
5512                         // This is probably because the system was stopped while
5513                         // installd was in the middle of messing with its libs
5514                         // directory.  Ask installd to fix that.
5515                         int ret = mInstaller.fixUid(pkgName, pkg.applicationInfo.uid,
5516                                 pkg.applicationInfo.uid);
5517                         if (ret >= 0) {
5518                             recovered = true;
5519                             String msg = "Package " + pkg.packageName
5520                                     + " unexpectedly changed to uid 0; recovered to " +
5521                                     + pkg.applicationInfo.uid;
5522                             reportSettingsProblem(Log.WARN, msg);
5523                         }
5524                     }
5525                     if (!recovered && ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0
5526                             || (scanFlags&SCAN_BOOTING) != 0)) {
5527                         // If this is a system app, we can at least delete its
5528                         // current data so the application will still work.
5529                         int ret = removeDataDirsLI(pkgName);
5530                         if (ret >= 0) {
5531                             // TODO: Kill the processes first
5532                             // Old data gone!
5533                             String prefix = (parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0
5534                                     ? "System package " : "Third party package ";
5535                             String msg = prefix + pkg.packageName
5536                                     + " has changed from uid: "
5537                                     + currentUid + " to "
5538                                     + pkg.applicationInfo.uid + "; old data erased";
5539                             reportSettingsProblem(Log.WARN, msg);
5540                             recovered = true;
5541
5542                             // And now re-install the app.
5543                             ret = createDataDirsLI(pkgName, pkg.applicationInfo.uid,
5544                                                    pkg.applicationInfo.seinfo);
5545                             if (ret == -1) {
5546                                 // Ack should not happen!
5547                                 msg = prefix + pkg.packageName
5548                                         + " could not have data directory re-created after delete.";
5549                                 reportSettingsProblem(Log.WARN, msg);
5550                                 throw new PackageManagerException(
5551                                         INSTALL_FAILED_INSUFFICIENT_STORAGE, msg);
5552                             }
5553                         }
5554                         if (!recovered) {
5555                             mHasSystemUidErrors = true;
5556                         }
5557                     } else if (!recovered) {
5558                         // If we allow this install to proceed, we will be broken.
5559                         // Abort, abort!
5560                         throw new PackageManagerException(INSTALL_FAILED_UID_CHANGED,
5561                                 "scanPackageLI");
5562                     }
5563                     if (!recovered) {
5564                         pkg.applicationInfo.dataDir = "/mismatched_uid/settings_"
5565                             + pkg.applicationInfo.uid + "/fs_"
5566                             + currentUid;
5567                         pkg.applicationInfo.nativeLibraryDir = pkg.applicationInfo.dataDir;
5568                         pkg.applicationInfo.nativeLibraryRootDir = pkg.applicationInfo.dataDir;
5569                         String msg = "Package " + pkg.packageName
5570                                 + " has mismatched uid: "
5571                                 + currentUid + " on disk, "
5572                                 + pkg.applicationInfo.uid + " in settings";
5573                         // writer
5574                         synchronized (mPackages) {
5575                             mSettings.mReadMessages.append(msg);
5576                             mSettings.mReadMessages.append('\n');
5577                             uidError = true;
5578                             if (!pkgSetting.uidError) {
5579                                 reportSettingsProblem(Log.ERROR, msg);
5580                             }
5581                         }
5582                     }
5583                 }
5584                 pkg.applicationInfo.dataDir = dataPath.getPath();
5585                 if (mShouldRestoreconData) {
5586                     Slog.i(TAG, "SELinux relabeling of " + pkg.packageName + " issued.");
5587                     mInstaller.restoreconData(pkg.packageName, pkg.applicationInfo.seinfo,
5588                                 pkg.applicationInfo.uid);
5589                 }
5590             } else {
5591                 if (DEBUG_PACKAGE_SCANNING) {
5592                     if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
5593                         Log.v(TAG, "Want this data dir: " + dataPath);
5594                 }
5595                 //invoke installer to do the actual installation
5596                 int ret = createDataDirsLI(pkgName, pkg.applicationInfo.uid,
5597                                            pkg.applicationInfo.seinfo);
5598                 if (ret < 0) {
5599                     // Error from installer
5600                     throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE,
5601                             "Unable to create data dirs [errorCode=" + ret + "]");
5602                 }
5603
5604                 if (dataPath.exists()) {
5605                     pkg.applicationInfo.dataDir = dataPath.getPath();
5606                 } else {
5607                     Slog.w(TAG, "Unable to create data directory: " + dataPath);
5608                     pkg.applicationInfo.dataDir = null;
5609                 }
5610             }
5611
5612             pkgSetting.uidError = uidError;
5613         }
5614
5615         final String path = scanFile.getPath();
5616         final String codePath = pkg.applicationInfo.getCodePath();
5617         final String cpuAbiOverride = deriveAbiOverride(pkg.cpuAbiOverride, pkgSetting);
5618         if (isSystemApp(pkg) && !isUpdatedSystemApp(pkg)) {
5619             setBundledAppAbisAndRoots(pkg, pkgSetting);
5620
5621             // If we haven't found any native libraries for the app, check if it has
5622             // renderscript code. We'll need to force the app to 32 bit if it has
5623             // renderscript bitcode.
5624             if (pkg.applicationInfo.primaryCpuAbi == null
5625                     && pkg.applicationInfo.secondaryCpuAbi == null
5626                     && Build.SUPPORTED_64_BIT_ABIS.length >  0) {
5627                 NativeLibraryHelper.Handle handle = null;
5628                 try {
5629                     handle = NativeLibraryHelper.Handle.create(scanFile);
5630                     if (NativeLibraryHelper.hasRenderscriptBitcode(handle)) {
5631                         pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
5632                     }
5633                 } catch (IOException ioe) {
5634                     Slog.w(TAG, "Error scanning system app : " + ioe);
5635                 } finally {
5636                     IoUtils.closeQuietly(handle);
5637                 }
5638             }
5639
5640             setNativeLibraryPaths(pkg);
5641         } else {
5642             // TODO: We can probably be smarter about this stuff. For installed apps,
5643             // we can calculate this information at install time once and for all. For
5644             // system apps, we can probably assume that this information doesn't change
5645             // after the first boot scan. As things stand, we do lots of unnecessary work.
5646
5647             // Give ourselves some initial paths; we'll come back for another
5648             // pass once we've determined ABI below.
5649             setNativeLibraryPaths(pkg);
5650
5651             final boolean isAsec = isForwardLocked(pkg) || isExternal(pkg);
5652             final String nativeLibraryRootStr = pkg.applicationInfo.nativeLibraryRootDir;
5653             final boolean useIsaSpecificSubdirs = pkg.applicationInfo.nativeLibraryRootRequiresIsa;
5654
5655             NativeLibraryHelper.Handle handle = null;
5656             try {
5657                 handle = NativeLibraryHelper.Handle.create(scanFile);
5658                 // TODO(multiArch): This can be null for apps that didn't go through the
5659                 // usual installation process. We can calculate it again, like we
5660                 // do during install time.
5661                 //
5662                 // TODO(multiArch): Why do we need to rescan ASEC apps again ? It seems totally
5663                 // unnecessary.
5664                 final File nativeLibraryRoot = new File(nativeLibraryRootStr);
5665
5666                 // Null out the abis so that they can be recalculated.
5667                 pkg.applicationInfo.primaryCpuAbi = null;
5668                 pkg.applicationInfo.secondaryCpuAbi = null;
5669                 if (isMultiArch(pkg.applicationInfo)) {
5670                     // Warn if we've set an abiOverride for multi-lib packages..
5671                     // By definition, we need to copy both 32 and 64 bit libraries for
5672                     // such packages.
5673                     if (pkg.cpuAbiOverride != null
5674                             && !NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(pkg.cpuAbiOverride)) {
5675                         Slog.w(TAG, "Ignoring abiOverride for multi arch application.");
5676                     }
5677
5678                     int abi32 = PackageManager.NO_NATIVE_LIBRARIES;
5679                     int abi64 = PackageManager.NO_NATIVE_LIBRARIES;
5680                     if (Build.SUPPORTED_32_BIT_ABIS.length > 0) {
5681                         if (isAsec) {
5682                             abi32 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_32_BIT_ABIS);
5683                         } else {
5684                             abi32 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
5685                                     nativeLibraryRoot, Build.SUPPORTED_32_BIT_ABIS,
5686                                     useIsaSpecificSubdirs);
5687                         }
5688                     }
5689
5690                     maybeThrowExceptionForMultiArchCopy(
5691                             "Error unpackaging 32 bit native libs for multiarch app.", abi32);
5692
5693                     if (Build.SUPPORTED_64_BIT_ABIS.length > 0) {
5694                         if (isAsec) {
5695                             abi64 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_64_BIT_ABIS);
5696                         } else {
5697                             abi64 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
5698                                     nativeLibraryRoot, Build.SUPPORTED_64_BIT_ABIS,
5699                                     useIsaSpecificSubdirs);
5700                         }
5701                     }
5702
5703                     maybeThrowExceptionForMultiArchCopy(
5704                             "Error unpackaging 64 bit native libs for multiarch app.", abi64);
5705
5706                     if (abi64 >= 0) {
5707                         pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[abi64];
5708                     }
5709
5710                     if (abi32 >= 0) {
5711                         final String abi = Build.SUPPORTED_32_BIT_ABIS[abi32];
5712                         if (abi64 >= 0) {
5713                             pkg.applicationInfo.secondaryCpuAbi = abi;
5714                         } else {
5715                             pkg.applicationInfo.primaryCpuAbi = abi;
5716                         }
5717                     }
5718                 } else {
5719                     String[] abiList = (cpuAbiOverride != null) ?
5720                             new String[] { cpuAbiOverride } : Build.SUPPORTED_ABIS;
5721
5722                     // Enable gross and lame hacks for apps that are built with old
5723                     // SDK tools. We must scan their APKs for renderscript bitcode and
5724                     // not launch them if it's present. Don't bother checking on devices
5725                     // that don't have 64 bit support.
5726                     boolean needsRenderScriptOverride = false;
5727                     if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && cpuAbiOverride == null &&
5728                             NativeLibraryHelper.hasRenderscriptBitcode(handle)) {
5729                         abiList = Build.SUPPORTED_32_BIT_ABIS;
5730                         needsRenderScriptOverride = true;
5731                     }
5732
5733                     final int copyRet;
5734                     if (isAsec) {
5735                         copyRet = NativeLibraryHelper.findSupportedAbi(handle, abiList);
5736                     } else {
5737                         copyRet = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
5738                                 nativeLibraryRoot, abiList, useIsaSpecificSubdirs);
5739                     }
5740
5741                     if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) {
5742                         throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
5743                                 "Error unpackaging native libs for app, errorCode=" + copyRet);
5744                     }
5745
5746                     if (copyRet >= 0) {
5747                         pkg.applicationInfo.primaryCpuAbi = abiList[copyRet];
5748                     } else if (copyRet == PackageManager.NO_NATIVE_LIBRARIES && cpuAbiOverride != null) {
5749                         pkg.applicationInfo.primaryCpuAbi = cpuAbiOverride;
5750                     } else if (needsRenderScriptOverride) {
5751                         pkg.applicationInfo.primaryCpuAbi = abiList[0];
5752                     }
5753                 }
5754             } catch (IOException ioe) {
5755                 Slog.e(TAG, "Unable to get canonical file " + ioe.toString());
5756             } finally {
5757                 IoUtils.closeQuietly(handle);
5758             }
5759
5760             // Now that we've calculated the ABIs and determined if it's an internal app,
5761             // we will go ahead and populate the nativeLibraryPath.
5762             setNativeLibraryPaths(pkg);
5763
5764             if (DEBUG_INSTALL) Slog.i(TAG, "Linking native library dir for " + path);
5765             final int[] userIds = sUserManager.getUserIds();
5766             synchronized (mInstallLock) {
5767                 // Create a native library symlink only if we have native libraries
5768                 // and if the native libraries are 32 bit libraries. We do not provide
5769                 // this symlink for 64 bit libraries.
5770                 if (pkg.applicationInfo.primaryCpuAbi != null &&
5771                         !VMRuntime.is64BitAbi(pkg.applicationInfo.primaryCpuAbi)) {
5772                     final String nativeLibPath = pkg.applicationInfo.nativeLibraryDir;
5773                     for (int userId : userIds) {
5774                         if (mInstaller.linkNativeLibraryDirectory(pkg.packageName, nativeLibPath, userId) < 0) {
5775                             throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
5776                                     "Failed linking native library dir (user=" + userId + ")");
5777                         }
5778                     }
5779                 }
5780             }
5781         }
5782
5783         // This is a special case for the "system" package, where the ABI is
5784         // dictated by the zygote configuration (and init.rc). We should keep track
5785         // of this ABI so that we can deal with "normal" applications that run under
5786         // the same UID correctly.
5787         if (mPlatformPackage == pkg) {
5788             pkg.applicationInfo.primaryCpuAbi = VMRuntime.getRuntime().is64Bit() ?
5789                     Build.SUPPORTED_64_BIT_ABIS[0] : Build.SUPPORTED_32_BIT_ABIS[0];
5790         }
5791
5792         pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
5793         pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
5794         pkgSetting.cpuAbiOverrideString = cpuAbiOverride;
5795         // Copy the derived override back to the parsed package, so that we can
5796         // update the package settings accordingly.
5797         pkg.cpuAbiOverride = cpuAbiOverride;
5798
5799         if (DEBUG_ABI_SELECTION) {
5800             Slog.d(TAG, "Resolved nativeLibraryRoot for " + pkg.applicationInfo.packageName
5801                     + " to root=" + pkg.applicationInfo.nativeLibraryRootDir + ", isa="
5802                     + pkg.applicationInfo.nativeLibraryRootRequiresIsa);
5803         }
5804
5805         // Push the derived path down into PackageSettings so we know what to
5806         // clean up at uninstall time.
5807         pkgSetting.legacyNativeLibraryPathString = pkg.applicationInfo.nativeLibraryRootDir;
5808
5809         if (DEBUG_ABI_SELECTION) {
5810             Log.d(TAG, "Abis for package[" + pkg.packageName + "] are" +
5811                     " primary=" + pkg.applicationInfo.primaryCpuAbi +
5812                     " secondary=" + pkg.applicationInfo.secondaryCpuAbi);
5813         }
5814
5815         if ((scanFlags&SCAN_BOOTING) == 0 && pkgSetting.sharedUser != null) {
5816             // We don't do this here during boot because we can do it all
5817             // at once after scanning all existing packages.
5818             //
5819             // We also do this *before* we perform dexopt on this package, so that
5820             // we can avoid redundant dexopts, and also to make sure we've got the
5821             // code and package path correct.
5822             adjustCpuAbisForSharedUserLPw(pkgSetting.sharedUser.packages,
5823                     pkg, forceDex, (scanFlags & SCAN_DEFER_DEX) != 0);
5824         }
5825
5826         if ((scanFlags & SCAN_NO_DEX) == 0) {
5827             if (performDexOptLI(pkg, null /* instruction sets */, forceDex,
5828                     (scanFlags & SCAN_DEFER_DEX) != 0, false) == DEX_OPT_FAILED) {
5829                 throw new PackageManagerException(INSTALL_FAILED_DEXOPT, "scanPackageLI");
5830             }
5831         }
5832
5833         if (mFactoryTest && pkg.requestedPermissions.contains(
5834                 android.Manifest.permission.FACTORY_TEST)) {
5835             pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST;
5836         }
5837
5838         ArrayList<PackageParser.Package> clientLibPkgs = null;
5839
5840         // writer
5841         synchronized (mPackages) {
5842             if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
5843                 // Only system apps can add new shared libraries.
5844                 if (pkg.libraryNames != null) {
5845                     for (int i=0; i<pkg.libraryNames.size(); i++) {
5846                         String name = pkg.libraryNames.get(i);
5847                         boolean allowed = false;
5848                         if (isUpdatedSystemApp(pkg)) {
5849                             // New library entries can only be added through the
5850                             // system image.  This is important to get rid of a lot
5851                             // of nasty edge cases: for example if we allowed a non-
5852                             // system update of the app to add a library, then uninstalling
5853                             // the update would make the library go away, and assumptions
5854                             // we made such as through app install filtering would now
5855                             // have allowed apps on the device which aren't compatible
5856                             // with it.  Better to just have the restriction here, be
5857                             // conservative, and create many fewer cases that can negatively
5858                             // impact the user experience.
5859                             final PackageSetting sysPs = mSettings
5860                                     .getDisabledSystemPkgLPr(pkg.packageName);
5861                             if (sysPs.pkg != null && sysPs.pkg.libraryNames != null) {
5862                                 for (int j=0; j<sysPs.pkg.libraryNames.size(); j++) {
5863                                     if (name.equals(sysPs.pkg.libraryNames.get(j))) {
5864                                         allowed = true;
5865                                         allowed = true;
5866                                         break;
5867                                     }
5868                                 }
5869                             }
5870                         } else {
5871                             allowed = true;
5872                         }
5873                         if (allowed) {
5874                             if (!mSharedLibraries.containsKey(name)) {
5875                                 mSharedLibraries.put(name, new SharedLibraryEntry(null, pkg.packageName));
5876                             } else if (!name.equals(pkg.packageName)) {
5877                                 Slog.w(TAG, "Package " + pkg.packageName + " library "
5878                                         + name + " already exists; skipping");
5879                             }
5880                         } else {
5881                             Slog.w(TAG, "Package " + pkg.packageName + " declares lib "
5882                                     + name + " that is not declared on system image; skipping");
5883                         }
5884                     }
5885                     if ((scanFlags&SCAN_BOOTING) == 0) {
5886                         // If we are not booting, we need to update any applications
5887                         // that are clients of our shared library.  If we are booting,
5888                         // this will all be done once the scan is complete.
5889                         clientLibPkgs = updateAllSharedLibrariesLPw(pkg);
5890                     }
5891                 }
5892             }
5893         }
5894
5895         // We also need to dexopt any apps that are dependent on this library.  Note that
5896         // if these fail, we should abort the install since installing the library will
5897         // result in some apps being broken.
5898         if (clientLibPkgs != null) {
5899             if ((scanFlags & SCAN_NO_DEX) == 0) {
5900                 for (int i = 0; i < clientLibPkgs.size(); i++) {
5901                     PackageParser.Package clientPkg = clientLibPkgs.get(i);
5902                     if (performDexOptLI(clientPkg, null /* instruction sets */, forceDex,
5903                             (scanFlags & SCAN_DEFER_DEX) != 0, false) == DEX_OPT_FAILED) {
5904                         throw new PackageManagerException(INSTALL_FAILED_DEXOPT,
5905                                 "scanPackageLI failed to dexopt clientLibPkgs");
5906                     }
5907                 }
5908             }
5909         }
5910
5911         // Request the ActivityManager to kill the process(only for existing packages)
5912         // so that we do not end up in a confused state while the user is still using the older
5913         // version of the application while the new one gets installed.
5914         if ((scanFlags & SCAN_REPLACING) != 0) {
5915             killApplication(pkg.applicationInfo.packageName,
5916                         pkg.applicationInfo.uid, "update pkg");
5917         }
5918
5919         // Also need to kill any apps that are dependent on the library.
5920         if (clientLibPkgs != null) {
5921             for (int i=0; i<clientLibPkgs.size(); i++) {
5922                 PackageParser.Package clientPkg = clientLibPkgs.get(i);
5923                 killApplication(clientPkg.applicationInfo.packageName,
5924                         clientPkg.applicationInfo.uid, "update lib");
5925             }
5926         }
5927
5928         // writer
5929         synchronized (mPackages) {
5930             // We don't expect installation to fail beyond this point
5931
5932             // Add the new setting to mSettings
5933             mSettings.insertPackageSettingLPw(pkgSetting, pkg);
5934             // Add the new setting to mPackages
5935             mPackages.put(pkg.applicationInfo.packageName, pkg);
5936             // Make sure we don't accidentally delete its data.
5937             final Iterator<PackageCleanItem> iter = mSettings.mPackagesToBeCleaned.iterator();
5938             while (iter.hasNext()) {
5939                 PackageCleanItem item = iter.next();
5940                 if (pkgName.equals(item.packageName)) {
5941                     iter.remove();
5942                 }
5943             }
5944
5945             // Take care of first install / last update times.
5946             if (currentTime != 0) {
5947                 if (pkgSetting.firstInstallTime == 0) {
5948                     pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = currentTime;
5949                 } else if ((scanFlags&SCAN_UPDATE_TIME) != 0) {
5950                     pkgSetting.lastUpdateTime = currentTime;
5951                 }
5952             } else if (pkgSetting.firstInstallTime == 0) {
5953                 // We need *something*.  Take time time stamp of the file.
5954                 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = scanFileTime;
5955             } else if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) != 0) {
5956                 if (scanFileTime != pkgSetting.timeStamp) {
5957                     // A package on the system image has changed; consider this
5958                     // to be an update.
5959                     pkgSetting.lastUpdateTime = scanFileTime;
5960                 }
5961             }
5962
5963             // Add the package's KeySets to the global KeySetManagerService
5964             KeySetManagerService ksms = mSettings.mKeySetManagerService;
5965             try {
5966                 // Old KeySetData no longer valid.
5967                 ksms.removeAppKeySetDataLPw(pkg.packageName);
5968                 ksms.addSigningKeySetToPackageLPw(pkg.packageName, pkg.mSigningKeys);
5969                 if (pkg.mKeySetMapping != null) {
5970                     for (Map.Entry<String, ArraySet<PublicKey>> entry :
5971                             pkg.mKeySetMapping.entrySet()) {
5972                         if (entry.getValue() != null) {
5973                             ksms.addDefinedKeySetToPackageLPw(pkg.packageName,
5974                                                           entry.getValue(), entry.getKey());
5975                         }
5976                     }
5977                     if (pkg.mUpgradeKeySets != null) {
5978                         for (String upgradeAlias : pkg.mUpgradeKeySets) {
5979                             ksms.addUpgradeKeySetToPackageLPw(pkg.packageName, upgradeAlias);
5980                         }
5981                     }
5982                 }
5983             } catch (NullPointerException e) {
5984                 Slog.e(TAG, "Could not add KeySet to " + pkg.packageName, e);
5985             } catch (IllegalArgumentException e) {
5986                 Slog.e(TAG, "Could not add KeySet to malformed package" + pkg.packageName, e);
5987             }
5988
5989             int N = pkg.providers.size();
5990             StringBuilder r = null;
5991             int i;
5992             for (i=0; i<N; i++) {
5993                 PackageParser.Provider p = pkg.providers.get(i);
5994                 p.info.processName = fixProcessName(pkg.applicationInfo.processName,
5995                         p.info.processName, pkg.applicationInfo.uid);
5996                 mProviders.addProvider(p);
5997                 p.syncable = p.info.isSyncable;
5998                 if (p.info.authority != null) {
5999                     String names[] = p.info.authority.split(";");
6000                     p.info.authority = null;
6001                     for (int j = 0; j < names.length; j++) {
6002                         if (j == 1 && p.syncable) {
6003                             // We only want the first authority for a provider to possibly be
6004                             // syncable, so if we already added this provider using a different
6005                             // authority clear the syncable flag. We copy the provider before
6006                             // changing it because the mProviders object contains a reference
6007                             // to a provider that we don't want to change.
6008                             // Only do this for the second authority since the resulting provider
6009                             // object can be the same for all future authorities for this provider.
6010                             p = new PackageParser.Provider(p);
6011                             p.syncable = false;
6012                         }
6013                         if (!mProvidersByAuthority.containsKey(names[j])) {
6014                             mProvidersByAuthority.put(names[j], p);
6015                             if (p.info.authority == null) {
6016                                 p.info.authority = names[j];
6017                             } else {
6018                                 p.info.authority = p.info.authority + ";" + names[j];
6019                             }
6020                             if (DEBUG_PACKAGE_SCANNING) {
6021                                 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
6022                                     Log.d(TAG, "Registered content provider: " + names[j]
6023                                             + ", className = " + p.info.name + ", isSyncable = "
6024                                             + p.info.isSyncable);
6025                             }
6026                         } else {
6027                             PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
6028                             Slog.w(TAG, "Skipping provider name " + names[j] +
6029                                     " (in package " + pkg.applicationInfo.packageName +
6030                                     "): name already used by "
6031                                     + ((other != null && other.getComponentName() != null)
6032                                             ? other.getComponentName().getPackageName() : "?"));
6033                         }
6034                     }
6035                 }
6036                 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
6037                     if (r == null) {
6038                         r = new StringBuilder(256);
6039                     } else {
6040                         r.append(' ');
6041                     }
6042                     r.append(p.info.name);
6043                 }
6044             }
6045             if (r != null) {
6046                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Providers: " + r);
6047             }
6048
6049             N = pkg.services.size();
6050             r = null;
6051             for (i=0; i<N; i++) {
6052                 PackageParser.Service s = pkg.services.get(i);
6053                 s.info.processName = fixProcessName(pkg.applicationInfo.processName,
6054                         s.info.processName, pkg.applicationInfo.uid);
6055                 mServices.addService(s);
6056                 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
6057                     if (r == null) {
6058                         r = new StringBuilder(256);
6059                     } else {
6060                         r.append(' ');
6061                     }
6062                     r.append(s.info.name);
6063                 }
6064             }
6065             if (r != null) {
6066                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Services: " + r);
6067             }
6068
6069             N = pkg.receivers.size();
6070             r = null;
6071             for (i=0; i<N; i++) {
6072                 PackageParser.Activity a = pkg.receivers.get(i);
6073                 a.info.processName = fixProcessName(pkg.applicationInfo.processName,
6074                         a.info.processName, pkg.applicationInfo.uid);
6075                 mReceivers.addActivity(a, "receiver");
6076                 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
6077                     if (r == null) {
6078                         r = new StringBuilder(256);
6079                     } else {
6080                         r.append(' ');
6081                     }
6082                     r.append(a.info.name);
6083                 }
6084             }
6085             if (r != null) {
6086                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Receivers: " + r);
6087             }
6088
6089             N = pkg.activities.size();
6090             r = null;
6091             for (i=0; i<N; i++) {
6092                 PackageParser.Activity a = pkg.activities.get(i);
6093                 a.info.processName = fixProcessName(pkg.applicationInfo.processName,
6094                         a.info.processName, pkg.applicationInfo.uid);
6095                 mActivities.addActivity(a, "activity");
6096                 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
6097                     if (r == null) {
6098                         r = new StringBuilder(256);
6099                     } else {
6100                         r.append(' ');
6101                     }
6102                     r.append(a.info.name);
6103                 }
6104             }
6105             if (r != null) {
6106                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Activities: " + r);
6107             }
6108
6109             N = pkg.permissionGroups.size();
6110             r = null;
6111             for (i=0; i<N; i++) {
6112                 PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i);
6113                 PackageParser.PermissionGroup cur = mPermissionGroups.get(pg.info.name);
6114                 if (cur == null) {
6115                     mPermissionGroups.put(pg.info.name, pg);
6116                     if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
6117                         if (r == null) {
6118                             r = new StringBuilder(256);
6119                         } else {
6120                             r.append(' ');
6121                         }
6122                         r.append(pg.info.name);
6123                     }
6124                 } else {
6125                     Slog.w(TAG, "Permission group " + pg.info.name + " from package "
6126                             + pg.info.packageName + " ignored: original from "
6127                             + cur.info.packageName);
6128                     if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
6129                         if (r == null) {
6130                             r = new StringBuilder(256);
6131                         } else {
6132                             r.append(' ');
6133                         }
6134                         r.append("DUP:");
6135                         r.append(pg.info.name);
6136                     }
6137                 }
6138             }
6139             if (r != null) {
6140                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Permission Groups: " + r);
6141             }
6142
6143             N = pkg.permissions.size();
6144             r = null;
6145             for (i=0; i<N; i++) {
6146                 PackageParser.Permission p = pkg.permissions.get(i);
6147                 HashMap<String, BasePermission> permissionMap =
6148                         p.tree ? mSettings.mPermissionTrees
6149                         : mSettings.mPermissions;
6150                 p.group = mPermissionGroups.get(p.info.group);
6151                 if (p.info.group == null || p.group != null) {
6152                     BasePermission bp = permissionMap.get(p.info.name);
6153
6154                     // Allow system apps to redefine non-system permissions
6155                     if (bp != null && !Objects.equals(bp.sourcePackage, p.info.packageName)) {
6156                         final boolean currentOwnerIsSystem = (bp.perm != null
6157                                 && isSystemApp(bp.perm.owner));
6158                         if (isSystemApp(p.owner)) {
6159                             if (bp.type == BasePermission.TYPE_BUILTIN && bp.perm == null) {
6160                                 // It's a built-in permission and no owner, take ownership now
6161                                 bp.packageSetting = pkgSetting;
6162                                 bp.perm = p;
6163                                 bp.uid = pkg.applicationInfo.uid;
6164                                 bp.sourcePackage = p.info.packageName;
6165                             } else if (!currentOwnerIsSystem) {
6166                                 String msg = "New decl " + p.owner + " of permission  "
6167                                         + p.info.name + " is system; overriding " + bp.sourcePackage;
6168                                 reportSettingsProblem(Log.WARN, msg);
6169                                 bp = null;
6170                             }
6171                         }
6172                     }
6173
6174                     if (bp == null) {
6175                         bp = new BasePermission(p.info.name, p.info.packageName,
6176                                 BasePermission.TYPE_NORMAL);
6177                         permissionMap.put(p.info.name, bp);
6178                     }
6179
6180                     if (bp.perm == null) {
6181                         if (bp.sourcePackage == null
6182                                 || bp.sourcePackage.equals(p.info.packageName)) {
6183                             BasePermission tree = findPermissionTreeLP(p.info.name);
6184                             if (tree == null
6185                                     || tree.sourcePackage.equals(p.info.packageName)) {
6186                                 bp.packageSetting = pkgSetting;
6187                                 bp.perm = p;
6188                                 bp.uid = pkg.applicationInfo.uid;
6189                                 bp.sourcePackage = p.info.packageName;
6190                                 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
6191                                     if (r == null) {
6192                                         r = new StringBuilder(256);
6193                                     } else {
6194                                         r.append(' ');
6195                                     }
6196                                     r.append(p.info.name);
6197                                 }
6198                             } else {
6199                                 Slog.w(TAG, "Permission " + p.info.name + " from package "
6200                                         + p.info.packageName + " ignored: base tree "
6201                                         + tree.name + " is from package "
6202                                         + tree.sourcePackage);
6203                             }
6204                         } else {
6205                             Slog.w(TAG, "Permission " + p.info.name + " from package "
6206                                     + p.info.packageName + " ignored: original from "
6207                                     + bp.sourcePackage);
6208                         }
6209                     } else if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
6210                         if (r == null) {
6211                             r = new StringBuilder(256);
6212                         } else {
6213                             r.append(' ');
6214                         }
6215                         r.append("DUP:");
6216                         r.append(p.info.name);
6217                     }
6218                     if (bp.perm == p) {
6219                         bp.protectionLevel = p.info.protectionLevel;
6220                     }
6221                 } else {
6222                     Slog.w(TAG, "Permission " + p.info.name + " from package "
6223                             + p.info.packageName + " ignored: no group "
6224                             + p.group);
6225                 }
6226             }
6227             if (r != null) {
6228                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Permissions: " + r);
6229             }
6230
6231             N = pkg.instrumentation.size();
6232             r = null;
6233             for (i=0; i<N; i++) {
6234                 PackageParser.Instrumentation a = pkg.instrumentation.get(i);
6235                 a.info.packageName = pkg.applicationInfo.packageName;
6236                 a.info.sourceDir = pkg.applicationInfo.sourceDir;
6237                 a.info.publicSourceDir = pkg.applicationInfo.publicSourceDir;
6238                 a.info.splitSourceDirs = pkg.applicationInfo.splitSourceDirs;
6239                 a.info.splitPublicSourceDirs = pkg.applicationInfo.splitPublicSourceDirs;
6240                 a.info.dataDir = pkg.applicationInfo.dataDir;
6241
6242                 // TODO: Update instrumentation.nativeLibraryDir as well ? Does it
6243                 // need other information about the application, like the ABI and what not ?
6244                 a.info.nativeLibraryDir = pkg.applicationInfo.nativeLibraryDir;
6245                 mInstrumentation.put(a.getComponentName(), a);
6246                 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
6247                     if (r == null) {
6248                         r = new StringBuilder(256);
6249                     } else {
6250                         r.append(' ');
6251                     }
6252                     r.append(a.info.name);
6253                 }
6254             }
6255             if (r != null) {
6256                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Instrumentation: " + r);
6257             }
6258
6259             if (pkg.protectedBroadcasts != null) {
6260                 N = pkg.protectedBroadcasts.size();
6261                 for (i=0; i<N; i++) {
6262                     mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i));
6263                 }
6264             }
6265
6266             pkgSetting.setTimeStamp(scanFileTime);
6267
6268             // Create idmap files for pairs of (packages, overlay packages).
6269             // Note: "android", ie framework-res.apk, is handled by native layers.
6270             if (pkg.mOverlayTarget != null) {
6271                 // This is an overlay package.
6272                 if (pkg.mOverlayTarget != null && !pkg.mOverlayTarget.equals("android")) {
6273                     if (!mOverlays.containsKey(pkg.mOverlayTarget)) {
6274                         mOverlays.put(pkg.mOverlayTarget,
6275                                 new HashMap<String, PackageParser.Package>());
6276                     }
6277                     HashMap<String, PackageParser.Package> map = mOverlays.get(pkg.mOverlayTarget);
6278                     map.put(pkg.packageName, pkg);
6279                     PackageParser.Package orig = mPackages.get(pkg.mOverlayTarget);
6280                     if (orig != null && !createIdmapForPackagePairLI(orig, pkg)) {
6281                         throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
6282                                 "scanPackageLI failed to createIdmap");
6283                     }
6284                 }
6285             } else if (mOverlays.containsKey(pkg.packageName) &&
6286                     !pkg.packageName.equals("android")) {
6287                 // This is a regular package, with one or more known overlay packages.
6288                 createIdmapsForPackageLI(pkg);
6289             }
6290         }
6291
6292         return pkg;
6293     }
6294
6295     /**
6296      * Adjusts ABIs for a set of packages belonging to a shared user so that they all match.
6297      * i.e, so that all packages can be run inside a single process if required.
6298      *
6299      * Optionally, callers can pass in a parsed package via {@code newPackage} in which case
6300      * this function will either try and make the ABI for all packages in {@code packagesForUser}
6301      * match {@code scannedPackage} or will update the ABI of {@code scannedPackage} to match
6302      * the ABI selected for {@code packagesForUser}. This variant is used when installing or
6303      * updating a package that belongs to a shared user.
6304      *
6305      * NOTE: We currently only match for the primary CPU abi string. Matching the secondary
6306      * adds unnecessary complexity.
6307      */
6308     private void adjustCpuAbisForSharedUserLPw(Set<PackageSetting> packagesForUser,
6309             PackageParser.Package scannedPackage, boolean forceDexOpt, boolean deferDexOpt) {
6310         String requiredInstructionSet = null;
6311         if (scannedPackage != null && scannedPackage.applicationInfo.primaryCpuAbi != null) {
6312             requiredInstructionSet = VMRuntime.getInstructionSet(
6313                      scannedPackage.applicationInfo.primaryCpuAbi);
6314         }
6315
6316         PackageSetting requirer = null;
6317         for (PackageSetting ps : packagesForUser) {
6318             // If packagesForUser contains scannedPackage, we skip it. This will happen
6319             // when scannedPackage is an update of an existing package. Without this check,
6320             // we will never be able to change the ABI of any package belonging to a shared
6321             // user, even if it's compatible with other packages.
6322             if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
6323                 if (ps.primaryCpuAbiString == null) {
6324                     continue;
6325                 }
6326
6327                 final String instructionSet = VMRuntime.getInstructionSet(ps.primaryCpuAbiString);
6328                 if (requiredInstructionSet != null && !instructionSet.equals(requiredInstructionSet)) {
6329                     // We have a mismatch between instruction sets (say arm vs arm64) warn about
6330                     // this but there's not much we can do.
6331                     String errorMessage = "Instruction set mismatch, "
6332                             + ((requirer == null) ? "[caller]" : requirer)
6333                             + " requires " + requiredInstructionSet + " whereas " + ps
6334                             + " requires " + instructionSet;
6335                     Slog.w(TAG, errorMessage);
6336                 }
6337
6338                 if (requiredInstructionSet == null) {
6339                     requiredInstructionSet = instructionSet;
6340                     requirer = ps;
6341                 }
6342             }
6343         }
6344
6345         if (requiredInstructionSet != null) {
6346             String adjustedAbi;
6347             if (requirer != null) {
6348                 // requirer != null implies that either scannedPackage was null or that scannedPackage
6349                 // did not require an ABI, in which case we have to adjust scannedPackage to match
6350                 // the ABI of the set (which is the same as requirer's ABI)
6351                 adjustedAbi = requirer.primaryCpuAbiString;
6352                 if (scannedPackage != null) {
6353                     scannedPackage.applicationInfo.primaryCpuAbi = adjustedAbi;
6354                 }
6355             } else {
6356                 // requirer == null implies that we're updating all ABIs in the set to
6357                 // match scannedPackage.
6358                 adjustedAbi =  scannedPackage.applicationInfo.primaryCpuAbi;
6359             }
6360
6361             for (PackageSetting ps : packagesForUser) {
6362                 if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
6363                     if (ps.primaryCpuAbiString != null) {
6364                         continue;
6365                     }
6366
6367                     ps.primaryCpuAbiString = adjustedAbi;
6368                     if (ps.pkg != null && ps.pkg.applicationInfo != null) {
6369                         ps.pkg.applicationInfo.primaryCpuAbi = adjustedAbi;
6370                         Slog.i(TAG, "Adjusting ABI for : " + ps.name + " to " + adjustedAbi);
6371
6372                         if (performDexOptLI(ps.pkg, null /* instruction sets */, forceDexOpt,
6373                                 deferDexOpt, true) == DEX_OPT_FAILED) {
6374                             ps.primaryCpuAbiString = null;
6375                             ps.pkg.applicationInfo.primaryCpuAbi = null;
6376                             return;
6377                         } else {
6378                             mInstaller.rmdex(ps.codePathString,
6379                                              getDexCodeInstructionSet(getPreferredInstructionSet()));
6380                         }
6381                     }
6382                 }
6383             }
6384         }
6385     }
6386
6387     private void setUpCustomResolverActivity(PackageParser.Package pkg) {
6388         synchronized (mPackages) {
6389             mResolverReplaced = true;
6390             // Set up information for custom user intent resolution activity.
6391             mResolveActivity.applicationInfo = pkg.applicationInfo;
6392             mResolveActivity.name = mCustomResolverComponentName.getClassName();
6393             mResolveActivity.packageName = pkg.applicationInfo.packageName;
6394             mResolveActivity.processName = null;
6395             mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
6396             mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS |
6397                     ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
6398             mResolveActivity.theme = 0;
6399             mResolveActivity.exported = true;
6400             mResolveActivity.enabled = true;
6401             mResolveInfo.activityInfo = mResolveActivity;
6402             mResolveInfo.priority = 0;
6403             mResolveInfo.preferredOrder = 0;
6404             mResolveInfo.match = 0;
6405             mResolveComponentName = mCustomResolverComponentName;
6406             Slog.i(TAG, "Replacing default ResolverActivity with custom activity: " +
6407                     mResolveComponentName);
6408         }
6409     }
6410
6411     private static String calculateBundledApkRoot(final String codePathString) {
6412         final File codePath = new File(codePathString);
6413         final File codeRoot;
6414         if (FileUtils.contains(Environment.getRootDirectory(), codePath)) {
6415             codeRoot = Environment.getRootDirectory();
6416         } else if (FileUtils.contains(Environment.getOemDirectory(), codePath)) {
6417             codeRoot = Environment.getOemDirectory();
6418         } else if (FileUtils.contains(Environment.getVendorDirectory(), codePath)) {
6419             codeRoot = Environment.getVendorDirectory();
6420         } else {
6421             // Unrecognized code path; take its top real segment as the apk root:
6422             // e.g. /something/app/blah.apk => /something
6423             try {
6424                 File f = codePath.getCanonicalFile();
6425                 File parent = f.getParentFile();    // non-null because codePath is a file
6426                 File tmp;
6427                 while ((tmp = parent.getParentFile()) != null) {
6428                     f = parent;
6429                     parent = tmp;
6430                 }
6431                 codeRoot = f;
6432                 Slog.w(TAG, "Unrecognized code path "
6433                         + codePath + " - using " + codeRoot);
6434             } catch (IOException e) {
6435                 // Can't canonicalize the code path -- shenanigans?
6436                 Slog.w(TAG, "Can't canonicalize code path " + codePath);
6437                 return Environment.getRootDirectory().getPath();
6438             }
6439         }
6440         return codeRoot.getPath();
6441     }
6442
6443     /**
6444      * Derive and set the location of native libraries for the given package,
6445      * which varies depending on where and how the package was installed.
6446      */
6447     private void setNativeLibraryPaths(PackageParser.Package pkg) {
6448         final ApplicationInfo info = pkg.applicationInfo;
6449         final String codePath = pkg.codePath;
6450         final File codeFile = new File(codePath);
6451         final boolean bundledApp = isSystemApp(info) && !isUpdatedSystemApp(info);
6452         final boolean asecApp = isForwardLocked(info) || isExternal(info);
6453
6454         info.nativeLibraryRootDir = null;
6455         info.nativeLibraryRootRequiresIsa = false;
6456         info.nativeLibraryDir = null;
6457         info.secondaryNativeLibraryDir = null;
6458
6459         if (isApkFile(codeFile)) {
6460             // Monolithic install
6461             if (bundledApp) {
6462                 // If "/system/lib64/apkname" exists, assume that is the per-package
6463                 // native library directory to use; otherwise use "/system/lib/apkname".
6464                 final String apkRoot = calculateBundledApkRoot(info.sourceDir);
6465                 final boolean is64Bit = VMRuntime.is64BitInstructionSet(
6466                         getPrimaryInstructionSet(info));
6467
6468                 // This is a bundled system app so choose the path based on the ABI.
6469                 // if it's a 64 bit abi, use lib64 otherwise use lib32. Note that this
6470                 // is just the default path.
6471                 final String apkName = deriveCodePathName(codePath);
6472                 final String libDir = is64Bit ? LIB64_DIR_NAME : LIB_DIR_NAME;
6473                 info.nativeLibraryRootDir = Environment.buildPath(new File(apkRoot), libDir,
6474                         apkName).getAbsolutePath();
6475
6476                 if (info.secondaryCpuAbi != null) {
6477                     final String secondaryLibDir = is64Bit ? LIB_DIR_NAME : LIB64_DIR_NAME;
6478                     info.secondaryNativeLibraryDir = Environment.buildPath(new File(apkRoot),
6479                             secondaryLibDir, apkName).getAbsolutePath();
6480                 }
6481             } else if (asecApp) {
6482                 info.nativeLibraryRootDir = new File(codeFile.getParentFile(), LIB_DIR_NAME)
6483                         .getAbsolutePath();
6484             } else {
6485                 final String apkName = deriveCodePathName(codePath);
6486                 info.nativeLibraryRootDir = new File(mAppLib32InstallDir, apkName)
6487                         .getAbsolutePath();
6488             }
6489
6490             info.nativeLibraryRootRequiresIsa = false;
6491             info.nativeLibraryDir = info.nativeLibraryRootDir;
6492         } else {
6493             // Cluster install
6494             info.nativeLibraryRootDir = new File(codeFile, LIB_DIR_NAME).getAbsolutePath();
6495             info.nativeLibraryRootRequiresIsa = true;
6496
6497             info.nativeLibraryDir = new File(info.nativeLibraryRootDir,
6498                     getPrimaryInstructionSet(info)).getAbsolutePath();
6499
6500             if (info.secondaryCpuAbi != null) {
6501                 info.secondaryNativeLibraryDir = new File(info.nativeLibraryRootDir,
6502                         VMRuntime.getInstructionSet(info.secondaryCpuAbi)).getAbsolutePath();
6503             }
6504         }
6505     }
6506
6507     /**
6508      * Calculate the abis and roots for a bundled app. These can uniquely
6509      * be determined from the contents of the system partition, i.e whether
6510      * it contains 64 or 32 bit shared libraries etc. We do not validate any
6511      * of this information, and instead assume that the system was built
6512      * sensibly.
6513      */
6514     private void setBundledAppAbisAndRoots(PackageParser.Package pkg,
6515                                            PackageSetting pkgSetting) {
6516         final String apkName = deriveCodePathName(pkg.applicationInfo.getCodePath());
6517
6518         // If "/system/lib64/apkname" exists, assume that is the per-package
6519         // native library directory to use; otherwise use "/system/lib/apkname".
6520         final String apkRoot = calculateBundledApkRoot(pkg.applicationInfo.sourceDir);
6521         setBundledAppAbi(pkg, apkRoot, apkName);
6522         // pkgSetting might be null during rescan following uninstall of updates
6523         // to a bundled app, so accommodate that possibility.  The settings in
6524         // that case will be established later from the parsed package.
6525         //
6526         // If the settings aren't null, sync them up with what we've just derived.
6527         // note that apkRoot isn't stored in the package settings.
6528         if (pkgSetting != null) {
6529             pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
6530             pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
6531         }
6532     }
6533
6534     /**
6535      * Deduces the ABI of a bundled app and sets the relevant fields on the
6536      * parsed pkg object.
6537      *
6538      * @param apkRoot the root of the installed apk, something like {@code /system} or {@code /oem}
6539      *        under which system libraries are installed.
6540      * @param apkName the name of the installed package.
6541      */
6542     private static void setBundledAppAbi(PackageParser.Package pkg, String apkRoot, String apkName) {
6543         final File codeFile = new File(pkg.codePath);
6544
6545         final boolean has64BitLibs;
6546         final boolean has32BitLibs;
6547         if (isApkFile(codeFile)) {
6548             // Monolithic install
6549             has64BitLibs = (new File(apkRoot, new File(LIB64_DIR_NAME, apkName).getPath())).exists();
6550             has32BitLibs = (new File(apkRoot, new File(LIB_DIR_NAME, apkName).getPath())).exists();
6551         } else {
6552             // Cluster install
6553             final File rootDir = new File(codeFile, LIB_DIR_NAME);
6554             if (!ArrayUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS)
6555                     && !TextUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS[0])) {
6556                 final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_64_BIT_ABIS[0]);
6557                 has64BitLibs = (new File(rootDir, isa)).exists();
6558             } else {
6559                 has64BitLibs = false;
6560             }
6561             if (!ArrayUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS)
6562                     && !TextUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS[0])) {
6563                 final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_32_BIT_ABIS[0]);
6564                 has32BitLibs = (new File(rootDir, isa)).exists();
6565             } else {
6566                 has32BitLibs = false;
6567             }
6568         }
6569
6570         if (has64BitLibs && !has32BitLibs) {
6571             // The package has 64 bit libs, but not 32 bit libs. Its primary
6572             // ABI should be 64 bit. We can safely assume here that the bundled
6573             // native libraries correspond to the most preferred ABI in the list.
6574
6575             pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
6576             pkg.applicationInfo.secondaryCpuAbi = null;
6577         } else if (has32BitLibs && !has64BitLibs) {
6578             // The package has 32 bit libs but not 64 bit libs. Its primary
6579             // ABI should be 32 bit.
6580
6581             pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
6582             pkg.applicationInfo.secondaryCpuAbi = null;
6583         } else if (has32BitLibs && has64BitLibs) {
6584             // The application has both 64 and 32 bit bundled libraries. We check
6585             // here that the app declares multiArch support, and warn if it doesn't.
6586             //
6587             // We will be lenient here and record both ABIs. The primary will be the
6588             // ABI that's higher on the list, i.e, a device that's configured to prefer
6589             // 64 bit apps will see a 64 bit primary ABI,
6590
6591             if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) == 0) {
6592                 Slog.e(TAG, "Package: " + pkg + " has multiple bundled libs, but is not multiarch.");
6593             }
6594
6595             if (VMRuntime.is64BitInstructionSet(getPreferredInstructionSet())) {
6596                 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
6597                 pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
6598             } else {
6599                 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
6600                 pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
6601             }
6602         } else {
6603             pkg.applicationInfo.primaryCpuAbi = null;
6604             pkg.applicationInfo.secondaryCpuAbi = null;
6605         }
6606     }
6607
6608     private void killApplication(String pkgName, int appId, String reason) {
6609         // Request the ActivityManager to kill the process(only for existing packages)
6610         // so that we do not end up in a confused state while the user is still using the older
6611         // version of the application while the new one gets installed.
6612         IActivityManager am = ActivityManagerNative.getDefault();
6613         if (am != null) {
6614             try {
6615                 am.killApplicationWithAppId(pkgName, appId, reason);
6616             } catch (RemoteException e) {
6617             }
6618         }
6619     }
6620
6621     void removePackageLI(PackageSetting ps, boolean chatty) {
6622         if (DEBUG_INSTALL) {
6623             if (chatty)
6624                 Log.d(TAG, "Removing package " + ps.name);
6625         }
6626
6627         // writer
6628         synchronized (mPackages) {
6629             mPackages.remove(ps.name);
6630             final PackageParser.Package pkg = ps.pkg;
6631             if (pkg != null) {
6632                 cleanPackageDataStructuresLILPw(pkg, chatty);
6633             }
6634         }
6635     }
6636
6637     void removeInstalledPackageLI(PackageParser.Package pkg, boolean chatty) {
6638         if (DEBUG_INSTALL) {
6639             if (chatty)
6640                 Log.d(TAG, "Removing package " + pkg.applicationInfo.packageName);
6641         }
6642
6643         // writer
6644         synchronized (mPackages) {
6645             mPackages.remove(pkg.applicationInfo.packageName);
6646             cleanPackageDataStructuresLILPw(pkg, chatty);
6647         }
6648     }
6649
6650     void cleanPackageDataStructuresLILPw(PackageParser.Package pkg, boolean chatty) {
6651         int N = pkg.providers.size();
6652         StringBuilder r = null;
6653         int i;
6654         for (i=0; i<N; i++) {
6655             PackageParser.Provider p = pkg.providers.get(i);
6656             mProviders.removeProvider(p);
6657             if (p.info.authority == null) {
6658
6659                 /* There was another ContentProvider with this authority when
6660                  * this app was installed so this authority is null,
6661                  * Ignore it as we don't have to unregister the provider.
6662                  */
6663                 continue;
6664             }
6665             String names[] = p.info.authority.split(";");
6666             for (int j = 0; j < names.length; j++) {
6667                 if (mProvidersByAuthority.get(names[j]) == p) {
6668                     mProvidersByAuthority.remove(names[j]);
6669                     if (DEBUG_REMOVE) {
6670                         if (chatty)
6671                             Log.d(TAG, "Unregistered content provider: " + names[j]
6672                                     + ", className = " + p.info.name + ", isSyncable = "
6673                                     + p.info.isSyncable);
6674                     }
6675                 }
6676             }
6677             if (DEBUG_REMOVE && chatty) {
6678                 if (r == null) {
6679                     r = new StringBuilder(256);
6680                 } else {
6681                     r.append(' ');
6682                 }
6683                 r.append(p.info.name);
6684             }
6685         }
6686         if (r != null) {
6687             if (DEBUG_REMOVE) Log.d(TAG, "  Providers: " + r);
6688         }
6689
6690         N = pkg.services.size();
6691         r = null;
6692         for (i=0; i<N; i++) {
6693             PackageParser.Service s = pkg.services.get(i);
6694             mServices.removeService(s);
6695             if (chatty) {
6696                 if (r == null) {
6697                     r = new StringBuilder(256);
6698                 } else {
6699                     r.append(' ');
6700                 }
6701                 r.append(s.info.name);
6702             }
6703         }
6704         if (r != null) {
6705             if (DEBUG_REMOVE) Log.d(TAG, "  Services: " + r);
6706         }
6707
6708         N = pkg.receivers.size();
6709         r = null;
6710         for (i=0; i<N; i++) {
6711             PackageParser.Activity a = pkg.receivers.get(i);
6712             mReceivers.removeActivity(a, "receiver");
6713             if (DEBUG_REMOVE && chatty) {
6714                 if (r == null) {
6715                     r = new StringBuilder(256);
6716                 } else {
6717                     r.append(' ');
6718                 }
6719                 r.append(a.info.name);
6720             }
6721         }
6722         if (r != null) {
6723             if (DEBUG_REMOVE) Log.d(TAG, "  Receivers: " + r);
6724         }
6725
6726         N = pkg.activities.size();
6727         r = null;
6728         for (i=0; i<N; i++) {
6729             PackageParser.Activity a = pkg.activities.get(i);
6730             mActivities.removeActivity(a, "activity");
6731             if (DEBUG_REMOVE && chatty) {
6732                 if (r == null) {
6733                     r = new StringBuilder(256);
6734                 } else {
6735                     r.append(' ');
6736                 }
6737                 r.append(a.info.name);
6738             }
6739         }
6740         if (r != null) {
6741             if (DEBUG_REMOVE) Log.d(TAG, "  Activities: " + r);
6742         }
6743
6744         N = pkg.permissions.size();
6745         r = null;
6746         for (i=0; i<N; i++) {
6747             PackageParser.Permission p = pkg.permissions.get(i);
6748             BasePermission bp = mSettings.mPermissions.get(p.info.name);
6749             if (bp == null) {
6750                 bp = mSettings.mPermissionTrees.get(p.info.name);
6751             }
6752             if (bp != null && bp.perm == p) {
6753                 bp.perm = null;
6754                 if (DEBUG_REMOVE && chatty) {
6755                     if (r == null) {
6756                         r = new StringBuilder(256);
6757                     } else {
6758                         r.append(' ');
6759                     }
6760                     r.append(p.info.name);
6761                 }
6762             }
6763             if ((p.info.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
6764                 ArraySet<String> appOpPerms = mAppOpPermissionPackages.get(p.info.name);
6765                 if (appOpPerms != null) {
6766                     appOpPerms.remove(pkg.packageName);
6767                 }
6768             }
6769         }
6770         if (r != null) {
6771             if (DEBUG_REMOVE) Log.d(TAG, "  Permissions: " + r);
6772         }
6773
6774         N = pkg.requestedPermissions.size();
6775         r = null;
6776         for (i=0; i<N; i++) {
6777             String perm = pkg.requestedPermissions.get(i);
6778             BasePermission bp = mSettings.mPermissions.get(perm);
6779             if (bp != null && (bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
6780                 ArraySet<String> appOpPerms = mAppOpPermissionPackages.get(perm);
6781                 if (appOpPerms != null) {
6782                     appOpPerms.remove(pkg.packageName);
6783                     if (appOpPerms.isEmpty()) {
6784                         mAppOpPermissionPackages.remove(perm);
6785                     }
6786                 }
6787             }
6788         }
6789         if (r != null) {
6790             if (DEBUG_REMOVE) Log.d(TAG, "  Permissions: " + r);
6791         }
6792
6793         N = pkg.instrumentation.size();
6794         r = null;
6795         for (i=0; i<N; i++) {
6796             PackageParser.Instrumentation a = pkg.instrumentation.get(i);
6797             mInstrumentation.remove(a.getComponentName());
6798             if (DEBUG_REMOVE && chatty) {
6799                 if (r == null) {
6800                     r = new StringBuilder(256);
6801                 } else {
6802                     r.append(' ');
6803                 }
6804                 r.append(a.info.name);
6805             }
6806         }
6807         if (r != null) {
6808             if (DEBUG_REMOVE) Log.d(TAG, "  Instrumentation: " + r);
6809         }
6810
6811         r = null;
6812         if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
6813             // Only system apps can hold shared libraries.
6814             if (pkg.libraryNames != null) {
6815                 for (i=0; i<pkg.libraryNames.size(); i++) {
6816                     String name = pkg.libraryNames.get(i);
6817                     SharedLibraryEntry cur = mSharedLibraries.get(name);
6818                     if (cur != null && cur.apk != null && cur.apk.equals(pkg.packageName)) {
6819                         mSharedLibraries.remove(name);
6820                         if (DEBUG_REMOVE && chatty) {
6821                             if (r == null) {
6822                                 r = new StringBuilder(256);
6823                             } else {
6824                                 r.append(' ');
6825                             }
6826                             r.append(name);
6827                         }
6828                     }
6829                 }
6830             }
6831         }
6832         if (r != null) {
6833             if (DEBUG_REMOVE) Log.d(TAG, "  Libraries: " + r);
6834         }
6835     }
6836
6837     private static boolean hasPermission(PackageParser.Package pkgInfo, String perm) {
6838         for (int i=pkgInfo.permissions.size()-1; i>=0; i--) {
6839             if (pkgInfo.permissions.get(i).info.name.equals(perm)) {
6840                 return true;
6841             }
6842         }
6843         return false;
6844     }
6845
6846     static final int UPDATE_PERMISSIONS_ALL = 1<<0;
6847     static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1<<1;
6848     static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1<<2;
6849
6850     private void updatePermissionsLPw(String changingPkg,
6851             PackageParser.Package pkgInfo, int flags) {
6852         // Make sure there are no dangling permission trees.
6853         Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator();
6854         while (it.hasNext()) {
6855             final BasePermission bp = it.next();
6856             if (bp.packageSetting == null) {
6857                 // We may not yet have parsed the package, so just see if
6858                 // we still know about its settings.
6859                 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage);
6860             }
6861             if (bp.packageSetting == null) {
6862                 Slog.w(TAG, "Removing dangling permission tree: " + bp.name
6863                         + " from package " + bp.sourcePackage);
6864                 it.remove();
6865             } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) {
6866                 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
6867                     Slog.i(TAG, "Removing old permission tree: " + bp.name
6868                             + " from package " + bp.sourcePackage);
6869                     flags |= UPDATE_PERMISSIONS_ALL;
6870                     it.remove();
6871                 }
6872             }
6873         }
6874
6875         // Make sure all dynamic permissions have been assigned to a package,
6876         // and make sure there are no dangling permissions.
6877         it = mSettings.mPermissions.values().iterator();
6878         while (it.hasNext()) {
6879             final BasePermission bp = it.next();
6880             if (bp.type == BasePermission.TYPE_DYNAMIC) {
6881                 if (DEBUG_SETTINGS) Log.v(TAG, "Dynamic permission: name="
6882                         + bp.name + " pkg=" + bp.sourcePackage
6883                         + " info=" + bp.pendingInfo);
6884                 if (bp.packageSetting == null && bp.pendingInfo != null) {
6885                     final BasePermission tree = findPermissionTreeLP(bp.name);
6886                     if (tree != null && tree.perm != null) {
6887                         bp.packageSetting = tree.packageSetting;
6888                         bp.perm = new PackageParser.Permission(tree.perm.owner,
6889                                 new PermissionInfo(bp.pendingInfo));
6890                         bp.perm.info.packageName = tree.perm.info.packageName;
6891                         bp.perm.info.name = bp.name;
6892                         bp.uid = tree.uid;
6893                     }
6894                 }
6895             }
6896             if (bp.packageSetting == null) {
6897                 // We may not yet have parsed the package, so just see if
6898                 // we still know about its settings.
6899                 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage);
6900             }
6901             if (bp.packageSetting == null) {
6902                 Slog.w(TAG, "Removing dangling permission: " + bp.name
6903                         + " from package " + bp.sourcePackage);
6904                 it.remove();
6905             } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) {
6906                 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
6907                     Slog.i(TAG, "Removing old permission: " + bp.name
6908                             + " from package " + bp.sourcePackage);
6909                     flags |= UPDATE_PERMISSIONS_ALL;
6910                     it.remove();
6911                 }
6912             }
6913         }
6914
6915         // Now update the permissions for all packages, in particular
6916         // replace the granted permissions of the system packages.
6917         if ((flags&UPDATE_PERMISSIONS_ALL) != 0) {
6918             for (PackageParser.Package pkg : mPackages.values()) {
6919                 if (pkg != pkgInfo) {
6920                     grantPermissionsLPw(pkg, (flags&UPDATE_PERMISSIONS_REPLACE_ALL) != 0,
6921                             changingPkg);
6922                 }
6923             }
6924         }
6925         
6926         if (pkgInfo != null) {
6927             grantPermissionsLPw(pkgInfo, (flags&UPDATE_PERMISSIONS_REPLACE_PKG) != 0, changingPkg);
6928         }
6929     }
6930
6931     private void grantPermissionsLPw(PackageParser.Package pkg, boolean replace,
6932             String packageOfInterest) {
6933         final PackageSetting ps = (PackageSetting) pkg.mExtras;
6934         if (ps == null) {
6935             return;
6936         }
6937         final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps;
6938         HashSet<String> origPermissions = gp.grantedPermissions;
6939         boolean changedPermission = false;
6940
6941         if (replace) {
6942             ps.permissionsFixed = false;
6943             if (gp == ps) {
6944                 origPermissions = new HashSet<String>(gp.grantedPermissions);
6945                 gp.grantedPermissions.clear();
6946                 gp.gids = mGlobalGids;
6947             }
6948         }
6949
6950         if (gp.gids == null) {
6951             gp.gids = mGlobalGids;
6952         }
6953
6954         final int N = pkg.requestedPermissions.size();
6955         for (int i=0; i<N; i++) {
6956             final String name = pkg.requestedPermissions.get(i);
6957             final boolean required = pkg.requestedPermissionsRequired.get(i);
6958             final BasePermission bp = mSettings.mPermissions.get(name);
6959             if (DEBUG_INSTALL) {
6960                 if (gp != ps) {
6961                     Log.i(TAG, "Package " + pkg.packageName + " checking " + name + ": " + bp);
6962                 }
6963             }
6964
6965             if (bp == null || bp.packageSetting == null) {
6966                 if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) {
6967                     Slog.w(TAG, "Unknown permission " + name
6968                             + " in package " + pkg.packageName);
6969                 }
6970                 continue;
6971             }
6972
6973             final String perm = bp.name;
6974             boolean allowed;
6975             boolean allowedSig = false;
6976             if ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
6977                 // Keep track of app op permissions.
6978                 ArraySet<String> pkgs = mAppOpPermissionPackages.get(bp.name);
6979                 if (pkgs == null) {
6980                     pkgs = new ArraySet<>();
6981                     mAppOpPermissionPackages.put(bp.name, pkgs);
6982                 }
6983                 pkgs.add(pkg.packageName);
6984             }
6985             final int level = bp.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE;
6986             if (level == PermissionInfo.PROTECTION_NORMAL
6987                     || level == PermissionInfo.PROTECTION_DANGEROUS) {
6988                 // We grant a normal or dangerous permission if any of the following
6989                 // are true:
6990                 // 1) The permission is required
6991                 // 2) The permission is optional, but was granted in the past
6992                 // 3) The permission is optional, but was requested by an
6993                 //    app in /system (not /data)
6994                 //
6995                 // Otherwise, reject the permission.
6996                 allowed = (required || origPermissions.contains(perm)
6997                         || (isSystemApp(ps) && !isUpdatedSystemApp(ps)));
6998             } else if (bp.packageSetting == null) {
6999                 // This permission is invalid; skip it.
7000                 allowed = false;
7001             } else if (level == PermissionInfo.PROTECTION_SIGNATURE) {
7002                 allowed = grantSignaturePermission(perm, pkg, bp, origPermissions);
7003                 if (allowed) {
7004                     allowedSig = true;
7005                 }
7006             } else {
7007                 allowed = false;
7008             }
7009             if (DEBUG_INSTALL) {
7010                 if (gp != ps) {
7011                     Log.i(TAG, "Package " + pkg.packageName + " granting " + perm);
7012                 }
7013             }
7014             if (allowed) {
7015                 if (!isSystemApp(ps) && ps.permissionsFixed) {
7016                     // If this is an existing, non-system package, then
7017                     // we can't add any new permissions to it.
7018                     if (!allowedSig && !gp.grantedPermissions.contains(perm)) {
7019                         // Except...  if this is a permission that was added
7020                         // to the platform (note: need to only do this when
7021                         // updating the platform).
7022                         allowed = isNewPlatformPermissionForPackage(perm, pkg);
7023                     }
7024                 }
7025                 if (allowed) {
7026                     if (!gp.grantedPermissions.contains(perm)) {
7027                         changedPermission = true;
7028                         gp.grantedPermissions.add(perm);
7029                         gp.gids = appendInts(gp.gids, bp.gids);
7030                     } else if (!ps.haveGids) {
7031                         gp.gids = appendInts(gp.gids, bp.gids);
7032                     }
7033                 } else {
7034                     if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) {
7035                         Slog.w(TAG, "Not granting permission " + perm
7036                                 + " to package " + pkg.packageName
7037                                 + " because it was previously installed without");
7038                     }
7039                 }
7040             } else {
7041                 if (gp.grantedPermissions.remove(perm)) {
7042                     changedPermission = true;
7043                     gp.gids = removeInts(gp.gids, bp.gids);
7044                     Slog.i(TAG, "Un-granting permission " + perm
7045                             + " from package " + pkg.packageName
7046                             + " (protectionLevel=" + bp.protectionLevel
7047                             + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
7048                             + ")");
7049                 } else if ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) == 0) {
7050                     // Don't print warning for app op permissions, since it is fine for them
7051                     // not to be granted, there is a UI for the user to decide.
7052                     if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) {
7053                         Slog.w(TAG, "Not granting permission " + perm
7054                                 + " to package " + pkg.packageName
7055                                 + " (protectionLevel=" + bp.protectionLevel
7056                                 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
7057                                 + ")");
7058                     }
7059                 }
7060             }
7061         }
7062
7063         if ((changedPermission || replace) && !ps.permissionsFixed &&
7064                 !isSystemApp(ps) || isUpdatedSystemApp(ps)){
7065             // This is the first that we have heard about this package, so the
7066             // permissions we have now selected are fixed until explicitly
7067             // changed.
7068             ps.permissionsFixed = true;
7069         }
7070         ps.haveGids = true;
7071     }
7072
7073     private boolean isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg) {
7074         boolean allowed = false;
7075         final int NP = PackageParser.NEW_PERMISSIONS.length;
7076         for (int ip=0; ip<NP; ip++) {
7077             final PackageParser.NewPermissionInfo npi
7078                     = PackageParser.NEW_PERMISSIONS[ip];
7079             if (npi.name.equals(perm)
7080                     && pkg.applicationInfo.targetSdkVersion < npi.sdkVersion) {
7081                 allowed = true;
7082                 Log.i(TAG, "Auto-granting " + perm + " to old pkg "
7083                         + pkg.packageName);
7084                 break;
7085             }
7086         }
7087         return allowed;
7088     }
7089
7090     private boolean grantSignaturePermission(String perm, PackageParser.Package pkg,
7091                                           BasePermission bp, HashSet<String> origPermissions) {
7092         boolean allowed;
7093         allowed = (compareSignatures(
7094                 bp.packageSetting.signatures.mSignatures, pkg.mSignatures)
7095                         == PackageManager.SIGNATURE_MATCH)
7096                 || (compareSignatures(mPlatformPackage.mSignatures, pkg.mSignatures)
7097                         == PackageManager.SIGNATURE_MATCH);
7098         if (!allowed && (bp.protectionLevel
7099                 & PermissionInfo.PROTECTION_FLAG_SYSTEM) != 0) {
7100             if (isSystemApp(pkg)) {
7101                 // For updated system applications, a system permission
7102                 // is granted only if it had been defined by the original application.
7103                 if (isUpdatedSystemApp(pkg)) {
7104                     final PackageSetting sysPs = mSettings
7105                             .getDisabledSystemPkgLPr(pkg.packageName);
7106                     final GrantedPermissions origGp = sysPs.sharedUser != null
7107                             ? sysPs.sharedUser : sysPs;
7108
7109                     if (origGp.grantedPermissions.contains(perm)) {
7110                         // If the original was granted this permission, we take
7111                         // that grant decision as read and propagate it to the
7112                         // update.
7113                         allowed = true;
7114                     } else {
7115                         // The system apk may have been updated with an older
7116                         // version of the one on the data partition, but which
7117                         // granted a new system permission that it didn't have
7118                         // before.  In this case we do want to allow the app to
7119                         // now get the new permission if the ancestral apk is
7120                         // privileged to get it.
7121                         if (sysPs.pkg != null && sysPs.isPrivileged()) {
7122                             for (int j=0;
7123                                     j<sysPs.pkg.requestedPermissions.size(); j++) {
7124                                 if (perm.equals(
7125                                         sysPs.pkg.requestedPermissions.get(j))) {
7126                                     allowed = true;
7127                                     break;
7128                                 }
7129                             }
7130                         }
7131                     }
7132                 } else {
7133                     allowed = isPrivilegedApp(pkg);
7134                 }
7135             }
7136         }
7137         if (!allowed && (bp.protectionLevel
7138                 & PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0) {
7139             // For development permissions, a development permission
7140             // is granted only if it was already granted.
7141             allowed = origPermissions.contains(perm);
7142         }
7143         return allowed;
7144     }
7145
7146     final class ActivityIntentResolver
7147             extends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo> {
7148         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
7149                 boolean defaultOnly, int userId) {
7150             if (!sUserManager.exists(userId)) return null;
7151             mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
7152             return super.queryIntent(intent, resolvedType, defaultOnly, userId);
7153         }
7154
7155         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
7156                 int userId) {
7157             if (!sUserManager.exists(userId)) return null;
7158             mFlags = flags;
7159             return super.queryIntent(intent, resolvedType,
7160                     (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId);
7161         }
7162
7163         public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
7164                 int flags, ArrayList<PackageParser.Activity> packageActivities, int userId) {
7165             if (!sUserManager.exists(userId)) return null;
7166             if (packageActivities == null) {
7167                 return null;
7168             }
7169             mFlags = flags;
7170             final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0;
7171             final int N = packageActivities.size();
7172             ArrayList<PackageParser.ActivityIntentInfo[]> listCut =
7173                 new ArrayList<PackageParser.ActivityIntentInfo[]>(N);
7174
7175             ArrayList<PackageParser.ActivityIntentInfo> intentFilters;
7176             for (int i = 0; i < N; ++i) {
7177                 intentFilters = packageActivities.get(i).intents;
7178                 if (intentFilters != null && intentFilters.size() > 0) {
7179                     PackageParser.ActivityIntentInfo[] array =
7180                             new PackageParser.ActivityIntentInfo[intentFilters.size()];
7181                     intentFilters.toArray(array);
7182                     listCut.add(array);
7183                 }
7184             }
7185             return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
7186         }
7187
7188         public final void addActivity(PackageParser.Activity a, String type) {
7189             final boolean systemApp = isSystemApp(a.info.applicationInfo);
7190             mActivities.put(a.getComponentName(), a);
7191             if (DEBUG_SHOW_INFO)
7192                 Log.v(
7193                 TAG, "  " + type + " " +
7194                 (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel : a.info.name) + ":");
7195             if (DEBUG_SHOW_INFO)
7196                 Log.v(TAG, "    Class=" + a.info.name);
7197             final int NI = a.intents.size();
7198             for (int j=0; j<NI; j++) {
7199                 PackageParser.ActivityIntentInfo intent = a.intents.get(j);
7200                 if (!systemApp && intent.getPriority() > 0 && "activity".equals(type)) {
7201                     intent.setPriority(0);
7202                     Log.w(TAG, "Package " + a.info.applicationInfo.packageName + " has activity "
7203                             + a.className + " with priority > 0, forcing to 0");
7204                 }
7205                 if (DEBUG_SHOW_INFO) {
7206                     Log.v(TAG, "    IntentFilter:");
7207                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
7208                 }
7209                 if (!intent.debugCheck()) {
7210                     Log.w(TAG, "==> For Activity " + a.info.name);
7211                 }
7212                 addFilter(intent);
7213             }
7214         }
7215
7216         public final void removeActivity(PackageParser.Activity a, String type) {
7217             mActivities.remove(a.getComponentName());
7218             if (DEBUG_SHOW_INFO) {
7219                 Log.v(TAG, "  " + type + " "
7220                         + (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel
7221                                 : a.info.name) + ":");
7222                 Log.v(TAG, "    Class=" + a.info.name);
7223             }
7224             final int NI = a.intents.size();
7225             for (int j=0; j<NI; j++) {
7226                 PackageParser.ActivityIntentInfo intent = a.intents.get(j);
7227                 if (DEBUG_SHOW_INFO) {
7228                     Log.v(TAG, "    IntentFilter:");
7229                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
7230                 }
7231                 removeFilter(intent);
7232             }
7233         }
7234
7235         @Override
7236         protected boolean allowFilterResult(
7237                 PackageParser.ActivityIntentInfo filter, List<ResolveInfo> dest) {
7238             ActivityInfo filterAi = filter.activity.info;
7239             for (int i=dest.size()-1; i>=0; i--) {
7240                 ActivityInfo destAi = dest.get(i).activityInfo;
7241                 if (destAi.name == filterAi.name
7242                         && destAi.packageName == filterAi.packageName) {
7243                     return false;
7244                 }
7245             }
7246             return true;
7247         }
7248
7249         @Override
7250         protected ActivityIntentInfo[] newArray(int size) {
7251             return new ActivityIntentInfo[size];
7252         }
7253
7254         @Override
7255         protected boolean isFilterStopped(PackageParser.ActivityIntentInfo filter, int userId) {
7256             if (!sUserManager.exists(userId)) return true;
7257             PackageParser.Package p = filter.activity.owner;
7258             if (p != null) {
7259                 PackageSetting ps = (PackageSetting)p.mExtras;
7260                 if (ps != null) {
7261                     // System apps are never considered stopped for purposes of
7262                     // filtering, because there may be no way for the user to
7263                     // actually re-launch them.
7264                     return (ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0
7265                             && ps.getStopped(userId);
7266                 }
7267             }
7268             return false;
7269         }
7270
7271         @Override
7272         protected boolean isPackageForFilter(String packageName,
7273                 PackageParser.ActivityIntentInfo info) {
7274             return packageName.equals(info.activity.owner.packageName);
7275         }
7276         
7277         @Override
7278         protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info,
7279                 int match, int userId) {
7280             if (!sUserManager.exists(userId)) return null;
7281             if (!mSettings.isEnabledLPr(info.activity.info, mFlags, userId)) {
7282                 return null;
7283             }
7284             final PackageParser.Activity activity = info.activity;
7285             if (mSafeMode && (activity.info.applicationInfo.flags
7286                     &ApplicationInfo.FLAG_SYSTEM) == 0) {
7287                 return null;
7288             }
7289             PackageSetting ps = (PackageSetting) activity.owner.mExtras;
7290             if (ps == null) {
7291                 return null;
7292             }
7293             ActivityInfo ai = PackageParser.generateActivityInfo(activity, mFlags,
7294                     ps.readUserState(userId), userId);
7295             if (ai == null) {
7296                 return null;
7297             }
7298             final ResolveInfo res = new ResolveInfo();
7299             res.activityInfo = ai;
7300             if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
7301                 res.filter = info;
7302             }
7303             res.priority = info.getPriority();
7304             res.preferredOrder = activity.owner.mPreferredOrder;
7305             //System.out.println("Result: " + res.activityInfo.className +
7306             //                   " = " + res.priority);
7307             res.match = match;
7308             res.isDefault = info.hasDefault;
7309             res.labelRes = info.labelRes;
7310             res.nonLocalizedLabel = info.nonLocalizedLabel;
7311             if (userNeedsBadging(userId)) {
7312                 res.noResourceId = true;
7313             } else {
7314                 res.icon = info.icon;
7315             }
7316             res.system = isSystemApp(res.activityInfo.applicationInfo);
7317             return res;
7318         }
7319
7320         @Override
7321         protected void sortResults(List<ResolveInfo> results) {
7322             Collections.sort(results, mResolvePrioritySorter);
7323         }
7324
7325         @Override
7326         protected void dumpFilter(PrintWriter out, String prefix,
7327                 PackageParser.ActivityIntentInfo filter) {
7328             out.print(prefix); out.print(
7329                     Integer.toHexString(System.identityHashCode(filter.activity)));
7330                     out.print(' ');
7331                     filter.activity.printComponentShortName(out);
7332                     out.print(" filter ");
7333                     out.println(Integer.toHexString(System.identityHashCode(filter)));
7334         }
7335
7336 //        List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) {
7337 //            final Iterator<ResolveInfo> i = resolveInfoList.iterator();
7338 //            final List<ResolveInfo> retList = Lists.newArrayList();
7339 //            while (i.hasNext()) {
7340 //                final ResolveInfo resolveInfo = i.next();
7341 //                if (isEnabledLP(resolveInfo.activityInfo)) {
7342 //                    retList.add(resolveInfo);
7343 //                }
7344 //            }
7345 //            return retList;
7346 //        }
7347
7348         // Keys are String (activity class name), values are Activity.
7349         private final HashMap<ComponentName, PackageParser.Activity> mActivities
7350                 = new HashMap<ComponentName, PackageParser.Activity>();
7351         private int mFlags;
7352     }
7353
7354     private final class ServiceIntentResolver
7355             extends IntentResolver<PackageParser.ServiceIntentInfo, ResolveInfo> {
7356         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
7357                 boolean defaultOnly, int userId) {
7358             mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
7359             return super.queryIntent(intent, resolvedType, defaultOnly, userId);
7360         }
7361
7362         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
7363                 int userId) {
7364             if (!sUserManager.exists(userId)) return null;
7365             mFlags = flags;
7366             return super.queryIntent(intent, resolvedType,
7367                     (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId);
7368         }
7369
7370         public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
7371                 int flags, ArrayList<PackageParser.Service> packageServices, int userId) {
7372             if (!sUserManager.exists(userId)) return null;
7373             if (packageServices == null) {
7374                 return null;
7375             }
7376             mFlags = flags;
7377             final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0;
7378             final int N = packageServices.size();
7379             ArrayList<PackageParser.ServiceIntentInfo[]> listCut =
7380                 new ArrayList<PackageParser.ServiceIntentInfo[]>(N);
7381
7382             ArrayList<PackageParser.ServiceIntentInfo> intentFilters;
7383             for (int i = 0; i < N; ++i) {
7384                 intentFilters = packageServices.get(i).intents;
7385                 if (intentFilters != null && intentFilters.size() > 0) {
7386                     PackageParser.ServiceIntentInfo[] array =
7387                             new PackageParser.ServiceIntentInfo[intentFilters.size()];
7388                     intentFilters.toArray(array);
7389                     listCut.add(array);
7390                 }
7391             }
7392             return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
7393         }
7394
7395         public final void addService(PackageParser.Service s) {
7396             mServices.put(s.getComponentName(), s);
7397             if (DEBUG_SHOW_INFO) {
7398                 Log.v(TAG, "  "
7399                         + (s.info.nonLocalizedLabel != null
7400                         ? s.info.nonLocalizedLabel : s.info.name) + ":");
7401                 Log.v(TAG, "    Class=" + s.info.name);
7402             }
7403             final int NI = s.intents.size();
7404             int j;
7405             for (j=0; j<NI; j++) {
7406                 PackageParser.ServiceIntentInfo intent = s.intents.get(j);
7407                 if (DEBUG_SHOW_INFO) {
7408                     Log.v(TAG, "    IntentFilter:");
7409                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
7410                 }
7411                 if (!intent.debugCheck()) {
7412                     Log.w(TAG, "==> For Service " + s.info.name);
7413                 }
7414                 addFilter(intent);
7415             }
7416         }
7417
7418         public final void removeService(PackageParser.Service s) {
7419             mServices.remove(s.getComponentName());
7420             if (DEBUG_SHOW_INFO) {
7421                 Log.v(TAG, "  " + (s.info.nonLocalizedLabel != null
7422                         ? s.info.nonLocalizedLabel : s.info.name) + ":");
7423                 Log.v(TAG, "    Class=" + s.info.name);
7424             }
7425             final int NI = s.intents.size();
7426             int j;
7427             for (j=0; j<NI; j++) {
7428                 PackageParser.ServiceIntentInfo intent = s.intents.get(j);
7429                 if (DEBUG_SHOW_INFO) {
7430                     Log.v(TAG, "    IntentFilter:");
7431                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
7432                 }
7433                 removeFilter(intent);
7434             }
7435         }
7436
7437         @Override
7438         protected boolean allowFilterResult(
7439                 PackageParser.ServiceIntentInfo filter, List<ResolveInfo> dest) {
7440             ServiceInfo filterSi = filter.service.info;
7441             for (int i=dest.size()-1; i>=0; i--) {
7442                 ServiceInfo destAi = dest.get(i).serviceInfo;
7443                 if (destAi.name == filterSi.name
7444                         && destAi.packageName == filterSi.packageName) {
7445                     return false;
7446                 }
7447             }
7448             return true;
7449         }
7450
7451         @Override
7452         protected PackageParser.ServiceIntentInfo[] newArray(int size) {
7453             return new PackageParser.ServiceIntentInfo[size];
7454         }
7455
7456         @Override
7457         protected boolean isFilterStopped(PackageParser.ServiceIntentInfo filter, int userId) {
7458             if (!sUserManager.exists(userId)) return true;
7459             PackageParser.Package p = filter.service.owner;
7460             if (p != null) {
7461                 PackageSetting ps = (PackageSetting)p.mExtras;
7462                 if (ps != null) {
7463                     // System apps are never considered stopped for purposes of
7464                     // filtering, because there may be no way for the user to
7465                     // actually re-launch them.
7466                     return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
7467                             && ps.getStopped(userId);
7468                 }
7469             }
7470             return false;
7471         }
7472
7473         @Override
7474         protected boolean isPackageForFilter(String packageName,
7475                 PackageParser.ServiceIntentInfo info) {
7476             return packageName.equals(info.service.owner.packageName);
7477         }
7478         
7479         @Override
7480         protected ResolveInfo newResult(PackageParser.ServiceIntentInfo filter,
7481                 int match, int userId) {
7482             if (!sUserManager.exists(userId)) return null;
7483             final PackageParser.ServiceIntentInfo info = (PackageParser.ServiceIntentInfo)filter;
7484             if (!mSettings.isEnabledLPr(info.service.info, mFlags, userId)) {
7485                 return null;
7486             }
7487             final PackageParser.Service service = info.service;
7488             if (mSafeMode && (service.info.applicationInfo.flags
7489                     &ApplicationInfo.FLAG_SYSTEM) == 0) {
7490                 return null;
7491             }
7492             PackageSetting ps = (PackageSetting) service.owner.mExtras;
7493             if (ps == null) {
7494                 return null;
7495             }
7496             ServiceInfo si = PackageParser.generateServiceInfo(service, mFlags,
7497                     ps.readUserState(userId), userId);
7498             if (si == null) {
7499                 return null;
7500             }
7501             final ResolveInfo res = new ResolveInfo();
7502             res.serviceInfo = si;
7503             if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
7504                 res.filter = filter;
7505             }
7506             res.priority = info.getPriority();
7507             res.preferredOrder = service.owner.mPreferredOrder;
7508             //System.out.println("Result: " + res.activityInfo.className +
7509             //                   " = " + res.priority);
7510             res.match = match;
7511             res.isDefault = info.hasDefault;
7512             res.labelRes = info.labelRes;
7513             res.nonLocalizedLabel = info.nonLocalizedLabel;
7514             res.icon = info.icon;
7515             res.system = isSystemApp(res.serviceInfo.applicationInfo);
7516             return res;
7517         }
7518
7519         @Override
7520         protected void sortResults(List<ResolveInfo> results) {
7521             Collections.sort(results, mResolvePrioritySorter);
7522         }
7523
7524         @Override
7525         protected void dumpFilter(PrintWriter out, String prefix,
7526                 PackageParser.ServiceIntentInfo filter) {
7527             out.print(prefix); out.print(
7528                     Integer.toHexString(System.identityHashCode(filter.service)));
7529                     out.print(' ');
7530                     filter.service.printComponentShortName(out);
7531                     out.print(" filter ");
7532                     out.println(Integer.toHexString(System.identityHashCode(filter)));
7533         }
7534
7535 //        List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) {
7536 //            final Iterator<ResolveInfo> i = resolveInfoList.iterator();
7537 //            final List<ResolveInfo> retList = Lists.newArrayList();
7538 //            while (i.hasNext()) {
7539 //                final ResolveInfo resolveInfo = (ResolveInfo) i;
7540 //                if (isEnabledLP(resolveInfo.serviceInfo)) {
7541 //                    retList.add(resolveInfo);
7542 //                }
7543 //            }
7544 //            return retList;
7545 //        }
7546
7547         // Keys are String (activity class name), values are Activity.
7548         private final HashMap<ComponentName, PackageParser.Service> mServices
7549                 = new HashMap<ComponentName, PackageParser.Service>();
7550         private int mFlags;
7551     };
7552
7553     private final class ProviderIntentResolver
7554             extends IntentResolver<PackageParser.ProviderIntentInfo, ResolveInfo> {
7555         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
7556                 boolean defaultOnly, int userId) {
7557             mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
7558             return super.queryIntent(intent, resolvedType, defaultOnly, userId);
7559         }
7560
7561         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
7562                 int userId) {
7563             if (!sUserManager.exists(userId))
7564                 return null;
7565             mFlags = flags;
7566             return super.queryIntent(intent, resolvedType,
7567                     (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId);
7568         }
7569
7570         public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
7571                 int flags, ArrayList<PackageParser.Provider> packageProviders, int userId) {
7572             if (!sUserManager.exists(userId))
7573                 return null;
7574             if (packageProviders == null) {
7575                 return null;
7576             }
7577             mFlags = flags;
7578             final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0;
7579             final int N = packageProviders.size();
7580             ArrayList<PackageParser.ProviderIntentInfo[]> listCut =
7581                     new ArrayList<PackageParser.ProviderIntentInfo[]>(N);
7582
7583             ArrayList<PackageParser.ProviderIntentInfo> intentFilters;
7584             for (int i = 0; i < N; ++i) {
7585                 intentFilters = packageProviders.get(i).intents;
7586                 if (intentFilters != null && intentFilters.size() > 0) {
7587                     PackageParser.ProviderIntentInfo[] array =
7588                             new PackageParser.ProviderIntentInfo[intentFilters.size()];
7589                     intentFilters.toArray(array);
7590                     listCut.add(array);
7591                 }
7592             }
7593             return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
7594         }
7595
7596         public final void addProvider(PackageParser.Provider p) {
7597             if (mProviders.containsKey(p.getComponentName())) {
7598                 Slog.w(TAG, "Provider " + p.getComponentName() + " already defined; ignoring");
7599                 return;
7600             }
7601
7602             mProviders.put(p.getComponentName(), p);
7603             if (DEBUG_SHOW_INFO) {
7604                 Log.v(TAG, "  "
7605                         + (p.info.nonLocalizedLabel != null
7606                                 ? p.info.nonLocalizedLabel : p.info.name) + ":");
7607                 Log.v(TAG, "    Class=" + p.info.name);
7608             }
7609             final int NI = p.intents.size();
7610             int j;
7611             for (j = 0; j < NI; j++) {
7612                 PackageParser.ProviderIntentInfo intent = p.intents.get(j);
7613                 if (DEBUG_SHOW_INFO) {
7614                     Log.v(TAG, "    IntentFilter:");
7615                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
7616                 }
7617                 if (!intent.debugCheck()) {
7618                     Log.w(TAG, "==> For Provider " + p.info.name);
7619                 }
7620                 addFilter(intent);
7621             }
7622         }
7623
7624         public final void removeProvider(PackageParser.Provider p) {
7625             mProviders.remove(p.getComponentName());
7626             if (DEBUG_SHOW_INFO) {
7627                 Log.v(TAG, "  " + (p.info.nonLocalizedLabel != null
7628                         ? p.info.nonLocalizedLabel : p.info.name) + ":");
7629                 Log.v(TAG, "    Class=" + p.info.name);
7630             }
7631             final int NI = p.intents.size();
7632             int j;
7633             for (j = 0; j < NI; j++) {
7634                 PackageParser.ProviderIntentInfo intent = p.intents.get(j);
7635                 if (DEBUG_SHOW_INFO) {
7636                     Log.v(TAG, "    IntentFilter:");
7637                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
7638                 }
7639                 removeFilter(intent);
7640             }
7641         }
7642
7643         @Override
7644         protected boolean allowFilterResult(
7645                 PackageParser.ProviderIntentInfo filter, List<ResolveInfo> dest) {
7646             ProviderInfo filterPi = filter.provider.info;
7647             for (int i = dest.size() - 1; i >= 0; i--) {
7648                 ProviderInfo destPi = dest.get(i).providerInfo;
7649                 if (destPi.name == filterPi.name
7650                         && destPi.packageName == filterPi.packageName) {
7651                     return false;
7652                 }
7653             }
7654             return true;
7655         }
7656
7657         @Override
7658         protected PackageParser.ProviderIntentInfo[] newArray(int size) {
7659             return new PackageParser.ProviderIntentInfo[size];
7660         }
7661
7662         @Override
7663         protected boolean isFilterStopped(PackageParser.ProviderIntentInfo filter, int userId) {
7664             if (!sUserManager.exists(userId))
7665                 return true;
7666             PackageParser.Package p = filter.provider.owner;
7667             if (p != null) {
7668                 PackageSetting ps = (PackageSetting) p.mExtras;
7669                 if (ps != null) {
7670                     // System apps are never considered stopped for purposes of
7671                     // filtering, because there may be no way for the user to
7672                     // actually re-launch them.
7673                     return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
7674                             && ps.getStopped(userId);
7675                 }
7676             }
7677             return false;
7678         }
7679
7680         @Override
7681         protected boolean isPackageForFilter(String packageName,
7682                 PackageParser.ProviderIntentInfo info) {
7683             return packageName.equals(info.provider.owner.packageName);
7684         }
7685
7686         @Override
7687         protected ResolveInfo newResult(PackageParser.ProviderIntentInfo filter,
7688                 int match, int userId) {
7689             if (!sUserManager.exists(userId))
7690                 return null;
7691             final PackageParser.ProviderIntentInfo info = filter;
7692             if (!mSettings.isEnabledLPr(info.provider.info, mFlags, userId)) {
7693                 return null;
7694             }
7695             final PackageParser.Provider provider = info.provider;
7696             if (mSafeMode && (provider.info.applicationInfo.flags
7697                     & ApplicationInfo.FLAG_SYSTEM) == 0) {
7698                 return null;
7699             }
7700             PackageSetting ps = (PackageSetting) provider.owner.mExtras;
7701             if (ps == null) {
7702                 return null;
7703             }
7704             ProviderInfo pi = PackageParser.generateProviderInfo(provider, mFlags,
7705                     ps.readUserState(userId), userId);
7706             if (pi == null) {
7707                 return null;
7708             }
7709             final ResolveInfo res = new ResolveInfo();
7710             res.providerInfo = pi;
7711             if ((mFlags & PackageManager.GET_RESOLVED_FILTER) != 0) {
7712                 res.filter = filter;
7713             }
7714             res.priority = info.getPriority();
7715             res.preferredOrder = provider.owner.mPreferredOrder;
7716             res.match = match;
7717             res.isDefault = info.hasDefault;
7718             res.labelRes = info.labelRes;
7719             res.nonLocalizedLabel = info.nonLocalizedLabel;
7720             res.icon = info.icon;
7721             res.system = isSystemApp(res.providerInfo.applicationInfo);
7722             return res;
7723         }
7724
7725         @Override
7726         protected void sortResults(List<ResolveInfo> results) {
7727             Collections.sort(results, mResolvePrioritySorter);
7728         }
7729
7730         @Override
7731         protected void dumpFilter(PrintWriter out, String prefix,
7732                 PackageParser.ProviderIntentInfo filter) {
7733             out.print(prefix);
7734             out.print(
7735                     Integer.toHexString(System.identityHashCode(filter.provider)));
7736             out.print(' ');
7737             filter.provider.printComponentShortName(out);
7738             out.print(" filter ");
7739             out.println(Integer.toHexString(System.identityHashCode(filter)));
7740         }
7741
7742         private final HashMap<ComponentName, PackageParser.Provider> mProviders
7743                 = new HashMap<ComponentName, PackageParser.Provider>();
7744         private int mFlags;
7745     };
7746
7747     private static final Comparator<ResolveInfo> mResolvePrioritySorter =
7748             new Comparator<ResolveInfo>() {
7749         public int compare(ResolveInfo r1, ResolveInfo r2) {
7750             int v1 = r1.priority;
7751             int v2 = r2.priority;
7752             //System.out.println("Comparing: q1=" + q1 + " q2=" + q2);
7753             if (v1 != v2) {
7754                 return (v1 > v2) ? -1 : 1;
7755             }
7756             v1 = r1.preferredOrder;
7757             v2 = r2.preferredOrder;
7758             if (v1 != v2) {
7759                 return (v1 > v2) ? -1 : 1;
7760             }
7761             if (r1.isDefault != r2.isDefault) {
7762                 return r1.isDefault ? -1 : 1;
7763             }
7764             v1 = r1.match;
7765             v2 = r2.match;
7766             //System.out.println("Comparing: m1=" + m1 + " m2=" + m2);
7767             if (v1 != v2) {
7768                 return (v1 > v2) ? -1 : 1;
7769             }
7770             if (r1.system != r2.system) {
7771                 return r1.system ? -1 : 1;
7772             }
7773             return 0;
7774         }
7775     };
7776
7777     private static final Comparator<ProviderInfo> mProviderInitOrderSorter =
7778             new Comparator<ProviderInfo>() {
7779         public int compare(ProviderInfo p1, ProviderInfo p2) {
7780             final int v1 = p1.initOrder;
7781             final int v2 = p2.initOrder;
7782             return (v1 > v2) ? -1 : ((v1 < v2) ? 1 : 0);
7783         }
7784     };
7785
7786     static final void sendPackageBroadcast(String action, String pkg,
7787             Bundle extras, String targetPkg, IIntentReceiver finishedReceiver,
7788             int[] userIds) {
7789         IActivityManager am = ActivityManagerNative.getDefault();
7790         if (am != null) {
7791             try {
7792                 if (userIds == null) {
7793                     userIds = am.getRunningUserIds();
7794                 }
7795                 for (int id : userIds) {
7796                     final Intent intent = new Intent(action,
7797                             pkg != null ? Uri.fromParts("package", pkg, null) : null);
7798                     if (extras != null) {
7799                         intent.putExtras(extras);
7800                     }
7801                     if (targetPkg != null) {
7802                         intent.setPackage(targetPkg);
7803                     }
7804                     // Modify the UID when posting to other users
7805                     int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
7806                     if (uid > 0 && UserHandle.getUserId(uid) != id) {
7807                         uid = UserHandle.getUid(id, UserHandle.getAppId(uid));
7808                         intent.putExtra(Intent.EXTRA_UID, uid);
7809                     }
7810                     intent.putExtra(Intent.EXTRA_USER_HANDLE, id);
7811                     intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
7812                     if (DEBUG_BROADCASTS) {
7813                         RuntimeException here = new RuntimeException("here");
7814                         here.fillInStackTrace();
7815                         Slog.d(TAG, "Sending to user " + id + ": "
7816                                 + intent.toShortString(false, true, false, false)
7817                                 + " " + intent.getExtras(), here);
7818                     }
7819                     am.broadcastIntent(null, intent, null, finishedReceiver,
7820                             0, null, null, null, android.app.AppOpsManager.OP_NONE,
7821                             finishedReceiver != null, false, id);
7822                 }
7823             } catch (RemoteException ex) {
7824             }
7825         }
7826     }
7827
7828     /**
7829      * Check if the external storage media is available. This is true if there
7830      * is a mounted external storage medium or if the external storage is
7831      * emulated.
7832      */
7833     private boolean isExternalMediaAvailable() {
7834         return mMediaMounted || Environment.isExternalStorageEmulated();
7835     }
7836
7837     @Override
7838     public PackageCleanItem nextPackageToClean(PackageCleanItem lastPackage) {
7839         // writer
7840         synchronized (mPackages) {
7841             if (!isExternalMediaAvailable()) {
7842                 // If the external storage is no longer mounted at this point,
7843                 // the caller may not have been able to delete all of this
7844                 // packages files and can not delete any more.  Bail.
7845                 return null;
7846             }
7847             final ArrayList<PackageCleanItem> pkgs = mSettings.mPackagesToBeCleaned;
7848             if (lastPackage != null) {
7849                 pkgs.remove(lastPackage);
7850             }
7851             if (pkgs.size() > 0) {
7852                 return pkgs.get(0);
7853             }
7854         }
7855         return null;
7856     }
7857
7858     void schedulePackageCleaning(String packageName, int userId, boolean andCode) {
7859         final Message msg = mHandler.obtainMessage(START_CLEANING_PACKAGE,
7860                 userId, andCode ? 1 : 0, packageName);
7861         if (mSystemReady) {
7862             msg.sendToTarget();
7863         } else {
7864             if (mPostSystemReadyMessages == null) {
7865                 mPostSystemReadyMessages = new ArrayList<>();
7866             }
7867             mPostSystemReadyMessages.add(msg);
7868         }
7869     }
7870
7871     void startCleaningPackages() {
7872         // reader
7873         synchronized (mPackages) {
7874             if (!isExternalMediaAvailable()) {
7875                 return;
7876             }
7877             if (mSettings.mPackagesToBeCleaned.isEmpty()) {
7878                 return;
7879             }
7880         }
7881         Intent intent = new Intent(PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE);
7882         intent.setComponent(DEFAULT_CONTAINER_COMPONENT);
7883         IActivityManager am = ActivityManagerNative.getDefault();
7884         if (am != null) {
7885             try {
7886                 am.startService(null, intent, null, UserHandle.USER_OWNER);
7887             } catch (RemoteException e) {
7888             }
7889         }
7890     }
7891
7892     @Override
7893     public void installPackage(String originPath, IPackageInstallObserver2 observer,
7894             int installFlags, String installerPackageName, VerificationParams verificationParams,
7895             String packageAbiOverride) {
7896         installPackageAsUser(originPath, observer, installFlags, installerPackageName, verificationParams,
7897                 packageAbiOverride, UserHandle.getCallingUserId());
7898     }
7899
7900     @Override
7901     public void installPackageAsUser(String originPath, IPackageInstallObserver2 observer,
7902             int installFlags, String installerPackageName, VerificationParams verificationParams,
7903             String packageAbiOverride, int userId) {
7904         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null);
7905
7906         final int callingUid = Binder.getCallingUid();
7907         enforceCrossUserPermission(callingUid, userId, true, true, "installPackageAsUser");
7908
7909         if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
7910             try {
7911                 if (observer != null) {
7912                     observer.onPackageInstalled("", INSTALL_FAILED_USER_RESTRICTED, null, null);
7913                 }
7914             } catch (RemoteException re) {
7915             }
7916             return;
7917         }
7918
7919         if ((callingUid == Process.SHELL_UID) || (callingUid == Process.ROOT_UID)) {
7920             installFlags |= PackageManager.INSTALL_FROM_ADB;
7921
7922         } else {
7923             // Caller holds INSTALL_PACKAGES permission, so we're less strict
7924             // about installerPackageName.
7925
7926             installFlags &= ~PackageManager.INSTALL_FROM_ADB;
7927             installFlags &= ~PackageManager.INSTALL_ALL_USERS;
7928         }
7929
7930         UserHandle user;
7931         if ((installFlags & PackageManager.INSTALL_ALL_USERS) != 0) {
7932             user = UserHandle.ALL;
7933         } else {
7934             user = new UserHandle(userId);
7935         }
7936
7937         verificationParams.setInstallerUid(callingUid);
7938
7939         final File originFile = new File(originPath);
7940         final OriginInfo origin = OriginInfo.fromUntrustedFile(originFile);
7941
7942         final Message msg = mHandler.obtainMessage(INIT_COPY);
7943         msg.obj = new InstallParams(origin, observer, installFlags,
7944                 installerPackageName, verificationParams, user, packageAbiOverride);
7945         mHandler.sendMessage(msg);
7946     }
7947
7948     void installStage(String packageName, File stagedDir, String stagedCid,
7949             IPackageInstallObserver2 observer, PackageInstaller.SessionParams params,
7950             String installerPackageName, int installerUid, UserHandle user) {
7951         final VerificationParams verifParams = new VerificationParams(null, params.originatingUri,
7952                 params.referrerUri, installerUid, null);
7953
7954         final OriginInfo origin;
7955         if (stagedDir != null) {
7956             origin = OriginInfo.fromStagedFile(stagedDir);
7957         } else {
7958             origin = OriginInfo.fromStagedContainer(stagedCid);
7959         }
7960
7961         final Message msg = mHandler.obtainMessage(INIT_COPY);
7962         msg.obj = new InstallParams(origin, observer, params.installFlags,
7963                 installerPackageName, verifParams, user, params.abiOverride);
7964         mHandler.sendMessage(msg);
7965     }
7966
7967     private void sendPackageAddedForUser(String packageName, PackageSetting pkgSetting, int userId) {
7968         Bundle extras = new Bundle(1);
7969         extras.putInt(Intent.EXTRA_UID, UserHandle.getUid(userId, pkgSetting.appId));
7970
7971         sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
7972                 packageName, extras, null, null, new int[] {userId});
7973         try {
7974             IActivityManager am = ActivityManagerNative.getDefault();
7975             final boolean isSystem =
7976                     isSystemApp(pkgSetting) || isUpdatedSystemApp(pkgSetting);
7977             if (isSystem && am.isUserRunning(userId, false)) {
7978                 // The just-installed/enabled app is bundled on the system, so presumed
7979                 // to be able to run automatically without needing an explicit launch.
7980                 // Send it a BOOT_COMPLETED if it would ordinarily have gotten one.
7981                 Intent bcIntent = new Intent(Intent.ACTION_BOOT_COMPLETED)
7982                         .addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES)
7983                         .setPackage(packageName);
7984                 am.broadcastIntent(null, bcIntent, null, null, 0, null, null, null,
7985                         android.app.AppOpsManager.OP_NONE, false, false, userId);
7986             }
7987         } catch (RemoteException e) {
7988             // shouldn't happen
7989             Slog.w(TAG, "Unable to bootstrap installed package", e);
7990         }
7991     }
7992
7993     @Override
7994     public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden,
7995             int userId) {
7996         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
7997         PackageSetting pkgSetting;
7998         final int uid = Binder.getCallingUid();
7999         enforceCrossUserPermission(uid, userId, true, true,
8000                 "setApplicationHiddenSetting for user " + userId);
8001
8002         if (hidden && isPackageDeviceAdmin(packageName, userId)) {
8003             Slog.w(TAG, "Not hiding package " + packageName + ": has active device admin");
8004             return false;
8005         }
8006
8007         long callingId = Binder.clearCallingIdentity();
8008         try {
8009             boolean sendAdded = false;
8010             boolean sendRemoved = false;
8011             // writer
8012             synchronized (mPackages) {
8013                 pkgSetting = mSettings.mPackages.get(packageName);
8014                 if (pkgSetting == null) {
8015                     return false;
8016                 }
8017                 if (pkgSetting.getHidden(userId) != hidden) {
8018                     pkgSetting.setHidden(hidden, userId);
8019                     mSettings.writePackageRestrictionsLPr(userId);
8020                     if (hidden) {
8021                         sendRemoved = true;
8022                     } else {
8023                         sendAdded = true;
8024                     }
8025                 }
8026             }
8027             if (sendAdded) {
8028                 sendPackageAddedForUser(packageName, pkgSetting, userId);
8029                 return true;
8030             }
8031             if (sendRemoved) {
8032                 killApplication(packageName, UserHandle.getUid(userId, pkgSetting.appId),
8033                         "hiding pkg");
8034                 sendApplicationHiddenForUser(packageName, pkgSetting, userId);
8035             }
8036         } finally {
8037             Binder.restoreCallingIdentity(callingId);
8038         }
8039         return false;
8040     }
8041
8042     private void sendApplicationHiddenForUser(String packageName, PackageSetting pkgSetting,
8043             int userId) {
8044         final PackageRemovedInfo info = new PackageRemovedInfo();
8045         info.removedPackage = packageName;
8046         info.removedUsers = new int[] {userId};
8047         info.uid = UserHandle.getUid(userId, pkgSetting.appId);
8048         info.sendBroadcast(false, false, false);
8049     }
8050
8051     /**
8052      * Returns true if application is not found or there was an error. Otherwise it returns
8053      * the hidden state of the package for the given user.
8054      */
8055     @Override
8056     public boolean getApplicationHiddenSettingAsUser(String packageName, int userId) {
8057         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
8058         enforceCrossUserPermission(Binder.getCallingUid(), userId, true,
8059                 false, "getApplicationHidden for user " + userId);
8060         PackageSetting pkgSetting;
8061         long callingId = Binder.clearCallingIdentity();
8062         try {
8063             // writer
8064             synchronized (mPackages) {
8065                 pkgSetting = mSettings.mPackages.get(packageName);
8066                 if (pkgSetting == null) {
8067                     return true;
8068                 }
8069                 return pkgSetting.getHidden(userId);
8070             }
8071         } finally {
8072             Binder.restoreCallingIdentity(callingId);
8073         }
8074     }
8075
8076     /**
8077      * @hide
8078      */
8079     @Override
8080     public int installExistingPackageAsUser(String packageName, int userId) {
8081         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES,
8082                 null);
8083         PackageSetting pkgSetting;
8084         final int uid = Binder.getCallingUid();
8085         enforceCrossUserPermission(uid, userId, true, true, "installExistingPackage for user "
8086                 + userId);
8087         if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
8088             return PackageManager.INSTALL_FAILED_USER_RESTRICTED;
8089         }
8090
8091         long callingId = Binder.clearCallingIdentity();
8092         try {
8093             boolean sendAdded = false;
8094             Bundle extras = new Bundle(1);
8095
8096             // writer
8097             synchronized (mPackages) {
8098                 pkgSetting = mSettings.mPackages.get(packageName);
8099                 if (pkgSetting == null) {
8100                     return PackageManager.INSTALL_FAILED_INVALID_URI;
8101                 }
8102                 if (!pkgSetting.getInstalled(userId)) {
8103                     pkgSetting.setInstalled(true, userId);
8104                     pkgSetting.setHidden(false, userId);
8105                     mSettings.writePackageRestrictionsLPr(userId);
8106                     sendAdded = true;
8107                 }
8108             }
8109
8110             if (sendAdded) {
8111                 sendPackageAddedForUser(packageName, pkgSetting, userId);
8112             }
8113         } finally {
8114             Binder.restoreCallingIdentity(callingId);
8115         }
8116
8117         return PackageManager.INSTALL_SUCCEEDED;
8118     }
8119
8120     boolean isUserRestricted(int userId, String restrictionKey) {
8121         Bundle restrictions = sUserManager.getUserRestrictions(userId);
8122         if (restrictions.getBoolean(restrictionKey, false)) {
8123             Log.w(TAG, "User is restricted: " + restrictionKey);
8124             return true;
8125         }
8126         return false;
8127     }
8128
8129     @Override
8130     public void verifyPendingInstall(int id, int verificationCode) throws RemoteException {
8131         mContext.enforceCallingOrSelfPermission(
8132                 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
8133                 "Only package verification agents can verify applications");
8134
8135         final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
8136         final PackageVerificationResponse response = new PackageVerificationResponse(
8137                 verificationCode, Binder.getCallingUid());
8138         msg.arg1 = id;
8139         msg.obj = response;
8140         mHandler.sendMessage(msg);
8141     }
8142
8143     @Override
8144     public void extendVerificationTimeout(int id, int verificationCodeAtTimeout,
8145             long millisecondsToDelay) {
8146         mContext.enforceCallingOrSelfPermission(
8147                 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
8148                 "Only package verification agents can extend verification timeouts");
8149
8150         final PackageVerificationState state = mPendingVerification.get(id);
8151         final PackageVerificationResponse response = new PackageVerificationResponse(
8152                 verificationCodeAtTimeout, Binder.getCallingUid());
8153
8154         if (millisecondsToDelay > PackageManager.MAXIMUM_VERIFICATION_TIMEOUT) {
8155             millisecondsToDelay = PackageManager.MAXIMUM_VERIFICATION_TIMEOUT;
8156         }
8157         if (millisecondsToDelay < 0) {
8158             millisecondsToDelay = 0;
8159         }
8160         if ((verificationCodeAtTimeout != PackageManager.VERIFICATION_ALLOW)
8161                 && (verificationCodeAtTimeout != PackageManager.VERIFICATION_REJECT)) {
8162             verificationCodeAtTimeout = PackageManager.VERIFICATION_REJECT;
8163         }
8164
8165         if ((state != null) && !state.timeoutExtended()) {
8166             state.extendTimeout();
8167
8168             final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
8169             msg.arg1 = id;
8170             msg.obj = response;
8171             mHandler.sendMessageDelayed(msg, millisecondsToDelay);
8172         }
8173     }
8174
8175     private void broadcastPackageVerified(int verificationId, Uri packageUri,
8176             int verificationCode, UserHandle user) {
8177         final Intent intent = new Intent(Intent.ACTION_PACKAGE_VERIFIED);
8178         intent.setDataAndType(packageUri, PACKAGE_MIME_TYPE);
8179         intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
8180         intent.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
8181         intent.putExtra(PackageManager.EXTRA_VERIFICATION_RESULT, verificationCode);
8182
8183         mContext.sendBroadcastAsUser(intent, user,
8184                 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT);
8185     }
8186
8187     private ComponentName matchComponentForVerifier(String packageName,
8188             List<ResolveInfo> receivers) {
8189         ActivityInfo targetReceiver = null;
8190
8191         final int NR = receivers.size();
8192         for (int i = 0; i < NR; i++) {
8193             final ResolveInfo info = receivers.get(i);
8194             if (info.activityInfo == null) {
8195                 continue;
8196             }
8197
8198             if (packageName.equals(info.activityInfo.packageName)) {
8199                 targetReceiver = info.activityInfo;
8200                 break;
8201             }
8202         }
8203
8204         if (targetReceiver == null) {
8205             return null;
8206         }
8207
8208         return new ComponentName(targetReceiver.packageName, targetReceiver.name);
8209     }
8210
8211     private List<ComponentName> matchVerifiers(PackageInfoLite pkgInfo,
8212             List<ResolveInfo> receivers, final PackageVerificationState verificationState) {
8213         if (pkgInfo.verifiers.length == 0) {
8214             return null;
8215         }
8216
8217         final int N = pkgInfo.verifiers.length;
8218         final List<ComponentName> sufficientVerifiers = new ArrayList<ComponentName>(N + 1);
8219         for (int i = 0; i < N; i++) {
8220             final VerifierInfo verifierInfo = pkgInfo.verifiers[i];
8221
8222             final ComponentName comp = matchComponentForVerifier(verifierInfo.packageName,
8223                     receivers);
8224             if (comp == null) {
8225                 continue;
8226             }
8227
8228             final int verifierUid = getUidForVerifier(verifierInfo);
8229             if (verifierUid == -1) {
8230                 continue;
8231             }
8232
8233             if (DEBUG_VERIFY) {
8234                 Slog.d(TAG, "Added sufficient verifier " + verifierInfo.packageName
8235                         + " with the correct signature");
8236             }
8237             sufficientVerifiers.add(comp);
8238             verificationState.addSufficientVerifier(verifierUid);
8239         }
8240
8241         return sufficientVerifiers;
8242     }
8243
8244     private int getUidForVerifier(VerifierInfo verifierInfo) {
8245         synchronized (mPackages) {
8246             final PackageParser.Package pkg = mPackages.get(verifierInfo.packageName);
8247             if (pkg == null) {
8248                 return -1;
8249             } else if (pkg.mSignatures.length != 1) {
8250                 Slog.i(TAG, "Verifier package " + verifierInfo.packageName
8251                         + " has more than one signature; ignoring");
8252                 return -1;
8253             }
8254
8255             /*
8256              * If the public key of the package's signature does not match
8257              * our expected public key, then this is a different package and
8258              * we should skip.
8259              */
8260
8261             final byte[] expectedPublicKey;
8262             try {
8263                 final Signature verifierSig = pkg.mSignatures[0];
8264                 final PublicKey publicKey = verifierSig.getPublicKey();
8265                 expectedPublicKey = publicKey.getEncoded();
8266             } catch (CertificateException e) {
8267                 return -1;
8268             }
8269
8270             final byte[] actualPublicKey = verifierInfo.publicKey.getEncoded();
8271
8272             if (!Arrays.equals(actualPublicKey, expectedPublicKey)) {
8273                 Slog.i(TAG, "Verifier package " + verifierInfo.packageName
8274                         + " does not have the expected public key; ignoring");
8275                 return -1;
8276             }
8277
8278             return pkg.applicationInfo.uid;
8279         }
8280     }
8281
8282     @Override
8283     public void finishPackageInstall(int token) {
8284         enforceSystemOrRoot("Only the system is allowed to finish installs");
8285
8286         if (DEBUG_INSTALL) {
8287             Slog.v(TAG, "BM finishing package install for " + token);
8288         }
8289
8290         final Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0);
8291         mHandler.sendMessage(msg);
8292     }
8293
8294     /**
8295      * Get the verification agent timeout.
8296      *
8297      * @return verification timeout in milliseconds
8298      */
8299     private long getVerificationTimeout() {
8300         return android.provider.Settings.Global.getLong(mContext.getContentResolver(),
8301                 android.provider.Settings.Global.PACKAGE_VERIFIER_TIMEOUT,
8302                 DEFAULT_VERIFICATION_TIMEOUT);
8303     }
8304
8305     /**
8306      * Get the default verification agent response code.
8307      *
8308      * @return default verification response code
8309      */
8310     private int getDefaultVerificationResponse() {
8311         return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
8312                 android.provider.Settings.Global.PACKAGE_VERIFIER_DEFAULT_RESPONSE,
8313                 DEFAULT_VERIFICATION_RESPONSE);
8314     }
8315
8316     /**
8317      * Check whether or not package verification has been enabled.
8318      *
8319      * @return true if verification should be performed
8320      */
8321     private boolean isVerificationEnabled(int userId, int installFlags) {
8322         if (!DEFAULT_VERIFY_ENABLE) {
8323             return false;
8324         }
8325
8326         boolean ensureVerifyAppsEnabled = isUserRestricted(userId, UserManager.ENSURE_VERIFY_APPS);
8327
8328         // Check if installing from ADB
8329         if ((installFlags & PackageManager.INSTALL_FROM_ADB) != 0) {
8330             // Do not run verification in a test harness environment
8331             if (ActivityManager.isRunningInTestHarness()) {
8332                 return false;
8333             }
8334             if (ensureVerifyAppsEnabled) {
8335                 return true;
8336             }
8337             // Check if the developer does not want package verification for ADB installs
8338             if (android.provider.Settings.Global.getInt(mContext.getContentResolver(),
8339                     android.provider.Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, 1) == 0) {
8340                 return false;
8341             }
8342         }
8343
8344         if (ensureVerifyAppsEnabled) {
8345             return true;
8346         }
8347
8348         return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
8349                 android.provider.Settings.Global.PACKAGE_VERIFIER_ENABLE, 1) == 1;
8350     }
8351
8352     /**
8353      * Get the "allow unknown sources" setting.
8354      *
8355      * @return the current "allow unknown sources" setting
8356      */
8357     private int getUnknownSourcesSettings() {
8358         return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
8359                 android.provider.Settings.Global.INSTALL_NON_MARKET_APPS,
8360                 -1);
8361     }
8362
8363     @Override
8364     public void setInstallerPackageName(String targetPackage, String installerPackageName) {
8365         final int uid = Binder.getCallingUid();
8366         // writer
8367         synchronized (mPackages) {
8368             PackageSetting targetPackageSetting = mSettings.mPackages.get(targetPackage);
8369             if (targetPackageSetting == null) {
8370                 throw new IllegalArgumentException("Unknown target package: " + targetPackage);
8371             }
8372
8373             PackageSetting installerPackageSetting;
8374             if (installerPackageName != null) {
8375                 installerPackageSetting = mSettings.mPackages.get(installerPackageName);
8376                 if (installerPackageSetting == null) {
8377                     throw new IllegalArgumentException("Unknown installer package: "
8378                             + installerPackageName);
8379                 }
8380             } else {
8381                 installerPackageSetting = null;
8382             }
8383
8384             Signature[] callerSignature;
8385             Object obj = mSettings.getUserIdLPr(uid);
8386             if (obj != null) {
8387                 if (obj instanceof SharedUserSetting) {
8388                     callerSignature = ((SharedUserSetting)obj).signatures.mSignatures;
8389                 } else if (obj instanceof PackageSetting) {
8390                     callerSignature = ((PackageSetting)obj).signatures.mSignatures;
8391                 } else {
8392                     throw new SecurityException("Bad object " + obj + " for uid " + uid);
8393                 }
8394             } else {
8395                 throw new SecurityException("Unknown calling uid " + uid);
8396             }
8397
8398             // Verify: can't set installerPackageName to a package that is
8399             // not signed with the same cert as the caller.
8400             if (installerPackageSetting != null) {
8401                 if (compareSignatures(callerSignature,
8402                         installerPackageSetting.signatures.mSignatures)
8403                         != PackageManager.SIGNATURE_MATCH) {
8404                     throw new SecurityException(
8405                             "Caller does not have same cert as new installer package "
8406                             + installerPackageName);
8407                 }
8408             }
8409
8410             // Verify: if target already has an installer package, it must
8411             // be signed with the same cert as the caller.
8412             if (targetPackageSetting.installerPackageName != null) {
8413                 PackageSetting setting = mSettings.mPackages.get(
8414                         targetPackageSetting.installerPackageName);
8415                 // If the currently set package isn't valid, then it's always
8416                 // okay to change it.
8417                 if (setting != null) {
8418                     if (compareSignatures(callerSignature,
8419                             setting.signatures.mSignatures)
8420                             != PackageManager.SIGNATURE_MATCH) {
8421                         throw new SecurityException(
8422                                 "Caller does not have same cert as old installer package "
8423                                 + targetPackageSetting.installerPackageName);
8424                     }
8425                 }
8426             }
8427
8428             // Okay!
8429             targetPackageSetting.installerPackageName = installerPackageName;
8430             scheduleWriteSettingsLocked();
8431         }
8432     }
8433
8434     private void processPendingInstall(final InstallArgs args, final int currentStatus) {
8435         // Queue up an async operation since the package installation may take a little while.
8436         mHandler.post(new Runnable() {
8437             public void run() {
8438                 mHandler.removeCallbacks(this);
8439                  // Result object to be returned
8440                 PackageInstalledInfo res = new PackageInstalledInfo();
8441                 res.returnCode = currentStatus;
8442                 res.uid = -1;
8443                 res.pkg = null;
8444                 res.removedInfo = new PackageRemovedInfo();
8445                 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
8446                     args.doPreInstall(res.returnCode);
8447                     synchronized (mInstallLock) {
8448                         installPackageLI(args, res);
8449                     }
8450                     args.doPostInstall(res.returnCode, res.uid);
8451                 }
8452
8453                 // A restore should be performed at this point if (a) the install
8454                 // succeeded, (b) the operation is not an update, and (c) the new
8455                 // package has not opted out of backup participation.
8456                 final boolean update = res.removedInfo.removedPackage != null;
8457                 final int flags = (res.pkg == null) ? 0 : res.pkg.applicationInfo.flags;
8458                 boolean doRestore = !update
8459                         && ((flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0);
8460
8461                 // Set up the post-install work request bookkeeping.  This will be used
8462                 // and cleaned up by the post-install event handling regardless of whether
8463                 // there's a restore pass performed.  Token values are >= 1.
8464                 int token;
8465                 if (mNextInstallToken < 0) mNextInstallToken = 1;
8466                 token = mNextInstallToken++;
8467
8468                 PostInstallData data = new PostInstallData(args, res);
8469                 mRunningInstalls.put(token, data);
8470                 if (DEBUG_INSTALL) Log.v(TAG, "+ starting restore round-trip " + token);
8471
8472                 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && doRestore) {
8473                     // Pass responsibility to the Backup Manager.  It will perform a
8474                     // restore if appropriate, then pass responsibility back to the
8475                     // Package Manager to run the post-install observer callbacks
8476                     // and broadcasts.
8477                     IBackupManager bm = IBackupManager.Stub.asInterface(
8478                             ServiceManager.getService(Context.BACKUP_SERVICE));
8479                     if (bm != null) {
8480                         if (DEBUG_INSTALL) Log.v(TAG, "token " + token
8481                                 + " to BM for possible restore");
8482                         try {
8483                             bm.restoreAtInstall(res.pkg.applicationInfo.packageName, token);
8484                         } catch (RemoteException e) {
8485                             // can't happen; the backup manager is local
8486                         } catch (Exception e) {
8487                             Slog.e(TAG, "Exception trying to enqueue restore", e);
8488                             doRestore = false;
8489                         }
8490                     } else {
8491                         Slog.e(TAG, "Backup Manager not found!");
8492                         doRestore = false;
8493                     }
8494                 }
8495
8496                 if (!doRestore) {
8497                     // No restore possible, or the Backup Manager was mysteriously not
8498                     // available -- just fire the post-install work request directly.
8499                     if (DEBUG_INSTALL) Log.v(TAG, "No restore - queue post-install for " + token);
8500                     Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0);
8501                     mHandler.sendMessage(msg);
8502                 }
8503             }
8504         });
8505     }
8506
8507     private abstract class HandlerParams {
8508         private static final int MAX_RETRIES = 4;
8509
8510         /**
8511          * Number of times startCopy() has been attempted and had a non-fatal
8512          * error.
8513          */
8514         private int mRetries = 0;
8515
8516         /** User handle for the user requesting the information or installation. */
8517         private final UserHandle mUser;
8518
8519         HandlerParams(UserHandle user) {
8520             mUser = user;
8521         }
8522
8523         UserHandle getUser() {
8524             return mUser;
8525         }
8526
8527         final boolean startCopy() {
8528             boolean res;
8529             try {
8530                 if (DEBUG_INSTALL) Slog.i(TAG, "startCopy " + mUser + ": " + this);
8531
8532                 if (++mRetries > MAX_RETRIES) {
8533                     Slog.w(TAG, "Failed to invoke remote methods on default container service. Giving up");
8534                     mHandler.sendEmptyMessage(MCS_GIVE_UP);
8535                     handleServiceError();
8536                     return false;
8537                 } else {
8538                     handleStartCopy();
8539                     res = true;
8540                 }
8541             } catch (RemoteException e) {
8542                 if (DEBUG_INSTALL) Slog.i(TAG, "Posting install MCS_RECONNECT");
8543                 mHandler.sendEmptyMessage(MCS_RECONNECT);
8544                 res = false;
8545             }
8546             handleReturnCode();
8547             return res;
8548         }
8549
8550         final void serviceError() {
8551             if (DEBUG_INSTALL) Slog.i(TAG, "serviceError");
8552             handleServiceError();
8553             handleReturnCode();
8554         }
8555
8556         abstract void handleStartCopy() throws RemoteException;
8557         abstract void handleServiceError();
8558         abstract void handleReturnCode();
8559     }
8560
8561     class MeasureParams extends HandlerParams {
8562         private final PackageStats mStats;
8563         private boolean mSuccess;
8564
8565         private final IPackageStatsObserver mObserver;
8566
8567         public MeasureParams(PackageStats stats, IPackageStatsObserver observer) {
8568             super(new UserHandle(stats.userHandle));
8569             mObserver = observer;
8570             mStats = stats;
8571         }
8572
8573         @Override
8574         public String toString() {
8575             return "MeasureParams{"
8576                 + Integer.toHexString(System.identityHashCode(this))
8577                 + " " + mStats.packageName + "}";
8578         }
8579
8580         @Override
8581         void handleStartCopy() throws RemoteException {
8582             synchronized (mInstallLock) {
8583                 mSuccess = getPackageSizeInfoLI(mStats.packageName, mStats.userHandle, mStats);
8584             }
8585
8586             if (mSuccess) {
8587                 final boolean mounted;
8588                 if (Environment.isExternalStorageEmulated()) {
8589                     mounted = true;
8590                 } else {
8591                     final String status = Environment.getExternalStorageState();
8592                     mounted = (Environment.MEDIA_MOUNTED.equals(status)
8593                             || Environment.MEDIA_MOUNTED_READ_ONLY.equals(status));
8594                 }
8595
8596                 if (mounted) {
8597                     final UserEnvironment userEnv = new UserEnvironment(mStats.userHandle);
8598
8599                     mStats.externalCacheSize = calculateDirectorySize(mContainerService,
8600                             userEnv.buildExternalStorageAppCacheDirs(mStats.packageName));
8601
8602                     mStats.externalDataSize = calculateDirectorySize(mContainerService,
8603                             userEnv.buildExternalStorageAppDataDirs(mStats.packageName));
8604
8605                     // Always subtract cache size, since it's a subdirectory
8606                     mStats.externalDataSize -= mStats.externalCacheSize;
8607
8608                     mStats.externalMediaSize = calculateDirectorySize(mContainerService,
8609                             userEnv.buildExternalStorageAppMediaDirs(mStats.packageName));
8610
8611                     mStats.externalObbSize = calculateDirectorySize(mContainerService,
8612                             userEnv.buildExternalStorageAppObbDirs(mStats.packageName));
8613                 }
8614             }
8615         }
8616
8617         @Override
8618         void handleReturnCode() {
8619             if (mObserver != null) {
8620                 try {
8621                     mObserver.onGetStatsCompleted(mStats, mSuccess);
8622                 } catch (RemoteException e) {
8623                     Slog.i(TAG, "Observer no longer exists.");
8624                 }
8625             }
8626         }
8627
8628         @Override
8629         void handleServiceError() {
8630             Slog.e(TAG, "Could not measure application " + mStats.packageName
8631                             + " external storage");
8632         }
8633     }
8634
8635     private static long calculateDirectorySize(IMediaContainerService mcs, File[] paths)
8636             throws RemoteException {
8637         long result = 0;
8638         for (File path : paths) {
8639             result += mcs.calculateDirectorySize(path.getAbsolutePath());
8640         }
8641         return result;
8642     }
8643
8644     private static void clearDirectory(IMediaContainerService mcs, File[] paths) {
8645         for (File path : paths) {
8646             try {
8647                 mcs.clearDirectory(path.getAbsolutePath());
8648             } catch (RemoteException e) {
8649             }
8650         }
8651     }
8652
8653     static class OriginInfo {
8654         /**
8655          * Location where install is coming from, before it has been
8656          * copied/renamed into place. This could be a single monolithic APK
8657          * file, or a cluster directory. This location may be untrusted.
8658          */
8659         final File file;
8660         final String cid;
8661
8662         /**
8663          * Flag indicating that {@link #file} or {@link #cid} has already been
8664          * staged, meaning downstream users don't need to defensively copy the
8665          * contents.
8666          */
8667         final boolean staged;
8668
8669         /**
8670          * Flag indicating that {@link #file} or {@link #cid} is an already
8671          * installed app that is being moved.
8672          */
8673         final boolean existing;
8674
8675         final String resolvedPath;
8676         final File resolvedFile;
8677
8678         static OriginInfo fromNothing() {
8679             return new OriginInfo(null, null, false, false);
8680         }
8681
8682         static OriginInfo fromUntrustedFile(File file) {
8683             return new OriginInfo(file, null, false, false);
8684         }
8685
8686         static OriginInfo fromExistingFile(File file) {
8687             return new OriginInfo(file, null, false, true);
8688         }
8689
8690         static OriginInfo fromStagedFile(File file) {
8691             return new OriginInfo(file, null, true, false);
8692         }
8693
8694         static OriginInfo fromStagedContainer(String cid) {
8695             return new OriginInfo(null, cid, true, false);
8696         }
8697
8698         private OriginInfo(File file, String cid, boolean staged, boolean existing) {
8699             this.file = file;
8700             this.cid = cid;
8701             this.staged = staged;
8702             this.existing = existing;
8703
8704             if (cid != null) {
8705                 resolvedPath = PackageHelper.getSdDir(cid);
8706                 resolvedFile = new File(resolvedPath);
8707             } else if (file != null) {
8708                 resolvedPath = file.getAbsolutePath();
8709                 resolvedFile = file;
8710             } else {
8711                 resolvedPath = null;
8712                 resolvedFile = null;
8713             }
8714         }
8715     }
8716
8717     class InstallParams extends HandlerParams {
8718         final OriginInfo origin;
8719         final IPackageInstallObserver2 observer;
8720         int installFlags;
8721         final String installerPackageName;
8722         final VerificationParams verificationParams;
8723         private InstallArgs mArgs;
8724         private int mRet;
8725         final String packageAbiOverride;
8726
8727         InstallParams(OriginInfo origin, IPackageInstallObserver2 observer, int installFlags,
8728                 String installerPackageName, VerificationParams verificationParams, UserHandle user,
8729                 String packageAbiOverride) {
8730             super(user);
8731             this.origin = origin;
8732             this.observer = observer;
8733             this.installFlags = installFlags;
8734             this.installerPackageName = installerPackageName;
8735             this.verificationParams = verificationParams;
8736             this.packageAbiOverride = packageAbiOverride;
8737         }
8738
8739         @Override
8740         public String toString() {
8741             return "InstallParams{" + Integer.toHexString(System.identityHashCode(this))
8742                     + " file=" + origin.file + " cid=" + origin.cid + "}";
8743         }
8744
8745         public ManifestDigest getManifestDigest() {
8746             if (verificationParams == null) {
8747                 return null;
8748             }
8749             return verificationParams.getManifestDigest();
8750         }
8751
8752         private int installLocationPolicy(PackageInfoLite pkgLite) {
8753             String packageName = pkgLite.packageName;
8754             int installLocation = pkgLite.installLocation;
8755             boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
8756             // reader
8757             synchronized (mPackages) {
8758                 PackageParser.Package pkg = mPackages.get(packageName);
8759                 if (pkg != null) {
8760                     if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
8761                         // Check for downgrading.
8762                         if ((installFlags & PackageManager.INSTALL_ALLOW_DOWNGRADE) == 0) {
8763                             if (pkgLite.versionCode < pkg.mVersionCode) {
8764                                 Slog.w(TAG, "Can't install update of " + packageName
8765                                         + " update version " + pkgLite.versionCode
8766                                         + " is older than installed version "
8767                                         + pkg.mVersionCode);
8768                                 return PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE;
8769                             }
8770                         }
8771                         // Check for updated system application.
8772                         if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
8773                             if (onSd) {
8774                                 Slog.w(TAG, "Cannot install update to system app on sdcard");
8775                                 return PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION;
8776                             }
8777                             return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
8778                         } else {
8779                             if (onSd) {
8780                                 // Install flag overrides everything.
8781                                 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
8782                             }
8783                             // If current upgrade specifies particular preference
8784                             if (installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) {
8785                                 // Application explicitly specified internal.
8786                                 return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
8787                             } else if (installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) {
8788                                 // App explictly prefers external. Let policy decide
8789                             } else {
8790                                 // Prefer previous location
8791                                 if (isExternal(pkg)) {
8792                                     return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
8793                                 }
8794                                 return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
8795                             }
8796                         }
8797                     } else {
8798                         // Invalid install. Return error code
8799                         return PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS;
8800                     }
8801                 }
8802             }
8803             // All the special cases have been taken care of.
8804             // Return result based on recommended install location.
8805             if (onSd) {
8806                 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
8807             }
8808             return pkgLite.recommendedInstallLocation;
8809         }
8810
8811         /*
8812          * Invoke remote method to get package information and install
8813          * location values. Override install location based on default
8814          * policy if needed and then create install arguments based
8815          * on the install location.
8816          */
8817         public void handleStartCopy() throws RemoteException {
8818             int ret = PackageManager.INSTALL_SUCCEEDED;
8819
8820             // If we're already staged, we've firmly committed to an install location
8821             if (origin.staged) {
8822                 if (origin.file != null) {
8823                     installFlags |= PackageManager.INSTALL_INTERNAL;
8824                     installFlags &= ~PackageManager.INSTALL_EXTERNAL;
8825                 } else if (origin.cid != null) {
8826                     installFlags |= PackageManager.INSTALL_EXTERNAL;
8827                     installFlags &= ~PackageManager.INSTALL_INTERNAL;
8828                 } else {
8829                     throw new IllegalStateException("Invalid stage location");
8830                 }
8831             }
8832
8833             final boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
8834             final boolean onInt = (installFlags & PackageManager.INSTALL_INTERNAL) != 0;
8835
8836             PackageInfoLite pkgLite = null;
8837
8838             if (onInt && onSd) {
8839                 // Check if both bits are set.
8840                 Slog.w(TAG, "Conflicting flags specified for installing on both internal and external");
8841                 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
8842             } else {
8843                 pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, installFlags,
8844                         packageAbiOverride);
8845
8846                 /*
8847                  * If we have too little free space, try to free cache
8848                  * before giving up.
8849                  */
8850                 if (!origin.staged && pkgLite.recommendedInstallLocation
8851                         == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
8852                     // TODO: focus freeing disk space on the target device
8853                     final StorageManager storage = StorageManager.from(mContext);
8854                     final long lowThreshold = storage.getStorageLowBytes(
8855                             Environment.getDataDirectory());
8856
8857                     final long sizeBytes = mContainerService.calculateInstalledSize(
8858                             origin.resolvedPath, isForwardLocked(), packageAbiOverride);
8859
8860                     if (mInstaller.freeCache(sizeBytes + lowThreshold) >= 0) {
8861                         pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath,
8862                                 installFlags, packageAbiOverride);
8863                     }
8864
8865                     /*
8866                      * The cache free must have deleted the file we
8867                      * downloaded to install.
8868                      *
8869                      * TODO: fix the "freeCache" call to not delete
8870                      *       the file we care about.
8871                      */
8872                     if (pkgLite.recommendedInstallLocation
8873                             == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
8874                         pkgLite.recommendedInstallLocation
8875                             = PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE;
8876                     }
8877                 }
8878             }
8879
8880             if (ret == PackageManager.INSTALL_SUCCEEDED) {
8881                 int loc = pkgLite.recommendedInstallLocation;
8882                 if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION) {
8883                     ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
8884                 } else if (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS) {
8885                     ret = PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
8886                 } else if (loc == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
8887                     ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
8888                 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_APK) {
8889                     ret = PackageManager.INSTALL_FAILED_INVALID_APK;
8890                 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
8891                     ret = PackageManager.INSTALL_FAILED_INVALID_URI;
8892                 } else if (loc == PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE) {
8893                     ret = PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE;
8894                 } else {
8895                     // Override with defaults if needed.
8896                     loc = installLocationPolicy(pkgLite);
8897                     if (loc == PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE) {
8898                         ret = PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
8899                     } else if (!onSd && !onInt) {
8900                         // Override install location with flags
8901                         if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) {
8902                             // Set the flag to install on external media.
8903                             installFlags |= PackageManager.INSTALL_EXTERNAL;
8904                             installFlags &= ~PackageManager.INSTALL_INTERNAL;
8905                         } else {
8906                             // Make sure the flag for installing on external
8907                             // media is unset
8908                             installFlags |= PackageManager.INSTALL_INTERNAL;
8909                             installFlags &= ~PackageManager.INSTALL_EXTERNAL;
8910                         }
8911                     }
8912                 }
8913             }
8914
8915             final InstallArgs args = createInstallArgs(this);
8916             mArgs = args;
8917
8918             if (ret == PackageManager.INSTALL_SUCCEEDED) {
8919                  /*
8920                  * ADB installs appear as UserHandle.USER_ALL, and can only be performed by
8921                  * UserHandle.USER_OWNER, so use the package verifier for UserHandle.USER_OWNER.
8922                  */
8923                 int userIdentifier = getUser().getIdentifier();
8924                 if (userIdentifier == UserHandle.USER_ALL
8925                         && ((installFlags & PackageManager.INSTALL_FROM_ADB) != 0)) {
8926                     userIdentifier = UserHandle.USER_OWNER;
8927                 }
8928
8929                 /*
8930                  * Determine if we have any installed package verifiers. If we
8931                  * do, then we'll defer to them to verify the packages.
8932                  */
8933                 final int requiredUid = mRequiredVerifierPackage == null ? -1
8934                         : getPackageUid(mRequiredVerifierPackage, userIdentifier);
8935                 if (!origin.existing && requiredUid != -1
8936                         && isVerificationEnabled(userIdentifier, installFlags)) {
8937                     final Intent verification = new Intent(
8938                             Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
8939                     verification.setDataAndType(Uri.fromFile(new File(origin.resolvedPath)),
8940                             PACKAGE_MIME_TYPE);
8941                     verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
8942
8943                     final List<ResolveInfo> receivers = queryIntentReceivers(verification,
8944                             PACKAGE_MIME_TYPE, PackageManager.GET_DISABLED_COMPONENTS,
8945                             0 /* TODO: Which userId? */);
8946
8947                     if (DEBUG_VERIFY) {
8948                         Slog.d(TAG, "Found " + receivers.size() + " verifiers for intent "
8949                                 + verification.toString() + " with " + pkgLite.verifiers.length
8950                                 + " optional verifiers");
8951                     }
8952
8953                     final int verificationId = mPendingVerificationToken++;
8954
8955                     verification.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
8956
8957                     verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_PACKAGE,
8958                             installerPackageName);
8959
8960                     verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALL_FLAGS,
8961                             installFlags);
8962
8963                     verification.putExtra(PackageManager.EXTRA_VERIFICATION_PACKAGE_NAME,
8964                             pkgLite.packageName);
8965
8966                     verification.putExtra(PackageManager.EXTRA_VERIFICATION_VERSION_CODE,
8967                             pkgLite.versionCode);
8968
8969                     if (verificationParams != null) {
8970                         if (verificationParams.getVerificationURI() != null) {
8971                            verification.putExtra(PackageManager.EXTRA_VERIFICATION_URI,
8972                                  verificationParams.getVerificationURI());
8973                         }
8974                         if (verificationParams.getOriginatingURI() != null) {
8975                             verification.putExtra(Intent.EXTRA_ORIGINATING_URI,
8976                                   verificationParams.getOriginatingURI());
8977                         }
8978                         if (verificationParams.getReferrer() != null) {
8979                             verification.putExtra(Intent.EXTRA_REFERRER,
8980                                   verificationParams.getReferrer());
8981                         }
8982                         if (verificationParams.getOriginatingUid() >= 0) {
8983                             verification.putExtra(Intent.EXTRA_ORIGINATING_UID,
8984                                   verificationParams.getOriginatingUid());
8985                         }
8986                         if (verificationParams.getInstallerUid() >= 0) {
8987                             verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_UID,
8988                                   verificationParams.getInstallerUid());
8989                         }
8990                     }
8991
8992                     final PackageVerificationState verificationState = new PackageVerificationState(
8993                             requiredUid, args);
8994
8995                     mPendingVerification.append(verificationId, verificationState);
8996
8997                     final List<ComponentName> sufficientVerifiers = matchVerifiers(pkgLite,
8998                             receivers, verificationState);
8999
9000                     /*
9001                      * If any sufficient verifiers were listed in the package
9002                      * manifest, attempt to ask them.
9003                      */
9004                     if (sufficientVerifiers != null) {
9005                         final int N = sufficientVerifiers.size();
9006                         if (N == 0) {
9007                             Slog.i(TAG, "Additional verifiers required, but none installed.");
9008                             ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
9009                         } else {
9010                             for (int i = 0; i < N; i++) {
9011                                 final ComponentName verifierComponent = sufficientVerifiers.get(i);
9012
9013                                 final Intent sufficientIntent = new Intent(verification);
9014                                 sufficientIntent.setComponent(verifierComponent);
9015
9016                                 mContext.sendBroadcastAsUser(sufficientIntent, getUser());
9017                             }
9018                         }
9019                     }
9020
9021                     final ComponentName requiredVerifierComponent = matchComponentForVerifier(
9022                             mRequiredVerifierPackage, receivers);
9023                     if (ret == PackageManager.INSTALL_SUCCEEDED
9024                             && mRequiredVerifierPackage != null) {
9025                         /*
9026                          * Send the intent to the required verification agent,
9027                          * but only start the verification timeout after the
9028                          * target BroadcastReceivers have run.
9029                          */
9030                         verification.setComponent(requiredVerifierComponent);
9031                         mContext.sendOrderedBroadcastAsUser(verification, getUser(),
9032                                 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
9033                                 new BroadcastReceiver() {
9034                                     @Override
9035                                     public void onReceive(Context context, Intent intent) {
9036                                         final Message msg = mHandler
9037                                                 .obtainMessage(CHECK_PENDING_VERIFICATION);
9038                                         msg.arg1 = verificationId;
9039                                         mHandler.sendMessageDelayed(msg, getVerificationTimeout());
9040                                     }
9041                                 }, null, 0, null, null);
9042
9043                         /*
9044                          * We don't want the copy to proceed until verification
9045                          * succeeds, so null out this field.
9046                          */
9047                         mArgs = null;
9048                     }
9049                 } else {
9050                     /*
9051                      * No package verification is enabled, so immediately start
9052                      * the remote call to initiate copy using temporary file.
9053                      */
9054                     ret = args.copyApk(mContainerService, true);
9055                 }
9056             }
9057
9058             mRet = ret;
9059         }
9060
9061         @Override
9062         void handleReturnCode() {
9063             // If mArgs is null, then MCS couldn't be reached. When it
9064             // reconnects, it will try again to install. At that point, this
9065             // will succeed.
9066             if (mArgs != null) {
9067                 processPendingInstall(mArgs, mRet);
9068             }
9069         }
9070
9071         @Override
9072         void handleServiceError() {
9073             mArgs = createInstallArgs(this);
9074             mRet = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
9075         }
9076
9077         public boolean isForwardLocked() {
9078             return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
9079         }
9080     }
9081
9082     /**
9083      * Used during creation of InstallArgs
9084      *
9085      * @param installFlags package installation flags
9086      * @return true if should be installed on external storage
9087      */
9088     private static boolean installOnSd(int installFlags) {
9089         if ((installFlags & PackageManager.INSTALL_INTERNAL) != 0) {
9090             return false;
9091         }
9092         if ((installFlags & PackageManager.INSTALL_EXTERNAL) != 0) {
9093             return true;
9094         }
9095         return false;
9096     }
9097
9098     /**
9099      * Used during creation of InstallArgs
9100      *
9101      * @param installFlags package installation flags
9102      * @return true if should be installed as forward locked
9103      */
9104     private static boolean installForwardLocked(int installFlags) {
9105         return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
9106     }
9107
9108     private InstallArgs createInstallArgs(InstallParams params) {
9109         if (installOnSd(params.installFlags) || params.isForwardLocked()) {
9110             return new AsecInstallArgs(params);
9111         } else {
9112             return new FileInstallArgs(params);
9113         }
9114     }
9115
9116     /**
9117      * Create args that describe an existing installed package. Typically used
9118      * when cleaning up old installs, or used as a move source.
9119      */
9120     private InstallArgs createInstallArgsForExisting(int installFlags, String codePath,
9121             String resourcePath, String nativeLibraryRoot, String[] instructionSets) {
9122         final boolean isInAsec;
9123         if (installOnSd(installFlags)) {
9124             /* Apps on SD card are always in ASEC containers. */
9125             isInAsec = true;
9126         } else if (installForwardLocked(installFlags)
9127                 && !codePath.startsWith(mDrmAppPrivateInstallDir.getAbsolutePath())) {
9128             /*
9129              * Forward-locked apps are only in ASEC containers if they're the
9130              * new style
9131              */
9132             isInAsec = true;
9133         } else {
9134             isInAsec = false;
9135         }
9136
9137         if (isInAsec) {
9138             return new AsecInstallArgs(codePath, instructionSets,
9139                     installOnSd(installFlags), installForwardLocked(installFlags));
9140         } else {
9141             return new FileInstallArgs(codePath, resourcePath, nativeLibraryRoot,
9142                     instructionSets);
9143         }
9144     }
9145
9146     static abstract class InstallArgs {
9147         /** @see InstallParams#origin */
9148         final OriginInfo origin;
9149
9150         final IPackageInstallObserver2 observer;
9151         // Always refers to PackageManager flags only
9152         final int installFlags;
9153         final String installerPackageName;
9154         final ManifestDigest manifestDigest;
9155         final UserHandle user;
9156         final String abiOverride;
9157
9158         // The list of instruction sets supported by this app. This is currently
9159         // only used during the rmdex() phase to clean up resources. We can get rid of this
9160         // if we move dex files under the common app path.
9161         /* nullable */ String[] instructionSets;
9162
9163         InstallArgs(OriginInfo origin, IPackageInstallObserver2 observer, int installFlags,
9164                 String installerPackageName, ManifestDigest manifestDigest, UserHandle user,
9165                 String[] instructionSets, String abiOverride) {
9166             this.origin = origin;
9167             this.installFlags = installFlags;
9168             this.observer = observer;
9169             this.installerPackageName = installerPackageName;
9170             this.manifestDigest = manifestDigest;
9171             this.user = user;
9172             this.instructionSets = instructionSets;
9173             this.abiOverride = abiOverride;
9174         }
9175
9176         abstract int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException;
9177         abstract int doPreInstall(int status);
9178
9179         /**
9180          * Rename package into final resting place. All paths on the given
9181          * scanned package should be updated to reflect the rename.
9182          */
9183         abstract boolean doRename(int status, PackageParser.Package pkg, String oldCodePath);
9184         abstract int doPostInstall(int status, int uid);
9185
9186         /** @see PackageSettingBase#codePathString */
9187         abstract String getCodePath();
9188         /** @see PackageSettingBase#resourcePathString */
9189         abstract String getResourcePath();
9190         abstract String getLegacyNativeLibraryPath();
9191
9192         // Need installer lock especially for dex file removal.
9193         abstract void cleanUpResourcesLI();
9194         abstract boolean doPostDeleteLI(boolean delete);
9195         abstract boolean checkFreeStorage(IMediaContainerService imcs) throws RemoteException;
9196
9197         /**
9198          * Called before the source arguments are copied. This is used mostly
9199          * for MoveParams when it needs to read the source file to put it in the
9200          * destination.
9201          */
9202         int doPreCopy() {
9203             return PackageManager.INSTALL_SUCCEEDED;
9204         }
9205
9206         /**
9207          * Called after the source arguments are copied. This is used mostly for
9208          * MoveParams when it needs to read the source file to put it in the
9209          * destination.
9210          *
9211          * @return
9212          */
9213         int doPostCopy(int uid) {
9214             return PackageManager.INSTALL_SUCCEEDED;
9215         }
9216
9217         protected boolean isFwdLocked() {
9218             return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
9219         }
9220
9221         protected boolean isExternal() {
9222             return (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
9223         }
9224
9225         UserHandle getUser() {
9226             return user;
9227         }
9228     }
9229
9230     /**
9231      * Logic to handle installation of non-ASEC applications, including copying
9232      * and renaming logic.
9233      */
9234     class FileInstallArgs extends InstallArgs {
9235         private File codeFile;
9236         private File resourceFile;
9237         private File legacyNativeLibraryPath;
9238
9239         // Example topology:
9240         // /data/app/com.example/base.apk
9241         // /data/app/com.example/split_foo.apk
9242         // /data/app/com.example/lib/arm/libfoo.so
9243         // /data/app/com.example/lib/arm64/libfoo.so
9244         // /data/app/com.example/dalvik/arm/base.apk@classes.dex
9245
9246         /** New install */
9247         FileInstallArgs(InstallParams params) {
9248             super(params.origin, params.observer, params.installFlags,
9249                     params.installerPackageName, params.getManifestDigest(), params.getUser(),
9250                     null /* instruction sets */, params.packageAbiOverride);
9251             if (isFwdLocked()) {
9252                 throw new IllegalArgumentException("Forward locking only supported in ASEC");
9253             }
9254         }
9255
9256         /** Existing install */
9257         FileInstallArgs(String codePath, String resourcePath, String legacyNativeLibraryPath,
9258                 String[] instructionSets) {
9259             super(OriginInfo.fromNothing(), null, 0, null, null, null, instructionSets, null);
9260             this.codeFile = (codePath != null) ? new File(codePath) : null;
9261             this.resourceFile = (resourcePath != null) ? new File(resourcePath) : null;
9262             this.legacyNativeLibraryPath = (legacyNativeLibraryPath != null) ?
9263                     new File(legacyNativeLibraryPath) : null;
9264         }
9265
9266         boolean checkFreeStorage(IMediaContainerService imcs) throws RemoteException {
9267             final long sizeBytes = imcs.calculateInstalledSize(origin.file.getAbsolutePath(),
9268                     isFwdLocked(), abiOverride);
9269
9270             final StorageManager storage = StorageManager.from(mContext);
9271             return (sizeBytes <= storage.getStorageBytesUntilLow(Environment.getDataDirectory()));
9272         }
9273
9274         int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
9275             if (origin.staged) {
9276                 Slog.d(TAG, origin.file + " already staged; skipping copy");
9277                 codeFile = origin.file;
9278                 resourceFile = origin.file;
9279                 return PackageManager.INSTALL_SUCCEEDED;
9280             }
9281
9282             try {
9283                 final File tempDir = mInstallerService.allocateInternalStageDirLegacy();
9284                 codeFile = tempDir;
9285                 resourceFile = tempDir;
9286             } catch (IOException e) {
9287                 Slog.w(TAG, "Failed to create copy file: " + e);
9288                 return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
9289             }
9290
9291             final IParcelFileDescriptorFactory target = new IParcelFileDescriptorFactory.Stub() {
9292                 @Override
9293                 public ParcelFileDescriptor open(String name, int mode) throws RemoteException {
9294                     if (!FileUtils.isValidExtFilename(name)) {
9295                         throw new IllegalArgumentException("Invalid filename: " + name);
9296                     }
9297                     try {
9298                         final File file = new File(codeFile, name);
9299                         final FileDescriptor fd = Os.open(file.getAbsolutePath(),
9300                                 O_RDWR | O_CREAT, 0644);
9301                         Os.chmod(file.getAbsolutePath(), 0644);
9302                         return new ParcelFileDescriptor(fd);
9303                     } catch (ErrnoException e) {
9304                         throw new RemoteException("Failed to open: " + e.getMessage());
9305                     }
9306                 }
9307             };
9308
9309             int ret = PackageManager.INSTALL_SUCCEEDED;
9310             ret = imcs.copyPackage(origin.file.getAbsolutePath(), target);
9311             if (ret != PackageManager.INSTALL_SUCCEEDED) {
9312                 Slog.e(TAG, "Failed to copy package");
9313                 return ret;
9314             }
9315
9316             final File libraryRoot = new File(codeFile, LIB_DIR_NAME);
9317             NativeLibraryHelper.Handle handle = null;
9318             try {
9319                 handle = NativeLibraryHelper.Handle.create(codeFile);
9320                 ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot,
9321                         abiOverride);
9322             } catch (IOException e) {
9323                 Slog.e(TAG, "Copying native libraries failed", e);
9324                 ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
9325             } finally {
9326                 IoUtils.closeQuietly(handle);
9327             }
9328
9329             return ret;
9330         }
9331
9332         int doPreInstall(int status) {
9333             if (status != PackageManager.INSTALL_SUCCEEDED) {
9334                 cleanUp();
9335             }
9336             return status;
9337         }
9338
9339         boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
9340             if (status != PackageManager.INSTALL_SUCCEEDED) {
9341                 cleanUp();
9342                 return false;
9343             } else {
9344                 final File beforeCodeFile = codeFile;
9345                 final File afterCodeFile = getNextCodePath(pkg.packageName);
9346
9347                 Slog.d(TAG, "Renaming " + beforeCodeFile + " to " + afterCodeFile);
9348                 try {
9349                     Os.rename(beforeCodeFile.getAbsolutePath(), afterCodeFile.getAbsolutePath());
9350                 } catch (ErrnoException e) {
9351                     Slog.d(TAG, "Failed to rename", e);
9352                     return false;
9353                 }
9354
9355                 if (!SELinux.restoreconRecursive(afterCodeFile)) {
9356                     Slog.d(TAG, "Failed to restorecon");
9357                     return false;
9358                 }
9359
9360                 // Reflect the rename internally
9361                 codeFile = afterCodeFile;
9362                 resourceFile = afterCodeFile;
9363
9364                 // Reflect the rename in scanned details
9365                 pkg.codePath = afterCodeFile.getAbsolutePath();
9366                 pkg.baseCodePath = FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile,
9367                         pkg.baseCodePath);
9368                 pkg.splitCodePaths = FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile,
9369                         pkg.splitCodePaths);
9370
9371                 // Reflect the rename in app info
9372                 pkg.applicationInfo.setCodePath(pkg.codePath);
9373                 pkg.applicationInfo.setBaseCodePath(pkg.baseCodePath);
9374                 pkg.applicationInfo.setSplitCodePaths(pkg.splitCodePaths);
9375                 pkg.applicationInfo.setResourcePath(pkg.codePath);
9376                 pkg.applicationInfo.setBaseResourcePath(pkg.baseCodePath);
9377                 pkg.applicationInfo.setSplitResourcePaths(pkg.splitCodePaths);
9378
9379                 return true;
9380             }
9381         }
9382
9383         int doPostInstall(int status, int uid) {
9384             if (status != PackageManager.INSTALL_SUCCEEDED) {
9385                 cleanUp();
9386             }
9387             return status;
9388         }
9389
9390         @Override
9391         String getCodePath() {
9392             return (codeFile != null) ? codeFile.getAbsolutePath() : null;
9393         }
9394
9395         @Override
9396         String getResourcePath() {
9397             return (resourceFile != null) ? resourceFile.getAbsolutePath() : null;
9398         }
9399
9400         @Override
9401         String getLegacyNativeLibraryPath() {
9402             return (legacyNativeLibraryPath != null) ? legacyNativeLibraryPath.getAbsolutePath() : null;
9403         }
9404
9405         private boolean cleanUp() {
9406             if (codeFile == null || !codeFile.exists()) {
9407                 return false;
9408             }
9409
9410             if (codeFile.isDirectory()) {
9411                 FileUtils.deleteContents(codeFile);
9412             }
9413             codeFile.delete();
9414
9415             if (resourceFile != null && !FileUtils.contains(codeFile, resourceFile)) {
9416                 resourceFile.delete();
9417             }
9418
9419             if (legacyNativeLibraryPath != null && !FileUtils.contains(codeFile, legacyNativeLibraryPath)) {
9420                 if (!FileUtils.deleteContents(legacyNativeLibraryPath)) {
9421                     Slog.w(TAG, "Couldn't delete native library directory " + legacyNativeLibraryPath);
9422                 }
9423                 legacyNativeLibraryPath.delete();
9424             }
9425
9426             return true;
9427         }
9428
9429         void cleanUpResourcesLI() {
9430             // Try enumerating all code paths before deleting
9431             List<String> allCodePaths = Collections.EMPTY_LIST;
9432             if (codeFile != null && codeFile.exists()) {
9433                 try {
9434                     final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0);
9435                     allCodePaths = pkg.getAllCodePaths();
9436                 } catch (PackageParserException e) {
9437                     // Ignored; we tried our best
9438                 }
9439             }
9440
9441             cleanUp();
9442
9443             if (!allCodePaths.isEmpty()) {
9444                 if (instructionSets == null) {
9445                     throw new IllegalStateException("instructionSet == null");
9446                 }
9447                 String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
9448                 for (String codePath : allCodePaths) {
9449                     for (String dexCodeInstructionSet : dexCodeInstructionSets) {
9450                         int retCode = mInstaller.rmdex(codePath, dexCodeInstructionSet);
9451                         if (retCode < 0) {
9452                             Slog.w(TAG, "Couldn't remove dex file for package: "
9453                                     + " at location " + codePath + ", retcode=" + retCode);
9454                             // we don't consider this to be a failure of the core package deletion
9455                         }
9456                     }
9457                 }
9458             }
9459         }
9460
9461         boolean doPostDeleteLI(boolean delete) {
9462             // XXX err, shouldn't we respect the delete flag?
9463             cleanUpResourcesLI();
9464             return true;
9465         }
9466     }
9467
9468     private boolean isAsecExternal(String cid) {
9469         final String asecPath = PackageHelper.getSdFilesystem(cid);
9470         return !asecPath.startsWith(mAsecInternalPath);
9471     }
9472
9473     private static void maybeThrowExceptionForMultiArchCopy(String message, int copyRet) throws
9474             PackageManagerException {
9475         if (copyRet < 0) {
9476             if (copyRet != PackageManager.NO_NATIVE_LIBRARIES &&
9477                     copyRet != PackageManager.INSTALL_FAILED_NO_MATCHING_ABIS) {
9478                 throw new PackageManagerException(copyRet, message);
9479             }
9480         }
9481     }
9482
9483     /**
9484      * Extract the MountService "container ID" from the full code path of an
9485      * .apk.
9486      */
9487     static String cidFromCodePath(String fullCodePath) {
9488         int eidx = fullCodePath.lastIndexOf("/");
9489         String subStr1 = fullCodePath.substring(0, eidx);
9490         int sidx = subStr1.lastIndexOf("/");
9491         return subStr1.substring(sidx+1, eidx);
9492     }
9493
9494     /**
9495      * Logic to handle installation of ASEC applications, including copying and
9496      * renaming logic.
9497      */
9498     class AsecInstallArgs extends InstallArgs {
9499         static final String RES_FILE_NAME = "pkg.apk";
9500         static final String PUBLIC_RES_FILE_NAME = "res.zip";
9501
9502         String cid;
9503         String packagePath;
9504         String resourcePath;
9505         String legacyNativeLibraryDir;
9506
9507         /** New install */
9508         AsecInstallArgs(InstallParams params) {
9509             super(params.origin, params.observer, params.installFlags,
9510                     params.installerPackageName, params.getManifestDigest(),
9511                     params.getUser(), null /* instruction sets */,
9512                     params.packageAbiOverride);
9513         }
9514
9515         /** Existing install */
9516         AsecInstallArgs(String fullCodePath, String[] instructionSets,
9517                         boolean isExternal, boolean isForwardLocked) {
9518             super(OriginInfo.fromNothing(), null, (isExternal ? INSTALL_EXTERNAL : 0)
9519                     | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null,
9520                     instructionSets, null);
9521             // Hackily pretend we're still looking at a full code path
9522             if (!fullCodePath.endsWith(RES_FILE_NAME)) {
9523                 fullCodePath = new File(fullCodePath, RES_FILE_NAME).getAbsolutePath();
9524             }
9525
9526             // Extract cid from fullCodePath
9527             int eidx = fullCodePath.lastIndexOf("/");
9528             String subStr1 = fullCodePath.substring(0, eidx);
9529             int sidx = subStr1.lastIndexOf("/");
9530             cid = subStr1.substring(sidx+1, eidx);
9531             setMountPath(subStr1);
9532         }
9533
9534         AsecInstallArgs(String cid, String[] instructionSets, boolean isForwardLocked) {
9535             super(OriginInfo.fromNothing(), null, (isAsecExternal(cid) ? INSTALL_EXTERNAL : 0)
9536                     | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null,
9537                     instructionSets, null);
9538             this.cid = cid;
9539             setMountPath(PackageHelper.getSdDir(cid));
9540         }
9541
9542         void createCopyFile() {
9543             cid = mInstallerService.allocateExternalStageCidLegacy();
9544         }
9545
9546         boolean checkFreeStorage(IMediaContainerService imcs) throws RemoteException {
9547             final long sizeBytes = imcs.calculateInstalledSize(packagePath, isFwdLocked(),
9548                     abiOverride);
9549
9550             final File target;
9551             if (isExternal()) {
9552                 target = new UserEnvironment(UserHandle.USER_OWNER).getExternalStorageDirectory();
9553             } else {
9554                 target = Environment.getDataDirectory();
9555             }
9556
9557             final StorageManager storage = StorageManager.from(mContext);
9558             return (sizeBytes <= storage.getStorageBytesUntilLow(target));
9559         }
9560
9561         int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
9562             if (origin.staged) {
9563                 Slog.d(TAG, origin.cid + " already staged; skipping copy");
9564                 cid = origin.cid;
9565                 setMountPath(PackageHelper.getSdDir(cid));
9566                 return PackageManager.INSTALL_SUCCEEDED;
9567             }
9568
9569             if (temp) {
9570                 createCopyFile();
9571             } else {
9572                 /*
9573                  * Pre-emptively destroy the container since it's destroyed if
9574                  * copying fails due to it existing anyway.
9575                  */
9576                 PackageHelper.destroySdDir(cid);
9577             }
9578
9579             final String newMountPath = imcs.copyPackageToContainer(
9580                     origin.file.getAbsolutePath(), cid, getEncryptKey(), isExternal(),
9581                     isFwdLocked(), deriveAbiOverride(abiOverride, null /* settings */));
9582
9583             if (newMountPath != null) {
9584                 setMountPath(newMountPath);
9585                 return PackageManager.INSTALL_SUCCEEDED;
9586             } else {
9587                 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
9588             }
9589         }
9590
9591         @Override
9592         String getCodePath() {
9593             return packagePath;
9594         }
9595
9596         @Override
9597         String getResourcePath() {
9598             return resourcePath;
9599         }
9600
9601         @Override
9602         String getLegacyNativeLibraryPath() {
9603             return legacyNativeLibraryDir;
9604         }
9605
9606         int doPreInstall(int status) {
9607             if (status != PackageManager.INSTALL_SUCCEEDED) {
9608                 // Destroy container
9609                 PackageHelper.destroySdDir(cid);
9610             } else {
9611                 boolean mounted = PackageHelper.isContainerMounted(cid);
9612                 if (!mounted) {
9613                     String newMountPath = PackageHelper.mountSdDir(cid, getEncryptKey(),
9614                             Process.SYSTEM_UID);
9615                     if (newMountPath != null) {
9616                         setMountPath(newMountPath);
9617                     } else {
9618                         return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
9619                     }
9620                 }
9621             }
9622             return status;
9623         }
9624
9625         boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
9626             String newCacheId = getNextCodePath(oldCodePath, pkg.packageName, "/" + RES_FILE_NAME);
9627             String newMountPath = null;
9628             if (PackageHelper.isContainerMounted(cid)) {
9629                 // Unmount the container
9630                 if (!PackageHelper.unMountSdDir(cid)) {
9631                     Slog.i(TAG, "Failed to unmount " + cid + " before renaming");
9632                     return false;
9633                 }
9634             }
9635             if (!PackageHelper.renameSdDir(cid, newCacheId)) {
9636                 Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId +
9637                         " which might be stale. Will try to clean up.");
9638                 // Clean up the stale container and proceed to recreate.
9639                 if (!PackageHelper.destroySdDir(newCacheId)) {
9640                     Slog.e(TAG, "Very strange. Cannot clean up stale container " + newCacheId);
9641                     return false;
9642                 }
9643                 // Successfully cleaned up stale container. Try to rename again.
9644                 if (!PackageHelper.renameSdDir(cid, newCacheId)) {
9645                     Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId
9646                             + " inspite of cleaning it up.");
9647                     return false;
9648                 }
9649             }
9650             if (!PackageHelper.isContainerMounted(newCacheId)) {
9651                 Slog.w(TAG, "Mounting container " + newCacheId);
9652                 newMountPath = PackageHelper.mountSdDir(newCacheId,
9653                         getEncryptKey(), Process.SYSTEM_UID);
9654             } else {
9655                 newMountPath = PackageHelper.getSdDir(newCacheId);
9656             }
9657             if (newMountPath == null) {
9658                 Slog.w(TAG, "Failed to get cache path for  " + newCacheId);
9659                 return false;
9660             }
9661             Log.i(TAG, "Succesfully renamed " + cid +
9662                     " to " + newCacheId +
9663                     " at new path: " + newMountPath);
9664             cid = newCacheId;
9665
9666             final File beforeCodeFile = new File(packagePath);
9667             setMountPath(newMountPath);
9668             final File afterCodeFile = new File(packagePath);
9669
9670             // Reflect the rename in scanned details
9671             pkg.codePath = afterCodeFile.getAbsolutePath();
9672             pkg.baseCodePath = FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile,
9673                     pkg.baseCodePath);
9674             pkg.splitCodePaths = FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile,
9675                     pkg.splitCodePaths);
9676
9677             // Reflect the rename in app info
9678             pkg.applicationInfo.setCodePath(pkg.codePath);
9679             pkg.applicationInfo.setBaseCodePath(pkg.baseCodePath);
9680             pkg.applicationInfo.setSplitCodePaths(pkg.splitCodePaths);
9681             pkg.applicationInfo.setResourcePath(pkg.codePath);
9682             pkg.applicationInfo.setBaseResourcePath(pkg.baseCodePath);
9683             pkg.applicationInfo.setSplitResourcePaths(pkg.splitCodePaths);
9684
9685             return true;
9686         }
9687
9688         private void setMountPath(String mountPath) {
9689             final File mountFile = new File(mountPath);
9690
9691             final File monolithicFile = new File(mountFile, RES_FILE_NAME);
9692             if (monolithicFile.exists()) {
9693                 packagePath = monolithicFile.getAbsolutePath();
9694                 if (isFwdLocked()) {
9695                     resourcePath = new File(mountFile, PUBLIC_RES_FILE_NAME).getAbsolutePath();
9696                 } else {
9697                     resourcePath = packagePath;
9698                 }
9699             } else {
9700                 packagePath = mountFile.getAbsolutePath();
9701                 resourcePath = packagePath;
9702             }
9703
9704             legacyNativeLibraryDir = new File(mountFile, LIB_DIR_NAME).getAbsolutePath();
9705         }
9706
9707         int doPostInstall(int status, int uid) {
9708             if (status != PackageManager.INSTALL_SUCCEEDED) {
9709                 cleanUp();
9710             } else {
9711                 final int groupOwner;
9712                 final String protectedFile;
9713                 if (isFwdLocked()) {
9714                     groupOwner = UserHandle.getSharedAppGid(uid);
9715                     protectedFile = RES_FILE_NAME;
9716                 } else {
9717                     groupOwner = -1;
9718                     protectedFile = null;
9719                 }
9720
9721                 if (uid < Process.FIRST_APPLICATION_UID
9722                         || !PackageHelper.fixSdPermissions(cid, groupOwner, protectedFile)) {
9723                     Slog.e(TAG, "Failed to finalize " + cid);
9724                     PackageHelper.destroySdDir(cid);
9725                     return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
9726                 }
9727
9728                 boolean mounted = PackageHelper.isContainerMounted(cid);
9729                 if (!mounted) {
9730                     PackageHelper.mountSdDir(cid, getEncryptKey(), Process.myUid());
9731                 }
9732             }
9733             return status;
9734         }
9735
9736         private void cleanUp() {
9737             if (DEBUG_SD_INSTALL) Slog.i(TAG, "cleanUp");
9738
9739             // Destroy secure container
9740             PackageHelper.destroySdDir(cid);
9741         }
9742
9743         private List<String> getAllCodePaths() {
9744             final File codeFile = new File(getCodePath());
9745             if (codeFile != null && codeFile.exists()) {
9746                 try {
9747                     final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0);
9748                     return pkg.getAllCodePaths();
9749                 } catch (PackageParserException e) {
9750                     // Ignored; we tried our best
9751                 }
9752             }
9753             return Collections.EMPTY_LIST;
9754         }
9755
9756         void cleanUpResourcesLI() {
9757             // Enumerate all code paths before deleting
9758             cleanUpResourcesLI(getAllCodePaths());
9759         }
9760
9761         private void cleanUpResourcesLI(List<String> allCodePaths) {
9762             cleanUp();
9763
9764             if (!allCodePaths.isEmpty()) {
9765                 if (instructionSets == null) {
9766                     throw new IllegalStateException("instructionSet == null");
9767                 }
9768                 String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
9769                 for (String codePath : allCodePaths) {
9770                     for (String dexCodeInstructionSet : dexCodeInstructionSets) {
9771                         int retCode = mInstaller.rmdex(codePath, dexCodeInstructionSet);
9772                         if (retCode < 0) {
9773                             Slog.w(TAG, "Couldn't remove dex file for package: "
9774                                     + " at location " + codePath + ", retcode=" + retCode);
9775                             // we don't consider this to be a failure of the core package deletion
9776                         }
9777                     }
9778                 }
9779             }
9780         }
9781
9782         boolean matchContainer(String app) {
9783             if (cid.startsWith(app)) {
9784                 return true;
9785             }
9786             return false;
9787         }
9788
9789         String getPackageName() {
9790             return getAsecPackageName(cid);
9791         }
9792
9793         boolean doPostDeleteLI(boolean delete) {
9794             if (DEBUG_SD_INSTALL) Slog.i(TAG, "doPostDeleteLI() del=" + delete);
9795             final List<String> allCodePaths = getAllCodePaths();
9796             boolean mounted = PackageHelper.isContainerMounted(cid);
9797             if (mounted) {
9798                 // Unmount first
9799                 if (PackageHelper.unMountSdDir(cid)) {
9800                     mounted = false;
9801                 }
9802             }
9803             if (!mounted && delete) {
9804                 cleanUpResourcesLI(allCodePaths);
9805             }
9806             return !mounted;
9807         }
9808
9809         @Override
9810         int doPreCopy() {
9811             if (isFwdLocked()) {
9812                 if (!PackageHelper.fixSdPermissions(cid,
9813                         getPackageUid(DEFAULT_CONTAINER_PACKAGE, 0), RES_FILE_NAME)) {
9814                     return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
9815                 }
9816             }
9817
9818             return PackageManager.INSTALL_SUCCEEDED;
9819         }
9820
9821         @Override
9822         int doPostCopy(int uid) {
9823             if (isFwdLocked()) {
9824                 if (uid < Process.FIRST_APPLICATION_UID
9825                         || !PackageHelper.fixSdPermissions(cid, UserHandle.getSharedAppGid(uid),
9826                                 RES_FILE_NAME)) {
9827                     Slog.e(TAG, "Failed to finalize " + cid);
9828                     PackageHelper.destroySdDir(cid);
9829                     return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
9830                 }
9831             }
9832
9833             return PackageManager.INSTALL_SUCCEEDED;
9834         }
9835     }
9836
9837     static String getAsecPackageName(String packageCid) {
9838         int idx = packageCid.lastIndexOf("-");
9839         if (idx == -1) {
9840             return packageCid;
9841         }
9842         return packageCid.substring(0, idx);
9843     }
9844
9845     // Utility method used to create code paths based on package name and available index.
9846     private static String getNextCodePath(String oldCodePath, String prefix, String suffix) {
9847         String idxStr = "";
9848         int idx = 1;
9849         // Fall back to default value of idx=1 if prefix is not
9850         // part of oldCodePath
9851         if (oldCodePath != null) {
9852             String subStr = oldCodePath;
9853             // Drop the suffix right away
9854             if (suffix != null && subStr.endsWith(suffix)) {
9855                 subStr = subStr.substring(0, subStr.length() - suffix.length());
9856             }
9857             // If oldCodePath already contains prefix find out the
9858             // ending index to either increment or decrement.
9859             int sidx = subStr.lastIndexOf(prefix);
9860             if (sidx != -1) {
9861                 subStr = subStr.substring(sidx + prefix.length());
9862                 if (subStr != null) {
9863                     if (subStr.startsWith(INSTALL_PACKAGE_SUFFIX)) {
9864                         subStr = subStr.substring(INSTALL_PACKAGE_SUFFIX.length());
9865                     }
9866                     try {
9867                         idx = Integer.parseInt(subStr);
9868                         if (idx <= 1) {
9869                             idx++;
9870                         } else {
9871                             idx--;
9872                         }
9873                     } catch(NumberFormatException e) {
9874                     }
9875                 }
9876             }
9877         }
9878         idxStr = INSTALL_PACKAGE_SUFFIX + Integer.toString(idx);
9879         return prefix + idxStr;
9880     }
9881
9882     private File getNextCodePath(String packageName) {
9883         int suffix = 1;
9884         File result;
9885         do {
9886             result = new File(mAppInstallDir, packageName + "-" + suffix);
9887             suffix++;
9888         } while (result.exists());
9889         return result;
9890     }
9891
9892     // Utility method used to ignore ADD/REMOVE events
9893     // by directory observer.
9894     private static boolean ignoreCodePath(String fullPathStr) {
9895         String apkName = deriveCodePathName(fullPathStr);
9896         int idx = apkName.lastIndexOf(INSTALL_PACKAGE_SUFFIX);
9897         if (idx != -1 && ((idx+1) < apkName.length())) {
9898             // Make sure the package ends with a numeral
9899             String version = apkName.substring(idx+1);
9900             try {
9901                 Integer.parseInt(version);
9902                 return true;
9903             } catch (NumberFormatException e) {}
9904         }
9905         return false;
9906     }
9907     
9908     // Utility method that returns the relative package path with respect
9909     // to the installation directory. Like say for /data/data/com.test-1.apk
9910     // string com.test-1 is returned.
9911     static String deriveCodePathName(String codePath) {
9912         if (codePath == null) {
9913             return null;
9914         }
9915         final File codeFile = new File(codePath);
9916         final String name = codeFile.getName();
9917         if (codeFile.isDirectory()) {
9918             return name;
9919         } else if (name.endsWith(".apk") || name.endsWith(".tmp")) {
9920             final int lastDot = name.lastIndexOf('.');
9921             return name.substring(0, lastDot);
9922         } else {
9923             Slog.w(TAG, "Odd, " + codePath + " doesn't look like an APK");
9924             return null;
9925         }
9926     }
9927
9928     class PackageInstalledInfo {
9929         String name;
9930         int uid;
9931         // The set of users that originally had this package installed.
9932         int[] origUsers;
9933         // The set of users that now have this package installed.
9934         int[] newUsers;
9935         PackageParser.Package pkg;
9936         int returnCode;
9937         String returnMsg;
9938         PackageRemovedInfo removedInfo;
9939
9940         public void setError(int code, String msg) {
9941             returnCode = code;
9942             returnMsg = msg;
9943             Slog.w(TAG, msg);
9944         }
9945
9946         public void setError(String msg, PackageParserException e) {
9947             returnCode = e.error;
9948             returnMsg = ExceptionUtils.getCompleteMessage(msg, e);
9949             Slog.w(TAG, msg, e);
9950         }
9951
9952         public void setError(String msg, PackageManagerException e) {
9953             returnCode = e.error;
9954             returnMsg = ExceptionUtils.getCompleteMessage(msg, e);
9955             Slog.w(TAG, msg, e);
9956         }
9957
9958         // In some error cases we want to convey more info back to the observer
9959         String origPackage;
9960         String origPermission;
9961     }
9962
9963     /*
9964      * Install a non-existing package.
9965      */
9966     private void installNewPackageLI(PackageParser.Package pkg,
9967             int parseFlags, int scanFlags, UserHandle user,
9968             String installerPackageName, PackageInstalledInfo res) {
9969         // Remember this for later, in case we need to rollback this install
9970         String pkgName = pkg.packageName;
9971
9972         if (DEBUG_INSTALL) Slog.d(TAG, "installNewPackageLI: " + pkg);
9973         boolean dataDirExists = getDataPathForPackage(pkg.packageName, 0).exists();
9974         synchronized(mPackages) {
9975             if (mSettings.mRenamedPackages.containsKey(pkgName)) {
9976                 // A package with the same name is already installed, though
9977                 // it has been renamed to an older name.  The package we
9978                 // are trying to install should be installed as an update to
9979                 // the existing one, but that has not been requested, so bail.
9980                 res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName
9981                         + " without first uninstalling package running as "
9982                         + mSettings.mRenamedPackages.get(pkgName));
9983                 return;
9984             }
9985             if (mPackages.containsKey(pkgName)) {
9986                 // Don't allow installation over an existing package with the same name.
9987                 res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName
9988                         + " without first uninstalling.");
9989                 return;
9990             }
9991         }
9992
9993         try {
9994             PackageParser.Package newPackage = scanPackageLI(pkg, parseFlags, scanFlags,
9995                     System.currentTimeMillis(), user);
9996
9997             updateSettingsLI(newPackage, installerPackageName, null, null, res);
9998             // delete the partially installed application. the data directory will have to be
9999             // restored if it was already existing
10000             if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
10001                 // remove package from internal structures.  Note that we want deletePackageX to
10002                 // delete the package data and cache directories that it created in
10003                 // scanPackageLocked, unless those directories existed before we even tried to
10004                 // install.
10005                 deletePackageLI(pkgName, UserHandle.ALL, false, null, null,
10006                         dataDirExists ? PackageManager.DELETE_KEEP_DATA : 0,
10007                                 res.removedInfo, true);
10008             }
10009
10010         } catch (PackageManagerException e) {
10011             res.setError("Package couldn't be installed in " + pkg.codePath, e);
10012         }
10013     }
10014
10015     private boolean checkUpgradeKeySetLP(PackageSetting oldPS, PackageParser.Package newPkg) {
10016         // Upgrade keysets are being used.  Determine if new package has a superset of the
10017         // required keys.
10018         long[] upgradeKeySets = oldPS.keySetData.getUpgradeKeySets();
10019         KeySetManagerService ksms = mSettings.mKeySetManagerService;
10020         for (int i = 0; i < upgradeKeySets.length; i++) {
10021             Set<PublicKey> upgradeSet = ksms.getPublicKeysFromKeySetLPr(upgradeKeySets[i]);
10022             if (newPkg.mSigningKeys.containsAll(upgradeSet)) {
10023                 return true;
10024             }
10025         }
10026         return false;
10027     }
10028
10029     private void replacePackageLI(PackageParser.Package pkg,
10030             int parseFlags, int scanFlags, UserHandle user,
10031             String installerPackageName, PackageInstalledInfo res) {
10032         PackageParser.Package oldPackage;
10033         String pkgName = pkg.packageName;
10034         int[] allUsers;
10035         boolean[] perUserInstalled;
10036
10037         // First find the old package info and check signatures
10038         synchronized(mPackages) {
10039             oldPackage = mPackages.get(pkgName);
10040             if (DEBUG_INSTALL) Slog.d(TAG, "replacePackageLI: new=" + pkg + ", old=" + oldPackage);
10041             PackageSetting ps = mSettings.mPackages.get(pkgName);
10042             if (ps == null || !ps.keySetData.isUsingUpgradeKeySets() || ps.sharedUser != null) {
10043                 // default to original signature matching
10044                 if (compareSignatures(oldPackage.mSignatures, pkg.mSignatures)
10045                     != PackageManager.SIGNATURE_MATCH) {
10046                     res.setError(INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES,
10047                             "New package has a different signature: " + pkgName);
10048                     return;
10049                 }
10050             } else {
10051                 if(!checkUpgradeKeySetLP(ps, pkg)) {
10052                     res.setError(INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES,
10053                             "New package not signed by keys specified by upgrade-keysets: "
10054                             + pkgName);
10055                     return;
10056                 }
10057             }
10058
10059             // In case of rollback, remember per-user/profile install state
10060             allUsers = sUserManager.getUserIds();
10061             perUserInstalled = new boolean[allUsers.length];
10062             for (int i = 0; i < allUsers.length; i++) {
10063                 perUserInstalled[i] = ps != null ? ps.getInstalled(allUsers[i]) : false;
10064             }
10065         }
10066
10067         boolean sysPkg = (isSystemApp(oldPackage));
10068         if (sysPkg) {
10069             replaceSystemPackageLI(oldPackage, pkg, parseFlags, scanFlags,
10070                     user, allUsers, perUserInstalled, installerPackageName, res);
10071         } else {
10072             replaceNonSystemPackageLI(oldPackage, pkg, parseFlags, scanFlags,
10073                     user, allUsers, perUserInstalled, installerPackageName, res);
10074         }
10075     }
10076
10077     private void replaceNonSystemPackageLI(PackageParser.Package deletedPackage,
10078             PackageParser.Package pkg, int parseFlags, int scanFlags, UserHandle user,
10079             int[] allUsers, boolean[] perUserInstalled,
10080             String installerPackageName, PackageInstalledInfo res) {
10081         String pkgName = deletedPackage.packageName;
10082         boolean deletedPkg = true;
10083         boolean updatedSettings = false;
10084
10085         if (DEBUG_INSTALL) Slog.d(TAG, "replaceNonSystemPackageLI: new=" + pkg + ", old="
10086                 + deletedPackage);
10087         long origUpdateTime;
10088         if (pkg.mExtras != null) {
10089             origUpdateTime = ((PackageSetting)pkg.mExtras).lastUpdateTime;
10090         } else {
10091             origUpdateTime = 0;
10092         }
10093
10094         // First delete the existing package while retaining the data directory
10095         if (!deletePackageLI(pkgName, null, true, null, null, PackageManager.DELETE_KEEP_DATA,
10096                 res.removedInfo, true)) {
10097             // If the existing package wasn't successfully deleted
10098             res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE, "replaceNonSystemPackageLI");
10099             deletedPkg = false;
10100         } else {
10101             // Successfully deleted the old package; proceed with replace.
10102
10103             // If deleted package lived in a container, give users a chance to
10104             // relinquish resources before killing.
10105             if (isForwardLocked(deletedPackage) || isExternal(deletedPackage)) {
10106                 if (DEBUG_INSTALL) {
10107                     Slog.i(TAG, "upgrading pkg " + deletedPackage + " is ASEC-hosted -> UNAVAILABLE");
10108                 }
10109                 final int[] uidArray = new int[] { deletedPackage.applicationInfo.uid };
10110                 final ArrayList<String> pkgList = new ArrayList<String>(1);
10111                 pkgList.add(deletedPackage.applicationInfo.packageName);
10112                 sendResourcesChangedBroadcast(false, true, pkgList, uidArray, null);
10113             }
10114
10115             deleteCodeCacheDirsLI(pkgName);
10116             try {
10117                 final PackageParser.Package newPackage = scanPackageLI(pkg, parseFlags,
10118                         scanFlags | SCAN_UPDATE_TIME, System.currentTimeMillis(), user);
10119                 updateSettingsLI(newPackage, installerPackageName, allUsers, perUserInstalled, res);
10120                 updatedSettings = true;
10121             } catch (PackageManagerException e) {
10122                 res.setError("Package couldn't be installed in " + pkg.codePath, e);
10123             }
10124         }
10125
10126         if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
10127             // remove package from internal structures.  Note that we want deletePackageX to
10128             // delete the package data and cache directories that it created in
10129             // scanPackageLocked, unless those directories existed before we even tried to
10130             // install.
10131             if(updatedSettings) {
10132                 if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, rolling pack: " + pkgName);
10133                 deletePackageLI(
10134                         pkgName, null, true, allUsers, perUserInstalled,
10135                         PackageManager.DELETE_KEEP_DATA,
10136                                 res.removedInfo, true);
10137             }
10138             // Since we failed to install the new package we need to restore the old
10139             // package that we deleted.
10140             if (deletedPkg) {
10141                 if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, reinstalling: " + deletedPackage);
10142                 File restoreFile = new File(deletedPackage.codePath);
10143                 // Parse old package
10144                 boolean oldOnSd = isExternal(deletedPackage);
10145                 int oldParseFlags  = mDefParseFlags | PackageParser.PARSE_CHATTY |
10146                         (isForwardLocked(deletedPackage) ? PackageParser.PARSE_FORWARD_LOCK : 0) |
10147                         (oldOnSd ? PackageParser.PARSE_ON_SDCARD : 0);
10148                 int oldScanFlags = SCAN_UPDATE_SIGNATURE | SCAN_UPDATE_TIME;
10149                 try {
10150                     scanPackageLI(restoreFile, oldParseFlags, oldScanFlags, origUpdateTime, null);
10151                 } catch (PackageManagerException e) {
10152                     Slog.e(TAG, "Failed to restore package : " + pkgName + " after failed upgrade: "
10153                             + e.getMessage());
10154                     return;
10155                 }
10156                 // Restore of old package succeeded. Update permissions.
10157                 // writer
10158                 synchronized (mPackages) {
10159                     updatePermissionsLPw(deletedPackage.packageName, deletedPackage,
10160                             UPDATE_PERMISSIONS_ALL);
10161                     // can downgrade to reader
10162                     mSettings.writeLPr();
10163                 }
10164                 Slog.i(TAG, "Successfully restored package : " + pkgName + " after failed upgrade");
10165             }
10166         }
10167     }
10168
10169     private void replaceSystemPackageLI(PackageParser.Package deletedPackage,
10170             PackageParser.Package pkg, int parseFlags, int scanFlags, UserHandle user,
10171             int[] allUsers, boolean[] perUserInstalled,
10172             String installerPackageName, PackageInstalledInfo res) {
10173         if (DEBUG_INSTALL) Slog.d(TAG, "replaceSystemPackageLI: new=" + pkg
10174                 + ", old=" + deletedPackage);
10175         boolean disabledSystem = false;
10176         boolean updatedSettings = false;
10177         parseFlags |= PackageParser.PARSE_IS_SYSTEM;
10178         if ((deletedPackage.applicationInfo.flags&ApplicationInfo.FLAG_PRIVILEGED) != 0) {
10179             parseFlags |= PackageParser.PARSE_IS_PRIVILEGED;
10180         }
10181         String packageName = deletedPackage.packageName;
10182         if (packageName == null) {
10183             res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE,
10184                     "Attempt to delete null packageName.");
10185             return;
10186         }
10187         PackageParser.Package oldPkg;
10188         PackageSetting oldPkgSetting;
10189         // reader
10190         synchronized (mPackages) {
10191             oldPkg = mPackages.get(packageName);
10192             oldPkgSetting = mSettings.mPackages.get(packageName);
10193             if((oldPkg == null) || (oldPkg.applicationInfo == null) ||
10194                     (oldPkgSetting == null)) {
10195                 res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE,
10196                         "Couldn't find package:" + packageName + " information");
10197                 return;
10198             }
10199         }
10200
10201         killApplication(packageName, oldPkg.applicationInfo.uid, "replace sys pkg");
10202
10203         res.removedInfo.uid = oldPkg.applicationInfo.uid;
10204         res.removedInfo.removedPackage = packageName;
10205         // Remove existing system package
10206         removePackageLI(oldPkgSetting, true);
10207         // writer
10208         synchronized (mPackages) {
10209             disabledSystem = mSettings.disableSystemPackageLPw(packageName);
10210             if (!disabledSystem && deletedPackage != null) {
10211                 // We didn't need to disable the .apk as a current system package,
10212                 // which means we are replacing another update that is already
10213                 // installed.  We need to make sure to delete the older one's .apk.
10214                 res.removedInfo.args = createInstallArgsForExisting(0,
10215                         deletedPackage.applicationInfo.getCodePath(),
10216                         deletedPackage.applicationInfo.getResourcePath(),
10217                         deletedPackage.applicationInfo.nativeLibraryRootDir,
10218                         getAppDexInstructionSets(deletedPackage.applicationInfo));
10219             } else {
10220                 res.removedInfo.args = null;
10221             }
10222         }
10223
10224         // Successfully disabled the old package. Now proceed with re-installation
10225         deleteCodeCacheDirsLI(packageName);
10226
10227         res.returnCode = PackageManager.INSTALL_SUCCEEDED;
10228         pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
10229
10230         PackageParser.Package newPackage = null;
10231         try {
10232             newPackage = scanPackageLI(pkg, parseFlags, scanFlags, 0, user);
10233             if (newPackage.mExtras != null) {
10234                 final PackageSetting newPkgSetting = (PackageSetting) newPackage.mExtras;
10235                 newPkgSetting.firstInstallTime = oldPkgSetting.firstInstallTime;
10236                 newPkgSetting.lastUpdateTime = System.currentTimeMillis();
10237
10238                 // is the update attempting to change shared user? that isn't going to work...
10239                 if (oldPkgSetting.sharedUser != newPkgSetting.sharedUser) {
10240                     res.setError(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
10241                             "Forbidding shared user change from " + oldPkgSetting.sharedUser
10242                             + " to " + newPkgSetting.sharedUser);
10243                     updatedSettings = true;
10244                 }
10245             }
10246
10247             if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
10248                 updateSettingsLI(newPackage, installerPackageName, allUsers, perUserInstalled, res);
10249                 updatedSettings = true;
10250             }
10251
10252         } catch (PackageManagerException e) {
10253             res.setError("Package couldn't be installed in " + pkg.codePath, e);
10254         }
10255
10256         if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
10257             // Re installation failed. Restore old information
10258             // Remove new pkg information
10259             if (newPackage != null) {
10260                 removeInstalledPackageLI(newPackage, true);
10261             }
10262             // Add back the old system package
10263             try {
10264                 scanPackageLI(oldPkg, parseFlags, SCAN_UPDATE_SIGNATURE, 0, user);
10265             } catch (PackageManagerException e) {
10266                 Slog.e(TAG, "Failed to restore original package: " + e.getMessage());
10267             }
10268             // Restore the old system information in Settings
10269             synchronized (mPackages) {
10270                 if (disabledSystem) {
10271                     mSettings.enableSystemPackageLPw(packageName);
10272                 }
10273                 if (updatedSettings) {
10274                     mSettings.setInstallerPackageName(packageName,
10275                             oldPkgSetting.installerPackageName);
10276                 }
10277                 mSettings.writeLPr();
10278             }
10279         }
10280     }
10281
10282     private void updateSettingsLI(PackageParser.Package newPackage, String installerPackageName,
10283             int[] allUsers, boolean[] perUserInstalled,
10284             PackageInstalledInfo res) {
10285         String pkgName = newPackage.packageName;
10286         synchronized (mPackages) {
10287             //write settings. the installStatus will be incomplete at this stage.
10288             //note that the new package setting would have already been
10289             //added to mPackages. It hasn't been persisted yet.
10290             mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_INCOMPLETE);
10291             mSettings.writeLPr();
10292         }
10293
10294         if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + newPackage.codePath);
10295
10296         synchronized (mPackages) {
10297             updatePermissionsLPw(newPackage.packageName, newPackage,
10298                     UPDATE_PERMISSIONS_REPLACE_PKG | (newPackage.permissions.size() > 0
10299                             ? UPDATE_PERMISSIONS_ALL : 0));
10300             // For system-bundled packages, we assume that installing an upgraded version
10301             // of the package implies that the user actually wants to run that new code,
10302             // so we enable the package.
10303             if (isSystemApp(newPackage)) {
10304                 // NB: implicit assumption that system package upgrades apply to all users
10305                 if (DEBUG_INSTALL) {
10306                     Slog.d(TAG, "Implicitly enabling system package on upgrade: " + pkgName);
10307                 }
10308                 PackageSetting ps = mSettings.mPackages.get(pkgName);
10309                 if (ps != null) {
10310                     if (res.origUsers != null) {
10311                         for (int userHandle : res.origUsers) {
10312                             ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT,
10313                                     userHandle, installerPackageName);
10314                         }
10315                     }
10316                     // Also convey the prior install/uninstall state
10317                     if (allUsers != null && perUserInstalled != null) {
10318                         for (int i = 0; i < allUsers.length; i++) {
10319                             if (DEBUG_INSTALL) {
10320                                 Slog.d(TAG, "    user " + allUsers[i]
10321                                         + " => " + perUserInstalled[i]);
10322                             }
10323                             ps.setInstalled(perUserInstalled[i], allUsers[i]);
10324                         }
10325                         // these install state changes will be persisted in the
10326                         // upcoming call to mSettings.writeLPr().
10327                     }
10328                 }
10329             }
10330             res.name = pkgName;
10331             res.uid = newPackage.applicationInfo.uid;
10332             res.pkg = newPackage;
10333             mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_COMPLETE);
10334             mSettings.setInstallerPackageName(pkgName, installerPackageName);
10335             res.returnCode = PackageManager.INSTALL_SUCCEEDED;
10336             //to update install status
10337             mSettings.writeLPr();
10338         }
10339     }
10340
10341     private void installPackageLI(InstallArgs args, PackageInstalledInfo res) {
10342         final int installFlags = args.installFlags;
10343         String installerPackageName = args.installerPackageName;
10344         File tmpPackageFile = new File(args.getCodePath());
10345         boolean forwardLocked = ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0);
10346         boolean onSd = ((installFlags & PackageManager.INSTALL_EXTERNAL) != 0);
10347         boolean replace = false;
10348         final int scanFlags = SCAN_NEW_INSTALL | SCAN_FORCE_DEX | SCAN_UPDATE_SIGNATURE;
10349         // Result object to be returned
10350         res.returnCode = PackageManager.INSTALL_SUCCEEDED;
10351
10352         if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile);
10353         // Retrieve PackageSettings and parse package
10354         final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY
10355                 | (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0)
10356                 | (onSd ? PackageParser.PARSE_ON_SDCARD : 0);
10357         PackageParser pp = new PackageParser();
10358         pp.setSeparateProcesses(mSeparateProcesses);
10359         pp.setDisplayMetrics(mMetrics);
10360
10361         final PackageParser.Package pkg;
10362         try {
10363             pkg = pp.parsePackage(tmpPackageFile, parseFlags);
10364         } catch (PackageParserException e) {
10365             res.setError("Failed parse during installPackageLI", e);
10366             return;
10367         }
10368
10369         // Mark that we have an install time CPU ABI override.
10370         pkg.cpuAbiOverride = args.abiOverride;
10371
10372         String pkgName = res.name = pkg.packageName;
10373         if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_TEST_ONLY) != 0) {
10374             if ((installFlags & PackageManager.INSTALL_ALLOW_TEST) == 0) {
10375                 res.setError(INSTALL_FAILED_TEST_ONLY, "installPackageLI");
10376                 return;
10377             }
10378         }
10379
10380         try {
10381             pp.collectCertificates(pkg, parseFlags);
10382             pp.collectManifestDigest(pkg);
10383         } catch (PackageParserException e) {
10384             res.setError("Failed collect during installPackageLI", e);
10385             return;
10386         }
10387
10388         /* If the installer passed in a manifest digest, compare it now. */
10389         if (args.manifestDigest != null) {
10390             if (DEBUG_INSTALL) {
10391                 final String parsedManifest = pkg.manifestDigest == null ? "null"
10392                         : pkg.manifestDigest.toString();
10393                 Slog.d(TAG, "Comparing manifests: " + args.manifestDigest.toString() + " vs. "
10394                         + parsedManifest);
10395             }
10396
10397             if (!args.manifestDigest.equals(pkg.manifestDigest)) {
10398                 res.setError(INSTALL_FAILED_PACKAGE_CHANGED, "Manifest digest changed");
10399                 return;
10400             }
10401         } else if (DEBUG_INSTALL) {
10402             final String parsedManifest = pkg.manifestDigest == null
10403                     ? "null" : pkg.manifestDigest.toString();
10404             Slog.d(TAG, "manifestDigest was not present, but parser got: " + parsedManifest);
10405         }
10406
10407         // Get rid of all references to package scan path via parser.
10408         pp = null;
10409         String oldCodePath = null;
10410         boolean systemApp = false;
10411         synchronized (mPackages) {
10412             // Check whether the newly-scanned package wants to define an already-defined perm
10413             int N = pkg.permissions.size();
10414             for (int i = N-1; i >= 0; i--) {
10415                 PackageParser.Permission perm = pkg.permissions.get(i);
10416                 BasePermission bp = mSettings.mPermissions.get(perm.info.name);
10417                 if (bp != null) {
10418                     // If the defining package is signed with our cert, it's okay.  This
10419                     // also includes the "updating the same package" case, of course.
10420                     // "updating same package" could also involve key-rotation.
10421                     final boolean sigsOk;
10422                     if (!bp.sourcePackage.equals(pkg.packageName)
10423                             || !(bp.packageSetting instanceof PackageSetting)
10424                             || !bp.packageSetting.keySetData.isUsingUpgradeKeySets()
10425                             || ((PackageSetting) bp.packageSetting).sharedUser != null) {
10426                         sigsOk = compareSignatures(bp.packageSetting.signatures.mSignatures,
10427                                 pkg.mSignatures) == PackageManager.SIGNATURE_MATCH;
10428                     } else {
10429                         sigsOk = checkUpgradeKeySetLP((PackageSetting) bp.packageSetting, pkg);
10430                     }
10431                     if (!sigsOk) {
10432                         // If the owning package is the system itself, we log but allow
10433                         // install to proceed; we fail the install on all other permission
10434                         // redefinitions.
10435                         if (!bp.sourcePackage.equals("android")) {
10436                             res.setError(INSTALL_FAILED_DUPLICATE_PERMISSION, "Package "
10437                                     + pkg.packageName + " attempting to redeclare permission "
10438                                     + perm.info.name + " already owned by " + bp.sourcePackage);
10439                             res.origPermission = perm.info.name;
10440                             res.origPackage = bp.sourcePackage;
10441                             return;
10442                         } else {
10443                             Slog.w(TAG, "Package " + pkg.packageName
10444                                     + " attempting to redeclare system permission "
10445                                     + perm.info.name + "; ignoring new declaration");
10446                             pkg.permissions.remove(i);
10447                         }
10448                     }
10449                 }
10450             }
10451
10452             // Check if installing already existing package
10453             if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
10454                 String oldName = mSettings.mRenamedPackages.get(pkgName);
10455                 if (pkg.mOriginalPackages != null
10456                         && pkg.mOriginalPackages.contains(oldName)
10457                         && mPackages.containsKey(oldName)) {
10458                     // This package is derived from an original package,
10459                     // and this device has been updating from that original
10460                     // name.  We must continue using the original name, so
10461                     // rename the new package here.
10462                     pkg.setPackageName(oldName);
10463                     pkgName = pkg.packageName;
10464                     replace = true;
10465                     if (DEBUG_INSTALL) Slog.d(TAG, "Replacing existing renamed package: oldName="
10466                             + oldName + " pkgName=" + pkgName);
10467                 } else if (mPackages.containsKey(pkgName)) {
10468                     // This package, under its official name, already exists
10469                     // on the device; we should replace it.
10470                     replace = true;
10471                     if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing pacakge: " + pkgName);
10472                 }
10473             }
10474             PackageSetting ps = mSettings.mPackages.get(pkgName);
10475             if (ps != null) {
10476                 if (DEBUG_INSTALL) Slog.d(TAG, "Existing package: " + ps);
10477                 oldCodePath = mSettings.mPackages.get(pkgName).codePathString;
10478                 if (ps.pkg != null && ps.pkg.applicationInfo != null) {
10479                     systemApp = (ps.pkg.applicationInfo.flags &
10480                             ApplicationInfo.FLAG_SYSTEM) != 0;
10481                 }
10482                 res.origUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
10483             }
10484         }
10485
10486         if (systemApp && onSd) {
10487             // Disable updates to system apps on sdcard
10488             res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
10489                     "Cannot install updates to system apps on sdcard");
10490             return;
10491         }
10492
10493         if (!args.doRename(res.returnCode, pkg, oldCodePath)) {
10494             res.setError(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename");
10495             return;
10496         }
10497
10498         if (replace) {
10499             replacePackageLI(pkg, parseFlags, scanFlags | SCAN_REPLACING, args.user,
10500                     installerPackageName, res);
10501         } else {
10502             installNewPackageLI(pkg, parseFlags, scanFlags | SCAN_DELETE_DATA_ON_FAILURES,
10503                     args.user, installerPackageName, res);
10504         }
10505         synchronized (mPackages) {
10506             final PackageSetting ps = mSettings.mPackages.get(pkgName);
10507             if (ps != null) {
10508                 res.newUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
10509             }
10510         }
10511     }
10512
10513     private static boolean isForwardLocked(PackageParser.Package pkg) {
10514         return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0;
10515     }
10516
10517     private static boolean isForwardLocked(ApplicationInfo info) {
10518         return (info.flags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0;
10519     }
10520
10521     private boolean isForwardLocked(PackageSetting ps) {
10522         return (ps.pkgFlags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0;
10523     }
10524
10525     private static boolean isMultiArch(PackageSetting ps) {
10526         return (ps.pkgFlags & ApplicationInfo.FLAG_MULTIARCH) != 0;
10527     }
10528
10529     private static boolean isMultiArch(ApplicationInfo info) {
10530         return (info.flags & ApplicationInfo.FLAG_MULTIARCH) != 0;
10531     }
10532
10533     private static boolean isExternal(PackageParser.Package pkg) {
10534         return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
10535     }
10536
10537     private static boolean isExternal(PackageSetting ps) {
10538         return (ps.pkgFlags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
10539     }
10540
10541     private static boolean isExternal(ApplicationInfo info) {
10542         return (info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
10543     }
10544
10545     private static boolean isSystemApp(PackageParser.Package pkg) {
10546         return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10547     }
10548
10549     private static boolean isPrivilegedApp(PackageParser.Package pkg) {
10550         return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_PRIVILEGED) != 0;
10551     }
10552
10553     private static boolean isSystemApp(ApplicationInfo info) {
10554         return (info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10555     }
10556
10557     private static boolean isSystemApp(PackageSetting ps) {
10558         return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0;
10559     }
10560
10561     private static boolean isUpdatedSystemApp(PackageSetting ps) {
10562         return (ps.pkgFlags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
10563     }
10564
10565     private static boolean isUpdatedSystemApp(PackageParser.Package pkg) {
10566         return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
10567     }
10568
10569     private static boolean isUpdatedSystemApp(ApplicationInfo info) {
10570         return (info.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
10571     }
10572
10573     private int packageFlagsToInstallFlags(PackageSetting ps) {
10574         int installFlags = 0;
10575         if (isExternal(ps)) {
10576             installFlags |= PackageManager.INSTALL_EXTERNAL;
10577         }
10578         if (isForwardLocked(ps)) {
10579             installFlags |= PackageManager.INSTALL_FORWARD_LOCK;
10580         }
10581         return installFlags;
10582     }
10583
10584     private void deleteTempPackageFiles() {
10585         final FilenameFilter filter = new FilenameFilter() {
10586             public boolean accept(File dir, String name) {
10587                 return name.startsWith("vmdl") && name.endsWith(".tmp");
10588             }
10589         };
10590         for (File file : mDrmAppPrivateInstallDir.listFiles(filter)) {
10591             file.delete();
10592         }
10593     }
10594
10595     @Override
10596     public void deletePackageAsUser(String packageName, IPackageDeleteObserver observer, int userId,
10597             int flags) {
10598         deletePackage(packageName, new LegacyPackageDeleteObserver(observer).getBinder(), userId,
10599                 flags);
10600     }
10601
10602     @Override
10603     public void deletePackage(final String packageName,
10604             final IPackageDeleteObserver2 observer, final int userId, final int flags) {
10605         mContext.enforceCallingOrSelfPermission(
10606                 android.Manifest.permission.DELETE_PACKAGES, null);
10607         final int uid = Binder.getCallingUid();
10608         if (UserHandle.getUserId(uid) != userId) {
10609             mContext.enforceCallingPermission(
10610                     android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10611                     "deletePackage for user " + userId);
10612         }
10613         if (isUserRestricted(userId, UserManager.DISALLOW_UNINSTALL_APPS)) {
10614             try {
10615                 observer.onPackageDeleted(packageName,
10616                         PackageManager.DELETE_FAILED_USER_RESTRICTED, null);
10617             } catch (RemoteException re) {
10618             }
10619             return;
10620         }
10621
10622         boolean uninstallBlocked = false;
10623         if ((flags & PackageManager.DELETE_ALL_USERS) != 0) {
10624             int[] users = sUserManager.getUserIds();
10625             for (int i = 0; i < users.length; ++i) {
10626                 if (getBlockUninstallForUser(packageName, users[i])) {
10627                     uninstallBlocked = true;
10628                     break;
10629                 }
10630             }
10631         } else {
10632             uninstallBlocked = getBlockUninstallForUser(packageName, userId);
10633         }
10634         if (uninstallBlocked) {
10635             try {
10636                 observer.onPackageDeleted(packageName, PackageManager.DELETE_FAILED_OWNER_BLOCKED,
10637                         null);
10638             } catch (RemoteException re) {
10639             }
10640             return;
10641         }
10642
10643         if (DEBUG_REMOVE) {
10644             Slog.d(TAG, "deletePackageAsUser: pkg=" + packageName + " user=" + userId);
10645         }
10646         // Queue up an async operation since the package deletion may take a little while.
10647         mHandler.post(new Runnable() {
10648             public void run() {
10649                 mHandler.removeCallbacks(this);
10650                 final int returnCode = deletePackageX(packageName, userId, flags);
10651                 if (observer != null) {
10652                     try {
10653                         observer.onPackageDeleted(packageName, returnCode, null);
10654                     } catch (RemoteException e) {
10655                         Log.i(TAG, "Observer no longer exists.");
10656                     } //end catch
10657                 } //end if
10658             } //end run
10659         });
10660     }
10661
10662     private boolean isPackageDeviceAdmin(String packageName, int userId) {
10663         IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
10664                 ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
10665         try {
10666             if (dpm != null) {
10667                 if (dpm.isDeviceOwner(packageName)) {
10668                     return true;
10669                 }
10670                 int[] users;
10671                 if (userId == UserHandle.USER_ALL) {
10672                     users = sUserManager.getUserIds();
10673                 } else {
10674                     users = new int[]{userId};
10675                 }
10676                 for (int i = 0; i < users.length; ++i) {
10677                     if (dpm.packageHasActiveAdmins(packageName, users[i])) {
10678                         return true;
10679                     }
10680                 }
10681             }
10682         } catch (RemoteException e) {
10683         }
10684         return false;
10685     }
10686
10687     /**
10688      *  This method is an internal method that could be get invoked either
10689      *  to delete an installed package or to clean up a failed installation.
10690      *  After deleting an installed package, a broadcast is sent to notify any
10691      *  listeners that the package has been installed. For cleaning up a failed
10692      *  installation, the broadcast is not necessary since the package's
10693      *  installation wouldn't have sent the initial broadcast either
10694      *  The key steps in deleting a package are
10695      *  deleting the package information in internal structures like mPackages,
10696      *  deleting the packages base directories through installd
10697      *  updating mSettings to reflect current status
10698      *  persisting settings for later use
10699      *  sending a broadcast if necessary
10700      */
10701     private int deletePackageX(String packageName, int userId, int flags) {
10702         final PackageRemovedInfo info = new PackageRemovedInfo();
10703         final boolean res;
10704
10705         final UserHandle removeForUser = (flags & PackageManager.DELETE_ALL_USERS) != 0
10706                 ? UserHandle.ALL : new UserHandle(userId);
10707
10708         if (isPackageDeviceAdmin(packageName, removeForUser.getIdentifier())) {
10709             Slog.w(TAG, "Not removing package " + packageName + ": has active device admin");
10710             return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER;
10711         }
10712
10713         boolean removedForAllUsers = false;
10714         boolean systemUpdate = false;
10715
10716         // for the uninstall-updates case and restricted profiles, remember the per-
10717         // userhandle installed state
10718         int[] allUsers;
10719         boolean[] perUserInstalled;
10720         synchronized (mPackages) {
10721             PackageSetting ps = mSettings.mPackages.get(packageName);
10722             allUsers = sUserManager.getUserIds();
10723             perUserInstalled = new boolean[allUsers.length];
10724             for (int i = 0; i < allUsers.length; i++) {
10725                 perUserInstalled[i] = ps != null ? ps.getInstalled(allUsers[i]) : false;
10726             }
10727         }
10728
10729         synchronized (mInstallLock) {
10730             if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageX: pkg=" + packageName + " user=" + userId);
10731             res = deletePackageLI(packageName, removeForUser,
10732                     true, allUsers, perUserInstalled,
10733                     flags | REMOVE_CHATTY, info, true);
10734             systemUpdate = info.isRemovedPackageSystemUpdate;
10735             if (res && !systemUpdate && mPackages.get(packageName) == null) {
10736                 removedForAllUsers = true;
10737             }
10738             if (DEBUG_REMOVE) Slog.d(TAG, "delete res: systemUpdate=" + systemUpdate
10739                     + " removedForAllUsers=" + removedForAllUsers);
10740         }
10741
10742         if (res) {
10743             info.sendBroadcast(true, systemUpdate, removedForAllUsers);
10744
10745             // If the removed package was a system update, the old system package
10746             // was re-enabled; we need to broadcast this information
10747             if (systemUpdate) {
10748                 Bundle extras = new Bundle(1);
10749                 extras.putInt(Intent.EXTRA_UID, info.removedAppId >= 0
10750                         ? info.removedAppId : info.uid);
10751                 extras.putBoolean(Intent.EXTRA_REPLACING, true);
10752
10753                 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
10754                         extras, null, null, null);
10755                 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, packageName,
10756                         extras, null, null, null);
10757                 sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, null,
10758                         null, packageName, null, null);
10759             }
10760         }
10761         // Force a gc here.
10762         Runtime.getRuntime().gc();
10763         // Delete the resources here after sending the broadcast to let
10764         // other processes clean up before deleting resources.
10765         if (info.args != null) {
10766             synchronized (mInstallLock) {
10767                 info.args.doPostDeleteLI(true);
10768             }
10769         }
10770
10771         return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR;
10772     }
10773
10774     static class PackageRemovedInfo {
10775         String removedPackage;
10776         int uid = -1;
10777         int removedAppId = -1;
10778         int[] removedUsers = null;
10779         boolean isRemovedPackageSystemUpdate = false;
10780         // Clean up resources deleted packages.
10781         InstallArgs args = null;
10782
10783         void sendBroadcast(boolean fullRemove, boolean replacing, boolean removedForAllUsers) {
10784             Bundle extras = new Bundle(1);
10785             extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid);
10786             extras.putBoolean(Intent.EXTRA_DATA_REMOVED, fullRemove);
10787             if (replacing) {
10788                 extras.putBoolean(Intent.EXTRA_REPLACING, true);
10789             }
10790             extras.putBoolean(Intent.EXTRA_REMOVED_FOR_ALL_USERS, removedForAllUsers);
10791             if (removedPackage != null) {
10792                 sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED, removedPackage,
10793                         extras, null, null, removedUsers);
10794                 if (fullRemove && !replacing) {
10795                     sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED, removedPackage,
10796                             extras, null, null, removedUsers);
10797                 }
10798             }
10799             if (removedAppId >= 0) {
10800                 sendPackageBroadcast(Intent.ACTION_UID_REMOVED, null, extras, null, null,
10801                         removedUsers);
10802             }
10803         }
10804     }
10805
10806     /*
10807      * This method deletes the package from internal data structures. If the DONT_DELETE_DATA
10808      * flag is not set, the data directory is removed as well.
10809      * make sure this flag is set for partially installed apps. If not its meaningless to
10810      * delete a partially installed application.
10811      */
10812     private void removePackageDataLI(PackageSetting ps,
10813             int[] allUserHandles, boolean[] perUserInstalled,
10814             PackageRemovedInfo outInfo, int flags, boolean writeSettings) {
10815         String packageName = ps.name;
10816         if (DEBUG_REMOVE) Slog.d(TAG, "removePackageDataLI: " + ps);
10817         removePackageLI(ps, (flags&REMOVE_CHATTY) != 0);
10818         // Retrieve object to delete permissions for shared user later on
10819         final PackageSetting deletedPs;
10820         // reader
10821         synchronized (mPackages) {
10822             deletedPs = mSettings.mPackages.get(packageName);
10823             if (outInfo != null) {
10824                 outInfo.removedPackage = packageName;
10825                 outInfo.removedUsers = deletedPs != null
10826                         ? deletedPs.queryInstalledUsers(sUserManager.getUserIds(), true)
10827                         : null;
10828             }
10829         }
10830         if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) {
10831             removeDataDirsLI(packageName);
10832             schedulePackageCleaning(packageName, UserHandle.USER_ALL, true);
10833         }
10834         // writer
10835         synchronized (mPackages) {
10836             if (deletedPs != null) {
10837                 if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) {
10838                     if (outInfo != null) {
10839                         mSettings.mKeySetManagerService.removeAppKeySetDataLPw(packageName);
10840                         outInfo.removedAppId = mSettings.removePackageLPw(packageName);
10841                     }
10842                     if (deletedPs != null) {
10843                         updatePermissionsLPw(deletedPs.name, null, 0);
10844                         if (deletedPs.sharedUser != null) {
10845                             // remove permissions associated with package
10846                             mSettings.updateSharedUserPermsLPw(deletedPs, mGlobalGids);
10847                         }
10848                     }
10849                     clearPackagePreferredActivitiesLPw(deletedPs.name, UserHandle.USER_ALL);
10850                 }
10851                 // make sure to preserve per-user disabled state if this removal was just
10852                 // a downgrade of a system app to the factory package
10853                 if (allUserHandles != null && perUserInstalled != null) {
10854                     if (DEBUG_REMOVE) {
10855                         Slog.d(TAG, "Propagating install state across downgrade");
10856                     }
10857                     for (int i = 0; i < allUserHandles.length; i++) {
10858                         if (DEBUG_REMOVE) {
10859                             Slog.d(TAG, "    user " + allUserHandles[i]
10860                                     + " => " + perUserInstalled[i]);
10861                         }
10862                         ps.setInstalled(perUserInstalled[i], allUserHandles[i]);
10863                     }
10864                 }
10865             }
10866             // can downgrade to reader
10867             if (writeSettings) {
10868                 // Save settings now
10869                 mSettings.writeLPr();
10870             }
10871         }
10872         if (outInfo != null) {
10873             // A user ID was deleted here. Go through all users and remove it
10874             // from KeyStore.
10875             removeKeystoreDataIfNeeded(UserHandle.USER_ALL, outInfo.removedAppId);
10876         }
10877     }
10878
10879     static boolean locationIsPrivileged(File path) {
10880         try {
10881             final String privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app")
10882                     .getCanonicalPath();
10883             return path.getCanonicalPath().startsWith(privilegedAppDir);
10884         } catch (IOException e) {
10885             Slog.e(TAG, "Unable to access code path " + path);
10886         }
10887         return false;
10888     }
10889
10890     /*
10891      * Tries to delete system package.
10892      */
10893     private boolean deleteSystemPackageLI(PackageSetting newPs,
10894             int[] allUserHandles, boolean[] perUserInstalled,
10895             int flags, PackageRemovedInfo outInfo, boolean writeSettings) {
10896         final boolean applyUserRestrictions
10897                 = (allUserHandles != null) && (perUserInstalled != null);
10898         PackageSetting disabledPs = null;
10899         // Confirm if the system package has been updated
10900         // An updated system app can be deleted. This will also have to restore
10901         // the system pkg from system partition
10902         // reader
10903         synchronized (mPackages) {
10904             disabledPs = mSettings.getDisabledSystemPkgLPr(newPs.name);
10905         }
10906         if (DEBUG_REMOVE) Slog.d(TAG, "deleteSystemPackageLI: newPs=" + newPs
10907                 + " disabledPs=" + disabledPs);
10908         if (disabledPs == null) {
10909             Slog.w(TAG, "Attempt to delete unknown system package "+ newPs.name);
10910             return false;
10911         } else if (DEBUG_REMOVE) {
10912             Slog.d(TAG, "Deleting system pkg from data partition");
10913         }
10914         if (DEBUG_REMOVE) {
10915             if (applyUserRestrictions) {
10916                 Slog.d(TAG, "Remembering install states:");
10917                 for (int i = 0; i < allUserHandles.length; i++) {
10918                     Slog.d(TAG, "   u=" + allUserHandles[i] + " inst=" + perUserInstalled[i]);
10919                 }
10920             }
10921         }
10922         // Delete the updated package
10923         outInfo.isRemovedPackageSystemUpdate = true;
10924         if (disabledPs.versionCode < newPs.versionCode) {
10925             // Delete data for downgrades
10926             flags &= ~PackageManager.DELETE_KEEP_DATA;
10927         } else {
10928             // Preserve data by setting flag
10929             flags |= PackageManager.DELETE_KEEP_DATA;
10930         }
10931         boolean ret = deleteInstalledPackageLI(newPs, true, flags,
10932                 allUserHandles, perUserInstalled, outInfo, writeSettings);
10933         if (!ret) {
10934             return false;
10935         }
10936         // writer
10937         synchronized (mPackages) {
10938             // Reinstate the old system package
10939             mSettings.enableSystemPackageLPw(newPs.name);
10940             // Remove any native libraries from the upgraded package.
10941             NativeLibraryHelper.removeNativeBinariesLI(newPs.legacyNativeLibraryPathString);
10942         }
10943         // Install the system package
10944         if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs);
10945         int parseFlags = PackageParser.PARSE_MUST_BE_APK | PackageParser.PARSE_IS_SYSTEM;
10946         if (locationIsPrivileged(disabledPs.codePath)) {
10947             parseFlags |= PackageParser.PARSE_IS_PRIVILEGED;
10948         }
10949
10950         final PackageParser.Package newPkg;
10951         try {
10952             newPkg = scanPackageLI(disabledPs.codePath, parseFlags, SCAN_NO_PATHS, 0, null);
10953         } catch (PackageManagerException e) {
10954             Slog.w(TAG, "Failed to restore system package:" + newPs.name + ": " + e.getMessage());
10955             return false;
10956         }
10957
10958         // writer
10959         synchronized (mPackages) {
10960             PackageSetting ps = mSettings.mPackages.get(newPkg.packageName);
10961             updatePermissionsLPw(newPkg.packageName, newPkg,
10962                     UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG);
10963             if (applyUserRestrictions) {
10964                 if (DEBUG_REMOVE) {
10965                     Slog.d(TAG, "Propagating install state across reinstall");
10966                 }
10967                 for (int i = 0; i < allUserHandles.length; i++) {
10968                     if (DEBUG_REMOVE) {
10969                         Slog.d(TAG, "    user " + allUserHandles[i]
10970                                 + " => " + perUserInstalled[i]);
10971                     }
10972                     ps.setInstalled(perUserInstalled[i], allUserHandles[i]);
10973                 }
10974                 // Regardless of writeSettings we need to ensure that this restriction
10975                 // state propagation is persisted
10976                 mSettings.writeAllUsersPackageRestrictionsLPr();
10977             }
10978             // can downgrade to reader here
10979             if (writeSettings) {
10980                 mSettings.writeLPr();
10981             }
10982         }
10983         return true;
10984     }
10985
10986     private boolean deleteInstalledPackageLI(PackageSetting ps,
10987             boolean deleteCodeAndResources, int flags,
10988             int[] allUserHandles, boolean[] perUserInstalled,
10989             PackageRemovedInfo outInfo, boolean writeSettings) {
10990         if (outInfo != null) {
10991             outInfo.uid = ps.appId;
10992         }
10993
10994         // Delete package data from internal structures and also remove data if flag is set
10995         removePackageDataLI(ps, allUserHandles, perUserInstalled, outInfo, flags, writeSettings);
10996
10997         // Delete application code and resources
10998         if (deleteCodeAndResources && (outInfo != null)) {
10999             outInfo.args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
11000                     ps.codePathString, ps.resourcePathString, ps.legacyNativeLibraryPathString,
11001                     getAppDexInstructionSets(ps));
11002             if (DEBUG_SD_INSTALL) Slog.i(TAG, "args=" + outInfo.args);
11003         }
11004         return true;
11005     }
11006
11007     @Override
11008     public boolean setBlockUninstallForUser(String packageName, boolean blockUninstall,
11009             int userId) {
11010         mContext.enforceCallingOrSelfPermission(
11011                 android.Manifest.permission.DELETE_PACKAGES, null);
11012         synchronized (mPackages) {
11013             PackageSetting ps = mSettings.mPackages.get(packageName);
11014             if (ps == null) {
11015                 Log.i(TAG, "Package doesn't exist in set block uninstall " + packageName);
11016                 return false;
11017             }
11018             if (!ps.getInstalled(userId)) {
11019                 // Can't block uninstall for an app that is not installed or enabled.
11020                 Log.i(TAG, "Package not installed in set block uninstall " + packageName);
11021                 return false;
11022             }
11023             ps.setBlockUninstall(blockUninstall, userId);
11024             mSettings.writePackageRestrictionsLPr(userId);
11025         }
11026         return true;
11027     }
11028
11029     @Override
11030     public boolean getBlockUninstallForUser(String packageName, int userId) {
11031         synchronized (mPackages) {
11032             PackageSetting ps = mSettings.mPackages.get(packageName);
11033             if (ps == null) {
11034                 Log.i(TAG, "Package doesn't exist in get block uninstall " + packageName);
11035                 return false;
11036             }
11037             return ps.getBlockUninstall(userId);
11038         }
11039     }
11040
11041     /*
11042      * This method handles package deletion in general
11043      */
11044     private boolean deletePackageLI(String packageName, UserHandle user,
11045             boolean deleteCodeAndResources, int[] allUserHandles, boolean[] perUserInstalled,
11046             int flags, PackageRemovedInfo outInfo,
11047             boolean writeSettings) {
11048         if (packageName == null) {
11049             Slog.w(TAG, "Attempt to delete null packageName.");
11050             return false;
11051         }
11052         if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: " + packageName + " user " + user);
11053         PackageSetting ps;
11054         boolean dataOnly = false;
11055         int removeUser = -1;
11056         int appId = -1;
11057         synchronized (mPackages) {
11058             ps = mSettings.mPackages.get(packageName);
11059             if (ps == null) {
11060                 Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
11061                 return false;
11062             }
11063             if ((!isSystemApp(ps) || (flags&PackageManager.DELETE_SYSTEM_APP) != 0) && user != null
11064                     && user.getIdentifier() != UserHandle.USER_ALL) {
11065                 // The caller is asking that the package only be deleted for a single
11066                 // user.  To do this, we just mark its uninstalled state and delete
11067                 // its data.  If this is a system app, we only allow this to happen if
11068                 // they have set the special DELETE_SYSTEM_APP which requests different
11069                 // semantics than normal for uninstalling system apps.
11070                 if (DEBUG_REMOVE) Slog.d(TAG, "Only deleting for single user");
11071                 ps.setUserState(user.getIdentifier(),
11072                         COMPONENT_ENABLED_STATE_DEFAULT,
11073                         false, //installed
11074                         true,  //stopped
11075                         true,  //notLaunched
11076                         false, //hidden
11077                         null, null, null,
11078                         false // blockUninstall
11079                         );
11080                 if (!isSystemApp(ps)) {
11081                     if (ps.isAnyInstalled(sUserManager.getUserIds())) {
11082                         // Other user still have this package installed, so all
11083                         // we need to do is clear this user's data and save that
11084                         // it is uninstalled.
11085                         if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users");
11086                         removeUser = user.getIdentifier();
11087                         appId = ps.appId;
11088                         mSettings.writePackageRestrictionsLPr(removeUser);
11089                     } else {
11090                         // We need to set it back to 'installed' so the uninstall
11091                         // broadcasts will be sent correctly.
11092                         if (DEBUG_REMOVE) Slog.d(TAG, "Not installed by other users, full delete");
11093                         ps.setInstalled(true, user.getIdentifier());
11094                     }
11095                 } else {
11096                     // This is a system app, so we assume that the
11097                     // other users still have this package installed, so all
11098                     // we need to do is clear this user's data and save that
11099                     // it is uninstalled.
11100                     if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app");
11101                     removeUser = user.getIdentifier();
11102                     appId = ps.appId;
11103                     mSettings.writePackageRestrictionsLPr(removeUser);
11104                 }
11105             }
11106         }
11107
11108         if (removeUser >= 0) {
11109             // From above, we determined that we are deleting this only
11110             // for a single user.  Continue the work here.
11111             if (DEBUG_REMOVE) Slog.d(TAG, "Updating install state for user: " + removeUser);
11112             if (outInfo != null) {
11113                 outInfo.removedPackage = packageName;
11114                 outInfo.removedAppId = appId;
11115                 outInfo.removedUsers = new int[] {removeUser};
11116             }
11117             mInstaller.clearUserData(packageName, removeUser);
11118             removeKeystoreDataIfNeeded(removeUser, appId);
11119             schedulePackageCleaning(packageName, removeUser, false);
11120             return true;
11121         }
11122
11123         if (dataOnly) {
11124             // Delete application data first
11125             if (DEBUG_REMOVE) Slog.d(TAG, "Removing package data only");
11126             removePackageDataLI(ps, null, null, outInfo, flags, writeSettings);
11127             return true;
11128         }
11129
11130         boolean ret = false;
11131         if (isSystemApp(ps)) {
11132             if (DEBUG_REMOVE) Slog.d(TAG, "Removing system package:" + ps.name);
11133             // When an updated system application is deleted we delete the existing resources as well and
11134             // fall back to existing code in system partition
11135             ret = deleteSystemPackageLI(ps, allUserHandles, perUserInstalled,
11136                     flags, outInfo, writeSettings);
11137         } else {
11138             if (DEBUG_REMOVE) Slog.d(TAG, "Removing non-system package:" + ps.name);
11139             // Kill application pre-emptively especially for apps on sd.
11140             killApplication(packageName, ps.appId, "uninstall pkg");
11141             ret = deleteInstalledPackageLI(ps, deleteCodeAndResources, flags,
11142                     allUserHandles, perUserInstalled,
11143                     outInfo, writeSettings);
11144         }
11145
11146         return ret;
11147     }
11148
11149     private final class ClearStorageConnection implements ServiceConnection {
11150         IMediaContainerService mContainerService;
11151
11152         @Override
11153         public void onServiceConnected(ComponentName name, IBinder service) {
11154             synchronized (this) {
11155                 mContainerService = IMediaContainerService.Stub.asInterface(service);
11156                 notifyAll();
11157             }
11158         }
11159
11160         @Override
11161         public void onServiceDisconnected(ComponentName name) {
11162         }
11163     }
11164
11165     private void clearExternalStorageDataSync(String packageName, int userId, boolean allData) {
11166         final boolean mounted;
11167         if (Environment.isExternalStorageEmulated()) {
11168             mounted = true;
11169         } else {
11170             final String status = Environment.getExternalStorageState();
11171
11172             mounted = status.equals(Environment.MEDIA_MOUNTED)
11173                     || status.equals(Environment.MEDIA_MOUNTED_READ_ONLY);
11174         }
11175
11176         if (!mounted) {
11177             return;
11178         }
11179
11180         final Intent containerIntent = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
11181         int[] users;
11182         if (userId == UserHandle.USER_ALL) {
11183             users = sUserManager.getUserIds();
11184         } else {
11185             users = new int[] { userId };
11186         }
11187         final ClearStorageConnection conn = new ClearStorageConnection();
11188         if (mContext.bindServiceAsUser(
11189                 containerIntent, conn, Context.BIND_AUTO_CREATE, UserHandle.OWNER)) {
11190             try {
11191                 for (int curUser : users) {
11192                     long timeout = SystemClock.uptimeMillis() + 5000;
11193                     synchronized (conn) {
11194                         long now = SystemClock.uptimeMillis();
11195                         while (conn.mContainerService == null && now < timeout) {
11196                             try {
11197                                 conn.wait(timeout - now);
11198                             } catch (InterruptedException e) {
11199                             }
11200                         }
11201                     }
11202                     if (conn.mContainerService == null) {
11203                         return;
11204                     }
11205
11206                     final UserEnvironment userEnv = new UserEnvironment(curUser);
11207                     clearDirectory(conn.mContainerService,
11208                             userEnv.buildExternalStorageAppCacheDirs(packageName));
11209                     if (allData) {
11210                         clearDirectory(conn.mContainerService,
11211                                 userEnv.buildExternalStorageAppDataDirs(packageName));
11212                         clearDirectory(conn.mContainerService,
11213                                 userEnv.buildExternalStorageAppMediaDirs(packageName));
11214                     }
11215                 }
11216             } finally {
11217                 mContext.unbindService(conn);
11218             }
11219         }
11220     }
11221
11222     @Override
11223     public void clearApplicationUserData(final String packageName,
11224             final IPackageDataObserver observer, final int userId) {
11225         mContext.enforceCallingOrSelfPermission(
11226                 android.Manifest.permission.CLEAR_APP_USER_DATA, null);
11227         enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, "clear application data");
11228         // Queue up an async operation since the package deletion may take a little while.
11229         mHandler.post(new Runnable() {
11230             public void run() {
11231                 mHandler.removeCallbacks(this);
11232                 final boolean succeeded;
11233                 synchronized (mInstallLock) {
11234                     succeeded = clearApplicationUserDataLI(packageName, userId);
11235                 }
11236                 clearExternalStorageDataSync(packageName, userId, true);
11237                 if (succeeded) {
11238                     // invoke DeviceStorageMonitor's update method to clear any notifications
11239                     DeviceStorageMonitorInternal
11240                             dsm = LocalServices.getService(DeviceStorageMonitorInternal.class);
11241                     if (dsm != null) {
11242                         dsm.checkMemory();
11243                     }
11244                 }
11245                 if(observer != null) {
11246                     try {
11247                         observer.onRemoveCompleted(packageName, succeeded);
11248                     } catch (RemoteException e) {
11249                         Log.i(TAG, "Observer no longer exists.");
11250                     }
11251                 } //end if observer
11252             } //end run
11253         });
11254     }
11255
11256     private boolean clearApplicationUserDataLI(String packageName, int userId) {
11257         if (packageName == null) {
11258             Slog.w(TAG, "Attempt to delete null packageName.");
11259             return false;
11260         }
11261
11262         // Try finding details about the requested package
11263         PackageParser.Package pkg;
11264         synchronized (mPackages) {
11265             pkg = mPackages.get(packageName);
11266             if (pkg == null) {
11267                 final PackageSetting ps = mSettings.mPackages.get(packageName);
11268                 if (ps != null) {
11269                     pkg = ps.pkg;
11270                 }
11271             }
11272         }
11273
11274         if (pkg == null) {
11275             Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
11276         }
11277
11278         // Always delete data directories for package, even if we found no other
11279         // record of app. This helps users recover from UID mismatches without
11280         // resorting to a full data wipe.
11281         int retCode = mInstaller.clearUserData(packageName, userId);
11282         if (retCode < 0) {
11283             Slog.w(TAG, "Couldn't remove cache files for package: " + packageName);
11284             return false;
11285         }
11286
11287         if (pkg == null) {
11288             return false;
11289         }
11290
11291         if (pkg != null && pkg.applicationInfo != null) {
11292             final int appId = pkg.applicationInfo.uid;
11293             removeKeystoreDataIfNeeded(userId, appId);
11294         }
11295
11296         // Create a native library symlink only if we have native libraries
11297         // and if the native libraries are 32 bit libraries. We do not provide
11298         // this symlink for 64 bit libraries.
11299         if (pkg != null && pkg.applicationInfo.primaryCpuAbi != null &&
11300                 !VMRuntime.is64BitAbi(pkg.applicationInfo.primaryCpuAbi)) {
11301             final String nativeLibPath = pkg.applicationInfo.nativeLibraryDir;
11302             if (mInstaller.linkNativeLibraryDirectory(pkg.packageName, nativeLibPath, userId) < 0) {
11303                 Slog.w(TAG, "Failed linking native library dir");
11304                 return false;
11305             }
11306         }
11307
11308         return true;
11309     }
11310
11311     /**
11312      * Remove entries from the keystore daemon. Will only remove it if the
11313      * {@code appId} is valid.
11314      */
11315     private static void removeKeystoreDataIfNeeded(int userId, int appId) {
11316         if (appId < 0) {
11317             return;
11318         }
11319
11320         final KeyStore keyStore = KeyStore.getInstance();
11321         if (keyStore != null) {
11322             if (userId == UserHandle.USER_ALL) {
11323                 for (final int individual : sUserManager.getUserIds()) {
11324                     keyStore.clearUid(UserHandle.getUid(individual, appId));
11325                 }
11326             } else {
11327                 keyStore.clearUid(UserHandle.getUid(userId, appId));
11328             }
11329         } else {
11330             Slog.w(TAG, "Could not contact keystore to clear entries for app id " + appId);
11331         }
11332     }
11333
11334     @Override
11335     public void deleteApplicationCacheFiles(final String packageName,
11336             final IPackageDataObserver observer) {
11337         mContext.enforceCallingOrSelfPermission(
11338                 android.Manifest.permission.DELETE_CACHE_FILES, null);
11339         // Queue up an async operation since the package deletion may take a little while.
11340         final int userId = UserHandle.getCallingUserId();
11341         mHandler.post(new Runnable() {
11342             public void run() {
11343                 mHandler.removeCallbacks(this);
11344                 final boolean succeded;
11345                 synchronized (mInstallLock) {
11346                     succeded = deleteApplicationCacheFilesLI(packageName, userId);
11347                 }
11348                 clearExternalStorageDataSync(packageName, userId, false);
11349                 if(observer != null) {
11350                     try {
11351                         observer.onRemoveCompleted(packageName, succeded);
11352                     } catch (RemoteException e) {
11353                         Log.i(TAG, "Observer no longer exists.");
11354                     }
11355                 } //end if observer
11356             } //end run
11357         });
11358     }
11359
11360     private boolean deleteApplicationCacheFilesLI(String packageName, int userId) {
11361         if (packageName == null) {
11362             Slog.w(TAG, "Attempt to delete null packageName.");
11363             return false;
11364         }
11365         PackageParser.Package p;
11366         synchronized (mPackages) {
11367             p = mPackages.get(packageName);
11368         }
11369         if (p == null) {
11370             Slog.w(TAG, "Package named '" + packageName +"' doesn't exist.");
11371             return false;
11372         }
11373         final ApplicationInfo applicationInfo = p.applicationInfo;
11374         if (applicationInfo == null) {
11375             Slog.w(TAG, "Package " + packageName + " has no applicationInfo.");
11376             return false;
11377         }
11378         int retCode = mInstaller.deleteCacheFiles(packageName, userId);
11379         if (retCode < 0) {
11380             Slog.w(TAG, "Couldn't remove cache files for package: "
11381                        + packageName + " u" + userId);
11382             return false;
11383         }
11384         return true;
11385     }
11386
11387     @Override
11388     public void getPackageSizeInfo(final String packageName, int userHandle,
11389             final IPackageStatsObserver observer) {
11390         mContext.enforceCallingOrSelfPermission(
11391                 android.Manifest.permission.GET_PACKAGE_SIZE, null);
11392         if (packageName == null) {
11393             throw new IllegalArgumentException("Attempt to get size of null packageName");
11394         }
11395
11396         PackageStats stats = new PackageStats(packageName, userHandle);
11397
11398         /*
11399          * Queue up an async operation since the package measurement may take a
11400          * little while.
11401          */
11402         Message msg = mHandler.obtainMessage(INIT_COPY);
11403         msg.obj = new MeasureParams(stats, observer);
11404         mHandler.sendMessage(msg);
11405     }
11406
11407     private boolean getPackageSizeInfoLI(String packageName, int userHandle,
11408             PackageStats pStats) {
11409         if (packageName == null) {
11410             Slog.w(TAG, "Attempt to get size of null packageName.");
11411             return false;
11412         }
11413         PackageParser.Package p;
11414         boolean dataOnly = false;
11415         String libDirRoot = null;
11416         String asecPath = null;
11417         PackageSetting ps = null;
11418         synchronized (mPackages) {
11419             p = mPackages.get(packageName);
11420             ps = mSettings.mPackages.get(packageName);
11421             if(p == null) {
11422                 dataOnly = true;
11423                 if((ps == null) || (ps.pkg == null)) {
11424                     Slog.w(TAG, "Package named '" + packageName +"' doesn't exist.");
11425                     return false;
11426                 }
11427                 p = ps.pkg;
11428             }
11429             if (ps != null) {
11430                 libDirRoot = ps.legacyNativeLibraryPathString;
11431             }
11432             if (p != null && (isExternal(p) || isForwardLocked(p))) {
11433                 String secureContainerId = cidFromCodePath(p.applicationInfo.getBaseCodePath());
11434                 if (secureContainerId != null) {
11435                     asecPath = PackageHelper.getSdFilesystem(secureContainerId);
11436                 }
11437             }
11438         }
11439         String publicSrcDir = null;
11440         if(!dataOnly) {
11441             final ApplicationInfo applicationInfo = p.applicationInfo;
11442             if (applicationInfo == null) {
11443                 Slog.w(TAG, "Package " + packageName + " has no applicationInfo.");
11444                 return false;
11445             }
11446             if (isForwardLocked(p)) {
11447                 publicSrcDir = applicationInfo.getBaseResourcePath();
11448             }
11449         }
11450         // TODO: extend to measure size of split APKs
11451         // TODO(multiArch): Extend getSizeInfo to look at the full subdirectory tree,
11452         // not just the first level.
11453         // TODO(multiArch): Extend getSizeInfo to look at *all* instruction sets, not
11454         // just the primary.
11455         String[] dexCodeInstructionSets = getDexCodeInstructionSets(getAppDexInstructionSets(ps));
11456         int res = mInstaller.getSizeInfo(packageName, userHandle, p.baseCodePath, libDirRoot,
11457                 publicSrcDir, asecPath, dexCodeInstructionSets, pStats);
11458         if (res < 0) {
11459             return false;
11460         }
11461
11462         // Fix-up for forward-locked applications in ASEC containers.
11463         if (!isExternal(p)) {
11464             pStats.codeSize += pStats.externalCodeSize;
11465             pStats.externalCodeSize = 0L;
11466         }
11467
11468         return true;
11469     }
11470
11471
11472     @Override
11473     public void addPackageToPreferred(String packageName) {
11474         Slog.w(TAG, "addPackageToPreferred: this is now a no-op");
11475     }
11476
11477     @Override
11478     public void removePackageFromPreferred(String packageName) {
11479         Slog.w(TAG, "removePackageFromPreferred: this is now a no-op");
11480     }
11481
11482     @Override
11483     public List<PackageInfo> getPreferredPackages(int flags) {
11484         return new ArrayList<PackageInfo>();
11485     }
11486
11487     private int getUidTargetSdkVersionLockedLPr(int uid) {
11488         Object obj = mSettings.getUserIdLPr(uid);
11489         if (obj instanceof SharedUserSetting) {
11490             final SharedUserSetting sus = (SharedUserSetting) obj;
11491             int vers = Build.VERSION_CODES.CUR_DEVELOPMENT;
11492             final Iterator<PackageSetting> it = sus.packages.iterator();
11493             while (it.hasNext()) {
11494                 final PackageSetting ps = it.next();
11495                 if (ps.pkg != null) {
11496                     int v = ps.pkg.applicationInfo.targetSdkVersion;
11497                     if (v < vers) vers = v;
11498                 }
11499             }
11500             return vers;
11501         } else if (obj instanceof PackageSetting) {
11502             final PackageSetting ps = (PackageSetting) obj;
11503             if (ps.pkg != null) {
11504                 return ps.pkg.applicationInfo.targetSdkVersion;
11505             }
11506         }
11507         return Build.VERSION_CODES.CUR_DEVELOPMENT;
11508     }
11509
11510     @Override
11511     public void addPreferredActivity(IntentFilter filter, int match,
11512             ComponentName[] set, ComponentName activity, int userId) {
11513         addPreferredActivityInternal(filter, match, set, activity, true, userId,
11514                 "Adding preferred");
11515     }
11516
11517     private void addPreferredActivityInternal(IntentFilter filter, int match,
11518             ComponentName[] set, ComponentName activity, boolean always, int userId,
11519             String opname) {
11520         // writer
11521         int callingUid = Binder.getCallingUid();
11522         enforceCrossUserPermission(callingUid, userId, true, false, "add preferred activity");
11523         if (filter.countActions() == 0) {
11524             Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
11525             return;
11526         }
11527         synchronized (mPackages) {
11528             if (mContext.checkCallingOrSelfPermission(
11529                     android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
11530                     != PackageManager.PERMISSION_GRANTED) {
11531                 if (getUidTargetSdkVersionLockedLPr(callingUid)
11532                         < Build.VERSION_CODES.FROYO) {
11533                     Slog.w(TAG, "Ignoring addPreferredActivity() from uid "
11534                             + callingUid);
11535                     return;
11536                 }
11537                 mContext.enforceCallingOrSelfPermission(
11538                         android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
11539             }
11540
11541             PreferredIntentResolver pir = mSettings.editPreferredActivitiesLPw(userId);
11542             Slog.i(TAG, opname + " activity " + activity.flattenToShortString() + " for user "
11543                     + userId + ":");
11544             filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
11545             pir.addFilter(new PreferredActivity(filter, match, set, activity, always));
11546             mSettings.writePackageRestrictionsLPr(userId);
11547         }
11548     }
11549
11550     @Override
11551     public void replacePreferredActivity(IntentFilter filter, int match,
11552             ComponentName[] set, ComponentName activity, int userId) {
11553         if (filter.countActions() != 1) {
11554             throw new IllegalArgumentException(
11555                     "replacePreferredActivity expects filter to have only 1 action.");
11556         }
11557         if (filter.countDataAuthorities() != 0
11558                 || filter.countDataPaths() != 0
11559                 || filter.countDataSchemes() > 1
11560                 || filter.countDataTypes() != 0) {
11561             throw new IllegalArgumentException(
11562                     "replacePreferredActivity expects filter to have no data authorities, " +
11563                     "paths, or types; and at most one scheme.");
11564         }
11565
11566         final int callingUid = Binder.getCallingUid();
11567         enforceCrossUserPermission(callingUid, userId, true, false, "replace preferred activity");
11568         synchronized (mPackages) {
11569             if (mContext.checkCallingOrSelfPermission(
11570                     android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
11571                     != PackageManager.PERMISSION_GRANTED) {
11572                 if (getUidTargetSdkVersionLockedLPr(callingUid)
11573                         < Build.VERSION_CODES.FROYO) {
11574                     Slog.w(TAG, "Ignoring replacePreferredActivity() from uid "
11575                             + Binder.getCallingUid());
11576                     return;
11577                 }
11578                 mContext.enforceCallingOrSelfPermission(
11579                         android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
11580             }
11581
11582             PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
11583             if (pir != null) {
11584                 // Get all of the existing entries that exactly match this filter.
11585                 ArrayList<PreferredActivity> existing = pir.findFilters(filter);
11586                 if (existing != null && existing.size() == 1) {
11587                     PreferredActivity cur = existing.get(0);
11588                     if (DEBUG_PREFERRED) {
11589                         Slog.i(TAG, "Checking replace of preferred:");
11590                         filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
11591                         if (!cur.mPref.mAlways) {
11592                             Slog.i(TAG, "  -- CUR; not mAlways!");
11593                         } else {
11594                             Slog.i(TAG, "  -- CUR: mMatch=" + cur.mPref.mMatch);
11595                             Slog.i(TAG, "  -- CUR: mSet="
11596                                     + Arrays.toString(cur.mPref.mSetComponents));
11597                             Slog.i(TAG, "  -- CUR: mComponent=" + cur.mPref.mShortComponent);
11598                             Slog.i(TAG, "  -- NEW: mMatch="
11599                                     + (match&IntentFilter.MATCH_CATEGORY_MASK));
11600                             Slog.i(TAG, "  -- CUR: mSet=" + Arrays.toString(set));
11601                             Slog.i(TAG, "  -- CUR: mComponent=" + activity.flattenToShortString());
11602                         }
11603                     }
11604                     if (cur.mPref.mAlways && cur.mPref.mComponent.equals(activity)
11605                             && cur.mPref.mMatch == (match&IntentFilter.MATCH_CATEGORY_MASK)
11606                             && cur.mPref.sameSet(set)) {
11607                         // Setting the preferred activity to what it happens to be already
11608                         if (DEBUG_PREFERRED) {
11609                             Slog.i(TAG, "Replacing with same preferred activity "
11610                                     + cur.mPref.mShortComponent + " for user "
11611                                     + userId + ":");
11612                             filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
11613                         }
11614                         return;
11615                     }
11616                 }
11617
11618                 if (existing != null) {
11619                     if (DEBUG_PREFERRED) {
11620                         Slog.i(TAG, existing.size() + " existing preferred matches for:");
11621                         filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
11622                     }
11623                     for (int i = 0; i < existing.size(); i++) {
11624                         PreferredActivity pa = existing.get(i);
11625                         if (DEBUG_PREFERRED) {
11626                             Slog.i(TAG, "Removing existing preferred activity "
11627                                     + pa.mPref.mComponent + ":");
11628                             pa.dump(new LogPrinter(Log.INFO, TAG), "  ");
11629                         }
11630                         pir.removeFilter(pa);
11631                     }
11632                 }
11633             }
11634             addPreferredActivityInternal(filter, match, set, activity, true, userId,
11635                     "Replacing preferred");
11636         }
11637     }
11638
11639     @Override
11640     public void clearPackagePreferredActivities(String packageName) {
11641         final int uid = Binder.getCallingUid();
11642         // writer
11643         synchronized (mPackages) {
11644             PackageParser.Package pkg = mPackages.get(packageName);
11645             if (pkg == null || pkg.applicationInfo.uid != uid) {
11646                 if (mContext.checkCallingOrSelfPermission(
11647                         android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
11648                         != PackageManager.PERMISSION_GRANTED) {
11649                     if (getUidTargetSdkVersionLockedLPr(Binder.getCallingUid())
11650                             < Build.VERSION_CODES.FROYO) {
11651                         Slog.w(TAG, "Ignoring clearPackagePreferredActivities() from uid "
11652                                 + Binder.getCallingUid());
11653                         return;
11654                     }
11655                     mContext.enforceCallingOrSelfPermission(
11656                             android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
11657                 }
11658             }
11659
11660             int user = UserHandle.getCallingUserId();
11661             if (clearPackagePreferredActivitiesLPw(packageName, user)) {
11662                 mSettings.writePackageRestrictionsLPr(user);
11663                 scheduleWriteSettingsLocked();
11664             }
11665         }
11666     }
11667
11668     /** This method takes a specific user id as well as UserHandle.USER_ALL. */
11669     boolean clearPackagePreferredActivitiesLPw(String packageName, int userId) {
11670         ArrayList<PreferredActivity> removed = null;
11671         boolean changed = false;
11672         for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
11673             final int thisUserId = mSettings.mPreferredActivities.keyAt(i);
11674             PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
11675             if (userId != UserHandle.USER_ALL && userId != thisUserId) {
11676                 continue;
11677             }
11678             Iterator<PreferredActivity> it = pir.filterIterator();
11679             while (it.hasNext()) {
11680                 PreferredActivity pa = it.next();
11681                 // Mark entry for removal only if it matches the package name
11682                 // and the entry is of type "always".
11683                 if (packageName == null ||
11684                         (pa.mPref.mComponent.getPackageName().equals(packageName)
11685                                 && pa.mPref.mAlways)) {
11686                     if (removed == null) {
11687                         removed = new ArrayList<PreferredActivity>();
11688                     }
11689                     removed.add(pa);
11690                 }
11691             }
11692             if (removed != null) {
11693                 for (int j=0; j<removed.size(); j++) {
11694                     PreferredActivity pa = removed.get(j);
11695                     pir.removeFilter(pa);
11696                 }
11697                 changed = true;
11698             }
11699         }
11700         return changed;
11701     }
11702
11703     @Override
11704     public void resetPreferredActivities(int userId) {
11705         /* TODO: Actually use userId. Why is it being passed in? */
11706         mContext.enforceCallingOrSelfPermission(
11707                 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
11708         // writer
11709         synchronized (mPackages) {
11710             int user = UserHandle.getCallingUserId();
11711             clearPackagePreferredActivitiesLPw(null, user);
11712             mSettings.readDefaultPreferredAppsLPw(this, user);
11713             mSettings.writePackageRestrictionsLPr(user);
11714             scheduleWriteSettingsLocked();
11715         }
11716     }
11717
11718     @Override
11719     public int getPreferredActivities(List<IntentFilter> outFilters,
11720             List<ComponentName> outActivities, String packageName) {
11721
11722         int num = 0;
11723         final int userId = UserHandle.getCallingUserId();
11724         // reader
11725         synchronized (mPackages) {
11726             PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
11727             if (pir != null) {
11728                 final Iterator<PreferredActivity> it = pir.filterIterator();
11729                 while (it.hasNext()) {
11730                     final PreferredActivity pa = it.next();
11731                     if (packageName == null
11732                             || (pa.mPref.mComponent.getPackageName().equals(packageName)
11733                                     && pa.mPref.mAlways)) {
11734                         if (outFilters != null) {
11735                             outFilters.add(new IntentFilter(pa));
11736                         }
11737                         if (outActivities != null) {
11738                             outActivities.add(pa.mPref.mComponent);
11739                         }
11740                     }
11741                 }
11742             }
11743         }
11744
11745         return num;
11746     }
11747
11748     @Override
11749     public void addPersistentPreferredActivity(IntentFilter filter, ComponentName activity,
11750             int userId) {
11751         int callingUid = Binder.getCallingUid();
11752         if (callingUid != Process.SYSTEM_UID) {
11753             throw new SecurityException(
11754                     "addPersistentPreferredActivity can only be run by the system");
11755         }
11756         if (filter.countActions() == 0) {
11757             Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
11758             return;
11759         }
11760         synchronized (mPackages) {
11761             Slog.i(TAG, "Adding persistent preferred activity " + activity + " for user " + userId +
11762                     " :");
11763             filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
11764             mSettings.editPersistentPreferredActivitiesLPw(userId).addFilter(
11765                     new PersistentPreferredActivity(filter, activity));
11766             mSettings.writePackageRestrictionsLPr(userId);
11767         }
11768     }
11769
11770     @Override
11771     public void clearPackagePersistentPreferredActivities(String packageName, int userId) {
11772         int callingUid = Binder.getCallingUid();
11773         if (callingUid != Process.SYSTEM_UID) {
11774             throw new SecurityException(
11775                     "clearPackagePersistentPreferredActivities can only be run by the system");
11776         }
11777         ArrayList<PersistentPreferredActivity> removed = null;
11778         boolean changed = false;
11779         synchronized (mPackages) {
11780             for (int i=0; i<mSettings.mPersistentPreferredActivities.size(); i++) {
11781                 final int thisUserId = mSettings.mPersistentPreferredActivities.keyAt(i);
11782                 PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
11783                         .valueAt(i);
11784                 if (userId != thisUserId) {
11785                     continue;
11786                 }
11787                 Iterator<PersistentPreferredActivity> it = ppir.filterIterator();
11788                 while (it.hasNext()) {
11789                     PersistentPreferredActivity ppa = it.next();
11790                     // Mark entry for removal only if it matches the package name.
11791                     if (ppa.mComponent.getPackageName().equals(packageName)) {
11792                         if (removed == null) {
11793                             removed = new ArrayList<PersistentPreferredActivity>();
11794                         }
11795                         removed.add(ppa);
11796                     }
11797                 }
11798                 if (removed != null) {
11799                     for (int j=0; j<removed.size(); j++) {
11800                         PersistentPreferredActivity ppa = removed.get(j);
11801                         ppir.removeFilter(ppa);
11802                     }
11803                     changed = true;
11804                 }
11805             }
11806
11807             if (changed) {
11808                 mSettings.writePackageRestrictionsLPr(userId);
11809             }
11810         }
11811     }
11812
11813     @Override
11814     public void addCrossProfileIntentFilter(IntentFilter intentFilter, String ownerPackage,
11815             int ownerUserId, int sourceUserId, int targetUserId, int flags) {
11816         mContext.enforceCallingOrSelfPermission(
11817                         android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
11818         int callingUid = Binder.getCallingUid();
11819         enforceOwnerRights(ownerPackage, ownerUserId, callingUid);
11820         enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
11821         if (intentFilter.countActions() == 0) {
11822             Slog.w(TAG, "Cannot set a crossProfile intent filter with no filter actions");
11823             return;
11824         }
11825         synchronized (mPackages) {
11826             CrossProfileIntentFilter filter = new CrossProfileIntentFilter(intentFilter,
11827                     ownerPackage, UserHandle.getUserId(callingUid), targetUserId, flags);
11828             mSettings.editCrossProfileIntentResolverLPw(sourceUserId).addFilter(filter);
11829             mSettings.writePackageRestrictionsLPr(sourceUserId);
11830         }
11831     }
11832
11833     @Override
11834     public void clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage,
11835             int ownerUserId) {
11836         mContext.enforceCallingOrSelfPermission(
11837                         android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
11838         int callingUid = Binder.getCallingUid();
11839         enforceOwnerRights(ownerPackage, ownerUserId, callingUid);
11840         enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
11841         int callingUserId = UserHandle.getUserId(callingUid);
11842         synchronized (mPackages) {
11843             CrossProfileIntentResolver resolver =
11844                     mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
11845             HashSet<CrossProfileIntentFilter> set =
11846                     new HashSet<CrossProfileIntentFilter>(resolver.filterSet());
11847             for (CrossProfileIntentFilter filter : set) {
11848                 if (filter.getOwnerPackage().equals(ownerPackage)
11849                         && filter.getOwnerUserId() == callingUserId) {
11850                     resolver.removeFilter(filter);
11851                 }
11852             }
11853             mSettings.writePackageRestrictionsLPr(sourceUserId);
11854         }
11855     }
11856
11857     // Enforcing that callingUid is owning pkg on userId
11858     private void enforceOwnerRights(String pkg, int userId, int callingUid) {
11859         // The system owns everything.
11860         if (UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) {
11861             return;
11862         }
11863         int callingUserId = UserHandle.getUserId(callingUid);
11864         if (callingUserId != userId) {
11865             throw new SecurityException("calling uid " + callingUid
11866                     + " pretends to own " + pkg + " on user " + userId + " but belongs to user "
11867                     + callingUserId);
11868         }
11869         PackageInfo pi = getPackageInfo(pkg, 0, callingUserId);
11870         if (pi == null) {
11871             throw new IllegalArgumentException("Unknown package " + pkg + " on user "
11872                     + callingUserId);
11873         }
11874         if (!UserHandle.isSameApp(pi.applicationInfo.uid, callingUid)) {
11875             throw new SecurityException("Calling uid " + callingUid
11876                     + " does not own package " + pkg);
11877         }
11878     }
11879
11880     @Override
11881     public ComponentName getHomeActivities(List<ResolveInfo> allHomeCandidates) {
11882         Intent intent = new Intent(Intent.ACTION_MAIN);
11883         intent.addCategory(Intent.CATEGORY_HOME);
11884
11885         final int callingUserId = UserHandle.getCallingUserId();
11886         List<ResolveInfo> list = queryIntentActivities(intent, null,
11887                 PackageManager.GET_META_DATA, callingUserId);
11888         ResolveInfo preferred = findPreferredActivity(intent, null, 0, list, 0,
11889                 true, false, false, callingUserId);
11890
11891         allHomeCandidates.clear();
11892         if (list != null) {
11893             for (ResolveInfo ri : list) {
11894                 allHomeCandidates.add(ri);
11895             }
11896         }
11897         return (preferred == null || preferred.activityInfo == null)
11898                 ? null
11899                 : new ComponentName(preferred.activityInfo.packageName,
11900                         preferred.activityInfo.name);
11901     }
11902
11903     @Override
11904     public void setApplicationEnabledSetting(String appPackageName,
11905             int newState, int flags, int userId, String callingPackage) {
11906         if (!sUserManager.exists(userId)) return;
11907         if (callingPackage == null) {
11908             callingPackage = Integer.toString(Binder.getCallingUid());
11909         }
11910         setEnabledSetting(appPackageName, null, newState, flags, userId, callingPackage);
11911     }
11912
11913     @Override
11914     public void setComponentEnabledSetting(ComponentName componentName,
11915             int newState, int flags, int userId) {
11916         if (!sUserManager.exists(userId)) return;
11917         setEnabledSetting(componentName.getPackageName(),
11918                 componentName.getClassName(), newState, flags, userId, null);
11919     }
11920
11921     private void setEnabledSetting(final String packageName, String className, int newState,
11922             final int flags, int userId, String callingPackage) {
11923         if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT
11924               || newState == COMPONENT_ENABLED_STATE_ENABLED
11925               || newState == COMPONENT_ENABLED_STATE_DISABLED
11926               || newState == COMPONENT_ENABLED_STATE_DISABLED_USER
11927               || newState == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED)) {
11928             throw new IllegalArgumentException("Invalid new component state: "
11929                     + newState);
11930         }
11931         PackageSetting pkgSetting;
11932         final int uid = Binder.getCallingUid();
11933         final int permission = mContext.checkCallingOrSelfPermission(
11934                 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
11935         enforceCrossUserPermission(uid, userId, false, true, "set enabled");
11936         final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
11937         boolean sendNow = false;
11938         boolean isApp = (className == null);
11939         String componentName = isApp ? packageName : className;
11940         int packageUid = -1;
11941         ArrayList<String> components;
11942
11943         // writer
11944         synchronized (mPackages) {
11945             pkgSetting = mSettings.mPackages.get(packageName);
11946             if (pkgSetting == null) {
11947                 if (className == null) {
11948                     throw new IllegalArgumentException(
11949                             "Unknown package: " + packageName);
11950                 }
11951                 throw new IllegalArgumentException(
11952                         "Unknown component: " + packageName
11953                         + "/" + className);
11954             }
11955             // Allow root and verify that userId is not being specified by a different user
11956             if (!allowedByPermission && !UserHandle.isSameApp(uid, pkgSetting.appId)) {
11957                 throw new SecurityException(
11958                         "Permission Denial: attempt to change component state from pid="
11959                         + Binder.getCallingPid()
11960                         + ", uid=" + uid + ", package uid=" + pkgSetting.appId);
11961             }
11962             if (className == null) {
11963                 // We're dealing with an application/package level state change
11964                 if (pkgSetting.getEnabled(userId) == newState) {
11965                     // Nothing to do
11966                     return;
11967                 }
11968                 if (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
11969                     || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {
11970                     // Don't care about who enables an app.
11971                     callingPackage = null;
11972                 }
11973                 pkgSetting.setEnabled(newState, userId, callingPackage);
11974                 // pkgSetting.pkg.mSetEnabled = newState;
11975             } else {
11976                 // We're dealing with a component level state change
11977                 // First, verify that this is a valid class name.
11978                 PackageParser.Package pkg = pkgSetting.pkg;
11979                 if (pkg == null || !pkg.hasComponentClassName(className)) {
11980                     if (pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.JELLY_BEAN) {
11981                         throw new IllegalArgumentException("Component class " + className
11982                                 + " does not exist in " + packageName);
11983                     } else {
11984                         Slog.w(TAG, "Failed setComponentEnabledSetting: component class "
11985                                 + className + " does not exist in " + packageName);
11986                     }
11987                 }
11988                 switch (newState) {
11989                 case COMPONENT_ENABLED_STATE_ENABLED:
11990                     if (!pkgSetting.enableComponentLPw(className, userId)) {
11991                         return;
11992                     }
11993                     break;
11994                 case COMPONENT_ENABLED_STATE_DISABLED:
11995                     if (!pkgSetting.disableComponentLPw(className, userId)) {
11996                         return;
11997                     }
11998                     break;
11999                 case COMPONENT_ENABLED_STATE_DEFAULT:
12000                     if (!pkgSetting.restoreComponentLPw(className, userId)) {
12001                         return;
12002                     }
12003                     break;
12004                 default:
12005                     Slog.e(TAG, "Invalid new component state: " + newState);
12006                     return;
12007                 }
12008             }
12009             mSettings.writePackageRestrictionsLPr(userId);
12010             components = mPendingBroadcasts.get(userId, packageName);
12011             final boolean newPackage = components == null;
12012             if (newPackage) {
12013                 components = new ArrayList<String>();
12014             }
12015             if (!components.contains(componentName)) {
12016                 components.add(componentName);
12017             }
12018             if ((flags&PackageManager.DONT_KILL_APP) == 0) {
12019                 sendNow = true;
12020                 // Purge entry from pending broadcast list if another one exists already
12021                 // since we are sending one right away.
12022                 mPendingBroadcasts.remove(userId, packageName);
12023             } else {
12024                 if (newPackage) {
12025                     mPendingBroadcasts.put(userId, packageName, components);
12026                 }
12027                 if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) {
12028                     // Schedule a message
12029                     mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, BROADCAST_DELAY);
12030                 }
12031             }
12032         }
12033
12034         long callingId = Binder.clearCallingIdentity();
12035         try {
12036             if (sendNow) {
12037                 packageUid = UserHandle.getUid(userId, pkgSetting.appId);
12038                 sendPackageChangedBroadcast(packageName,
12039                         (flags&PackageManager.DONT_KILL_APP) != 0, components, packageUid);
12040             }
12041         } finally {
12042             Binder.restoreCallingIdentity(callingId);
12043         }
12044     }
12045
12046     private void sendPackageChangedBroadcast(String packageName,
12047             boolean killFlag, ArrayList<String> componentNames, int packageUid) {
12048         if (DEBUG_INSTALL)
12049             Log.v(TAG, "Sending package changed: package=" + packageName + " components="
12050                     + componentNames);
12051         Bundle extras = new Bundle(4);
12052         extras.putString(Intent.EXTRA_CHANGED_COMPONENT_NAME, componentNames.get(0));
12053         String nameList[] = new String[componentNames.size()];
12054         componentNames.toArray(nameList);
12055         extras.putStringArray(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST, nameList);
12056         extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, killFlag);
12057         extras.putInt(Intent.EXTRA_UID, packageUid);
12058         sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED,  packageName, extras, null, null,
12059                 new int[] {UserHandle.getUserId(packageUid)});
12060     }
12061
12062     @Override
12063     public void setPackageStoppedState(String packageName, boolean stopped, int userId) {
12064         if (!sUserManager.exists(userId)) return;
12065         final int uid = Binder.getCallingUid();
12066         final int permission = mContext.checkCallingOrSelfPermission(
12067                 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
12068         final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
12069         enforceCrossUserPermission(uid, userId, true, true, "stop package");
12070         // writer
12071         synchronized (mPackages) {
12072             if (mSettings.setPackageStoppedStateLPw(packageName, stopped, allowedByPermission,
12073                     uid, userId)) {
12074                 scheduleWritePackageRestrictionsLocked(userId);
12075             }
12076         }
12077     }
12078
12079     @Override
12080     public String getInstallerPackageName(String packageName) {
12081         // reader
12082         synchronized (mPackages) {
12083             return mSettings.getInstallerPackageNameLPr(packageName);
12084         }
12085     }
12086
12087     @Override
12088     public int getApplicationEnabledSetting(String packageName, int userId) {
12089         if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
12090         int uid = Binder.getCallingUid();
12091         enforceCrossUserPermission(uid, userId, false, false, "get enabled");
12092         // reader
12093         synchronized (mPackages) {
12094             return mSettings.getApplicationEnabledSettingLPr(packageName, userId);
12095         }
12096     }
12097
12098     @Override
12099     public int getComponentEnabledSetting(ComponentName componentName, int userId) {
12100         if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
12101         int uid = Binder.getCallingUid();
12102         enforceCrossUserPermission(uid, userId, false, false, "get component enabled");
12103         // reader
12104         synchronized (mPackages) {
12105             return mSettings.getComponentEnabledSettingLPr(componentName, userId);
12106         }
12107     }
12108
12109     @Override
12110     public void enterSafeMode() {
12111         enforceSystemOrRoot("Only the system can request entering safe mode");
12112
12113         if (!mSystemReady) {
12114             mSafeMode = true;
12115         }
12116     }
12117
12118     @Override
12119     public void systemReady() {
12120         mSystemReady = true;
12121
12122         // Read the compatibilty setting when the system is ready.
12123         boolean compatibilityModeEnabled = android.provider.Settings.Global.getInt(
12124                 mContext.getContentResolver(),
12125                 android.provider.Settings.Global.COMPATIBILITY_MODE, 1) == 1;
12126         PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled);
12127         if (DEBUG_SETTINGS) {
12128             Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled);
12129         }
12130
12131         synchronized (mPackages) {
12132             // Verify that all of the preferred activity components actually
12133             // exist.  It is possible for applications to be updated and at
12134             // that point remove a previously declared activity component that
12135             // had been set as a preferred activity.  We try to clean this up
12136             // the next time we encounter that preferred activity, but it is
12137             // possible for the user flow to never be able to return to that
12138             // situation so here we do a sanity check to make sure we haven't
12139             // left any junk around.
12140             ArrayList<PreferredActivity> removed = new ArrayList<PreferredActivity>();
12141             for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
12142                 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
12143                 removed.clear();
12144                 for (PreferredActivity pa : pir.filterSet()) {
12145                     if (mActivities.mActivities.get(pa.mPref.mComponent) == null) {
12146                         removed.add(pa);
12147                     }
12148                 }
12149                 if (removed.size() > 0) {
12150                     for (int r=0; r<removed.size(); r++) {
12151                         PreferredActivity pa = removed.get(r);
12152                         Slog.w(TAG, "Removing dangling preferred activity: "
12153                                 + pa.mPref.mComponent);
12154                         pir.removeFilter(pa);
12155                     }
12156                     mSettings.writePackageRestrictionsLPr(
12157                             mSettings.mPreferredActivities.keyAt(i));
12158                 }
12159             }
12160         }
12161         sUserManager.systemReady();
12162
12163         // Kick off any messages waiting for system ready
12164         if (mPostSystemReadyMessages != null) {
12165             for (Message msg : mPostSystemReadyMessages) {
12166                 msg.sendToTarget();
12167             }
12168             mPostSystemReadyMessages = null;
12169         }
12170     }
12171
12172     @Override
12173     public boolean isSafeMode() {
12174         return mSafeMode;
12175     }
12176
12177     @Override
12178     public boolean hasSystemUidErrors() {
12179         return mHasSystemUidErrors;
12180     }
12181
12182     static String arrayToString(int[] array) {
12183         StringBuffer buf = new StringBuffer(128);
12184         buf.append('[');
12185         if (array != null) {
12186             for (int i=0; i<array.length; i++) {
12187                 if (i > 0) buf.append(", ");
12188                 buf.append(array[i]);
12189             }
12190         }
12191         buf.append(']');
12192         return buf.toString();
12193     }
12194
12195     static class DumpState {
12196         public static final int DUMP_LIBS = 1 << 0;
12197         public static final int DUMP_FEATURES = 1 << 1;
12198         public static final int DUMP_RESOLVERS = 1 << 2;
12199         public static final int DUMP_PERMISSIONS = 1 << 3;
12200         public static final int DUMP_PACKAGES = 1 << 4;
12201         public static final int DUMP_SHARED_USERS = 1 << 5;
12202         public static final int DUMP_MESSAGES = 1 << 6;
12203         public static final int DUMP_PROVIDERS = 1 << 7;
12204         public static final int DUMP_VERIFIERS = 1 << 8;
12205         public static final int DUMP_PREFERRED = 1 << 9;
12206         public static final int DUMP_PREFERRED_XML = 1 << 10;
12207         public static final int DUMP_KEYSETS = 1 << 11;
12208         public static final int DUMP_VERSION = 1 << 12;
12209         public static final int DUMP_INSTALLS = 1 << 13;
12210
12211         public static final int OPTION_SHOW_FILTERS = 1 << 0;
12212
12213         private int mTypes;
12214
12215         private int mOptions;
12216
12217         private boolean mTitlePrinted;
12218
12219         private SharedUserSetting mSharedUser;
12220
12221         public boolean isDumping(int type) {
12222             if (mTypes == 0 && type != DUMP_PREFERRED_XML) {
12223                 return true;
12224             }
12225
12226             return (mTypes & type) != 0;
12227         }
12228
12229         public void setDump(int type) {
12230             mTypes |= type;
12231         }
12232
12233         public boolean isOptionEnabled(int option) {
12234             return (mOptions & option) != 0;
12235         }
12236
12237         public void setOptionEnabled(int option) {
12238             mOptions |= option;
12239         }
12240
12241         public boolean onTitlePrinted() {
12242             final boolean printed = mTitlePrinted;
12243             mTitlePrinted = true;
12244             return printed;
12245         }
12246
12247         public boolean getTitlePrinted() {
12248             return mTitlePrinted;
12249         }
12250
12251         public void setTitlePrinted(boolean enabled) {
12252             mTitlePrinted = enabled;
12253         }
12254
12255         public SharedUserSetting getSharedUser() {
12256             return mSharedUser;
12257         }
12258
12259         public void setSharedUser(SharedUserSetting user) {
12260             mSharedUser = user;
12261         }
12262     }
12263
12264     @Override
12265     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12266         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
12267                 != PackageManager.PERMISSION_GRANTED) {
12268             pw.println("Permission Denial: can't dump ActivityManager from from pid="
12269                     + Binder.getCallingPid()
12270                     + ", uid=" + Binder.getCallingUid()
12271                     + " without permission "
12272                     + android.Manifest.permission.DUMP);
12273             return;
12274         }
12275
12276         DumpState dumpState = new DumpState();
12277         boolean fullPreferred = false;
12278         boolean checkin = false;
12279
12280         String packageName = null;
12281         
12282         int opti = 0;
12283         while (opti < args.length) {
12284             String opt = args[opti];
12285             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12286                 break;
12287             }
12288             opti++;
12289
12290             if ("-a".equals(opt)) {
12291                 // Right now we only know how to print all.
12292             } else if ("-h".equals(opt)) {
12293                 pw.println("Package manager dump options:");
12294                 pw.println("  [-h] [-f] [--checkin] [cmd] ...");
12295                 pw.println("    --checkin: dump for a checkin");
12296                 pw.println("    -f: print details of intent filters");
12297                 pw.println("    -h: print this help");
12298                 pw.println("  cmd may be one of:");
12299                 pw.println("    l[ibraries]: list known shared libraries");
12300                 pw.println("    f[ibraries]: list device features");
12301                 pw.println("    k[eysets]: print known keysets");
12302                 pw.println("    r[esolvers]: dump intent resolvers");
12303                 pw.println("    perm[issions]: dump permissions");
12304                 pw.println("    pref[erred]: print preferred package settings");
12305                 pw.println("    preferred-xml [--full]: print preferred package settings as xml");
12306                 pw.println("    prov[iders]: dump content providers");
12307                 pw.println("    p[ackages]: dump installed packages");
12308                 pw.println("    s[hared-users]: dump shared user IDs");
12309                 pw.println("    m[essages]: print collected runtime messages");
12310                 pw.println("    v[erifiers]: print package verifier info");
12311                 pw.println("    version: print database version info");
12312                 pw.println("    write: write current settings now");
12313                 pw.println("    <package.name>: info about given package");
12314                 pw.println("    installs: details about install sessions");
12315                 return;
12316             } else if ("--checkin".equals(opt)) {
12317                 checkin = true;
12318             } else if ("-f".equals(opt)) {
12319                 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
12320             } else {
12321                 pw.println("Unknown argument: " + opt + "; use -h for help");
12322             }
12323         }
12324
12325         // Is the caller requesting to dump a particular piece of data?
12326         if (opti < args.length) {
12327             String cmd = args[opti];
12328             opti++;
12329             // Is this a package name?
12330             if ("android".equals(cmd) || cmd.contains(".")) {
12331                 packageName = cmd;
12332                 // When dumping a single package, we always dump all of its
12333                 // filter information since the amount of data will be reasonable.
12334                 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
12335             } else if ("l".equals(cmd) || "libraries".equals(cmd)) {
12336                 dumpState.setDump(DumpState.DUMP_LIBS);
12337             } else if ("f".equals(cmd) || "features".equals(cmd)) {
12338                 dumpState.setDump(DumpState.DUMP_FEATURES);
12339             } else if ("r".equals(cmd) || "resolvers".equals(cmd)) {
12340                 dumpState.setDump(DumpState.DUMP_RESOLVERS);
12341             } else if ("perm".equals(cmd) || "permissions".equals(cmd)) {
12342                 dumpState.setDump(DumpState.DUMP_PERMISSIONS);
12343             } else if ("pref".equals(cmd) || "preferred".equals(cmd)) {
12344                 dumpState.setDump(DumpState.DUMP_PREFERRED);
12345             } else if ("preferred-xml".equals(cmd)) {
12346                 dumpState.setDump(DumpState.DUMP_PREFERRED_XML);
12347                 if (opti < args.length && "--full".equals(args[opti])) {
12348                     fullPreferred = true;
12349                     opti++;
12350                 }
12351             } else if ("p".equals(cmd) || "packages".equals(cmd)) {
12352                 dumpState.setDump(DumpState.DUMP_PACKAGES);
12353             } else if ("s".equals(cmd) || "shared-users".equals(cmd)) {
12354                 dumpState.setDump(DumpState.DUMP_SHARED_USERS);
12355             } else if ("prov".equals(cmd) || "providers".equals(cmd)) {
12356                 dumpState.setDump(DumpState.DUMP_PROVIDERS);
12357             } else if ("m".equals(cmd) || "messages".equals(cmd)) {
12358                 dumpState.setDump(DumpState.DUMP_MESSAGES);
12359             } else if ("v".equals(cmd) || "verifiers".equals(cmd)) {
12360                 dumpState.setDump(DumpState.DUMP_VERIFIERS);
12361             } else if ("version".equals(cmd)) {
12362                 dumpState.setDump(DumpState.DUMP_VERSION);
12363             } else if ("k".equals(cmd) || "keysets".equals(cmd)) {
12364                 dumpState.setDump(DumpState.DUMP_KEYSETS);
12365             } else if ("installs".equals(cmd)) {
12366                 dumpState.setDump(DumpState.DUMP_INSTALLS);
12367             } else if ("write".equals(cmd)) {
12368                 synchronized (mPackages) {
12369                     mSettings.writeLPr();
12370                     pw.println("Settings written.");
12371                     return;
12372                 }
12373             }
12374         }
12375
12376         if (checkin) {
12377             pw.println("vers,1");
12378         }
12379
12380         // reader
12381         synchronized (mPackages) {
12382             if (dumpState.isDumping(DumpState.DUMP_VERSION) && packageName == null) {
12383                 if (!checkin) {
12384                     if (dumpState.onTitlePrinted())
12385                         pw.println();
12386                     pw.println("Database versions:");
12387                     pw.print("  SDK Version:");
12388                     pw.print(" internal=");
12389                     pw.print(mSettings.mInternalSdkPlatform);
12390                     pw.print(" external=");
12391                     pw.println(mSettings.mExternalSdkPlatform);
12392                     pw.print("  DB Version:");
12393                     pw.print(" internal=");
12394                     pw.print(mSettings.mInternalDatabaseVersion);
12395                     pw.print(" external=");
12396                     pw.println(mSettings.mExternalDatabaseVersion);
12397                 }
12398             }
12399
12400             if (dumpState.isDumping(DumpState.DUMP_VERIFIERS) && packageName == null) {
12401                 if (!checkin) {
12402                     if (dumpState.onTitlePrinted())
12403                         pw.println();
12404                     pw.println("Verifiers:");
12405                     pw.print("  Required: ");
12406                     pw.print(mRequiredVerifierPackage);
12407                     pw.print(" (uid=");
12408                     pw.print(getPackageUid(mRequiredVerifierPackage, 0));
12409                     pw.println(")");
12410                 } else if (mRequiredVerifierPackage != null) {
12411                     pw.print("vrfy,"); pw.print(mRequiredVerifierPackage);
12412                     pw.print(","); pw.println(getPackageUid(mRequiredVerifierPackage, 0));
12413                 }
12414             }
12415
12416             if (dumpState.isDumping(DumpState.DUMP_LIBS) && packageName == null) {
12417                 boolean printedHeader = false;
12418                 final Iterator<String> it = mSharedLibraries.keySet().iterator();
12419                 while (it.hasNext()) {
12420                     String name = it.next();
12421                     SharedLibraryEntry ent = mSharedLibraries.get(name);
12422                     if (!checkin) {
12423                         if (!printedHeader) {
12424                             if (dumpState.onTitlePrinted())
12425                                 pw.println();
12426                             pw.println("Libraries:");
12427                             printedHeader = true;
12428                         }
12429                         pw.print("  ");
12430                     } else {
12431                         pw.print("lib,");
12432                     }
12433                     pw.print(name);
12434                     if (!checkin) {
12435                         pw.print(" -> ");
12436                     }
12437                     if (ent.path != null) {
12438                         if (!checkin) {
12439                             pw.print("(jar) ");
12440                             pw.print(ent.path);
12441                         } else {
12442                             pw.print(",jar,");
12443                             pw.print(ent.path);
12444                         }
12445                     } else {
12446                         if (!checkin) {
12447                             pw.print("(apk) ");
12448                             pw.print(ent.apk);
12449                         } else {
12450                             pw.print(",apk,");
12451                             pw.print(ent.apk);
12452                         }
12453                     }
12454                     pw.println();
12455                 }
12456             }
12457
12458             if (dumpState.isDumping(DumpState.DUMP_FEATURES) && packageName == null) {
12459                 if (dumpState.onTitlePrinted())
12460                     pw.println();
12461                 if (!checkin) {
12462                     pw.println("Features:");
12463                 }
12464                 Iterator<String> it = mAvailableFeatures.keySet().iterator();
12465                 while (it.hasNext()) {
12466                     String name = it.next();
12467                     if (!checkin) {
12468                         pw.print("  ");
12469                     } else {
12470                         pw.print("feat,");
12471                     }
12472                     pw.println(name);
12473                 }
12474             }
12475
12476             if (!checkin && dumpState.isDumping(DumpState.DUMP_RESOLVERS)) {
12477                 if (mActivities.dump(pw, dumpState.getTitlePrinted() ? "\nActivity Resolver Table:"
12478                         : "Activity Resolver Table:", "  ", packageName,
12479                         dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS))) {
12480                     dumpState.setTitlePrinted(true);
12481                 }
12482                 if (mReceivers.dump(pw, dumpState.getTitlePrinted() ? "\nReceiver Resolver Table:"
12483                         : "Receiver Resolver Table:", "  ", packageName,
12484                         dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS))) {
12485                     dumpState.setTitlePrinted(true);
12486                 }
12487                 if (mServices.dump(pw, dumpState.getTitlePrinted() ? "\nService Resolver Table:"
12488                         : "Service Resolver Table:", "  ", packageName,
12489                         dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS))) {
12490                     dumpState.setTitlePrinted(true);
12491                 }
12492                 if (mProviders.dump(pw, dumpState.getTitlePrinted() ? "\nProvider Resolver Table:"
12493                         : "Provider Resolver Table:", "  ", packageName,
12494                         dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS))) {
12495                     dumpState.setTitlePrinted(true);
12496                 }
12497             }
12498
12499             if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED)) {
12500                 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
12501                     PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
12502                     int user = mSettings.mPreferredActivities.keyAt(i);
12503                     if (pir.dump(pw,
12504                             dumpState.getTitlePrinted()
12505                                 ? "\nPreferred Activities User " + user + ":"
12506                                 : "Preferred Activities User " + user + ":", "  ",
12507                             packageName, true)) {
12508                         dumpState.setTitlePrinted(true);
12509                     }
12510                 }
12511             }
12512
12513             if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED_XML)) {
12514                 pw.flush();
12515                 FileOutputStream fout = new FileOutputStream(fd);
12516                 BufferedOutputStream str = new BufferedOutputStream(fout);
12517                 XmlSerializer serializer = new FastXmlSerializer();
12518                 try {
12519                     serializer.setOutput(str, "utf-8");
12520                     serializer.startDocument(null, true);
12521                     serializer.setFeature(
12522                             "http://xmlpull.org/v1/doc/features.html#indent-output", true);
12523                     mSettings.writePreferredActivitiesLPr(serializer, 0, fullPreferred);
12524                     serializer.endDocument();
12525                     serializer.flush();
12526                 } catch (IllegalArgumentException e) {
12527                     pw.println("Failed writing: " + e);
12528                 } catch (IllegalStateException e) {
12529                     pw.println("Failed writing: " + e);
12530                 } catch (IOException e) {
12531                     pw.println("Failed writing: " + e);
12532                 }
12533             }
12534
12535             if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) {
12536                 mSettings.dumpPermissionsLPr(pw, packageName, dumpState);
12537                 if (packageName == null) {
12538                     for (int iperm=0; iperm<mAppOpPermissionPackages.size(); iperm++) {
12539                         if (iperm == 0) {
12540                             if (dumpState.onTitlePrinted())
12541                                 pw.println();
12542                             pw.println("AppOp Permissions:");
12543                         }
12544                         pw.print("  AppOp Permission ");
12545                         pw.print(mAppOpPermissionPackages.keyAt(iperm));
12546                         pw.println(":");
12547                         ArraySet<String> pkgs = mAppOpPermissionPackages.valueAt(iperm);
12548                         for (int ipkg=0; ipkg<pkgs.size(); ipkg++) {
12549                             pw.print("    "); pw.println(pkgs.valueAt(ipkg));
12550                         }
12551                     }
12552                 }
12553             }
12554
12555             if (!checkin && dumpState.isDumping(DumpState.DUMP_PROVIDERS)) {
12556                 boolean printedSomething = false;
12557                 for (PackageParser.Provider p : mProviders.mProviders.values()) {
12558                     if (packageName != null && !packageName.equals(p.info.packageName)) {
12559                         continue;
12560                     }
12561                     if (!printedSomething) {
12562                         if (dumpState.onTitlePrinted())
12563                             pw.println();
12564                         pw.println("Registered ContentProviders:");
12565                         printedSomething = true;
12566                     }
12567                     pw.print("  "); p.printComponentShortName(pw); pw.println(":");
12568                     pw.print("    "); pw.println(p.toString());
12569                 }
12570                 printedSomething = false;
12571                 for (Map.Entry<String, PackageParser.Provider> entry :
12572                         mProvidersByAuthority.entrySet()) {
12573                     PackageParser.Provider p = entry.getValue();
12574                     if (packageName != null && !packageName.equals(p.info.packageName)) {
12575                         continue;
12576                     }
12577                     if (!printedSomething) {
12578                         if (dumpState.onTitlePrinted())
12579                             pw.println();
12580                         pw.println("ContentProvider Authorities:");
12581                         printedSomething = true;
12582                     }
12583                     pw.print("  ["); pw.print(entry.getKey()); pw.println("]:");
12584                     pw.print("    "); pw.println(p.toString());
12585                     if (p.info != null && p.info.applicationInfo != null) {
12586                         final String appInfo = p.info.applicationInfo.toString();
12587                         pw.print("      applicationInfo="); pw.println(appInfo);
12588                     }
12589                 }
12590             }
12591
12592             if (!checkin && dumpState.isDumping(DumpState.DUMP_KEYSETS)) {
12593                 mSettings.mKeySetManagerService.dumpLPr(pw, packageName, dumpState);
12594             }
12595
12596             if (dumpState.isDumping(DumpState.DUMP_PACKAGES)) {
12597                 mSettings.dumpPackagesLPr(pw, packageName, dumpState, checkin);
12598             }
12599
12600             if (!checkin && dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) {
12601                 mSettings.dumpSharedUsersLPr(pw, packageName, dumpState);
12602             }
12603
12604             if (!checkin && dumpState.isDumping(DumpState.DUMP_INSTALLS) && packageName == null) {
12605                 // XXX should handle packageName != null by dumping only install data that
12606                 // the given package is involved with.
12607                 if (dumpState.onTitlePrinted()) pw.println();
12608                 mInstallerService.dump(new IndentingPrintWriter(pw, "  ", 120));
12609             }
12610
12611             if (!checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES) && packageName == null) {
12612                 if (dumpState.onTitlePrinted()) pw.println();
12613                 mSettings.dumpReadMessagesLPr(pw, dumpState);
12614
12615                 pw.println();
12616                 pw.println("Package warning messages:");
12617                 final File fname = getSettingsProblemFile();
12618                 FileInputStream in = null;
12619                 try {
12620                     in = new FileInputStream(fname);
12621                     final int avail = in.available();
12622                     final byte[] data = new byte[avail];
12623                     in.read(data);
12624                     pw.print(new String(data));
12625                 } catch (FileNotFoundException e) {
12626                 } catch (IOException e) {
12627                 } finally {
12628                     if (in != null) {
12629                         try {
12630                             in.close();
12631                         } catch (IOException e) {
12632                         }
12633                     }
12634                 }
12635             }
12636
12637             if (checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES)) {
12638                 BufferedReader in = null;
12639                 String line = null;
12640                 try {
12641                     in = new BufferedReader(new FileReader(getSettingsProblemFile()));
12642                     while ((line = in.readLine()) != null) {
12643                         pw.print("msg,");
12644                         pw.println(line);
12645                     }
12646                 } catch (IOException ignored) {
12647                 } finally {
12648                     IoUtils.closeQuietly(in);
12649                 }
12650             }
12651         }
12652     }
12653
12654     // ------- apps on sdcard specific code -------
12655     static final boolean DEBUG_SD_INSTALL = false;
12656
12657     private static final String SD_ENCRYPTION_KEYSTORE_NAME = "AppsOnSD";
12658
12659     private static final String SD_ENCRYPTION_ALGORITHM = "AES";
12660
12661     private boolean mMediaMounted = false;
12662
12663     static String getEncryptKey() {
12664         try {
12665             String sdEncKey = SystemKeyStore.getInstance().retrieveKeyHexString(
12666                     SD_ENCRYPTION_KEYSTORE_NAME);
12667             if (sdEncKey == null) {
12668                 sdEncKey = SystemKeyStore.getInstance().generateNewKeyHexString(128,
12669                         SD_ENCRYPTION_ALGORITHM, SD_ENCRYPTION_KEYSTORE_NAME);
12670                 if (sdEncKey == null) {
12671                     Slog.e(TAG, "Failed to create encryption keys");
12672                     return null;
12673                 }
12674             }
12675             return sdEncKey;
12676         } catch (NoSuchAlgorithmException nsae) {
12677             Slog.e(TAG, "Failed to create encryption keys with exception: " + nsae);
12678             return null;
12679         } catch (IOException ioe) {
12680             Slog.e(TAG, "Failed to retrieve encryption keys with exception: " + ioe);
12681             return null;
12682         }
12683     }
12684
12685     /*
12686      * Update media status on PackageManager.
12687      */
12688     @Override
12689     public void updateExternalMediaStatus(final boolean mediaStatus, final boolean reportStatus) {
12690         int callingUid = Binder.getCallingUid();
12691         if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
12692             throw new SecurityException("Media status can only be updated by the system");
12693         }
12694         // reader; this apparently protects mMediaMounted, but should probably
12695         // be a different lock in that case.
12696         synchronized (mPackages) {
12697             Log.i(TAG, "Updating external media status from "
12698                     + (mMediaMounted ? "mounted" : "unmounted") + " to "
12699                     + (mediaStatus ? "mounted" : "unmounted"));
12700             if (DEBUG_SD_INSTALL)
12701                 Log.i(TAG, "updateExternalMediaStatus:: mediaStatus=" + mediaStatus
12702                         + ", mMediaMounted=" + mMediaMounted);
12703             if (mediaStatus == mMediaMounted) {
12704                 final Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1
12705                         : 0, -1);
12706                 mHandler.sendMessage(msg);
12707                 return;
12708             }
12709             mMediaMounted = mediaStatus;
12710         }
12711         // Queue up an async operation since the package installation may take a
12712         // little while.
12713         mHandler.post(new Runnable() {
12714             public void run() {
12715                 updateExternalMediaStatusInner(mediaStatus, reportStatus, true);
12716             }
12717         });
12718     }
12719
12720     /**
12721      * Called by MountService when the initial ASECs to scan are available.
12722      * Should block until all the ASEC containers are finished being scanned.
12723      */
12724     public void scanAvailableAsecs() {
12725         updateExternalMediaStatusInner(true, false, false);
12726         if (mShouldRestoreconData) {
12727             SELinuxMMAC.setRestoreconDone();
12728             mShouldRestoreconData = false;
12729         }
12730     }
12731
12732     /*
12733      * Collect information of applications on external media, map them against
12734      * existing containers and update information based on current mount status.
12735      * Please note that we always have to report status if reportStatus has been
12736      * set to true especially when unloading packages.
12737      */
12738     private void updateExternalMediaStatusInner(boolean isMounted, boolean reportStatus,
12739             boolean externalStorage) {
12740         ArrayMap<AsecInstallArgs, String> processCids = new ArrayMap<>();
12741         int[] uidArr = EmptyArray.INT;
12742
12743         final String[] list = PackageHelper.getSecureContainerList();
12744         if (ArrayUtils.isEmpty(list)) {
12745             Log.i(TAG, "No secure containers found");
12746         } else {
12747             // Process list of secure containers and categorize them
12748             // as active or stale based on their package internal state.
12749
12750             // reader
12751             synchronized (mPackages) {
12752                 for (String cid : list) {
12753                     // Leave stages untouched for now; installer service owns them
12754                     if (PackageInstallerService.isStageName(cid)) continue;
12755
12756                     if (DEBUG_SD_INSTALL)
12757                         Log.i(TAG, "Processing container " + cid);
12758                     String pkgName = getAsecPackageName(cid);
12759                     if (pkgName == null) {
12760                         Slog.i(TAG, "Found stale container " + cid + " with no package name");
12761                         continue;
12762                     }
12763                     if (DEBUG_SD_INSTALL)
12764                         Log.i(TAG, "Looking for pkg : " + pkgName);
12765
12766                     final PackageSetting ps = mSettings.mPackages.get(pkgName);
12767                     if (ps == null) {
12768                         Slog.i(TAG, "Found stale container " + cid + " with no matching settings");
12769                         continue;
12770                     }
12771
12772                     /*
12773                      * Skip packages that are not external if we're unmounting
12774                      * external storage.
12775                      */
12776                     if (externalStorage && !isMounted && !isExternal(ps)) {
12777                         continue;
12778                     }
12779
12780                     final AsecInstallArgs args = new AsecInstallArgs(cid,
12781                             getAppDexInstructionSets(ps), isForwardLocked(ps));
12782                     // The package status is changed only if the code path
12783                     // matches between settings and the container id.
12784                     if (ps.codePathString != null
12785                             && ps.codePathString.startsWith(args.getCodePath())) {
12786                         if (DEBUG_SD_INSTALL) {
12787                             Log.i(TAG, "Container : " + cid + " corresponds to pkg : " + pkgName
12788                                     + " at code path: " + ps.codePathString);
12789                         }
12790
12791                         // We do have a valid package installed on sdcard
12792                         processCids.put(args, ps.codePathString);
12793                         final int uid = ps.appId;
12794                         if (uid != -1) {
12795                             uidArr = ArrayUtils.appendInt(uidArr, uid);
12796                         }
12797                     } else {
12798                         Slog.i(TAG, "Found stale container " + cid + ": expected codePath="
12799                                 + ps.codePathString);
12800                     }
12801                 }
12802             }
12803
12804             Arrays.sort(uidArr);
12805         }
12806
12807         // Process packages with valid entries.
12808         if (isMounted) {
12809             if (DEBUG_SD_INSTALL)
12810                 Log.i(TAG, "Loading packages");
12811             loadMediaPackages(processCids, uidArr);
12812             startCleaningPackages();
12813             mInstallerService.onSecureContainersAvailable();
12814         } else {
12815             if (DEBUG_SD_INSTALL)
12816                 Log.i(TAG, "Unloading packages");
12817             unloadMediaPackages(processCids, uidArr, reportStatus);
12818         }
12819     }
12820
12821     private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
12822             ArrayList<String> pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
12823         int size = pkgList.size();
12824         if (size > 0) {
12825             // Send broadcasts here
12826             Bundle extras = new Bundle();
12827             extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList
12828                     .toArray(new String[size]));
12829             if (uidArr != null) {
12830                 extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidArr);
12831             }
12832             if (replacing) {
12833                 extras.putBoolean(Intent.EXTRA_REPLACING, replacing);
12834             }
12835             String action = mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE
12836                     : Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE;
12837             sendPackageBroadcast(action, null, extras, null, finishedReceiver, null);
12838         }
12839     }
12840
12841    /*
12842      * Look at potentially valid container ids from processCids If package
12843      * information doesn't match the one on record or package scanning fails,
12844      * the cid is added to list of removeCids. We currently don't delete stale
12845      * containers.
12846      */
12847     private void loadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int[] uidArr) {
12848         ArrayList<String> pkgList = new ArrayList<String>();
12849         Set<AsecInstallArgs> keys = processCids.keySet();
12850
12851         for (AsecInstallArgs args : keys) {
12852             String codePath = processCids.get(args);
12853             if (DEBUG_SD_INSTALL)
12854                 Log.i(TAG, "Loading container : " + args.cid);
12855             int retCode = PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
12856             try {
12857                 // Make sure there are no container errors first.
12858                 if (args.doPreInstall(PackageManager.INSTALL_SUCCEEDED) != PackageManager.INSTALL_SUCCEEDED) {
12859                     Slog.e(TAG, "Failed to mount cid : " + args.cid
12860                             + " when installing from sdcard");
12861                     continue;
12862                 }
12863                 // Check code path here.
12864                 if (codePath == null || !codePath.startsWith(args.getCodePath())) {
12865                     Slog.e(TAG, "Container " + args.cid + " cachepath " + args.getCodePath()
12866                             + " does not match one in settings " + codePath);
12867                     continue;
12868                 }
12869                 // Parse package
12870                 int parseFlags = mDefParseFlags;
12871                 if (args.isExternal()) {
12872                     parseFlags |= PackageParser.PARSE_ON_SDCARD;
12873                 }
12874                 if (args.isFwdLocked()) {
12875                     parseFlags |= PackageParser.PARSE_FORWARD_LOCK;
12876                 }
12877
12878                 synchronized (mInstallLock) {
12879                     PackageParser.Package pkg = null;
12880                     try {
12881                         pkg = scanPackageLI(new File(codePath), parseFlags, 0, 0, null);
12882                     } catch (PackageManagerException e) {
12883                         Slog.w(TAG, "Failed to scan " + codePath + ": " + e.getMessage());
12884                     }
12885                     // Scan the package
12886                     if (pkg != null) {
12887                         /*
12888                          * TODO why is the lock being held? doPostInstall is
12889                          * called in other places without the lock. This needs
12890                          * to be straightened out.
12891                          */
12892                         // writer
12893                         synchronized (mPackages) {
12894                             retCode = PackageManager.INSTALL_SUCCEEDED;
12895                             pkgList.add(pkg.packageName);
12896                             // Post process args
12897                             args.doPostInstall(PackageManager.INSTALL_SUCCEEDED,
12898                                     pkg.applicationInfo.uid);
12899                         }
12900                     } else {
12901                         Slog.i(TAG, "Failed to install pkg from  " + codePath + " from sdcard");
12902                     }
12903                 }
12904
12905             } finally {
12906                 if (retCode != PackageManager.INSTALL_SUCCEEDED) {
12907                     Log.w(TAG, "Container " + args.cid + " is stale, retCode=" + retCode);
12908                 }
12909             }
12910         }
12911         // writer
12912         synchronized (mPackages) {
12913             // If the platform SDK has changed since the last time we booted,
12914             // we need to re-grant app permission to catch any new ones that
12915             // appear. This is really a hack, and means that apps can in some
12916             // cases get permissions that the user didn't initially explicitly
12917             // allow... it would be nice to have some better way to handle
12918             // this situation.
12919             final boolean regrantPermissions = mSettings.mExternalSdkPlatform != mSdkVersion;
12920             if (regrantPermissions)
12921                 Slog.i(TAG, "Platform changed from " + mSettings.mExternalSdkPlatform + " to "
12922                         + mSdkVersion + "; regranting permissions for external storage");
12923             mSettings.mExternalSdkPlatform = mSdkVersion;
12924
12925             // Make sure group IDs have been assigned, and any permission
12926             // changes in other apps are accounted for
12927             updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL
12928                     | (regrantPermissions
12929                             ? (UPDATE_PERMISSIONS_REPLACE_PKG|UPDATE_PERMISSIONS_REPLACE_ALL)
12930                             : 0));
12931
12932             mSettings.updateExternalDatabaseVersion();
12933
12934             // can downgrade to reader
12935             // Persist settings
12936             mSettings.writeLPr();
12937         }
12938         // Send a broadcast to let everyone know we are done processing
12939         if (pkgList.size() > 0) {
12940             sendResourcesChangedBroadcast(true, false, pkgList, uidArr, null);
12941         }
12942     }
12943
12944    /*
12945      * Utility method to unload a list of specified containers
12946      */
12947     private void unloadAllContainers(Set<AsecInstallArgs> cidArgs) {
12948         // Just unmount all valid containers.
12949         for (AsecInstallArgs arg : cidArgs) {
12950             synchronized (mInstallLock) {
12951                 arg.doPostDeleteLI(false);
12952            }
12953        }
12954    }
12955
12956     /*
12957      * Unload packages mounted on external media. This involves deleting package
12958      * data from internal structures, sending broadcasts about diabled packages,
12959      * gc'ing to free up references, unmounting all secure containers
12960      * corresponding to packages on external media, and posting a
12961      * UPDATED_MEDIA_STATUS message if status has been requested. Please note
12962      * that we always have to post this message if status has been requested no
12963      * matter what.
12964      */
12965     private void unloadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int uidArr[],
12966             final boolean reportStatus) {
12967         if (DEBUG_SD_INSTALL)
12968             Log.i(TAG, "unloading media packages");
12969         ArrayList<String> pkgList = new ArrayList<String>();
12970         ArrayList<AsecInstallArgs> failedList = new ArrayList<AsecInstallArgs>();
12971         final Set<AsecInstallArgs> keys = processCids.keySet();
12972         for (AsecInstallArgs args : keys) {
12973             String pkgName = args.getPackageName();
12974             if (DEBUG_SD_INSTALL)
12975                 Log.i(TAG, "Trying to unload pkg : " + pkgName);
12976             // Delete package internally
12977             PackageRemovedInfo outInfo = new PackageRemovedInfo();
12978             synchronized (mInstallLock) {
12979                 boolean res = deletePackageLI(pkgName, null, false, null, null,
12980                         PackageManager.DELETE_KEEP_DATA, outInfo, false);
12981                 if (res) {
12982                     pkgList.add(pkgName);
12983                 } else {
12984                     Slog.e(TAG, "Failed to delete pkg from sdcard : " + pkgName);
12985                     failedList.add(args);
12986                 }
12987             }
12988         }
12989
12990         // reader
12991         synchronized (mPackages) {
12992             // We didn't update the settings after removing each package;
12993             // write them now for all packages.
12994             mSettings.writeLPr();
12995         }
12996
12997         // We have to absolutely send UPDATED_MEDIA_STATUS only
12998         // after confirming that all the receivers processed the ordered
12999         // broadcast when packages get disabled, force a gc to clean things up.
13000         // and unload all the containers.
13001         if (pkgList.size() > 0) {
13002             sendResourcesChangedBroadcast(false, false, pkgList, uidArr,
13003                     new IIntentReceiver.Stub() {
13004                 public void performReceive(Intent intent, int resultCode, String data,
13005                         Bundle extras, boolean ordered, boolean sticky,
13006                         int sendingUser) throws RemoteException {
13007                     Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS,
13008                             reportStatus ? 1 : 0, 1, keys);
13009                     mHandler.sendMessage(msg);
13010                 }
13011             });
13012         } else {
13013             Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1 : 0, -1,
13014                     keys);
13015             mHandler.sendMessage(msg);
13016         }
13017     }
13018
13019     /** Binder call */
13020     @Override
13021     public void movePackage(final String packageName, final IPackageMoveObserver observer,
13022             final int flags) {
13023         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
13024         UserHandle user = new UserHandle(UserHandle.getCallingUserId());
13025         int returnCode = PackageManager.MOVE_SUCCEEDED;
13026         int currInstallFlags = 0;
13027         int newInstallFlags = 0;
13028
13029         File codeFile = null;
13030         String installerPackageName = null;
13031         String packageAbiOverride = null;
13032
13033         // reader
13034         synchronized (mPackages) {
13035             final PackageParser.Package pkg = mPackages.get(packageName);
13036             final PackageSetting ps = mSettings.mPackages.get(packageName);
13037             if (pkg == null || ps == null) {
13038                 returnCode = PackageManager.MOVE_FAILED_DOESNT_EXIST;
13039             } else {
13040                 // Disable moving fwd locked apps and system packages
13041                 if (pkg.applicationInfo != null && isSystemApp(pkg)) {
13042                     Slog.w(TAG, "Cannot move system application");
13043                     returnCode = PackageManager.MOVE_FAILED_SYSTEM_PACKAGE;
13044                 } else if (pkg.mOperationPending) {
13045                     Slog.w(TAG, "Attempt to move package which has pending operations");
13046                     returnCode = PackageManager.MOVE_FAILED_OPERATION_PENDING;
13047                 } else {
13048                     // Find install location first
13049                     if ((flags & PackageManager.MOVE_EXTERNAL_MEDIA) != 0
13050                             && (flags & PackageManager.MOVE_INTERNAL) != 0) {
13051                         Slog.w(TAG, "Ambigous flags specified for move location.");
13052                         returnCode = PackageManager.MOVE_FAILED_INVALID_LOCATION;
13053                     } else {
13054                         newInstallFlags = (flags & PackageManager.MOVE_EXTERNAL_MEDIA) != 0
13055                                 ? PackageManager.INSTALL_EXTERNAL : PackageManager.INSTALL_INTERNAL;
13056                         currInstallFlags = isExternal(pkg)
13057                                 ? PackageManager.INSTALL_EXTERNAL : PackageManager.INSTALL_INTERNAL;
13058
13059                         if (newInstallFlags == currInstallFlags) {
13060                             Slog.w(TAG, "No move required. Trying to move to same location");
13061                             returnCode = PackageManager.MOVE_FAILED_INVALID_LOCATION;
13062                         } else {
13063                             if (isForwardLocked(pkg)) {
13064                                 currInstallFlags |= PackageManager.INSTALL_FORWARD_LOCK;
13065                                 newInstallFlags |= PackageManager.INSTALL_FORWARD_LOCK;
13066                             }
13067                         }
13068                     }
13069                     if (returnCode == PackageManager.MOVE_SUCCEEDED) {
13070                         pkg.mOperationPending = true;
13071                     }
13072                 }
13073
13074                 codeFile = new File(pkg.codePath);
13075                 installerPackageName = ps.installerPackageName;
13076                 packageAbiOverride = ps.cpuAbiOverrideString;
13077             }
13078         }
13079
13080         if (returnCode != PackageManager.MOVE_SUCCEEDED) {
13081             try {
13082                 observer.packageMoved(packageName, returnCode);
13083             } catch (RemoteException ignored) {
13084             }
13085             return;
13086         }
13087
13088         final IPackageInstallObserver2 installObserver = new IPackageInstallObserver2.Stub() {
13089             @Override
13090             public void onUserActionRequired(Intent intent) throws RemoteException {
13091                 throw new IllegalStateException();
13092             }
13093
13094             @Override
13095             public void onPackageInstalled(String basePackageName, int returnCode, String msg,
13096                     Bundle extras) throws RemoteException {
13097                 Slog.d(TAG, "Install result for move: "
13098                         + PackageManager.installStatusToString(returnCode, msg));
13099
13100                 // We usually have a new package now after the install, but if
13101                 // we failed we need to clear the pending flag on the original
13102                 // package object.
13103                 synchronized (mPackages) {
13104                     final PackageParser.Package pkg = mPackages.get(packageName);
13105                     if (pkg != null) {
13106                         pkg.mOperationPending = false;
13107                     }
13108                 }
13109
13110                 final int status = PackageManager.installStatusToPublicStatus(returnCode);
13111                 switch (status) {
13112                     case PackageInstaller.STATUS_SUCCESS:
13113                         observer.packageMoved(packageName, PackageManager.MOVE_SUCCEEDED);
13114                         break;
13115                     case PackageInstaller.STATUS_FAILURE_STORAGE:
13116                         observer.packageMoved(packageName, PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE);
13117                         break;
13118                     default:
13119                         observer.packageMoved(packageName, PackageManager.MOVE_FAILED_INTERNAL_ERROR);
13120                         break;
13121                 }
13122             }
13123         };
13124
13125         // Treat a move like reinstalling an existing app, which ensures that we
13126         // process everythign uniformly, like unpacking native libraries.
13127         newInstallFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
13128
13129         final Message msg = mHandler.obtainMessage(INIT_COPY);
13130         final OriginInfo origin = OriginInfo.fromExistingFile(codeFile);
13131         msg.obj = new InstallParams(origin, installObserver, newInstallFlags,
13132                 installerPackageName, null, user, packageAbiOverride);
13133         mHandler.sendMessage(msg);
13134     }
13135
13136     @Override
13137     public boolean setInstallLocation(int loc) {
13138         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS,
13139                 null);
13140         if (getInstallLocation() == loc) {
13141             return true;
13142         }
13143         if (loc == PackageHelper.APP_INSTALL_AUTO || loc == PackageHelper.APP_INSTALL_INTERNAL
13144                 || loc == PackageHelper.APP_INSTALL_EXTERNAL) {
13145             android.provider.Settings.Global.putInt(mContext.getContentResolver(),
13146                     android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, loc);
13147             return true;
13148         }
13149         return false;
13150    }
13151
13152     @Override
13153     public int getInstallLocation() {
13154         return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
13155                 android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION,
13156                 PackageHelper.APP_INSTALL_AUTO);
13157     }
13158
13159     /** Called by UserManagerService */
13160     void cleanUpUserLILPw(UserManagerService userManager, int userHandle) {
13161         mDirtyUsers.remove(userHandle);
13162         mSettings.removeUserLPw(userHandle);
13163         mPendingBroadcasts.remove(userHandle);
13164         if (mInstaller != null) {
13165             // Technically, we shouldn't be doing this with the package lock
13166             // held.  However, this is very rare, and there is already so much
13167             // other disk I/O going on, that we'll let it slide for now.
13168             mInstaller.removeUserDataDirs(userHandle);
13169         }
13170         mUserNeedsBadging.delete(userHandle);
13171         removeUnusedPackagesLILPw(userManager, userHandle);
13172     }
13173
13174     /**
13175      * We're removing userHandle and would like to remove any downloaded packages
13176      * that are no longer in use by any other user.
13177      * @param userHandle the user being removed
13178      */
13179     private void removeUnusedPackagesLILPw(UserManagerService userManager, final int userHandle) {
13180         final boolean DEBUG_CLEAN_APKS = false;
13181         int [] users = userManager.getUserIdsLPr();
13182         Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
13183         while (psit.hasNext()) {
13184             PackageSetting ps = psit.next();
13185             if (ps.pkg == null) {
13186                 continue;
13187             }
13188             final String packageName = ps.pkg.packageName;
13189             // Skip over if system app
13190             if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13191                 continue;
13192             }
13193             if (DEBUG_CLEAN_APKS) {
13194                 Slog.i(TAG, "Checking package " + packageName);
13195             }
13196             boolean keep = false;
13197             for (int i = 0; i < users.length; i++) {
13198                 if (users[i] != userHandle && ps.getInstalled(users[i])) {
13199                     keep = true;
13200                     if (DEBUG_CLEAN_APKS) {
13201                         Slog.i(TAG, "  Keeping package " + packageName + " for user "
13202                                 + users[i]);
13203                     }
13204                     break;
13205                 }
13206             }
13207             if (!keep) {
13208                 if (DEBUG_CLEAN_APKS) {
13209                     Slog.i(TAG, "  Removing package " + packageName);
13210                 }
13211                 mHandler.post(new Runnable() {
13212                     public void run() {
13213                         deletePackageX(packageName, userHandle, 0);
13214                     } //end run
13215                 });
13216             }
13217         }
13218     }
13219
13220     /** Called by UserManagerService */
13221     void createNewUserLILPw(int userHandle, File path) {
13222         if (mInstaller != null) {
13223             mInstaller.createUserConfig(userHandle);
13224             mSettings.createNewUserLILPw(this, mInstaller, userHandle, path);
13225         }
13226     }
13227
13228     @Override
13229     public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException {
13230         mContext.enforceCallingOrSelfPermission(
13231                 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
13232                 "Only package verification agents can read the verifier device identity");
13233
13234         synchronized (mPackages) {
13235             return mSettings.getVerifierDeviceIdentityLPw();
13236         }
13237     }
13238
13239     @Override
13240     public void setPermissionEnforced(String permission, boolean enforced) {
13241         mContext.enforceCallingOrSelfPermission(GRANT_REVOKE_PERMISSIONS, null);
13242         if (READ_EXTERNAL_STORAGE.equals(permission)) {
13243             synchronized (mPackages) {
13244                 if (mSettings.mReadExternalStorageEnforced == null
13245                         || mSettings.mReadExternalStorageEnforced != enforced) {
13246                     mSettings.mReadExternalStorageEnforced = enforced;
13247                     mSettings.writeLPr();
13248                 }
13249             }
13250             // kill any non-foreground processes so we restart them and
13251             // grant/revoke the GID.
13252             final IActivityManager am = ActivityManagerNative.getDefault();
13253             if (am != null) {
13254                 final long token = Binder.clearCallingIdentity();
13255                 try {
13256                     am.killProcessesBelowForeground("setPermissionEnforcement");
13257                 } catch (RemoteException e) {
13258                 } finally {
13259                     Binder.restoreCallingIdentity(token);
13260                 }
13261             }
13262         } else {
13263             throw new IllegalArgumentException("No selective enforcement for " + permission);
13264         }
13265     }
13266
13267     @Override
13268     @Deprecated
13269     public boolean isPermissionEnforced(String permission) {
13270         return true;
13271     }
13272
13273     @Override
13274     public boolean isStorageLow() {
13275         final long token = Binder.clearCallingIdentity();
13276         try {
13277             final DeviceStorageMonitorInternal
13278                     dsm = LocalServices.getService(DeviceStorageMonitorInternal.class);
13279             if (dsm != null) {
13280                 return dsm.isMemoryLow();
13281             } else {
13282                 return false;
13283             }
13284         } finally {
13285             Binder.restoreCallingIdentity(token);
13286         }
13287     }
13288
13289     @Override
13290     public IPackageInstaller getPackageInstaller() {
13291         return mInstallerService;
13292     }
13293
13294     private boolean userNeedsBadging(int userId) {
13295         int index = mUserNeedsBadging.indexOfKey(userId);
13296         if (index < 0) {
13297             final UserInfo userInfo;
13298             final long token = Binder.clearCallingIdentity();
13299             try {
13300                 userInfo = sUserManager.getUserInfo(userId);
13301             } finally {
13302                 Binder.restoreCallingIdentity(token);
13303             }
13304             final boolean b;
13305             if (userInfo != null && userInfo.isManagedProfile()) {
13306                 b = true;
13307             } else {
13308                 b = false;
13309             }
13310             mUserNeedsBadging.put(userId, b);
13311             return b;
13312         }
13313         return mUserNeedsBadging.valueAt(index);
13314     }
13315
13316     @Override
13317     public KeySet getKeySetByAlias(String packageName, String alias) {
13318         if (packageName == null || alias == null) {
13319             return null;
13320         }
13321         synchronized(mPackages) {
13322             final PackageParser.Package pkg = mPackages.get(packageName);
13323             if (pkg == null) {
13324                 Slog.w(TAG, "KeySet requested for unknown package:" + packageName);
13325                 throw new IllegalArgumentException("Unknown package: " + packageName);
13326             }
13327             KeySetManagerService ksms = mSettings.mKeySetManagerService;
13328             return new KeySet(ksms.getKeySetByAliasAndPackageNameLPr(packageName, alias));
13329         }
13330     }
13331
13332     @Override
13333     public KeySet getSigningKeySet(String packageName) {
13334         if (packageName == null) {
13335             return null;
13336         }
13337         synchronized(mPackages) {
13338             final PackageParser.Package pkg = mPackages.get(packageName);
13339             if (pkg == null) {
13340                 Slog.w(TAG, "KeySet requested for unknown package:" + packageName);
13341                 throw new IllegalArgumentException("Unknown package: " + packageName);
13342             }
13343             if (pkg.applicationInfo.uid != Binder.getCallingUid()
13344                     && Process.SYSTEM_UID != Binder.getCallingUid()) {
13345                 throw new SecurityException("May not access signing KeySet of other apps.");
13346             }
13347             KeySetManagerService ksms = mSettings.mKeySetManagerService;
13348             return new KeySet(ksms.getSigningKeySetByPackageNameLPr(packageName));
13349         }
13350     }
13351
13352     @Override
13353     public boolean isPackageSignedByKeySet(String packageName, KeySet ks) {
13354         if (packageName == null || ks == null) {
13355             return false;
13356         }
13357         synchronized(mPackages) {
13358             final PackageParser.Package pkg = mPackages.get(packageName);
13359             if (pkg == null) {
13360                 Slog.w(TAG, "KeySet requested for unknown package:" + packageName);
13361                 throw new IllegalArgumentException("Unknown package: " + packageName);
13362             }
13363             IBinder ksh = ks.getToken();
13364             if (ksh instanceof KeySetHandle) {
13365                 KeySetManagerService ksms = mSettings.mKeySetManagerService;
13366                 return ksms.packageIsSignedByLPr(packageName, (KeySetHandle) ksh);
13367             }
13368             return false;
13369         }
13370     }
13371
13372     @Override
13373     public boolean isPackageSignedByKeySetExactly(String packageName, KeySet ks) {
13374         if (packageName == null || ks == null) {
13375             return false;
13376         }
13377         synchronized(mPackages) {
13378             final PackageParser.Package pkg = mPackages.get(packageName);
13379             if (pkg == null) {
13380                 Slog.w(TAG, "KeySet requested for unknown package:" + packageName);
13381                 throw new IllegalArgumentException("Unknown package: " + packageName);
13382             }
13383             IBinder ksh = ks.getToken();
13384             if (ksh instanceof KeySetHandle) {
13385                 KeySetManagerService ksms = mSettings.mKeySetManagerService;
13386                 return ksms.packageIsSignedByExactlyLPr(packageName, (KeySetHandle) ksh);
13387             }
13388             return false;
13389         }
13390     }
13391 }