OSDN Git Service

Merge "Frameworks/base: Right transform in DngCreator" into lmp-mr1-dev
[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.app.usage.UsageStats;
88 import android.app.usage.UsageStatsManager;
89 import android.content.BroadcastReceiver;
90 import android.content.ComponentName;
91 import android.content.Context;
92 import android.content.IIntentReceiver;
93 import android.content.Intent;
94 import android.content.IntentFilter;
95 import android.content.IntentSender;
96 import android.content.IntentSender.SendIntentException;
97 import android.content.ServiceConnection;
98 import android.content.pm.ActivityInfo;
99 import android.content.pm.ApplicationInfo;
100 import android.content.pm.FeatureInfo;
101 import android.content.pm.IPackageDataObserver;
102 import android.content.pm.IPackageDeleteObserver;
103 import android.content.pm.IPackageDeleteObserver2;
104 import android.content.pm.IPackageInstallObserver2;
105 import android.content.pm.IPackageInstaller;
106 import android.content.pm.IPackageManager;
107 import android.content.pm.IPackageMoveObserver;
108 import android.content.pm.IPackageStatsObserver;
109 import android.content.pm.InstrumentationInfo;
110 import android.content.pm.KeySet;
111 import android.content.pm.ManifestDigest;
112 import android.content.pm.PackageCleanItem;
113 import android.content.pm.PackageInfo;
114 import android.content.pm.PackageInfoLite;
115 import android.content.pm.PackageInstaller;
116 import android.content.pm.PackageManager;
117 import android.content.pm.PackageManager.LegacyPackageDeleteObserver;
118 import android.content.pm.PackageParser.ActivityIntentInfo;
119 import android.content.pm.PackageParser.PackageLite;
120 import android.content.pm.PackageParser.PackageParserException;
121 import android.content.pm.PackageParser;
122 import android.content.pm.PackageStats;
123 import android.content.pm.PackageUserState;
124 import android.content.pm.ParceledListSlice;
125 import android.content.pm.PermissionGroupInfo;
126 import android.content.pm.PermissionInfo;
127 import android.content.pm.ProviderInfo;
128 import android.content.pm.ResolveInfo;
129 import android.content.pm.ServiceInfo;
130 import android.content.pm.Signature;
131 import android.content.pm.UserInfo;
132 import android.content.pm.VerificationParams;
133 import android.content.pm.VerifierDeviceIdentity;
134 import android.content.pm.VerifierInfo;
135 import android.content.res.Resources;
136 import android.hardware.display.DisplayManager;
137 import android.net.Uri;
138 import android.os.Binder;
139 import android.os.Build;
140 import android.os.Bundle;
141 import android.os.Environment;
142 import android.os.Environment.UserEnvironment;
143 import android.os.storage.StorageManager;
144 import android.os.Debug;
145 import android.os.FileUtils;
146 import android.os.Handler;
147 import android.os.IBinder;
148 import android.os.Looper;
149 import android.os.Message;
150 import android.os.Parcel;
151 import android.os.ParcelFileDescriptor;
152 import android.os.Process;
153 import android.os.RemoteException;
154 import android.os.SELinux;
155 import android.os.ServiceManager;
156 import android.os.SystemClock;
157 import android.os.SystemProperties;
158 import android.os.UserHandle;
159 import android.os.UserManager;
160 import android.security.KeyStore;
161 import android.security.SystemKeyStore;
162 import android.system.ErrnoException;
163 import android.system.Os;
164 import android.system.StructStat;
165 import android.text.TextUtils;
166 import android.util.ArraySet;
167 import android.util.AtomicFile;
168 import android.util.DisplayMetrics;
169 import android.util.EventLog;
170 import android.util.ExceptionUtils;
171 import android.util.Log;
172 import android.util.LogPrinter;
173 import android.util.PrintStreamPrinter;
174 import android.util.Slog;
175 import android.util.SparseArray;
176 import android.util.SparseBooleanArray;
177 import android.view.Display;
178
179 import java.io.BufferedInputStream;
180 import java.io.BufferedOutputStream;
181 import java.io.BufferedReader;
182 import java.io.File;
183 import java.io.FileDescriptor;
184 import java.io.FileInputStream;
185 import java.io.FileNotFoundException;
186 import java.io.FileOutputStream;
187 import java.io.FileReader;
188 import java.io.FilenameFilter;
189 import java.io.IOException;
190 import java.io.InputStream;
191 import java.io.PrintWriter;
192 import java.nio.charset.StandardCharsets;
193 import java.security.NoSuchAlgorithmException;
194 import java.security.PublicKey;
195 import java.security.cert.CertificateEncodingException;
196 import java.security.cert.CertificateException;
197 import java.text.SimpleDateFormat;
198 import java.util.ArrayList;
199 import java.util.Arrays;
200 import java.util.Collection;
201 import java.util.Collections;
202 import java.util.Comparator;
203 import java.util.Date;
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 long mDexOptLRUThresholdInMills;
333     final DisplayMetrics mMetrics;
334     final int mDefParseFlags;
335     final String[] mSeparateProcesses;
336     final boolean mIsUpgrade;
337
338     // This is where all application persistent data goes.
339     final File mAppDataDir;
340
341     // This is where all application persistent data goes for secondary users.
342     final File mUserAppDataDir;
343
344     /** The location for ASEC container files on internal storage. */
345     final String mAsecInternalPath;
346
347     // Used for privilege escalation. MUST NOT BE CALLED WITH mPackages
348     // LOCK HELD.  Can be called with mInstallLock held.
349     final Installer mInstaller;
350
351     /** Directory where installed third-party apps stored */
352     final File mAppInstallDir;
353
354     /**
355      * Directory to which applications installed internally have their
356      * 32 bit native libraries copied.
357      */
358     private File mAppLib32InstallDir;
359
360     // Directory containing the private parts (e.g. code and non-resource assets) of forward-locked
361     // apps.
362     final File mDrmAppPrivateInstallDir;
363
364     // ----------------------------------------------------------------
365
366     // Lock for state used when installing and doing other long running
367     // operations.  Methods that must be called with this lock held have
368     // the suffix "LI".
369     final Object mInstallLock = new Object();
370
371     // ----------------------------------------------------------------
372
373     // Keys are String (package name), values are Package.  This also serves
374     // as the lock for the global state.  Methods that must be called with
375     // this lock held have the prefix "LP".
376     final ArrayMap<String, PackageParser.Package> mPackages =
377             new ArrayMap<String, PackageParser.Package>();
378
379     // Tracks available target package names -> overlay package paths.
380     final ArrayMap<String, ArrayMap<String, PackageParser.Package>> mOverlays =
381         new ArrayMap<String, ArrayMap<String, PackageParser.Package>>();
382
383     final Settings mSettings;
384     boolean mRestoredSettings;
385
386     // System configuration read by SystemConfig.
387     final int[] mGlobalGids;
388     final SparseArray<ArraySet<String>> mSystemPermissions;
389     final ArrayMap<String, FeatureInfo> mAvailableFeatures;
390
391     // If mac_permissions.xml was found for seinfo labeling.
392     boolean mFoundPolicyFile;
393
394     // If a recursive restorecon of /data/data/<pkg> is needed.
395     private boolean mShouldRestoreconData = SELinuxMMAC.shouldRestorecon();
396
397     public static final class SharedLibraryEntry {
398         public final String path;
399         public final String apk;
400
401         SharedLibraryEntry(String _path, String _apk) {
402             path = _path;
403             apk = _apk;
404         }
405     }
406
407     // Currently known shared libraries.
408     final ArrayMap<String, SharedLibraryEntry> mSharedLibraries =
409             new ArrayMap<String, SharedLibraryEntry>();
410
411     // All available activities, for your resolving pleasure.
412     final ActivityIntentResolver mActivities =
413             new ActivityIntentResolver();
414
415     // All available receivers, for your resolving pleasure.
416     final ActivityIntentResolver mReceivers =
417             new ActivityIntentResolver();
418
419     // All available services, for your resolving pleasure.
420     final ServiceIntentResolver mServices = new ServiceIntentResolver();
421
422     // All available providers, for your resolving pleasure.
423     final ProviderIntentResolver mProviders = new ProviderIntentResolver();
424
425     // Mapping from provider base names (first directory in content URI codePath)
426     // to the provider information.
427     final ArrayMap<String, PackageParser.Provider> mProvidersByAuthority =
428             new ArrayMap<String, PackageParser.Provider>();
429
430     // Mapping from instrumentation class names to info about them.
431     final ArrayMap<ComponentName, PackageParser.Instrumentation> mInstrumentation =
432             new ArrayMap<ComponentName, PackageParser.Instrumentation>();
433
434     // Mapping from permission names to info about them.
435     final ArrayMap<String, PackageParser.PermissionGroup> mPermissionGroups =
436             new ArrayMap<String, PackageParser.PermissionGroup>();
437
438     // Packages whose data we have transfered into another package, thus
439     // should no longer exist.
440     final ArraySet<String> mTransferedPackages = new ArraySet<String>();
441     
442     // Broadcast actions that are only available to the system.
443     final ArraySet<String> mProtectedBroadcasts = new ArraySet<String>();
444
445     /** List of packages waiting for verification. */
446     final SparseArray<PackageVerificationState> mPendingVerification
447             = new SparseArray<PackageVerificationState>();
448
449     /** Set of packages associated with each app op permission. */
450     final ArrayMap<String, ArraySet<String>> mAppOpPermissionPackages = new ArrayMap<>();
451
452     final PackageInstallerService mInstallerService;
453
454     ArraySet<PackageParser.Package> mDeferredDexOpt = null;
455
456     // Cache of users who need badging.
457     SparseBooleanArray mUserNeedsBadging = new SparseBooleanArray();
458
459     /** Token for keys in mPendingVerification. */
460     private int mPendingVerificationToken = 0;
461
462     volatile boolean mSystemReady;
463     volatile boolean mSafeMode;
464     volatile boolean mHasSystemUidErrors;
465
466     ApplicationInfo mAndroidApplication;
467     final ActivityInfo mResolveActivity = new ActivityInfo();
468     final ResolveInfo mResolveInfo = new ResolveInfo();
469     ComponentName mResolveComponentName;
470     PackageParser.Package mPlatformPackage;
471     ComponentName mCustomResolverComponentName;
472
473     boolean mResolverReplaced = false;
474
475     // Set of pending broadcasts for aggregating enable/disable of components.
476     static class PendingPackageBroadcasts {
477         // for each user id, a map of <package name -> components within that package>
478         final SparseArray<ArrayMap<String, ArrayList<String>>> mUidMap;
479
480         public PendingPackageBroadcasts() {
481             mUidMap = new SparseArray<ArrayMap<String, ArrayList<String>>>(2);
482         }
483
484         public ArrayList<String> get(int userId, String packageName) {
485             ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId);
486             return packages.get(packageName);
487         }
488
489         public void put(int userId, String packageName, ArrayList<String> components) {
490             ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId);
491             packages.put(packageName, components);
492         }
493
494         public void remove(int userId, String packageName) {
495             ArrayMap<String, ArrayList<String>> packages = mUidMap.get(userId);
496             if (packages != null) {
497                 packages.remove(packageName);
498             }
499         }
500
501         public void remove(int userId) {
502             mUidMap.remove(userId);
503         }
504
505         public int userIdCount() {
506             return mUidMap.size();
507         }
508
509         public int userIdAt(int n) {
510             return mUidMap.keyAt(n);
511         }
512
513         public ArrayMap<String, ArrayList<String>> packagesForUserId(int userId) {
514             return mUidMap.get(userId);
515         }
516
517         public int size() {
518             // total number of pending broadcast entries across all userIds
519             int num = 0;
520             for (int i = 0; i< mUidMap.size(); i++) {
521                 num += mUidMap.valueAt(i).size();
522             }
523             return num;
524         }
525
526         public void clear() {
527             mUidMap.clear();
528         }
529
530         private ArrayMap<String, ArrayList<String>> getOrAllocate(int userId) {
531             ArrayMap<String, ArrayList<String>> map = mUidMap.get(userId);
532             if (map == null) {
533                 map = new ArrayMap<String, ArrayList<String>>();
534                 mUidMap.put(userId, map);
535             }
536             return map;
537         }
538     }
539     final PendingPackageBroadcasts mPendingBroadcasts = new PendingPackageBroadcasts();
540
541     // Service Connection to remote media container service to copy
542     // package uri's from external media onto secure containers
543     // or internal storage.
544     private IMediaContainerService mContainerService = null;
545
546     static final int SEND_PENDING_BROADCAST = 1;
547     static final int MCS_BOUND = 3;
548     static final int END_COPY = 4;
549     static final int INIT_COPY = 5;
550     static final int MCS_UNBIND = 6;
551     static final int START_CLEANING_PACKAGE = 7;
552     static final int FIND_INSTALL_LOC = 8;
553     static final int POST_INSTALL = 9;
554     static final int MCS_RECONNECT = 10;
555     static final int MCS_GIVE_UP = 11;
556     static final int UPDATED_MEDIA_STATUS = 12;
557     static final int WRITE_SETTINGS = 13;
558     static final int WRITE_PACKAGE_RESTRICTIONS = 14;
559     static final int PACKAGE_VERIFIED = 15;
560     static final int CHECK_PENDING_VERIFICATION = 16;
561
562     static final int WRITE_SETTINGS_DELAY = 10*1000;  // 10 seconds
563
564     // Delay time in millisecs
565     static final int BROADCAST_DELAY = 10 * 1000;
566
567     static UserManagerService sUserManager;
568
569     // Stores a list of users whose package restrictions file needs to be updated
570     private ArraySet<Integer> mDirtyUsers = new ArraySet<Integer>();
571
572     final private DefaultContainerConnection mDefContainerConn =
573             new DefaultContainerConnection();
574     class DefaultContainerConnection implements ServiceConnection {
575         public void onServiceConnected(ComponentName name, IBinder service) {
576             if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceConnected");
577             IMediaContainerService imcs =
578                 IMediaContainerService.Stub.asInterface(service);
579             mHandler.sendMessage(mHandler.obtainMessage(MCS_BOUND, imcs));
580         }
581
582         public void onServiceDisconnected(ComponentName name) {
583             if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceDisconnected");
584         }
585     };
586
587     // Recordkeeping of restore-after-install operations that are currently in flight
588     // between the Package Manager and the Backup Manager
589     class PostInstallData {
590         public InstallArgs args;
591         public PackageInstalledInfo res;
592
593         PostInstallData(InstallArgs _a, PackageInstalledInfo _r) {
594             args = _a;
595             res = _r;
596         }
597     };
598     final SparseArray<PostInstallData> mRunningInstalls = new SparseArray<PostInstallData>();
599     int mNextInstallToken = 1;  // nonzero; will be wrapped back to 1 when ++ overflows
600
601     private final String mRequiredVerifierPackage;
602
603     private final PackageUsage mPackageUsage = new PackageUsage();
604
605     private class PackageUsage {
606         private static final int WRITE_INTERVAL
607             = (DEBUG_DEXOPT) ? 0 : 30*60*1000; // 30m in ms
608
609         private final Object mFileLock = new Object();
610         private final AtomicLong mLastWritten = new AtomicLong(0);
611         private final AtomicBoolean mBackgroundWriteRunning = new AtomicBoolean(false);
612
613         private boolean mIsHistoricalPackageUsageAvailable = true;
614
615         boolean isHistoricalPackageUsageAvailable() {
616             return mIsHistoricalPackageUsageAvailable;
617         }
618
619         void write(boolean force) {
620             if (force) {
621                 writeInternal();
622                 return;
623             }
624             if (SystemClock.elapsedRealtime() - mLastWritten.get() < WRITE_INTERVAL
625                 && !DEBUG_DEXOPT) {
626                 return;
627             }
628             if (mBackgroundWriteRunning.compareAndSet(false, true)) {
629                 new Thread("PackageUsage_DiskWriter") {
630                     @Override
631                     public void run() {
632                         try {
633                             writeInternal();
634                         } finally {
635                             mBackgroundWriteRunning.set(false);
636                         }
637                     }
638                 }.start();
639             }
640         }
641
642         private void writeInternal() {
643             synchronized (mPackages) {
644                 synchronized (mFileLock) {
645                     AtomicFile file = getFile();
646                     FileOutputStream f = null;
647                     try {
648                         f = file.startWrite();
649                         BufferedOutputStream out = new BufferedOutputStream(f);
650                         FileUtils.setPermissions(file.getBaseFile().getPath(), 0660, SYSTEM_UID, PACKAGE_INFO_GID);
651                         StringBuilder sb = new StringBuilder();
652                         for (PackageParser.Package pkg : mPackages.values()) {
653                             if (pkg.mLastPackageUsageTimeInMills == 0) {
654                                 continue;
655                             }
656                             sb.setLength(0);
657                             sb.append(pkg.packageName);
658                             sb.append(' ');
659                             sb.append((long)pkg.mLastPackageUsageTimeInMills);
660                             sb.append('\n');
661                             out.write(sb.toString().getBytes(StandardCharsets.US_ASCII));
662                         }
663                         out.flush();
664                         file.finishWrite(f);
665                     } catch (IOException e) {
666                         if (f != null) {
667                             file.failWrite(f);
668                         }
669                         Log.e(TAG, "Failed to write package usage times", e);
670                     }
671                 }
672             }
673             mLastWritten.set(SystemClock.elapsedRealtime());
674         }
675
676         void readLP() {
677             synchronized (mFileLock) {
678                 AtomicFile file = getFile();
679                 BufferedInputStream in = null;
680                 try {
681                     in = new BufferedInputStream(file.openRead());
682                     StringBuffer sb = new StringBuffer();
683                     while (true) {
684                         String packageName = readToken(in, sb, ' ');
685                         if (packageName == null) {
686                             break;
687                         }
688                         String timeInMillisString = readToken(in, sb, '\n');
689                         if (timeInMillisString == null) {
690                             throw new IOException("Failed to find last usage time for package "
691                                                   + packageName);
692                         }
693                         PackageParser.Package pkg = mPackages.get(packageName);
694                         if (pkg == null) {
695                             continue;
696                         }
697                         long timeInMillis;
698                         try {
699                             timeInMillis = Long.parseLong(timeInMillisString.toString());
700                         } catch (NumberFormatException e) {
701                             throw new IOException("Failed to parse " + timeInMillisString
702                                                   + " as a long.", e);
703                         }
704                         pkg.mLastPackageUsageTimeInMills = timeInMillis;
705                     }
706                 } catch (FileNotFoundException expected) {
707                     mIsHistoricalPackageUsageAvailable = false;
708                 } catch (IOException e) {
709                     Log.w(TAG, "Failed to read package usage times", e);
710                 } finally {
711                     IoUtils.closeQuietly(in);
712                 }
713             }
714             mLastWritten.set(SystemClock.elapsedRealtime());
715         }
716
717         private String readToken(InputStream in, StringBuffer sb, char endOfToken)
718                 throws IOException {
719             sb.setLength(0);
720             while (true) {
721                 int ch = in.read();
722                 if (ch == -1) {
723                     if (sb.length() == 0) {
724                         return null;
725                     }
726                     throw new IOException("Unexpected EOF");
727                 }
728                 if (ch == endOfToken) {
729                     return sb.toString();
730                 }
731                 sb.append((char)ch);
732             }
733         }
734
735         private AtomicFile getFile() {
736             File dataDir = Environment.getDataDirectory();
737             File systemDir = new File(dataDir, "system");
738             File fname = new File(systemDir, "package-usage.list");
739             return new AtomicFile(fname);
740         }
741     }
742
743     class PackageHandler extends Handler {
744         private boolean mBound = false;
745         final ArrayList<HandlerParams> mPendingInstalls =
746             new ArrayList<HandlerParams>();
747
748         private boolean connectToService() {
749             if (DEBUG_SD_INSTALL) Log.i(TAG, "Trying to bind to" +
750                     " DefaultContainerService");
751             Intent service = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
752             Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
753             if (mContext.bindServiceAsUser(service, mDefContainerConn,
754                     Context.BIND_AUTO_CREATE, UserHandle.OWNER)) {
755                 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
756                 mBound = true;
757                 return true;
758             }
759             Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
760             return false;
761         }
762
763         private void disconnectService() {
764             mContainerService = null;
765             mBound = false;
766             Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
767             mContext.unbindService(mDefContainerConn);
768             Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
769         }
770
771         PackageHandler(Looper looper) {
772             super(looper);
773         }
774
775         public void handleMessage(Message msg) {
776             try {
777                 doHandleMessage(msg);
778             } finally {
779                 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
780             }
781         }
782         
783         void doHandleMessage(Message msg) {
784             switch (msg.what) {
785                 case INIT_COPY: {
786                     HandlerParams params = (HandlerParams) msg.obj;
787                     int idx = mPendingInstalls.size();
788                     if (DEBUG_INSTALL) Slog.i(TAG, "init_copy idx=" + idx + ": " + params);
789                     // If a bind was already initiated we dont really
790                     // need to do anything. The pending install
791                     // will be processed later on.
792                     if (!mBound) {
793                         // If this is the only one pending we might
794                         // have to bind to the service again.
795                         if (!connectToService()) {
796                             Slog.e(TAG, "Failed to bind to media container service");
797                             params.serviceError();
798                             return;
799                         } else {
800                             // Once we bind to the service, the first
801                             // pending request will be processed.
802                             mPendingInstalls.add(idx, params);
803                         }
804                     } else {
805                         mPendingInstalls.add(idx, params);
806                         // Already bound to the service. Just make
807                         // sure we trigger off processing the first request.
808                         if (idx == 0) {
809                             mHandler.sendEmptyMessage(MCS_BOUND);
810                         }
811                     }
812                     break;
813                 }
814                 case MCS_BOUND: {
815                     if (DEBUG_INSTALL) Slog.i(TAG, "mcs_bound");
816                     if (msg.obj != null) {
817                         mContainerService = (IMediaContainerService) msg.obj;
818                     }
819                     if (mContainerService == null) {
820                         // Something seriously wrong. Bail out
821                         Slog.e(TAG, "Cannot bind to media container service");
822                         for (HandlerParams params : mPendingInstalls) {
823                             // Indicate service bind error
824                             params.serviceError();
825                         }
826                         mPendingInstalls.clear();
827                     } else if (mPendingInstalls.size() > 0) {
828                         HandlerParams params = mPendingInstalls.get(0);
829                         if (params != null) {
830                             if (params.startCopy()) {
831                                 // We are done...  look for more work or to
832                                 // go idle.
833                                 if (DEBUG_SD_INSTALL) Log.i(TAG,
834                                         "Checking for more work or unbind...");
835                                 // Delete pending install
836                                 if (mPendingInstalls.size() > 0) {
837                                     mPendingInstalls.remove(0);
838                                 }
839                                 if (mPendingInstalls.size() == 0) {
840                                     if (mBound) {
841                                         if (DEBUG_SD_INSTALL) Log.i(TAG,
842                                                 "Posting delayed MCS_UNBIND");
843                                         removeMessages(MCS_UNBIND);
844                                         Message ubmsg = obtainMessage(MCS_UNBIND);
845                                         // Unbind after a little delay, to avoid
846                                         // continual thrashing.
847                                         sendMessageDelayed(ubmsg, 10000);
848                                     }
849                                 } else {
850                                     // There are more pending requests in queue.
851                                     // Just post MCS_BOUND message to trigger processing
852                                     // of next pending install.
853                                     if (DEBUG_SD_INSTALL) Log.i(TAG,
854                                             "Posting MCS_BOUND for next work");
855                                     mHandler.sendEmptyMessage(MCS_BOUND);
856                                 }
857                             }
858                         }
859                     } else {
860                         // Should never happen ideally.
861                         Slog.w(TAG, "Empty queue");
862                     }
863                     break;
864                 }
865                 case MCS_RECONNECT: {
866                     if (DEBUG_INSTALL) Slog.i(TAG, "mcs_reconnect");
867                     if (mPendingInstalls.size() > 0) {
868                         if (mBound) {
869                             disconnectService();
870                         }
871                         if (!connectToService()) {
872                             Slog.e(TAG, "Failed to bind to media container service");
873                             for (HandlerParams params : mPendingInstalls) {
874                                 // Indicate service bind error
875                                 params.serviceError();
876                             }
877                             mPendingInstalls.clear();
878                         }
879                     }
880                     break;
881                 }
882                 case MCS_UNBIND: {
883                     // If there is no actual work left, then time to unbind.
884                     if (DEBUG_INSTALL) Slog.i(TAG, "mcs_unbind");
885
886                     if (mPendingInstalls.size() == 0 && mPendingVerification.size() == 0) {
887                         if (mBound) {
888                             if (DEBUG_INSTALL) Slog.i(TAG, "calling disconnectService()");
889
890                             disconnectService();
891                         }
892                     } else if (mPendingInstalls.size() > 0) {
893                         // There are more pending requests in queue.
894                         // Just post MCS_BOUND message to trigger processing
895                         // of next pending install.
896                         mHandler.sendEmptyMessage(MCS_BOUND);
897                     }
898
899                     break;
900                 }
901                 case MCS_GIVE_UP: {
902                     if (DEBUG_INSTALL) Slog.i(TAG, "mcs_giveup too many retries");
903                     mPendingInstalls.remove(0);
904                     break;
905                 }
906                 case SEND_PENDING_BROADCAST: {
907                     String packages[];
908                     ArrayList<String> components[];
909                     int size = 0;
910                     int uids[];
911                     Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
912                     synchronized (mPackages) {
913                         if (mPendingBroadcasts == null) {
914                             return;
915                         }
916                         size = mPendingBroadcasts.size();
917                         if (size <= 0) {
918                             // Nothing to be done. Just return
919                             return;
920                         }
921                         packages = new String[size];
922                         components = new ArrayList[size];
923                         uids = new int[size];
924                         int i = 0;  // filling out the above arrays
925
926                         for (int n = 0; n < mPendingBroadcasts.userIdCount(); n++) {
927                             int packageUserId = mPendingBroadcasts.userIdAt(n);
928                             Iterator<Map.Entry<String, ArrayList<String>>> it
929                                     = mPendingBroadcasts.packagesForUserId(packageUserId)
930                                             .entrySet().iterator();
931                             while (it.hasNext() && i < size) {
932                                 Map.Entry<String, ArrayList<String>> ent = it.next();
933                                 packages[i] = ent.getKey();
934                                 components[i] = ent.getValue();
935                                 PackageSetting ps = mSettings.mPackages.get(ent.getKey());
936                                 uids[i] = (ps != null)
937                                         ? UserHandle.getUid(packageUserId, ps.appId)
938                                         : -1;
939                                 i++;
940                             }
941                         }
942                         size = i;
943                         mPendingBroadcasts.clear();
944                     }
945                     // Send broadcasts
946                     for (int i = 0; i < size; i++) {
947                         sendPackageChangedBroadcast(packages[i], true, components[i], uids[i]);
948                     }
949                     Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
950                     break;
951                 }
952                 case START_CLEANING_PACKAGE: {
953                     Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
954                     final String packageName = (String)msg.obj;
955                     final int userId = msg.arg1;
956                     final boolean andCode = msg.arg2 != 0;
957                     synchronized (mPackages) {
958                         if (userId == UserHandle.USER_ALL) {
959                             int[] users = sUserManager.getUserIds();
960                             for (int user : users) {
961                                 mSettings.addPackageToCleanLPw(
962                                         new PackageCleanItem(user, packageName, andCode));
963                             }
964                         } else {
965                             mSettings.addPackageToCleanLPw(
966                                     new PackageCleanItem(userId, packageName, andCode));
967                         }
968                     }
969                     Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
970                     startCleaningPackages();
971                 } break;
972                 case POST_INSTALL: {
973                     if (DEBUG_INSTALL) Log.v(TAG, "Handling post-install for " + msg.arg1);
974                     PostInstallData data = mRunningInstalls.get(msg.arg1);
975                     mRunningInstalls.delete(msg.arg1);
976                     boolean deleteOld = false;
977
978                     if (data != null) {
979                         InstallArgs args = data.args;
980                         PackageInstalledInfo res = data.res;
981
982                         if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
983                             res.removedInfo.sendBroadcast(false, true, false);
984                             Bundle extras = new Bundle(1);
985                             extras.putInt(Intent.EXTRA_UID, res.uid);
986                             // Determine the set of users who are adding this
987                             // package for the first time vs. those who are seeing
988                             // an update.
989                             int[] firstUsers;
990                             int[] updateUsers = new int[0];
991                             if (res.origUsers == null || res.origUsers.length == 0) {
992                                 firstUsers = res.newUsers;
993                             } else {
994                                 firstUsers = new int[0];
995                                 for (int i=0; i<res.newUsers.length; i++) {
996                                     int user = res.newUsers[i];
997                                     boolean isNew = true;
998                                     for (int j=0; j<res.origUsers.length; j++) {
999                                         if (res.origUsers[j] == user) {
1000                                             isNew = false;
1001                                             break;
1002                                         }
1003                                     }
1004                                     if (isNew) {
1005                                         int[] newFirst = new int[firstUsers.length+1];
1006                                         System.arraycopy(firstUsers, 0, newFirst, 0,
1007                                                 firstUsers.length);
1008                                         newFirst[firstUsers.length] = user;
1009                                         firstUsers = newFirst;
1010                                     } else {
1011                                         int[] newUpdate = new int[updateUsers.length+1];
1012                                         System.arraycopy(updateUsers, 0, newUpdate, 0,
1013                                                 updateUsers.length);
1014                                         newUpdate[updateUsers.length] = user;
1015                                         updateUsers = newUpdate;
1016                                     }
1017                                 }
1018                             }
1019                             sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
1020                                     res.pkg.applicationInfo.packageName,
1021                                     extras, null, null, firstUsers);
1022                             final boolean update = res.removedInfo.removedPackage != null;
1023                             if (update) {
1024                                 extras.putBoolean(Intent.EXTRA_REPLACING, true);
1025                             }
1026                             sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
1027                                     res.pkg.applicationInfo.packageName,
1028                                     extras, null, null, updateUsers);
1029                             if (update) {
1030                                 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
1031                                         res.pkg.applicationInfo.packageName,
1032                                         extras, null, null, updateUsers);
1033                                 sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
1034                                         null, null,
1035                                         res.pkg.applicationInfo.packageName, null, updateUsers);
1036
1037                                 // treat asec-hosted packages like removable media on upgrade
1038                                 if (isForwardLocked(res.pkg) || isExternal(res.pkg)) {
1039                                     if (DEBUG_INSTALL) {
1040                                         Slog.i(TAG, "upgrading pkg " + res.pkg
1041                                                 + " is ASEC-hosted -> AVAILABLE");
1042                                     }
1043                                     int[] uidArray = new int[] { res.pkg.applicationInfo.uid };
1044                                     ArrayList<String> pkgList = new ArrayList<String>(1);
1045                                     pkgList.add(res.pkg.applicationInfo.packageName);
1046                                     sendResourcesChangedBroadcast(true, true,
1047                                             pkgList,uidArray, null);
1048                                 }
1049                             }
1050                             if (res.removedInfo.args != null) {
1051                                 // Remove the replaced package's older resources safely now
1052                                 deleteOld = true;
1053                             }
1054
1055                             // Log current value of "unknown sources" setting
1056                             EventLog.writeEvent(EventLogTags.UNKNOWN_SOURCES_ENABLED,
1057                                 getUnknownSourcesSettings());
1058                         }
1059                         // Force a gc to clear up things
1060                         Runtime.getRuntime().gc();
1061                         // We delete after a gc for applications  on sdcard.
1062                         if (deleteOld) {
1063                             synchronized (mInstallLock) {
1064                                 res.removedInfo.args.doPostDeleteLI(true);
1065                             }
1066                         }
1067                         if (args.observer != null) {
1068                             try {
1069                                 Bundle extras = extrasForInstallResult(res);
1070                                 args.observer.onPackageInstalled(res.name, res.returnCode,
1071                                         res.returnMsg, extras);
1072                             } catch (RemoteException e) {
1073                                 Slog.i(TAG, "Observer no longer exists.");
1074                             }
1075                         }
1076                     } else {
1077                         Slog.e(TAG, "Bogus post-install token " + msg.arg1);
1078                     }
1079                 } break;
1080                 case UPDATED_MEDIA_STATUS: {
1081                     if (DEBUG_SD_INSTALL) Log.i(TAG, "Got message UPDATED_MEDIA_STATUS");
1082                     boolean reportStatus = msg.arg1 == 1;
1083                     boolean doGc = msg.arg2 == 1;
1084                     if (DEBUG_SD_INSTALL) Log.i(TAG, "reportStatus=" + reportStatus + ", doGc = " + doGc);
1085                     if (doGc) {
1086                         // Force a gc to clear up stale containers.
1087                         Runtime.getRuntime().gc();
1088                     }
1089                     if (msg.obj != null) {
1090                         @SuppressWarnings("unchecked")
1091                         Set<AsecInstallArgs> args = (Set<AsecInstallArgs>) msg.obj;
1092                         if (DEBUG_SD_INSTALL) Log.i(TAG, "Unloading all containers");
1093                         // Unload containers
1094                         unloadAllContainers(args);
1095                     }
1096                     if (reportStatus) {
1097                         try {
1098                             if (DEBUG_SD_INSTALL) Log.i(TAG, "Invoking MountService call back");
1099                             PackageHelper.getMountService().finishMediaUpdate();
1100                         } catch (RemoteException e) {
1101                             Log.e(TAG, "MountService not running?");
1102                         }
1103                     }
1104                 } break;
1105                 case WRITE_SETTINGS: {
1106                     Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1107                     synchronized (mPackages) {
1108                         removeMessages(WRITE_SETTINGS);
1109                         removeMessages(WRITE_PACKAGE_RESTRICTIONS);
1110                         mSettings.writeLPr();
1111                         mDirtyUsers.clear();
1112                     }
1113                     Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1114                 } break;
1115                 case WRITE_PACKAGE_RESTRICTIONS: {
1116                     Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1117                     synchronized (mPackages) {
1118                         removeMessages(WRITE_PACKAGE_RESTRICTIONS);
1119                         for (int userId : mDirtyUsers) {
1120                             mSettings.writePackageRestrictionsLPr(userId);
1121                         }
1122                         mDirtyUsers.clear();
1123                     }
1124                     Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1125                 } break;
1126                 case CHECK_PENDING_VERIFICATION: {
1127                     final int verificationId = msg.arg1;
1128                     final PackageVerificationState state = mPendingVerification.get(verificationId);
1129
1130                     if ((state != null) && !state.timeoutExtended()) {
1131                         final InstallArgs args = state.getInstallArgs();
1132                         final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
1133
1134                         Slog.i(TAG, "Verification timed out for " + originUri);
1135                         mPendingVerification.remove(verificationId);
1136
1137                         int ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
1138
1139                         if (getDefaultVerificationResponse() == PackageManager.VERIFICATION_ALLOW) {
1140                             Slog.i(TAG, "Continuing with installation of " + originUri);
1141                             state.setVerifierResponse(Binder.getCallingUid(),
1142                                     PackageManager.VERIFICATION_ALLOW_WITHOUT_SUFFICIENT);
1143                             broadcastPackageVerified(verificationId, originUri,
1144                                     PackageManager.VERIFICATION_ALLOW,
1145                                     state.getInstallArgs().getUser());
1146                             try {
1147                                 ret = args.copyApk(mContainerService, true);
1148                             } catch (RemoteException e) {
1149                                 Slog.e(TAG, "Could not contact the ContainerService");
1150                             }
1151                         } else {
1152                             broadcastPackageVerified(verificationId, originUri,
1153                                     PackageManager.VERIFICATION_REJECT,
1154                                     state.getInstallArgs().getUser());
1155                         }
1156
1157                         processPendingInstall(args, ret);
1158                         mHandler.sendEmptyMessage(MCS_UNBIND);
1159                     }
1160                     break;
1161                 }
1162                 case PACKAGE_VERIFIED: {
1163                     final int verificationId = msg.arg1;
1164
1165                     final PackageVerificationState state = mPendingVerification.get(verificationId);
1166                     if (state == null) {
1167                         Slog.w(TAG, "Invalid verification token " + verificationId + " received");
1168                         break;
1169                     }
1170
1171                     final PackageVerificationResponse response = (PackageVerificationResponse) msg.obj;
1172
1173                     state.setVerifierResponse(response.callerUid, response.code);
1174
1175                     if (state.isVerificationComplete()) {
1176                         mPendingVerification.remove(verificationId);
1177
1178                         final InstallArgs args = state.getInstallArgs();
1179                         final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
1180
1181                         int ret;
1182                         if (state.isInstallAllowed()) {
1183                             ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
1184                             broadcastPackageVerified(verificationId, originUri,
1185                                     response.code, state.getInstallArgs().getUser());
1186                             try {
1187                                 ret = args.copyApk(mContainerService, true);
1188                             } catch (RemoteException e) {
1189                                 Slog.e(TAG, "Could not contact the ContainerService");
1190                             }
1191                         } else {
1192                             ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
1193                         }
1194
1195                         processPendingInstall(args, ret);
1196
1197                         mHandler.sendEmptyMessage(MCS_UNBIND);
1198                     }
1199
1200                     break;
1201                 }
1202             }
1203         }
1204     }
1205
1206     Bundle extrasForInstallResult(PackageInstalledInfo res) {
1207         Bundle extras = null;
1208         switch (res.returnCode) {
1209             case PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION: {
1210                 extras = new Bundle();
1211                 extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PERMISSION,
1212                         res.origPermission);
1213                 extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PACKAGE,
1214                         res.origPackage);
1215                 break;
1216             }
1217         }
1218         return extras;
1219     }
1220
1221     void scheduleWriteSettingsLocked() {
1222         if (!mHandler.hasMessages(WRITE_SETTINGS)) {
1223             mHandler.sendEmptyMessageDelayed(WRITE_SETTINGS, WRITE_SETTINGS_DELAY);
1224         }
1225     }
1226
1227     void scheduleWritePackageRestrictionsLocked(int userId) {
1228         if (!sUserManager.exists(userId)) return;
1229         mDirtyUsers.add(userId);
1230         if (!mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) {
1231             mHandler.sendEmptyMessageDelayed(WRITE_PACKAGE_RESTRICTIONS, WRITE_SETTINGS_DELAY);
1232         }
1233     }
1234
1235     public static final PackageManagerService main(Context context, Installer installer,
1236             boolean factoryTest, boolean onlyCore) {
1237         PackageManagerService m = new PackageManagerService(context, installer,
1238                 factoryTest, onlyCore);
1239         ServiceManager.addService("package", m);
1240         return m;
1241     }
1242
1243     static String[] splitString(String str, char sep) {
1244         int count = 1;
1245         int i = 0;
1246         while ((i=str.indexOf(sep, i)) >= 0) {
1247             count++;
1248             i++;
1249         }
1250
1251         String[] res = new String[count];
1252         i=0;
1253         count = 0;
1254         int lastI=0;
1255         while ((i=str.indexOf(sep, i)) >= 0) {
1256             res[count] = str.substring(lastI, i);
1257             count++;
1258             i++;
1259             lastI = i;
1260         }
1261         res[count] = str.substring(lastI, str.length());
1262         return res;
1263     }
1264
1265     private static void getDefaultDisplayMetrics(Context context, DisplayMetrics metrics) {
1266         DisplayManager displayManager = (DisplayManager) context.getSystemService(
1267                 Context.DISPLAY_SERVICE);
1268         displayManager.getDisplay(Display.DEFAULT_DISPLAY).getMetrics(metrics);
1269     }
1270
1271     public PackageManagerService(Context context, Installer installer,
1272             boolean factoryTest, boolean onlyCore) {
1273         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START,
1274                 SystemClock.uptimeMillis());
1275
1276         if (mSdkVersion <= 0) {
1277             Slog.w(TAG, "**** ro.build.version.sdk not set!");
1278         }
1279
1280         mContext = context;
1281         mFactoryTest = factoryTest;
1282         mOnlyCore = onlyCore;
1283         mLazyDexOpt = "eng".equals(SystemProperties.get("ro.build.type"));
1284         mMetrics = new DisplayMetrics();
1285         mSettings = new Settings(context);
1286         mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID,
1287                 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PRIVILEGED);
1288         mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID,
1289                 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PRIVILEGED);
1290         mSettings.addSharedUserLPw("android.uid.log", LOG_UID,
1291                 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PRIVILEGED);
1292         mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID,
1293                 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PRIVILEGED);
1294         mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID,
1295                 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PRIVILEGED);
1296         mSettings.addSharedUserLPw("android.uid.shell", SHELL_UID,
1297                 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PRIVILEGED);
1298
1299         // TODO: add a property to control this?
1300         long dexOptLRUThresholdInMinutes;
1301         if (mLazyDexOpt) {
1302             dexOptLRUThresholdInMinutes = 30; // only last 30 minutes of apps for eng builds.
1303         } else {
1304             dexOptLRUThresholdInMinutes = 7 * 24 * 60; // apps used in the 7 days for users.
1305         }
1306         mDexOptLRUThresholdInMills = dexOptLRUThresholdInMinutes * 60 * 1000;
1307
1308         String separateProcesses = SystemProperties.get("debug.separate_processes");
1309         if (separateProcesses != null && separateProcesses.length() > 0) {
1310             if ("*".equals(separateProcesses)) {
1311                 mDefParseFlags = PackageParser.PARSE_IGNORE_PROCESSES;
1312                 mSeparateProcesses = null;
1313                 Slog.w(TAG, "Running with debug.separate_processes: * (ALL)");
1314             } else {
1315                 mDefParseFlags = 0;
1316                 mSeparateProcesses = separateProcesses.split(",");
1317                 Slog.w(TAG, "Running with debug.separate_processes: "
1318                         + separateProcesses);
1319             }
1320         } else {
1321             mDefParseFlags = 0;
1322             mSeparateProcesses = null;
1323         }
1324
1325         mInstaller = installer;
1326
1327         getDefaultDisplayMetrics(context, mMetrics);
1328
1329         SystemConfig systemConfig = SystemConfig.getInstance();
1330         mGlobalGids = systemConfig.getGlobalGids();
1331         mSystemPermissions = systemConfig.getSystemPermissions();
1332         mAvailableFeatures = systemConfig.getAvailableFeatures();
1333
1334         synchronized (mInstallLock) {
1335         // writer
1336         synchronized (mPackages) {
1337             mHandlerThread = new ServiceThread(TAG,
1338                     Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
1339             mHandlerThread.start();
1340             mHandler = new PackageHandler(mHandlerThread.getLooper());
1341             Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT);
1342
1343             File dataDir = Environment.getDataDirectory();
1344             mAppDataDir = new File(dataDir, "data");
1345             mAppInstallDir = new File(dataDir, "app");
1346             mAppLib32InstallDir = new File(dataDir, "app-lib");
1347             mAsecInternalPath = new File(dataDir, "app-asec").getPath();
1348             mUserAppDataDir = new File(dataDir, "user");
1349             mDrmAppPrivateInstallDir = new File(dataDir, "app-private");
1350
1351             sUserManager = new UserManagerService(context, this,
1352                     mInstallLock, mPackages);
1353
1354             // Propagate permission configuration in to package manager.
1355             ArrayMap<String, SystemConfig.PermissionEntry> permConfig
1356                     = systemConfig.getPermissions();
1357             for (int i=0; i<permConfig.size(); i++) {
1358                 SystemConfig.PermissionEntry perm = permConfig.valueAt(i);
1359                 BasePermission bp = mSettings.mPermissions.get(perm.name);
1360                 if (bp == null) {
1361                     bp = new BasePermission(perm.name, "android", BasePermission.TYPE_BUILTIN);
1362                     mSettings.mPermissions.put(perm.name, bp);
1363                 }
1364                 if (perm.gids != null) {
1365                     bp.gids = appendInts(bp.gids, perm.gids);
1366                 }
1367             }
1368
1369             ArrayMap<String, String> libConfig = systemConfig.getSharedLibraries();
1370             for (int i=0; i<libConfig.size(); i++) {
1371                 mSharedLibraries.put(libConfig.keyAt(i),
1372                         new SharedLibraryEntry(libConfig.valueAt(i), null));
1373             }
1374
1375             mFoundPolicyFile = SELinuxMMAC.readInstallPolicy();
1376
1377             mRestoredSettings = mSettings.readLPw(this, sUserManager.getUsers(false),
1378                     mSdkVersion, mOnlyCore);
1379
1380             String customResolverActivity = Resources.getSystem().getString(
1381                     R.string.config_customResolverActivity);
1382             if (TextUtils.isEmpty(customResolverActivity)) {
1383                 customResolverActivity = null;
1384             } else {
1385                 mCustomResolverComponentName = ComponentName.unflattenFromString(
1386                         customResolverActivity);
1387             }
1388
1389             long startTime = SystemClock.uptimeMillis();
1390
1391             EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START,
1392                     startTime);
1393
1394             // Set flag to monitor and not change apk file paths when
1395             // scanning install directories.
1396             final int scanFlags = SCAN_NO_PATHS | SCAN_DEFER_DEX | SCAN_BOOTING;
1397
1398             final ArraySet<String> alreadyDexOpted = new ArraySet<String>();
1399
1400             /**
1401              * Add everything in the in the boot class path to the
1402              * list of process files because dexopt will have been run
1403              * if necessary during zygote startup.
1404              */
1405             final String bootClassPath = System.getenv("BOOTCLASSPATH");
1406             final String systemServerClassPath = System.getenv("SYSTEMSERVERCLASSPATH");
1407
1408             if (bootClassPath != null) {
1409                 String[] bootClassPathElements = splitString(bootClassPath, ':');
1410                 for (String element : bootClassPathElements) {
1411                     alreadyDexOpted.add(element);
1412                 }
1413             } else {
1414                 Slog.w(TAG, "No BOOTCLASSPATH found!");
1415             }
1416
1417             if (systemServerClassPath != null) {
1418                 String[] systemServerClassPathElements = splitString(systemServerClassPath, ':');
1419                 for (String element : systemServerClassPathElements) {
1420                     alreadyDexOpted.add(element);
1421                 }
1422             } else {
1423                 Slog.w(TAG, "No SYSTEMSERVERCLASSPATH found!");
1424             }
1425
1426             final List<String> allInstructionSets = getAllInstructionSets();
1427             final String[] dexCodeInstructionSets =
1428                 getDexCodeInstructionSets(allInstructionSets.toArray(new String[allInstructionSets.size()]));
1429
1430             /**
1431              * Ensure all external libraries have had dexopt run on them.
1432              */
1433             if (mSharedLibraries.size() > 0) {
1434                 // NOTE: For now, we're compiling these system "shared libraries"
1435                 // (and framework jars) into all available architectures. It's possible
1436                 // to compile them only when we come across an app that uses them (there's
1437                 // already logic for that in scanPackageLI) but that adds some complexity.
1438                 for (String dexCodeInstructionSet : dexCodeInstructionSets) {
1439                     for (SharedLibraryEntry libEntry : mSharedLibraries.values()) {
1440                         final String lib = libEntry.path;
1441                         if (lib == null) {
1442                             continue;
1443                         }
1444
1445                         try {
1446                             byte dexoptRequired = DexFile.isDexOptNeededInternal(lib, null,
1447                                                                                  dexCodeInstructionSet,
1448                                                                                  false);
1449                             if (dexoptRequired != DexFile.UP_TO_DATE) {
1450                                 alreadyDexOpted.add(lib);
1451
1452                                 // The list of "shared libraries" we have at this point is
1453                                 if (dexoptRequired == DexFile.DEXOPT_NEEDED) {
1454                                     mInstaller.dexopt(lib, Process.SYSTEM_UID, true, dexCodeInstructionSet);
1455                                 } else {
1456                                     mInstaller.patchoat(lib, Process.SYSTEM_UID, true, dexCodeInstructionSet);
1457                                 }
1458                             }
1459                         } catch (FileNotFoundException e) {
1460                             Slog.w(TAG, "Library not found: " + lib);
1461                         } catch (IOException e) {
1462                             Slog.w(TAG, "Cannot dexopt " + lib + "; is it an APK or JAR? "
1463                                     + e.getMessage());
1464                         }
1465                     }
1466                 }
1467             }
1468
1469             File frameworkDir = new File(Environment.getRootDirectory(), "framework");
1470
1471             // Gross hack for now: we know this file doesn't contain any
1472             // code, so don't dexopt it to avoid the resulting log spew.
1473             alreadyDexOpted.add(frameworkDir.getPath() + "/framework-res.apk");
1474
1475             // Gross hack for now: we know this file is only part of
1476             // the boot class path for art, so don't dexopt it to
1477             // avoid the resulting log spew.
1478             alreadyDexOpted.add(frameworkDir.getPath() + "/core-libart.jar");
1479
1480             /**
1481              * And there are a number of commands implemented in Java, which
1482              * we currently need to do the dexopt on so that they can be
1483              * run from a non-root shell.
1484              */
1485             String[] frameworkFiles = frameworkDir.list();
1486             if (frameworkFiles != null) {
1487                 // TODO: We could compile these only for the most preferred ABI. We should
1488                 // first double check that the dex files for these commands are not referenced
1489                 // by other system apps.
1490                 for (String dexCodeInstructionSet : dexCodeInstructionSets) {
1491                     for (int i=0; i<frameworkFiles.length; i++) {
1492                         File libPath = new File(frameworkDir, frameworkFiles[i]);
1493                         String path = libPath.getPath();
1494                         // Skip the file if we already did it.
1495                         if (alreadyDexOpted.contains(path)) {
1496                             continue;
1497                         }
1498                         // Skip the file if it is not a type we want to dexopt.
1499                         if (!path.endsWith(".apk") && !path.endsWith(".jar")) {
1500                             continue;
1501                         }
1502                         try {
1503                             byte dexoptRequired = DexFile.isDexOptNeededInternal(path, null,
1504                                                                                  dexCodeInstructionSet,
1505                                                                                  false);
1506                             if (dexoptRequired == DexFile.DEXOPT_NEEDED) {
1507                                 mInstaller.dexopt(path, Process.SYSTEM_UID, true, dexCodeInstructionSet);
1508                             } else if (dexoptRequired == DexFile.PATCHOAT_NEEDED) {
1509                                 mInstaller.patchoat(path, Process.SYSTEM_UID, true, dexCodeInstructionSet);
1510                             }
1511                         } catch (FileNotFoundException e) {
1512                             Slog.w(TAG, "Jar not found: " + path);
1513                         } catch (IOException e) {
1514                             Slog.w(TAG, "Exception reading jar: " + path, e);
1515                         }
1516                     }
1517                 }
1518             }
1519
1520             // Collect vendor overlay packages.
1521             // (Do this before scanning any apps.)
1522             // For security and version matching reason, only consider
1523             // overlay packages if they reside in VENDOR_OVERLAY_DIR.
1524             File vendorOverlayDir = new File(VENDOR_OVERLAY_DIR);
1525             scanDirLI(vendorOverlayDir, PackageParser.PARSE_IS_SYSTEM
1526                     | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags | SCAN_TRUSTED_OVERLAY, 0);
1527
1528             // Find base frameworks (resource packages without code).
1529             scanDirLI(frameworkDir, PackageParser.PARSE_IS_SYSTEM
1530                     | PackageParser.PARSE_IS_SYSTEM_DIR
1531                     | PackageParser.PARSE_IS_PRIVILEGED,
1532                     scanFlags | SCAN_NO_DEX, 0);
1533
1534             // Collected privileged system packages.
1535             final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app");
1536             scanDirLI(privilegedAppDir, PackageParser.PARSE_IS_SYSTEM
1537                     | PackageParser.PARSE_IS_SYSTEM_DIR
1538                     | PackageParser.PARSE_IS_PRIVILEGED, scanFlags, 0);
1539
1540             // Collect ordinary system packages.
1541             final File systemAppDir = new File(Environment.getRootDirectory(), "app");
1542             scanDirLI(systemAppDir, PackageParser.PARSE_IS_SYSTEM
1543                     | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
1544
1545             // Collect all vendor packages.
1546             File vendorAppDir = new File("/vendor/app");
1547             try {
1548                 vendorAppDir = vendorAppDir.getCanonicalFile();
1549             } catch (IOException e) {
1550                 // failed to look up canonical path, continue with original one
1551             }
1552             scanDirLI(vendorAppDir, PackageParser.PARSE_IS_SYSTEM
1553                     | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
1554
1555             // Collect all OEM packages.
1556             final File oemAppDir = new File(Environment.getOemDirectory(), "app");
1557             scanDirLI(oemAppDir, PackageParser.PARSE_IS_SYSTEM
1558                     | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
1559
1560             if (DEBUG_UPGRADE) Log.v(TAG, "Running installd update commands");
1561             mInstaller.moveFiles();
1562
1563             // Prune any system packages that no longer exist.
1564             final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<String>();
1565             final ArrayMap<String, File> expectingBetter = new ArrayMap<>();
1566             if (!mOnlyCore) {
1567                 Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
1568                 while (psit.hasNext()) {
1569                     PackageSetting ps = psit.next();
1570
1571                     /*
1572                      * If this is not a system app, it can't be a
1573                      * disable system app.
1574                      */
1575                     if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
1576                         continue;
1577                     }
1578
1579                     /*
1580                      * If the package is scanned, it's not erased.
1581                      */
1582                     final PackageParser.Package scannedPkg = mPackages.get(ps.name);
1583                     if (scannedPkg != null) {
1584                         /*
1585                          * If the system app is both scanned and in the
1586                          * disabled packages list, then it must have been
1587                          * added via OTA. Remove it from the currently
1588                          * scanned package so the previously user-installed
1589                          * application can be scanned.
1590                          */
1591                         if (mSettings.isDisabledSystemPackageLPr(ps.name)) {
1592                             logCriticalInfo(Log.WARN, "Expecting better updated system app for "
1593                                     + ps.name + "; removing system app.  Last known codePath="
1594                                     + ps.codePathString + ", installStatus=" + ps.installStatus
1595                                     + ", versionCode=" + ps.versionCode + "; scanned versionCode="
1596                                     + scannedPkg.mVersionCode);
1597                             removePackageLI(ps, true);
1598                             expectingBetter.put(ps.name, ps.codePath);
1599                         }
1600
1601                         continue;
1602                     }
1603
1604                     if (!mSettings.isDisabledSystemPackageLPr(ps.name)) {
1605                         psit.remove();
1606                         logCriticalInfo(Log.WARN, "System package " + ps.name
1607                                 + " no longer exists; wiping its data");
1608                         removeDataDirsLI(ps.name);
1609                     } else {
1610                         final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(ps.name);
1611                         if (disabledPs.codePath == null || !disabledPs.codePath.exists()) {
1612                             possiblyDeletedUpdatedSystemApps.add(ps.name);
1613                         }
1614                     }
1615                 }
1616             }
1617
1618             //look for any incomplete package installations
1619             ArrayList<PackageSetting> deletePkgsList = mSettings.getListOfIncompleteInstallPackagesLPr();
1620             //clean up list
1621             for(int i = 0; i < deletePkgsList.size(); i++) {
1622                 //clean up here
1623                 cleanupInstallFailedPackage(deletePkgsList.get(i));
1624             }
1625             //delete tmp files
1626             deleteTempPackageFiles();
1627
1628             // Remove any shared userIDs that have no associated packages
1629             mSettings.pruneSharedUsersLPw();
1630
1631             if (!mOnlyCore) {
1632                 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,
1633                         SystemClock.uptimeMillis());
1634                 scanDirLI(mAppInstallDir, 0, scanFlags, 0);
1635
1636                 scanDirLI(mDrmAppPrivateInstallDir, PackageParser.PARSE_FORWARD_LOCK,
1637                         scanFlags, 0);
1638
1639                 /**
1640                  * Remove disable package settings for any updated system
1641                  * apps that were removed via an OTA. If they're not a
1642                  * previously-updated app, remove them completely.
1643                  * Otherwise, just revoke their system-level permissions.
1644                  */
1645                 for (String deletedAppName : possiblyDeletedUpdatedSystemApps) {
1646                     PackageParser.Package deletedPkg = mPackages.get(deletedAppName);
1647                     mSettings.removeDisabledSystemPackageLPw(deletedAppName);
1648
1649                     String msg;
1650                     if (deletedPkg == null) {
1651                         msg = "Updated system package " + deletedAppName
1652                                 + " no longer exists; wiping its data";
1653                         removeDataDirsLI(deletedAppName);
1654                     } else {
1655                         msg = "Updated system app + " + deletedAppName
1656                                 + " no longer present; removing system privileges for "
1657                                 + deletedAppName;
1658
1659                         deletedPkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM;
1660
1661                         PackageSetting deletedPs = mSettings.mPackages.get(deletedAppName);
1662                         deletedPs.pkgFlags &= ~ApplicationInfo.FLAG_SYSTEM;
1663                     }
1664                     logCriticalInfo(Log.WARN, msg);
1665                 }
1666
1667                 /**
1668                  * Make sure all system apps that we expected to appear on
1669                  * the userdata partition actually showed up. If they never
1670                  * appeared, crawl back and revive the system version.
1671                  */
1672                 for (int i = 0; i < expectingBetter.size(); i++) {
1673                     final String packageName = expectingBetter.keyAt(i);
1674                     if (!mPackages.containsKey(packageName)) {
1675                         final File scanFile = expectingBetter.valueAt(i);
1676
1677                         logCriticalInfo(Log.WARN, "Expected better " + packageName
1678                                 + " but never showed up; reverting to system");
1679
1680                         final int reparseFlags;
1681                         if (FileUtils.contains(privilegedAppDir, scanFile)) {
1682                             reparseFlags = PackageParser.PARSE_IS_SYSTEM
1683                                     | PackageParser.PARSE_IS_SYSTEM_DIR
1684                                     | PackageParser.PARSE_IS_PRIVILEGED;
1685                         } else if (FileUtils.contains(systemAppDir, scanFile)) {
1686                             reparseFlags = PackageParser.PARSE_IS_SYSTEM
1687                                     | PackageParser.PARSE_IS_SYSTEM_DIR;
1688                         } else if (FileUtils.contains(vendorAppDir, scanFile)) {
1689                             reparseFlags = PackageParser.PARSE_IS_SYSTEM
1690                                     | PackageParser.PARSE_IS_SYSTEM_DIR;
1691                         } else if (FileUtils.contains(oemAppDir, scanFile)) {
1692                             reparseFlags = PackageParser.PARSE_IS_SYSTEM
1693                                     | PackageParser.PARSE_IS_SYSTEM_DIR;
1694                         } else {
1695                             Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile);
1696                             continue;
1697                         }
1698
1699                         mSettings.enableSystemPackageLPw(packageName);
1700
1701                         try {
1702                             scanPackageLI(scanFile, reparseFlags, scanFlags, 0, null);
1703                         } catch (PackageManagerException e) {
1704                             Slog.e(TAG, "Failed to parse original system package: "
1705                                     + e.getMessage());
1706                         }
1707                     }
1708                 }
1709             }
1710
1711             // Now that we know all of the shared libraries, update all clients to have
1712             // the correct library paths.
1713             updateAllSharedLibrariesLPw();
1714
1715             for (SharedUserSetting setting : mSettings.getAllSharedUsersLPw()) {
1716                 // NOTE: We ignore potential failures here during a system scan (like
1717                 // the rest of the commands above) because there's precious little we
1718                 // can do about it. A settings error is reported, though.
1719                 adjustCpuAbisForSharedUserLPw(setting.packages, null /* scanned package */,
1720                         false /* force dexopt */, false /* defer dexopt */);
1721             }
1722
1723             // Now that we know all the packages we are keeping,
1724             // read and update their last usage times.
1725             mPackageUsage.readLP();
1726
1727             EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END,
1728                     SystemClock.uptimeMillis());
1729             Slog.i(TAG, "Time to scan packages: "
1730                     + ((SystemClock.uptimeMillis()-startTime)/1000f)
1731                     + " seconds");
1732
1733             // If the platform SDK has changed since the last time we booted,
1734             // we need to re-grant app permission to catch any new ones that
1735             // appear.  This is really a hack, and means that apps can in some
1736             // cases get permissions that the user didn't initially explicitly
1737             // allow...  it would be nice to have some better way to handle
1738             // this situation.
1739             final boolean regrantPermissions = mSettings.mInternalSdkPlatform
1740                     != mSdkVersion;
1741             if (regrantPermissions) Slog.i(TAG, "Platform changed from "
1742                     + mSettings.mInternalSdkPlatform + " to " + mSdkVersion
1743                     + "; regranting permissions for internal storage");
1744             mSettings.mInternalSdkPlatform = mSdkVersion;
1745             
1746             updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL
1747                     | (regrantPermissions
1748                             ? (UPDATE_PERMISSIONS_REPLACE_PKG|UPDATE_PERMISSIONS_REPLACE_ALL)
1749                             : 0));
1750
1751             // If this is the first boot, and it is a normal boot, then
1752             // we need to initialize the default preferred apps.
1753             if (!mRestoredSettings && !onlyCore) {
1754                 mSettings.readDefaultPreferredAppsLPw(this, 0);
1755             }
1756
1757             // If this is first boot after an OTA, and a normal boot, then
1758             // we need to clear code cache directories.
1759             mIsUpgrade = !Build.FINGERPRINT.equals(mSettings.mFingerprint);
1760             if (mIsUpgrade && !onlyCore) {
1761                 Slog.i(TAG, "Build fingerprint changed; clearing code caches");
1762                 for (String pkgName : mSettings.mPackages.keySet()) {
1763                     deleteCodeCacheDirsLI(pkgName);
1764                 }
1765                 mSettings.mFingerprint = Build.FINGERPRINT;
1766             }
1767
1768             // All the changes are done during package scanning.
1769             mSettings.updateInternalDatabaseVersion();
1770
1771             // can downgrade to reader
1772             mSettings.writeLPr();
1773
1774             EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY,
1775                     SystemClock.uptimeMillis());
1776
1777
1778             mRequiredVerifierPackage = getRequiredVerifierLPr();
1779         } // synchronized (mPackages)
1780         } // synchronized (mInstallLock)
1781
1782         mInstallerService = new PackageInstallerService(context, this, mAppInstallDir);
1783
1784         // Now after opening every single application zip, make sure they
1785         // are all flushed.  Not really needed, but keeps things nice and
1786         // tidy.
1787         Runtime.getRuntime().gc();
1788     }
1789
1790     @Override
1791     public boolean isFirstBoot() {
1792         return !mRestoredSettings;
1793     }
1794
1795     @Override
1796     public boolean isOnlyCoreApps() {
1797         return mOnlyCore;
1798     }
1799
1800     @Override
1801     public boolean isUpgrade() {
1802         return mIsUpgrade;
1803     }
1804
1805     private String getRequiredVerifierLPr() {
1806         final Intent verification = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
1807         final List<ResolveInfo> receivers = queryIntentReceivers(verification, PACKAGE_MIME_TYPE,
1808                 PackageManager.GET_DISABLED_COMPONENTS, 0 /* TODO: Which userId? */);
1809
1810         String requiredVerifier = null;
1811
1812         final int N = receivers.size();
1813         for (int i = 0; i < N; i++) {
1814             final ResolveInfo info = receivers.get(i);
1815
1816             if (info.activityInfo == null) {
1817                 continue;
1818             }
1819
1820             final String packageName = info.activityInfo.packageName;
1821
1822             final PackageSetting ps = mSettings.mPackages.get(packageName);
1823             if (ps == null) {
1824                 continue;
1825             }
1826
1827             final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps;
1828             if (!gp.grantedPermissions
1829                     .contains(android.Manifest.permission.PACKAGE_VERIFICATION_AGENT)) {
1830                 continue;
1831             }
1832
1833             if (requiredVerifier != null) {
1834                 throw new RuntimeException("There can be only one required verifier");
1835             }
1836
1837             requiredVerifier = packageName;
1838         }
1839
1840         return requiredVerifier;
1841     }
1842
1843     @Override
1844     public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1845             throws RemoteException {
1846         try {
1847             return super.onTransact(code, data, reply, flags);
1848         } catch (RuntimeException e) {
1849             if (!(e instanceof SecurityException) && !(e instanceof IllegalArgumentException)) {
1850                 Slog.wtf(TAG, "Package Manager Crash", e);
1851             }
1852             throw e;
1853         }
1854     }
1855
1856     void cleanupInstallFailedPackage(PackageSetting ps) {
1857         logCriticalInfo(Log.WARN, "Cleaning up incompletely installed app: " + ps.name);
1858
1859         removeDataDirsLI(ps.name);
1860         if (ps.codePath != null) {
1861             if (ps.codePath.isDirectory()) {
1862                 FileUtils.deleteContents(ps.codePath);
1863             }
1864             ps.codePath.delete();
1865         }
1866         if (ps.resourcePath != null && !ps.resourcePath.equals(ps.codePath)) {
1867             if (ps.resourcePath.isDirectory()) {
1868                 FileUtils.deleteContents(ps.resourcePath);
1869             }
1870             ps.resourcePath.delete();
1871         }
1872         mSettings.removePackageLPw(ps.name);
1873     }
1874
1875     static int[] appendInts(int[] cur, int[] add) {
1876         if (add == null) return cur;
1877         if (cur == null) return add;
1878         final int N = add.length;
1879         for (int i=0; i<N; i++) {
1880             cur = appendInt(cur, add[i]);
1881         }
1882         return cur;
1883     }
1884
1885     static int[] removeInts(int[] cur, int[] rem) {
1886         if (rem == null) return cur;
1887         if (cur == null) return cur;
1888         final int N = rem.length;
1889         for (int i=0; i<N; i++) {
1890             cur = removeInt(cur, rem[i]);
1891         }
1892         return cur;
1893     }
1894
1895     PackageInfo generatePackageInfo(PackageParser.Package p, int flags, int userId) {
1896         if (!sUserManager.exists(userId)) return null;
1897         final PackageSetting ps = (PackageSetting) p.mExtras;
1898         if (ps == null) {
1899             return null;
1900         }
1901         final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps;
1902         final PackageUserState state = ps.readUserState(userId);
1903         return PackageParser.generatePackageInfo(p, gp.gids, flags,
1904                 ps.firstInstallTime, ps.lastUpdateTime, gp.grantedPermissions,
1905                 state, userId);
1906     }
1907
1908     @Override
1909     public boolean isPackageAvailable(String packageName, int userId) {
1910         if (!sUserManager.exists(userId)) return false;
1911         enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "is package available");
1912         synchronized (mPackages) {
1913             PackageParser.Package p = mPackages.get(packageName);
1914             if (p != null) {
1915                 final PackageSetting ps = (PackageSetting) p.mExtras;
1916                 if (ps != null) {
1917                     final PackageUserState state = ps.readUserState(userId);
1918                     if (state != null) {
1919                         return PackageParser.isAvailable(state);
1920                     }
1921                 }
1922             }
1923         }
1924         return false;
1925     }
1926
1927     @Override
1928     public PackageInfo getPackageInfo(String packageName, int flags, int userId) {
1929         if (!sUserManager.exists(userId)) return null;
1930         enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get package info");
1931         // reader
1932         synchronized (mPackages) {
1933             PackageParser.Package p = mPackages.get(packageName);
1934             if (DEBUG_PACKAGE_INFO)
1935                 Log.v(TAG, "getPackageInfo " + packageName + ": " + p);
1936             if (p != null) {
1937                 return generatePackageInfo(p, flags, userId);
1938             }
1939             if((flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0) {
1940                 return generatePackageInfoFromSettingsLPw(packageName, flags, userId);
1941             }
1942         }
1943         return null;
1944     }
1945
1946     @Override
1947     public String[] currentToCanonicalPackageNames(String[] names) {
1948         String[] out = new String[names.length];
1949         // reader
1950         synchronized (mPackages) {
1951             for (int i=names.length-1; i>=0; i--) {
1952                 PackageSetting ps = mSettings.mPackages.get(names[i]);
1953                 out[i] = ps != null && ps.realName != null ? ps.realName : names[i];
1954             }
1955         }
1956         return out;
1957     }
1958     
1959     @Override
1960     public String[] canonicalToCurrentPackageNames(String[] names) {
1961         String[] out = new String[names.length];
1962         // reader
1963         synchronized (mPackages) {
1964             for (int i=names.length-1; i>=0; i--) {
1965                 String cur = mSettings.mRenamedPackages.get(names[i]);
1966                 out[i] = cur != null ? cur : names[i];
1967             }
1968         }
1969         return out;
1970     }
1971
1972     @Override
1973     public int getPackageUid(String packageName, int userId) {
1974         if (!sUserManager.exists(userId)) return -1;
1975         enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get package uid");
1976         // reader
1977         synchronized (mPackages) {
1978             PackageParser.Package p = mPackages.get(packageName);
1979             if(p != null) {
1980                 return UserHandle.getUid(userId, p.applicationInfo.uid);
1981             }
1982             PackageSetting ps = mSettings.mPackages.get(packageName);
1983             if((ps == null) || (ps.pkg == null) || (ps.pkg.applicationInfo == null)) {
1984                 return -1;
1985             }
1986             p = ps.pkg;
1987             return p != null ? UserHandle.getUid(userId, p.applicationInfo.uid) : -1;
1988         }
1989     }
1990
1991     @Override
1992     public int[] getPackageGids(String packageName) {
1993         // reader
1994         synchronized (mPackages) {
1995             PackageParser.Package p = mPackages.get(packageName);
1996             if (DEBUG_PACKAGE_INFO)
1997                 Log.v(TAG, "getPackageGids" + packageName + ": " + p);
1998             if (p != null) {
1999                 final PackageSetting ps = (PackageSetting)p.mExtras;
2000                 return ps.getGids();
2001             }
2002         }
2003         // stupid thing to indicate an error.
2004         return new int[0];
2005     }
2006
2007     static final PermissionInfo generatePermissionInfo(
2008             BasePermission bp, int flags) {
2009         if (bp.perm != null) {
2010             return PackageParser.generatePermissionInfo(bp.perm, flags);
2011         }
2012         PermissionInfo pi = new PermissionInfo();
2013         pi.name = bp.name;
2014         pi.packageName = bp.sourcePackage;
2015         pi.nonLocalizedLabel = bp.name;
2016         pi.protectionLevel = bp.protectionLevel;
2017         return pi;
2018     }
2019     
2020     @Override
2021     public PermissionInfo getPermissionInfo(String name, int flags) {
2022         // reader
2023         synchronized (mPackages) {
2024             final BasePermission p = mSettings.mPermissions.get(name);
2025             if (p != null) {
2026                 return generatePermissionInfo(p, flags);
2027             }
2028             return null;
2029         }
2030     }
2031
2032     @Override
2033     public List<PermissionInfo> queryPermissionsByGroup(String group, int flags) {
2034         // reader
2035         synchronized (mPackages) {
2036             ArrayList<PermissionInfo> out = new ArrayList<PermissionInfo>(10);
2037             for (BasePermission p : mSettings.mPermissions.values()) {
2038                 if (group == null) {
2039                     if (p.perm == null || p.perm.info.group == null) {
2040                         out.add(generatePermissionInfo(p, flags));
2041                     }
2042                 } else {
2043                     if (p.perm != null && group.equals(p.perm.info.group)) {
2044                         out.add(PackageParser.generatePermissionInfo(p.perm, flags));
2045                     }
2046                 }
2047             }
2048
2049             if (out.size() > 0) {
2050                 return out;
2051             }
2052             return mPermissionGroups.containsKey(group) ? out : null;
2053         }
2054     }
2055
2056     @Override
2057     public PermissionGroupInfo getPermissionGroupInfo(String name, int flags) {
2058         // reader
2059         synchronized (mPackages) {
2060             return PackageParser.generatePermissionGroupInfo(
2061                     mPermissionGroups.get(name), flags);
2062         }
2063     }
2064
2065     @Override
2066     public List<PermissionGroupInfo> getAllPermissionGroups(int flags) {
2067         // reader
2068         synchronized (mPackages) {
2069             final int N = mPermissionGroups.size();
2070             ArrayList<PermissionGroupInfo> out
2071                     = new ArrayList<PermissionGroupInfo>(N);
2072             for (PackageParser.PermissionGroup pg : mPermissionGroups.values()) {
2073                 out.add(PackageParser.generatePermissionGroupInfo(pg, flags));
2074             }
2075             return out;
2076         }
2077     }
2078
2079     private ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName, int flags,
2080             int userId) {
2081         if (!sUserManager.exists(userId)) return null;
2082         PackageSetting ps = mSettings.mPackages.get(packageName);
2083         if (ps != null) {
2084             if (ps.pkg == null) {
2085                 PackageInfo pInfo = generatePackageInfoFromSettingsLPw(packageName,
2086                         flags, userId);
2087                 if (pInfo != null) {
2088                     return pInfo.applicationInfo;
2089                 }
2090                 return null;
2091             }
2092             return PackageParser.generateApplicationInfo(ps.pkg, flags,
2093                     ps.readUserState(userId), userId);
2094         }
2095         return null;
2096     }
2097
2098     private PackageInfo generatePackageInfoFromSettingsLPw(String packageName, int flags,
2099             int userId) {
2100         if (!sUserManager.exists(userId)) return null;
2101         PackageSetting ps = mSettings.mPackages.get(packageName);
2102         if (ps != null) {
2103             PackageParser.Package pkg = ps.pkg;
2104             if (pkg == null) {
2105                 if ((flags & PackageManager.GET_UNINSTALLED_PACKAGES) == 0) {
2106                     return null;
2107                 }
2108                 // Only data remains, so we aren't worried about code paths
2109                 pkg = new PackageParser.Package(packageName);
2110                 pkg.applicationInfo.packageName = packageName;
2111                 pkg.applicationInfo.flags = ps.pkgFlags | ApplicationInfo.FLAG_IS_DATA_ONLY;
2112                 pkg.applicationInfo.dataDir =
2113                         getDataPathForPackage(packageName, 0).getPath();
2114                 pkg.applicationInfo.primaryCpuAbi = ps.primaryCpuAbiString;
2115                 pkg.applicationInfo.secondaryCpuAbi = ps.secondaryCpuAbiString;
2116             }
2117             return generatePackageInfo(pkg, flags, userId);
2118         }
2119         return null;
2120     }
2121
2122     @Override
2123     public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) {
2124         if (!sUserManager.exists(userId)) return null;
2125         enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get application info");
2126         // writer
2127         synchronized (mPackages) {
2128             PackageParser.Package p = mPackages.get(packageName);
2129             if (DEBUG_PACKAGE_INFO) Log.v(
2130                     TAG, "getApplicationInfo " + packageName
2131                     + ": " + p);
2132             if (p != null) {
2133                 PackageSetting ps = mSettings.mPackages.get(packageName);
2134                 if (ps == null) return null;
2135                 // Note: isEnabledLP() does not apply here - always return info
2136                 return PackageParser.generateApplicationInfo(
2137                         p, flags, ps.readUserState(userId), userId);
2138             }
2139             if ("android".equals(packageName)||"system".equals(packageName)) {
2140                 return mAndroidApplication;
2141             }
2142             if ((flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0) {
2143                 return generateApplicationInfoFromSettingsLPw(packageName, flags, userId);
2144             }
2145         }
2146         return null;
2147     }
2148
2149
2150     @Override
2151     public void freeStorageAndNotify(final long freeStorageSize, final IPackageDataObserver observer) {
2152         mContext.enforceCallingOrSelfPermission(
2153                 android.Manifest.permission.CLEAR_APP_CACHE, null);
2154         // Queue up an async operation since clearing cache may take a little while.
2155         mHandler.post(new Runnable() {
2156             public void run() {
2157                 mHandler.removeCallbacks(this);
2158                 int retCode = -1;
2159                 synchronized (mInstallLock) {
2160                     retCode = mInstaller.freeCache(freeStorageSize);
2161                     if (retCode < 0) {
2162                         Slog.w(TAG, "Couldn't clear application caches");
2163                     }
2164                 }
2165                 if (observer != null) {
2166                     try {
2167                         observer.onRemoveCompleted(null, (retCode >= 0));
2168                     } catch (RemoteException e) {
2169                         Slog.w(TAG, "RemoveException when invoking call back");
2170                     }
2171                 }
2172             }
2173         });
2174     }
2175
2176     @Override
2177     public void freeStorage(final long freeStorageSize, final IntentSender pi) {
2178         mContext.enforceCallingOrSelfPermission(
2179                 android.Manifest.permission.CLEAR_APP_CACHE, null);
2180         // Queue up an async operation since clearing cache may take a little while.
2181         mHandler.post(new Runnable() {
2182             public void run() {
2183                 mHandler.removeCallbacks(this);
2184                 int retCode = -1;
2185                 synchronized (mInstallLock) {
2186                     retCode = mInstaller.freeCache(freeStorageSize);
2187                     if (retCode < 0) {
2188                         Slog.w(TAG, "Couldn't clear application caches");
2189                     }
2190                 }
2191                 if(pi != null) {
2192                     try {
2193                         // Callback via pending intent
2194                         int code = (retCode >= 0) ? 1 : 0;
2195                         pi.sendIntent(null, code, null,
2196                                 null, null);
2197                     } catch (SendIntentException e1) {
2198                         Slog.i(TAG, "Failed to send pending intent");
2199                     }
2200                 }
2201             }
2202         });
2203     }
2204
2205     void freeStorage(long freeStorageSize) throws IOException {
2206         synchronized (mInstallLock) {
2207             if (mInstaller.freeCache(freeStorageSize) < 0) {
2208                 throw new IOException("Failed to free enough space");
2209             }
2210         }
2211     }
2212
2213     @Override
2214     public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) {
2215         if (!sUserManager.exists(userId)) return null;
2216         enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get activity info");
2217         synchronized (mPackages) {
2218             PackageParser.Activity a = mActivities.mActivities.get(component);
2219
2220             if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a);
2221             if (a != null && mSettings.isEnabledLPr(a.info, flags, userId)) {
2222                 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
2223                 if (ps == null) return null;
2224                 return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId),
2225                         userId);
2226             }
2227             if (mResolveComponentName.equals(component)) {
2228                 return PackageParser.generateActivityInfo(mResolveActivity, flags,
2229                         new PackageUserState(), userId);
2230             }
2231         }
2232         return null;
2233     }
2234
2235     @Override
2236     public boolean activitySupportsIntent(ComponentName component, Intent intent,
2237             String resolvedType) {
2238         synchronized (mPackages) {
2239             PackageParser.Activity a = mActivities.mActivities.get(component);
2240             if (a == null) {
2241                 return false;
2242             }
2243             for (int i=0; i<a.intents.size(); i++) {
2244                 if (a.intents.get(i).match(intent.getAction(), resolvedType, intent.getScheme(),
2245                         intent.getData(), intent.getCategories(), TAG) >= 0) {
2246                     return true;
2247                 }
2248             }
2249             return false;
2250         }
2251     }
2252
2253     @Override
2254     public ActivityInfo getReceiverInfo(ComponentName component, int flags, int userId) {
2255         if (!sUserManager.exists(userId)) return null;
2256         enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get receiver info");
2257         synchronized (mPackages) {
2258             PackageParser.Activity a = mReceivers.mActivities.get(component);
2259             if (DEBUG_PACKAGE_INFO) Log.v(
2260                 TAG, "getReceiverInfo " + component + ": " + a);
2261             if (a != null && mSettings.isEnabledLPr(a.info, flags, userId)) {
2262                 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
2263                 if (ps == null) return null;
2264                 return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId),
2265                         userId);
2266             }
2267         }
2268         return null;
2269     }
2270
2271     @Override
2272     public ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) {
2273         if (!sUserManager.exists(userId)) return null;
2274         enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get service info");
2275         synchronized (mPackages) {
2276             PackageParser.Service s = mServices.mServices.get(component);
2277             if (DEBUG_PACKAGE_INFO) Log.v(
2278                 TAG, "getServiceInfo " + component + ": " + s);
2279             if (s != null && mSettings.isEnabledLPr(s.info, flags, userId)) {
2280                 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
2281                 if (ps == null) return null;
2282                 return PackageParser.generateServiceInfo(s, flags, ps.readUserState(userId),
2283                         userId);
2284             }
2285         }
2286         return null;
2287     }
2288
2289     @Override
2290     public ProviderInfo getProviderInfo(ComponentName component, int flags, int userId) {
2291         if (!sUserManager.exists(userId)) return null;
2292         enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get provider info");
2293         synchronized (mPackages) {
2294             PackageParser.Provider p = mProviders.mProviders.get(component);
2295             if (DEBUG_PACKAGE_INFO) Log.v(
2296                 TAG, "getProviderInfo " + component + ": " + p);
2297             if (p != null && mSettings.isEnabledLPr(p.info, flags, userId)) {
2298                 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
2299                 if (ps == null) return null;
2300                 return PackageParser.generateProviderInfo(p, flags, ps.readUserState(userId),
2301                         userId);
2302             }
2303         }
2304         return null;
2305     }
2306
2307     @Override
2308     public String[] getSystemSharedLibraryNames() {
2309         Set<String> libSet;
2310         synchronized (mPackages) {
2311             libSet = mSharedLibraries.keySet();
2312             int size = libSet.size();
2313             if (size > 0) {
2314                 String[] libs = new String[size];
2315                 libSet.toArray(libs);
2316                 return libs;
2317             }
2318         }
2319         return null;
2320     }
2321
2322     @Override
2323     public FeatureInfo[] getSystemAvailableFeatures() {
2324         Collection<FeatureInfo> featSet;
2325         synchronized (mPackages) {
2326             featSet = mAvailableFeatures.values();
2327             int size = featSet.size();
2328             if (size > 0) {
2329                 FeatureInfo[] features = new FeatureInfo[size+1];
2330                 featSet.toArray(features);
2331                 FeatureInfo fi = new FeatureInfo();
2332                 fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version",
2333                         FeatureInfo.GL_ES_VERSION_UNDEFINED);
2334                 features[size] = fi;
2335                 return features;
2336             }
2337         }
2338         return null;
2339     }
2340
2341     @Override
2342     public boolean hasSystemFeature(String name) {
2343         synchronized (mPackages) {
2344             return mAvailableFeatures.containsKey(name);
2345         }
2346     }
2347
2348     private void checkValidCaller(int uid, int userId) {
2349         if (UserHandle.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0)
2350             return;
2351
2352         throw new SecurityException("Caller uid=" + uid
2353                 + " is not privileged to communicate with user=" + userId);
2354     }
2355
2356     @Override
2357     public int checkPermission(String permName, String pkgName) {
2358         synchronized (mPackages) {
2359             PackageParser.Package p = mPackages.get(pkgName);
2360             if (p != null && p.mExtras != null) {
2361                 PackageSetting ps = (PackageSetting)p.mExtras;
2362                 if (ps.sharedUser != null) {
2363                     if (ps.sharedUser.grantedPermissions.contains(permName)) {
2364                         return PackageManager.PERMISSION_GRANTED;
2365                     }
2366                 } else if (ps.grantedPermissions.contains(permName)) {
2367                     return PackageManager.PERMISSION_GRANTED;
2368                 }
2369             }
2370         }
2371         return PackageManager.PERMISSION_DENIED;
2372     }
2373
2374     @Override
2375     public int checkUidPermission(String permName, int uid) {
2376         synchronized (mPackages) {
2377             Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
2378             if (obj != null) {
2379                 GrantedPermissions gp = (GrantedPermissions)obj;
2380                 if (gp.grantedPermissions.contains(permName)) {
2381                     return PackageManager.PERMISSION_GRANTED;
2382                 }
2383             } else {
2384                 ArraySet<String> perms = mSystemPermissions.get(uid);
2385                 if (perms != null && perms.contains(permName)) {
2386                     return PackageManager.PERMISSION_GRANTED;
2387                 }
2388             }
2389         }
2390         return PackageManager.PERMISSION_DENIED;
2391     }
2392
2393     /**
2394      * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS
2395      * or INTERACT_ACROSS_USERS_FULL permissions, if the userid is not for the caller.
2396      * @param checkShell TODO(yamasani):
2397      * @param message the message to log on security exception
2398      */
2399     void enforceCrossUserPermission(int callingUid, int userId, boolean requireFullPermission,
2400             boolean checkShell, String message) {
2401         if (userId < 0) {
2402             throw new IllegalArgumentException("Invalid userId " + userId);
2403         }
2404         if (checkShell) {
2405             enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId);
2406         }
2407         if (userId == UserHandle.getUserId(callingUid)) return;
2408         if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
2409             if (requireFullPermission) {
2410                 mContext.enforceCallingOrSelfPermission(
2411                         android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
2412             } else {
2413                 try {
2414                     mContext.enforceCallingOrSelfPermission(
2415                             android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
2416                 } catch (SecurityException se) {
2417                     mContext.enforceCallingOrSelfPermission(
2418                             android.Manifest.permission.INTERACT_ACROSS_USERS, message);
2419                 }
2420             }
2421         }
2422     }
2423
2424     void enforceShellRestriction(String restriction, int callingUid, int userHandle) {
2425         if (callingUid == Process.SHELL_UID) {
2426             if (userHandle >= 0
2427                     && sUserManager.hasUserRestriction(restriction, userHandle)) {
2428                 throw new SecurityException("Shell does not have permission to access user "
2429                         + userHandle);
2430             } else if (userHandle < 0) {
2431                 Slog.e(TAG, "Unable to check shell permission for user " + userHandle + "\n\t"
2432                         + Debug.getCallers(3));
2433             }
2434         }
2435     }
2436
2437     private BasePermission findPermissionTreeLP(String permName) {
2438         for(BasePermission bp : mSettings.mPermissionTrees.values()) {
2439             if (permName.startsWith(bp.name) &&
2440                     permName.length() > bp.name.length() &&
2441                     permName.charAt(bp.name.length()) == '.') {
2442                 return bp;
2443             }
2444         }
2445         return null;
2446     }
2447
2448     private BasePermission checkPermissionTreeLP(String permName) {
2449         if (permName != null) {
2450             BasePermission bp = findPermissionTreeLP(permName);
2451             if (bp != null) {
2452                 if (bp.uid == UserHandle.getAppId(Binder.getCallingUid())) {
2453                     return bp;
2454                 }
2455                 throw new SecurityException("Calling uid "
2456                         + Binder.getCallingUid()
2457                         + " is not allowed to add to permission tree "
2458                         + bp.name + " owned by uid " + bp.uid);
2459             }
2460         }
2461         throw new SecurityException("No permission tree found for " + permName);
2462     }
2463
2464     static boolean compareStrings(CharSequence s1, CharSequence s2) {
2465         if (s1 == null) {
2466             return s2 == null;
2467         }
2468         if (s2 == null) {
2469             return false;
2470         }
2471         if (s1.getClass() != s2.getClass()) {
2472             return false;
2473         }
2474         return s1.equals(s2);
2475     }
2476     
2477     static boolean comparePermissionInfos(PermissionInfo pi1, PermissionInfo pi2) {
2478         if (pi1.icon != pi2.icon) return false;
2479         if (pi1.logo != pi2.logo) return false;
2480         if (pi1.protectionLevel != pi2.protectionLevel) return false;
2481         if (!compareStrings(pi1.name, pi2.name)) return false;
2482         if (!compareStrings(pi1.nonLocalizedLabel, pi2.nonLocalizedLabel)) return false;
2483         // We'll take care of setting this one.
2484         if (!compareStrings(pi1.packageName, pi2.packageName)) return false;
2485         // These are not currently stored in settings.
2486         //if (!compareStrings(pi1.group, pi2.group)) return false;
2487         //if (!compareStrings(pi1.nonLocalizedDescription, pi2.nonLocalizedDescription)) return false;
2488         //if (pi1.labelRes != pi2.labelRes) return false;
2489         //if (pi1.descriptionRes != pi2.descriptionRes) return false;
2490         return true;
2491     }
2492
2493     int permissionInfoFootprint(PermissionInfo info) {
2494         int size = info.name.length();
2495         if (info.nonLocalizedLabel != null) size += info.nonLocalizedLabel.length();
2496         if (info.nonLocalizedDescription != null) size += info.nonLocalizedDescription.length();
2497         return size;
2498     }
2499
2500     int calculateCurrentPermissionFootprintLocked(BasePermission tree) {
2501         int size = 0;
2502         for (BasePermission perm : mSettings.mPermissions.values()) {
2503             if (perm.uid == tree.uid) {
2504                 size += perm.name.length() + permissionInfoFootprint(perm.perm.info);
2505             }
2506         }
2507         return size;
2508     }
2509
2510     void enforcePermissionCapLocked(PermissionInfo info, BasePermission tree) {
2511         // We calculate the max size of permissions defined by this uid and throw
2512         // if that plus the size of 'info' would exceed our stated maximum.
2513         if (tree.uid != Process.SYSTEM_UID) {
2514             final int curTreeSize = calculateCurrentPermissionFootprintLocked(tree);
2515             if (curTreeSize + permissionInfoFootprint(info) > MAX_PERMISSION_TREE_FOOTPRINT) {
2516                 throw new SecurityException("Permission tree size cap exceeded");
2517             }
2518         }
2519     }
2520
2521     boolean addPermissionLocked(PermissionInfo info, boolean async) {
2522         if (info.labelRes == 0 && info.nonLocalizedLabel == null) {
2523             throw new SecurityException("Label must be specified in permission");
2524         }
2525         BasePermission tree = checkPermissionTreeLP(info.name);
2526         BasePermission bp = mSettings.mPermissions.get(info.name);
2527         boolean added = bp == null;
2528         boolean changed = true;
2529         int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel);
2530         if (added) {
2531             enforcePermissionCapLocked(info, tree);
2532             bp = new BasePermission(info.name, tree.sourcePackage,
2533                     BasePermission.TYPE_DYNAMIC);
2534         } else if (bp.type != BasePermission.TYPE_DYNAMIC) {
2535             throw new SecurityException(
2536                     "Not allowed to modify non-dynamic permission "
2537                     + info.name);
2538         } else {
2539             if (bp.protectionLevel == fixedLevel
2540                     && bp.perm.owner.equals(tree.perm.owner)
2541                     && bp.uid == tree.uid
2542                     && comparePermissionInfos(bp.perm.info, info)) {
2543                 changed = false;
2544             }
2545         }
2546         bp.protectionLevel = fixedLevel;
2547         info = new PermissionInfo(info);
2548         info.protectionLevel = fixedLevel;
2549         bp.perm = new PackageParser.Permission(tree.perm.owner, info);
2550         bp.perm.info.packageName = tree.perm.info.packageName;
2551         bp.uid = tree.uid;
2552         if (added) {
2553             mSettings.mPermissions.put(info.name, bp);
2554         }
2555         if (changed) {
2556             if (!async) {
2557                 mSettings.writeLPr();
2558             } else {
2559                 scheduleWriteSettingsLocked();
2560             }
2561         }
2562         return added;
2563     }
2564
2565     @Override
2566     public boolean addPermission(PermissionInfo info) {
2567         synchronized (mPackages) {
2568             return addPermissionLocked(info, false);
2569         }
2570     }
2571
2572     @Override
2573     public boolean addPermissionAsync(PermissionInfo info) {
2574         synchronized (mPackages) {
2575             return addPermissionLocked(info, true);
2576         }
2577     }
2578
2579     @Override
2580     public void removePermission(String name) {
2581         synchronized (mPackages) {
2582             checkPermissionTreeLP(name);
2583             BasePermission bp = mSettings.mPermissions.get(name);
2584             if (bp != null) {
2585                 if (bp.type != BasePermission.TYPE_DYNAMIC) {
2586                     throw new SecurityException(
2587                             "Not allowed to modify non-dynamic permission "
2588                             + name);
2589                 }
2590                 mSettings.mPermissions.remove(name);
2591                 mSettings.writeLPr();
2592             }
2593         }
2594     }
2595
2596     private static void checkGrantRevokePermissions(PackageParser.Package pkg, BasePermission bp) {
2597         int index = pkg.requestedPermissions.indexOf(bp.name);
2598         if (index == -1) {
2599             throw new SecurityException("Package " + pkg.packageName
2600                     + " has not requested permission " + bp.name);
2601         }
2602         boolean isNormal =
2603                 ((bp.protectionLevel&PermissionInfo.PROTECTION_MASK_BASE)
2604                         == PermissionInfo.PROTECTION_NORMAL);
2605         boolean isDangerous =
2606                 ((bp.protectionLevel&PermissionInfo.PROTECTION_MASK_BASE)
2607                         == PermissionInfo.PROTECTION_DANGEROUS);
2608         boolean isDevelopment =
2609                 ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0);
2610
2611         if (!isNormal && !isDangerous && !isDevelopment) {
2612             throw new SecurityException("Permission " + bp.name
2613                     + " is not a changeable permission type");
2614         }
2615
2616         if (isNormal || isDangerous) {
2617             if (pkg.requestedPermissionsRequired.get(index)) {
2618                 throw new SecurityException("Can't change " + bp.name
2619                         + ". It is required by the application");
2620             }
2621         }
2622     }
2623
2624     @Override
2625     public void grantPermission(String packageName, String permissionName) {
2626         mContext.enforceCallingOrSelfPermission(
2627                 android.Manifest.permission.GRANT_REVOKE_PERMISSIONS, null);
2628         synchronized (mPackages) {
2629             final PackageParser.Package pkg = mPackages.get(packageName);
2630             if (pkg == null) {
2631                 throw new IllegalArgumentException("Unknown package: " + packageName);
2632             }
2633             final BasePermission bp = mSettings.mPermissions.get(permissionName);
2634             if (bp == null) {
2635                 throw new IllegalArgumentException("Unknown permission: " + permissionName);
2636             }
2637
2638             checkGrantRevokePermissions(pkg, bp);
2639
2640             final PackageSetting ps = (PackageSetting) pkg.mExtras;
2641             if (ps == null) {
2642                 return;
2643             }
2644             final GrantedPermissions gp = (ps.sharedUser != null) ? ps.sharedUser : ps;
2645             if (gp.grantedPermissions.add(permissionName)) {
2646                 if (ps.haveGids) {
2647                     gp.gids = appendInts(gp.gids, bp.gids);
2648                 }
2649                 mSettings.writeLPr();
2650             }
2651         }
2652     }
2653
2654     @Override
2655     public void revokePermission(String packageName, String permissionName) {
2656         int changedAppId = -1;
2657
2658         synchronized (mPackages) {
2659             final PackageParser.Package pkg = mPackages.get(packageName);
2660             if (pkg == null) {
2661                 throw new IllegalArgumentException("Unknown package: " + packageName);
2662             }
2663             if (pkg.applicationInfo.uid != Binder.getCallingUid()) {
2664                 mContext.enforceCallingOrSelfPermission(
2665                         android.Manifest.permission.GRANT_REVOKE_PERMISSIONS, null);
2666             }
2667             final BasePermission bp = mSettings.mPermissions.get(permissionName);
2668             if (bp == null) {
2669                 throw new IllegalArgumentException("Unknown permission: " + permissionName);
2670             }
2671
2672             checkGrantRevokePermissions(pkg, bp);
2673
2674             final PackageSetting ps = (PackageSetting) pkg.mExtras;
2675             if (ps == null) {
2676                 return;
2677             }
2678             final GrantedPermissions gp = (ps.sharedUser != null) ? ps.sharedUser : ps;
2679             if (gp.grantedPermissions.remove(permissionName)) {
2680                 gp.grantedPermissions.remove(permissionName);
2681                 if (ps.haveGids) {
2682                     gp.gids = removeInts(gp.gids, bp.gids);
2683                 }
2684                 mSettings.writeLPr();
2685                 changedAppId = ps.appId;
2686             }
2687         }
2688
2689         if (changedAppId >= 0) {
2690             // We changed the perm on someone, kill its processes.
2691             IActivityManager am = ActivityManagerNative.getDefault();
2692             if (am != null) {
2693                 final int callingUserId = UserHandle.getCallingUserId();
2694                 final long ident = Binder.clearCallingIdentity();
2695                 try {
2696                     //XXX we should only revoke for the calling user's app permissions,
2697                     // but for now we impact all users.
2698                     //am.killUid(UserHandle.getUid(callingUserId, changedAppId),
2699                     //        "revoke " + permissionName);
2700                     int[] users = sUserManager.getUserIds();
2701                     for (int user : users) {
2702                         am.killUid(UserHandle.getUid(user, changedAppId),
2703                                 "revoke " + permissionName);
2704                     }
2705                 } catch (RemoteException e) {
2706                 } finally {
2707                     Binder.restoreCallingIdentity(ident);
2708                 }
2709             }
2710         }
2711     }
2712
2713     @Override
2714     public boolean isProtectedBroadcast(String actionName) {
2715         synchronized (mPackages) {
2716             return mProtectedBroadcasts.contains(actionName);
2717         }
2718     }
2719
2720     @Override
2721     public int checkSignatures(String pkg1, String pkg2) {
2722         synchronized (mPackages) {
2723             final PackageParser.Package p1 = mPackages.get(pkg1);
2724             final PackageParser.Package p2 = mPackages.get(pkg2);
2725             if (p1 == null || p1.mExtras == null
2726                     || p2 == null || p2.mExtras == null) {
2727                 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
2728             }
2729             return compareSignatures(p1.mSignatures, p2.mSignatures);
2730         }
2731     }
2732
2733     @Override
2734     public int checkUidSignatures(int uid1, int uid2) {
2735         // Map to base uids.
2736         uid1 = UserHandle.getAppId(uid1);
2737         uid2 = UserHandle.getAppId(uid2);
2738         // reader
2739         synchronized (mPackages) {
2740             Signature[] s1;
2741             Signature[] s2;
2742             Object obj = mSettings.getUserIdLPr(uid1);
2743             if (obj != null) {
2744                 if (obj instanceof SharedUserSetting) {
2745                     s1 = ((SharedUserSetting)obj).signatures.mSignatures;
2746                 } else if (obj instanceof PackageSetting) {
2747                     s1 = ((PackageSetting)obj).signatures.mSignatures;
2748                 } else {
2749                     return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
2750                 }
2751             } else {
2752                 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
2753             }
2754             obj = mSettings.getUserIdLPr(uid2);
2755             if (obj != null) {
2756                 if (obj instanceof SharedUserSetting) {
2757                     s2 = ((SharedUserSetting)obj).signatures.mSignatures;
2758                 } else if (obj instanceof PackageSetting) {
2759                     s2 = ((PackageSetting)obj).signatures.mSignatures;
2760                 } else {
2761                     return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
2762                 }
2763             } else {
2764                 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
2765             }
2766             return compareSignatures(s1, s2);
2767         }
2768     }
2769
2770     /**
2771      * Compares two sets of signatures. Returns:
2772      * <br />
2773      * {@link PackageManager#SIGNATURE_NEITHER_SIGNED}: if both signature sets are null,
2774      * <br />
2775      * {@link PackageManager#SIGNATURE_FIRST_NOT_SIGNED}: if the first signature set is null,
2776      * <br />
2777      * {@link PackageManager#SIGNATURE_SECOND_NOT_SIGNED}: if the second signature set is null,
2778      * <br />
2779      * {@link PackageManager#SIGNATURE_MATCH}: if the two signature sets are identical,
2780      * <br />
2781      * {@link PackageManager#SIGNATURE_NO_MATCH}: if the two signature sets differ.
2782      */
2783     static int compareSignatures(Signature[] s1, Signature[] s2) {
2784         if (s1 == null) {
2785             return s2 == null
2786                     ? PackageManager.SIGNATURE_NEITHER_SIGNED
2787                     : PackageManager.SIGNATURE_FIRST_NOT_SIGNED;
2788         }
2789
2790         if (s2 == null) {
2791             return PackageManager.SIGNATURE_SECOND_NOT_SIGNED;
2792         }
2793
2794         if (s1.length != s2.length) {
2795             return PackageManager.SIGNATURE_NO_MATCH;
2796         }
2797
2798         // Since both signature sets are of size 1, we can compare without HashSets.
2799         if (s1.length == 1) {
2800             return s1[0].equals(s2[0]) ?
2801                     PackageManager.SIGNATURE_MATCH :
2802                     PackageManager.SIGNATURE_NO_MATCH;
2803         }
2804
2805         ArraySet<Signature> set1 = new ArraySet<Signature>();
2806         for (Signature sig : s1) {
2807             set1.add(sig);
2808         }
2809         ArraySet<Signature> set2 = new ArraySet<Signature>();
2810         for (Signature sig : s2) {
2811             set2.add(sig);
2812         }
2813         // Make sure s2 contains all signatures in s1.
2814         if (set1.equals(set2)) {
2815             return PackageManager.SIGNATURE_MATCH;
2816         }
2817         return PackageManager.SIGNATURE_NO_MATCH;
2818     }
2819
2820     /**
2821      * If the database version for this type of package (internal storage or
2822      * external storage) is less than the version where package signatures
2823      * were updated, return true.
2824      */
2825     private boolean isCompatSignatureUpdateNeeded(PackageParser.Package scannedPkg) {
2826         return (isExternal(scannedPkg) && mSettings.isExternalDatabaseVersionOlderThan(
2827                 DatabaseVersion.SIGNATURE_END_ENTITY))
2828                 || (!isExternal(scannedPkg) && mSettings.isInternalDatabaseVersionOlderThan(
2829                         DatabaseVersion.SIGNATURE_END_ENTITY));
2830     }
2831
2832     /**
2833      * Used for backward compatibility to make sure any packages with
2834      * certificate chains get upgraded to the new style. {@code existingSigs}
2835      * will be in the old format (since they were stored on disk from before the
2836      * system upgrade) and {@code scannedSigs} will be in the newer format.
2837      */
2838     private int compareSignaturesCompat(PackageSignatures existingSigs,
2839             PackageParser.Package scannedPkg) {
2840         if (!isCompatSignatureUpdateNeeded(scannedPkg)) {
2841             return PackageManager.SIGNATURE_NO_MATCH;
2842         }
2843
2844         ArraySet<Signature> existingSet = new ArraySet<Signature>();
2845         for (Signature sig : existingSigs.mSignatures) {
2846             existingSet.add(sig);
2847         }
2848         ArraySet<Signature> scannedCompatSet = new ArraySet<Signature>();
2849         for (Signature sig : scannedPkg.mSignatures) {
2850             try {
2851                 Signature[] chainSignatures = sig.getChainSignatures();
2852                 for (Signature chainSig : chainSignatures) {
2853                     scannedCompatSet.add(chainSig);
2854                 }
2855             } catch (CertificateEncodingException e) {
2856                 scannedCompatSet.add(sig);
2857             }
2858         }
2859         /*
2860          * Make sure the expanded scanned set contains all signatures in the
2861          * existing one.
2862          */
2863         if (scannedCompatSet.equals(existingSet)) {
2864             // Migrate the old signatures to the new scheme.
2865             existingSigs.assignSignatures(scannedPkg.mSignatures);
2866             // The new KeySets will be re-added later in the scanning process.
2867             synchronized (mPackages) {
2868                 mSettings.mKeySetManagerService.removeAppKeySetDataLPw(scannedPkg.packageName);
2869             }
2870             return PackageManager.SIGNATURE_MATCH;
2871         }
2872         return PackageManager.SIGNATURE_NO_MATCH;
2873     }
2874
2875     @Override
2876     public String[] getPackagesForUid(int uid) {
2877         uid = UserHandle.getAppId(uid);
2878         // reader
2879         synchronized (mPackages) {
2880             Object obj = mSettings.getUserIdLPr(uid);
2881             if (obj instanceof SharedUserSetting) {
2882                 final SharedUserSetting sus = (SharedUserSetting) obj;
2883                 final int N = sus.packages.size();
2884                 final String[] res = new String[N];
2885                 final Iterator<PackageSetting> it = sus.packages.iterator();
2886                 int i = 0;
2887                 while (it.hasNext()) {
2888                     res[i++] = it.next().name;
2889                 }
2890                 return res;
2891             } else if (obj instanceof PackageSetting) {
2892                 final PackageSetting ps = (PackageSetting) obj;
2893                 return new String[] { ps.name };
2894             }
2895         }
2896         return null;
2897     }
2898
2899     @Override
2900     public String getNameForUid(int uid) {
2901         // reader
2902         synchronized (mPackages) {
2903             Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
2904             if (obj instanceof SharedUserSetting) {
2905                 final SharedUserSetting sus = (SharedUserSetting) obj;
2906                 return sus.name + ":" + sus.userId;
2907             } else if (obj instanceof PackageSetting) {
2908                 final PackageSetting ps = (PackageSetting) obj;
2909                 return ps.name;
2910             }
2911         }
2912         return null;
2913     }
2914
2915     @Override
2916     public int getUidForSharedUser(String sharedUserName) {
2917         if(sharedUserName == null) {
2918             return -1;
2919         }
2920         // reader
2921         synchronized (mPackages) {
2922             final SharedUserSetting suid = mSettings.getSharedUserLPw(sharedUserName, 0, false);
2923             if (suid == null) {
2924                 return -1;
2925             }
2926             return suid.userId;
2927         }
2928     }
2929
2930     @Override
2931     public int getFlagsForUid(int uid) {
2932         synchronized (mPackages) {
2933             Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
2934             if (obj instanceof SharedUserSetting) {
2935                 final SharedUserSetting sus = (SharedUserSetting) obj;
2936                 return sus.pkgFlags;
2937             } else if (obj instanceof PackageSetting) {
2938                 final PackageSetting ps = (PackageSetting) obj;
2939                 return ps.pkgFlags;
2940             }
2941         }
2942         return 0;
2943     }
2944
2945     @Override
2946     public boolean isUidPrivileged(int uid) {
2947         uid = UserHandle.getAppId(uid);
2948         // reader
2949         synchronized (mPackages) {
2950             Object obj = mSettings.getUserIdLPr(uid);
2951             if (obj instanceof SharedUserSetting) {
2952                 final SharedUserSetting sus = (SharedUserSetting) obj;
2953                 final Iterator<PackageSetting> it = sus.packages.iterator();
2954                 while (it.hasNext()) {
2955                     if (it.next().isPrivileged()) {
2956                         return true;
2957                     }
2958                 }
2959             } else if (obj instanceof PackageSetting) {
2960                 final PackageSetting ps = (PackageSetting) obj;
2961                 return ps.isPrivileged();
2962             }
2963         }
2964         return false;
2965     }
2966
2967     @Override
2968     public String[] getAppOpPermissionPackages(String permissionName) {
2969         synchronized (mPackages) {
2970             ArraySet<String> pkgs = mAppOpPermissionPackages.get(permissionName);
2971             if (pkgs == null) {
2972                 return null;
2973             }
2974             return pkgs.toArray(new String[pkgs.size()]);
2975         }
2976     }
2977
2978     @Override
2979     public ResolveInfo resolveIntent(Intent intent, String resolvedType,
2980             int flags, int userId) {
2981         if (!sUserManager.exists(userId)) return null;
2982         enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "resolve intent");
2983         List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId);
2984         return chooseBestActivity(intent, resolvedType, flags, query, userId);
2985     }
2986
2987     @Override
2988     public void setLastChosenActivity(Intent intent, String resolvedType, int flags,
2989             IntentFilter filter, int match, ComponentName activity) {
2990         final int userId = UserHandle.getCallingUserId();
2991         if (DEBUG_PREFERRED) {
2992             Log.v(TAG, "setLastChosenActivity intent=" + intent
2993                 + " resolvedType=" + resolvedType
2994                 + " flags=" + flags
2995                 + " filter=" + filter
2996                 + " match=" + match
2997                 + " activity=" + activity);
2998             filter.dump(new PrintStreamPrinter(System.out), "    ");
2999         }
3000         intent.setComponent(null);
3001         List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId);
3002         // Find any earlier preferred or last chosen entries and nuke them
3003         findPreferredActivity(intent, resolvedType,
3004                 flags, query, 0, false, true, false, userId);
3005         // Add the new activity as the last chosen for this filter
3006         addPreferredActivityInternal(filter, match, null, activity, false, userId,
3007                 "Setting last chosen");
3008     }
3009
3010     @Override
3011     public ResolveInfo getLastChosenActivity(Intent intent, String resolvedType, int flags) {
3012         final int userId = UserHandle.getCallingUserId();
3013         if (DEBUG_PREFERRED) Log.v(TAG, "Querying last chosen activity for " + intent);
3014         List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId);
3015         return findPreferredActivity(intent, resolvedType, flags, query, 0,
3016                 false, false, false, userId);
3017     }
3018
3019     private ResolveInfo chooseBestActivity(Intent intent, String resolvedType,
3020             int flags, List<ResolveInfo> query, int userId) {
3021         if (query != null) {
3022             final int N = query.size();
3023             if (N == 1) {
3024                 return query.get(0);
3025             } else if (N > 1) {
3026                 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3027                 // If there is more than one activity with the same priority,
3028                 // then let the user decide between them.
3029                 ResolveInfo r0 = query.get(0);
3030                 ResolveInfo r1 = query.get(1);
3031                 if (DEBUG_INTENT_MATCHING || debug) {
3032                     Slog.v(TAG, r0.activityInfo.name + "=" + r0.priority + " vs "
3033                             + r1.activityInfo.name + "=" + r1.priority);
3034                 }
3035                 // If the first activity has a higher priority, or a different
3036                 // default, then it is always desireable to pick it.
3037                 if (r0.priority != r1.priority
3038                         || r0.preferredOrder != r1.preferredOrder
3039                         || r0.isDefault != r1.isDefault) {
3040                     return query.get(0);
3041                 }
3042                 // If we have saved a preference for a preferred activity for
3043                 // this Intent, use that.
3044                 ResolveInfo ri = findPreferredActivity(intent, resolvedType,
3045                         flags, query, r0.priority, true, false, debug, userId);
3046                 if (ri != null) {
3047                     return ri;
3048                 }
3049                 if (userId != 0) {
3050                     ri = new ResolveInfo(mResolveInfo);
3051                     ri.activityInfo = new ActivityInfo(ri.activityInfo);
3052                     ri.activityInfo.applicationInfo = new ApplicationInfo(
3053                             ri.activityInfo.applicationInfo);
3054                     ri.activityInfo.applicationInfo.uid = UserHandle.getUid(userId,
3055                             UserHandle.getAppId(ri.activityInfo.applicationInfo.uid));
3056                     return ri;
3057                 }
3058                 return mResolveInfo;
3059             }
3060         }
3061         return null;
3062     }
3063
3064     private ResolveInfo findPersistentPreferredActivityLP(Intent intent, String resolvedType,
3065             int flags, List<ResolveInfo> query, boolean debug, int userId) {
3066         final int N = query.size();
3067         PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
3068                 .get(userId);
3069         // Get the list of persistent preferred activities that handle the intent
3070         if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for presistent preferred activities...");
3071         List<PersistentPreferredActivity> pprefs = ppir != null
3072                 ? ppir.queryIntent(intent, resolvedType,
3073                         (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId)
3074                 : null;
3075         if (pprefs != null && pprefs.size() > 0) {
3076             final int M = pprefs.size();
3077             for (int i=0; i<M; i++) {
3078                 final PersistentPreferredActivity ppa = pprefs.get(i);
3079                 if (DEBUG_PREFERRED || debug) {
3080                     Slog.v(TAG, "Checking PersistentPreferredActivity ds="
3081                             + (ppa.countDataSchemes() > 0 ? ppa.getDataScheme(0) : "<none>")
3082                             + "\n  component=" + ppa.mComponent);
3083                     ppa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
3084                 }
3085                 final ActivityInfo ai = getActivityInfo(ppa.mComponent,
3086                         flags | PackageManager.GET_DISABLED_COMPONENTS, userId);
3087                 if (DEBUG_PREFERRED || debug) {
3088                     Slog.v(TAG, "Found persistent preferred activity:");
3089                     if (ai != null) {
3090                         ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
3091                     } else {
3092                         Slog.v(TAG, "  null");
3093                     }
3094                 }
3095                 if (ai == null) {
3096                     // This previously registered persistent preferred activity
3097                     // component is no longer known. Ignore it and do NOT remove it.
3098                     continue;
3099                 }
3100                 for (int j=0; j<N; j++) {
3101                     final ResolveInfo ri = query.get(j);
3102                     if (!ri.activityInfo.applicationInfo.packageName
3103                             .equals(ai.applicationInfo.packageName)) {
3104                         continue;
3105                     }
3106                     if (!ri.activityInfo.name.equals(ai.name)) {
3107                         continue;
3108                     }
3109                     //  Found a persistent preference that can handle the intent.
3110                     if (DEBUG_PREFERRED || debug) {
3111                         Slog.v(TAG, "Returning persistent preferred activity: " +
3112                                 ri.activityInfo.packageName + "/" + ri.activityInfo.name);
3113                     }
3114                     return ri;
3115                 }
3116             }
3117         }
3118         return null;
3119     }
3120
3121     ResolveInfo findPreferredActivity(Intent intent, String resolvedType, int flags,
3122             List<ResolveInfo> query, int priority, boolean always,
3123             boolean removeMatches, boolean debug, int userId) {
3124         if (!sUserManager.exists(userId)) return null;
3125         // writer
3126         synchronized (mPackages) {
3127             if (intent.getSelector() != null) {
3128                 intent = intent.getSelector();
3129             }
3130             if (DEBUG_PREFERRED) intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION);
3131
3132             // Try to find a matching persistent preferred activity.
3133             ResolveInfo pri = findPersistentPreferredActivityLP(intent, resolvedType, flags, query,
3134                     debug, userId);
3135
3136             // If a persistent preferred activity matched, use it.
3137             if (pri != null) {
3138                 return pri;
3139             }
3140
3141             PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
3142             // Get the list of preferred activities that handle the intent
3143             if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for preferred activities...");
3144             List<PreferredActivity> prefs = pir != null
3145                     ? pir.queryIntent(intent, resolvedType,
3146                             (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId)
3147                     : null;
3148             if (prefs != null && prefs.size() > 0) {
3149                 boolean changed = false;
3150                 try {
3151                     // First figure out how good the original match set is.
3152                     // We will only allow preferred activities that came
3153                     // from the same match quality.
3154                     int match = 0;
3155
3156                     if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Figuring out best match...");
3157
3158                     final int N = query.size();
3159                     for (int j=0; j<N; j++) {
3160                         final ResolveInfo ri = query.get(j);
3161                         if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Match for " + ri.activityInfo
3162                                 + ": 0x" + Integer.toHexString(match));
3163                         if (ri.match > match) {
3164                             match = ri.match;
3165                         }
3166                     }
3167
3168                     if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Best match: 0x"
3169                             + Integer.toHexString(match));
3170
3171                     match &= IntentFilter.MATCH_CATEGORY_MASK;
3172                     final int M = prefs.size();
3173                     for (int i=0; i<M; i++) {
3174                         final PreferredActivity pa = prefs.get(i);
3175                         if (DEBUG_PREFERRED || debug) {
3176                             Slog.v(TAG, "Checking PreferredActivity ds="
3177                                     + (pa.countDataSchemes() > 0 ? pa.getDataScheme(0) : "<none>")
3178                                     + "\n  component=" + pa.mPref.mComponent);
3179                             pa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
3180                         }
3181                         if (pa.mPref.mMatch != match) {
3182                             if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping bad match "
3183                                     + Integer.toHexString(pa.mPref.mMatch));
3184                             continue;
3185                         }
3186                         // If it's not an "always" type preferred activity and that's what we're
3187                         // looking for, skip it.
3188                         if (always && !pa.mPref.mAlways) {
3189                             if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping mAlways=false entry");
3190                             continue;
3191                         }
3192                         final ActivityInfo ai = getActivityInfo(pa.mPref.mComponent,
3193                                 flags | PackageManager.GET_DISABLED_COMPONENTS, userId);
3194                         if (DEBUG_PREFERRED || debug) {
3195                             Slog.v(TAG, "Found preferred activity:");
3196                             if (ai != null) {
3197                                 ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
3198                             } else {
3199                                 Slog.v(TAG, "  null");
3200                             }
3201                         }
3202                         if (ai == null) {
3203                             // This previously registered preferred activity
3204                             // component is no longer known.  Most likely an update
3205                             // to the app was installed and in the new version this
3206                             // component no longer exists.  Clean it up by removing
3207                             // it from the preferred activities list, and skip it.
3208                             Slog.w(TAG, "Removing dangling preferred activity: "
3209                                     + pa.mPref.mComponent);
3210                             pir.removeFilter(pa);
3211                             changed = true;
3212                             continue;
3213                         }
3214                         for (int j=0; j<N; j++) {
3215                             final ResolveInfo ri = query.get(j);
3216                             if (!ri.activityInfo.applicationInfo.packageName
3217                                     .equals(ai.applicationInfo.packageName)) {
3218                                 continue;
3219                             }
3220                             if (!ri.activityInfo.name.equals(ai.name)) {
3221                                 continue;
3222                             }
3223
3224                             if (removeMatches) {
3225                                 pir.removeFilter(pa);
3226                                 changed = true;
3227                                 if (DEBUG_PREFERRED) {
3228                                     Slog.v(TAG, "Removing match " + pa.mPref.mComponent);
3229                                 }
3230                                 break;
3231                             }
3232
3233                             // Okay we found a previously set preferred or last chosen app.
3234                             // If the result set is different from when this
3235                             // was created, we need to clear it and re-ask the
3236                             // user their preference, if we're looking for an "always" type entry.
3237                             if (always && !pa.mPref.sameSet(query, priority)) {
3238                                 Slog.i(TAG, "Result set changed, dropping preferred activity for "
3239                                         + intent + " type " + resolvedType);
3240                                 if (DEBUG_PREFERRED) {
3241                                     Slog.v(TAG, "Removing preferred activity since set changed "
3242                                             + pa.mPref.mComponent);
3243                                 }
3244                                 pir.removeFilter(pa);
3245                                 // Re-add the filter as a "last chosen" entry (!always)
3246                                 PreferredActivity lastChosen = new PreferredActivity(
3247                                         pa, pa.mPref.mMatch, null, pa.mPref.mComponent, false);
3248                                 pir.addFilter(lastChosen);
3249                                 changed = true;
3250                                 return null;
3251                             }
3252
3253                             // Yay! Either the set matched or we're looking for the last chosen
3254                             if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Returning preferred activity: "
3255                                     + ri.activityInfo.packageName + "/" + ri.activityInfo.name);
3256                             return ri;
3257                         }
3258                     }
3259                 } finally {
3260                     if (changed) {
3261                         if (DEBUG_PREFERRED) {
3262                             Slog.v(TAG, "Preferred activity bookkeeping changed; writing restrictions");
3263                         }
3264                         scheduleWritePackageRestrictionsLocked(userId);
3265                     }
3266                 }
3267             }
3268         }
3269         if (DEBUG_PREFERRED || debug) Slog.v(TAG, "No preferred activity to return");
3270         return null;
3271     }
3272
3273     /*
3274      * Returns if intent can be forwarded from the sourceUserId to the targetUserId
3275      */
3276     @Override
3277     public boolean canForwardTo(Intent intent, String resolvedType, int sourceUserId,
3278             int targetUserId) {
3279         mContext.enforceCallingOrSelfPermission(
3280                 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
3281         List<CrossProfileIntentFilter> matches =
3282                 getMatchingCrossProfileIntentFilters(intent, resolvedType, sourceUserId);
3283         if (matches != null) {
3284             int size = matches.size();
3285             for (int i = 0; i < size; i++) {
3286                 if (matches.get(i).getTargetUserId() == targetUserId) return true;
3287             }
3288         }
3289         return false;
3290     }
3291
3292     private List<CrossProfileIntentFilter> getMatchingCrossProfileIntentFilters(Intent intent,
3293             String resolvedType, int userId) {
3294         CrossProfileIntentResolver resolver = mSettings.mCrossProfileIntentResolvers.get(userId);
3295         if (resolver != null) {
3296             return resolver.queryIntent(intent, resolvedType, false, userId);
3297         }
3298         return null;
3299     }
3300
3301     @Override
3302     public List<ResolveInfo> queryIntentActivities(Intent intent,
3303             String resolvedType, int flags, int userId) {
3304         if (!sUserManager.exists(userId)) return Collections.emptyList();
3305         enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "query intent activities");
3306         ComponentName comp = intent.getComponent();
3307         if (comp == null) {
3308             if (intent.getSelector() != null) {
3309                 intent = intent.getSelector(); 
3310                 comp = intent.getComponent();
3311             }
3312         }
3313
3314         if (comp != null) {
3315             final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
3316             final ActivityInfo ai = getActivityInfo(comp, flags, userId);
3317             if (ai != null) {
3318                 final ResolveInfo ri = new ResolveInfo();
3319                 ri.activityInfo = ai;
3320                 list.add(ri);
3321             }
3322             return list;
3323         }
3324
3325         // reader
3326         synchronized (mPackages) {
3327             final String pkgName = intent.getPackage();
3328             if (pkgName == null) {
3329                 List<CrossProfileIntentFilter> matchingFilters =
3330                         getMatchingCrossProfileIntentFilters(intent, resolvedType, userId);
3331                 // Check for results that need to skip the current profile.
3332                 ResolveInfo resolveInfo  = querySkipCurrentProfileIntents(matchingFilters, intent,
3333                         resolvedType, flags, userId);
3334                 if (resolveInfo != null) {
3335                     List<ResolveInfo> result = new ArrayList<ResolveInfo>(1);
3336                     result.add(resolveInfo);
3337                     return result;
3338                 }
3339                 // Check for cross profile results.
3340                 resolveInfo = queryCrossProfileIntents(
3341                         matchingFilters, intent, resolvedType, flags, userId);
3342
3343                 // Check for results in the current profile.
3344                 List<ResolveInfo> result = mActivities.queryIntent(
3345                         intent, resolvedType, flags, userId);
3346                 if (resolveInfo != null) {
3347                     result.add(resolveInfo);
3348                     Collections.sort(result, mResolvePrioritySorter);
3349                 }
3350                 return result;
3351             }
3352             final PackageParser.Package pkg = mPackages.get(pkgName);
3353             if (pkg != null) {
3354                 return mActivities.queryIntentForPackage(intent, resolvedType, flags,
3355                         pkg.activities, userId);
3356             }
3357             return new ArrayList<ResolveInfo>();
3358         }
3359     }
3360
3361     private ResolveInfo querySkipCurrentProfileIntents(
3362             List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
3363             int flags, int sourceUserId) {
3364         if (matchingFilters != null) {
3365             int size = matchingFilters.size();
3366             for (int i = 0; i < size; i ++) {
3367                 CrossProfileIntentFilter filter = matchingFilters.get(i);
3368                 if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0) {
3369                     // Checking if there are activities in the target user that can handle the
3370                     // intent.
3371                     ResolveInfo resolveInfo = checkTargetCanHandle(filter, intent, resolvedType,
3372                             flags, sourceUserId);
3373                     if (resolveInfo != null) {
3374                         return resolveInfo;
3375                     }
3376                 }
3377             }
3378         }
3379         return null;
3380     }
3381
3382     // Return matching ResolveInfo if any for skip current profile intent filters.
3383     private ResolveInfo queryCrossProfileIntents(
3384             List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
3385             int flags, int sourceUserId) {
3386         if (matchingFilters != null) {
3387             // Two {@link CrossProfileIntentFilter}s can have the same targetUserId and
3388             // match the same intent. For performance reasons, it is better not to
3389             // run queryIntent twice for the same userId
3390             SparseBooleanArray alreadyTriedUserIds = new SparseBooleanArray();
3391             int size = matchingFilters.size();
3392             for (int i = 0; i < size; i++) {
3393                 CrossProfileIntentFilter filter = matchingFilters.get(i);
3394                 int targetUserId = filter.getTargetUserId();
3395                 if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) == 0
3396                         && !alreadyTriedUserIds.get(targetUserId)) {
3397                     // Checking if there are activities in the target user that can handle the
3398                     // intent.
3399                     ResolveInfo resolveInfo = checkTargetCanHandle(filter, intent, resolvedType,
3400                             flags, sourceUserId);
3401                     if (resolveInfo != null) return resolveInfo;
3402                     alreadyTriedUserIds.put(targetUserId, true);
3403                 }
3404             }
3405         }
3406         return null;
3407     }
3408
3409     private ResolveInfo checkTargetCanHandle(CrossProfileIntentFilter filter, Intent intent,
3410             String resolvedType, int flags, int sourceUserId) {
3411         List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent,
3412                 resolvedType, flags, filter.getTargetUserId());
3413         if (resultTargetUser != null && !resultTargetUser.isEmpty()) {
3414             return createForwardingResolveInfo(filter, sourceUserId, filter.getTargetUserId());
3415         }
3416         return null;
3417     }
3418
3419     private ResolveInfo createForwardingResolveInfo(IntentFilter filter,
3420             int sourceUserId, int targetUserId) {
3421         ResolveInfo forwardingResolveInfo = new ResolveInfo();
3422         String className;
3423         if (targetUserId == UserHandle.USER_OWNER) {
3424             className = FORWARD_INTENT_TO_USER_OWNER;
3425         } else {
3426             className = FORWARD_INTENT_TO_MANAGED_PROFILE;
3427         }
3428         ComponentName forwardingActivityComponentName = new ComponentName(
3429                 mAndroidApplication.packageName, className);
3430         ActivityInfo forwardingActivityInfo = getActivityInfo(forwardingActivityComponentName, 0,
3431                 sourceUserId);
3432         if (targetUserId == UserHandle.USER_OWNER) {
3433             forwardingActivityInfo.showUserIcon = UserHandle.USER_OWNER;
3434             forwardingResolveInfo.noResourceId = true;
3435         }
3436         forwardingResolveInfo.activityInfo = forwardingActivityInfo;
3437         forwardingResolveInfo.priority = 0;
3438         forwardingResolveInfo.preferredOrder = 0;
3439         forwardingResolveInfo.match = 0;
3440         forwardingResolveInfo.isDefault = true;
3441         forwardingResolveInfo.filter = filter;
3442         forwardingResolveInfo.targetUserId = targetUserId;
3443         return forwardingResolveInfo;
3444     }
3445
3446     @Override
3447     public List<ResolveInfo> queryIntentActivityOptions(ComponentName caller,
3448             Intent[] specifics, String[] specificTypes, Intent intent,
3449             String resolvedType, int flags, int userId) {
3450         if (!sUserManager.exists(userId)) return Collections.emptyList();
3451         enforceCrossUserPermission(Binder.getCallingUid(), userId, false,
3452                 false, "query intent activity options");
3453         final String resultsAction = intent.getAction();
3454
3455         List<ResolveInfo> results = queryIntentActivities(intent, resolvedType, flags
3456                 | PackageManager.GET_RESOLVED_FILTER, userId);
3457
3458         if (DEBUG_INTENT_MATCHING) {
3459             Log.v(TAG, "Query " + intent + ": " + results);
3460         }
3461
3462         int specificsPos = 0;
3463         int N;
3464
3465         // todo: note that the algorithm used here is O(N^2).  This
3466         // isn't a problem in our current environment, but if we start running
3467         // into situations where we have more than 5 or 10 matches then this
3468         // should probably be changed to something smarter...
3469
3470         // First we go through and resolve each of the specific items
3471         // that were supplied, taking care of removing any corresponding
3472         // duplicate items in the generic resolve list.
3473         if (specifics != null) {
3474             for (int i=0; i<specifics.length; i++) {
3475                 final Intent sintent = specifics[i];
3476                 if (sintent == null) {
3477                     continue;
3478                 }
3479
3480                 if (DEBUG_INTENT_MATCHING) {
3481                     Log.v(TAG, "Specific #" + i + ": " + sintent);
3482                 }
3483
3484                 String action = sintent.getAction();
3485                 if (resultsAction != null && resultsAction.equals(action)) {
3486                     // If this action was explicitly requested, then don't
3487                     // remove things that have it.
3488                     action = null;
3489                 }
3490
3491                 ResolveInfo ri = null;
3492                 ActivityInfo ai = null;
3493
3494                 ComponentName comp = sintent.getComponent();
3495                 if (comp == null) {
3496                     ri = resolveIntent(
3497                         sintent,
3498                         specificTypes != null ? specificTypes[i] : null,
3499                             flags, userId);
3500                     if (ri == null) {
3501                         continue;
3502                     }
3503                     if (ri == mResolveInfo) {
3504                         // ACK!  Must do something better with this.
3505                     }
3506                     ai = ri.activityInfo;
3507                     comp = new ComponentName(ai.applicationInfo.packageName,
3508                             ai.name);
3509                 } else {
3510                     ai = getActivityInfo(comp, flags, userId);
3511                     if (ai == null) {
3512                         continue;
3513                     }
3514                 }
3515
3516                 // Look for any generic query activities that are duplicates
3517                 // of this specific one, and remove them from the results.
3518                 if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Specific #" + i + ": " + ai);
3519                 N = results.size();
3520                 int j;
3521                 for (j=specificsPos; j<N; j++) {
3522                     ResolveInfo sri = results.get(j);
3523                     if ((sri.activityInfo.name.equals(comp.getClassName())
3524                             && sri.activityInfo.applicationInfo.packageName.equals(
3525                                     comp.getPackageName()))
3526                         || (action != null && sri.filter.matchAction(action))) {
3527                         results.remove(j);
3528                         if (DEBUG_INTENT_MATCHING) Log.v(
3529                             TAG, "Removing duplicate item from " + j
3530                             + " due to specific " + specificsPos);
3531                         if (ri == null) {
3532                             ri = sri;
3533                         }
3534                         j--;
3535                         N--;
3536                     }
3537                 }
3538
3539                 // Add this specific item to its proper place.
3540                 if (ri == null) {
3541                     ri = new ResolveInfo();
3542                     ri.activityInfo = ai;
3543                 }
3544                 results.add(specificsPos, ri);
3545                 ri.specificIndex = i;
3546                 specificsPos++;
3547             }
3548         }
3549
3550         // Now we go through the remaining generic results and remove any
3551         // duplicate actions that are found here.
3552         N = results.size();
3553         for (int i=specificsPos; i<N-1; i++) {
3554             final ResolveInfo rii = results.get(i);
3555             if (rii.filter == null) {
3556                 continue;
3557             }
3558
3559             // Iterate over all of the actions of this result's intent
3560             // filter...  typically this should be just one.
3561             final Iterator<String> it = rii.filter.actionsIterator();
3562             if (it == null) {
3563                 continue;
3564             }
3565             while (it.hasNext()) {
3566                 final String action = it.next();
3567                 if (resultsAction != null && resultsAction.equals(action)) {
3568                     // If this action was explicitly requested, then don't
3569                     // remove things that have it.
3570                     continue;
3571                 }
3572                 for (int j=i+1; j<N; j++) {
3573                     final ResolveInfo rij = results.get(j);
3574                     if (rij.filter != null && rij.filter.hasAction(action)) {
3575                         results.remove(j);
3576                         if (DEBUG_INTENT_MATCHING) Log.v(
3577                             TAG, "Removing duplicate item from " + j
3578                             + " due to action " + action + " at " + i);
3579                         j--;
3580                         N--;
3581                     }
3582                 }
3583             }
3584
3585             // If the caller didn't request filter information, drop it now
3586             // so we don't have to marshall/unmarshall it.
3587             if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
3588                 rii.filter = null;
3589             }
3590         }
3591
3592         // Filter out the caller activity if so requested.
3593         if (caller != null) {
3594             N = results.size();
3595             for (int i=0; i<N; i++) {
3596                 ActivityInfo ainfo = results.get(i).activityInfo;
3597                 if (caller.getPackageName().equals(ainfo.applicationInfo.packageName)
3598                         && caller.getClassName().equals(ainfo.name)) {
3599                     results.remove(i);
3600                     break;
3601                 }
3602             }
3603         }
3604
3605         // If the caller didn't request filter information,
3606         // drop them now so we don't have to
3607         // marshall/unmarshall it.
3608         if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
3609             N = results.size();
3610             for (int i=0; i<N; i++) {
3611                 results.get(i).filter = null;
3612             }
3613         }
3614
3615         if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Result: " + results);
3616         return results;
3617     }
3618
3619     @Override
3620     public List<ResolveInfo> queryIntentReceivers(Intent intent, String resolvedType, int flags,
3621             int userId) {
3622         if (!sUserManager.exists(userId)) return Collections.emptyList();
3623         ComponentName comp = intent.getComponent();
3624         if (comp == null) {
3625             if (intent.getSelector() != null) {
3626                 intent = intent.getSelector(); 
3627                 comp = intent.getComponent();
3628             }
3629         }
3630         if (comp != null) {
3631             List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
3632             ActivityInfo ai = getReceiverInfo(comp, flags, userId);
3633             if (ai != null) {
3634                 ResolveInfo ri = new ResolveInfo();
3635                 ri.activityInfo = ai;
3636                 list.add(ri);
3637             }
3638             return list;
3639         }
3640
3641         // reader
3642         synchronized (mPackages) {
3643             String pkgName = intent.getPackage();
3644             if (pkgName == null) {
3645                 return mReceivers.queryIntent(intent, resolvedType, flags, userId);
3646             }
3647             final PackageParser.Package pkg = mPackages.get(pkgName);
3648             if (pkg != null) {
3649                 return mReceivers.queryIntentForPackage(intent, resolvedType, flags, pkg.receivers,
3650                         userId);
3651             }
3652             return null;
3653         }
3654     }
3655
3656     @Override
3657     public ResolveInfo resolveService(Intent intent, String resolvedType, int flags, int userId) {
3658         List<ResolveInfo> query = queryIntentServices(intent, resolvedType, flags, userId);
3659         if (!sUserManager.exists(userId)) return null;
3660         if (query != null) {
3661             if (query.size() >= 1) {
3662                 // If there is more than one service with the same priority,
3663                 // just arbitrarily pick the first one.
3664                 return query.get(0);
3665             }
3666         }
3667         return null;
3668     }
3669
3670     @Override
3671     public List<ResolveInfo> queryIntentServices(Intent intent, String resolvedType, int flags,
3672             int userId) {
3673         if (!sUserManager.exists(userId)) return Collections.emptyList();
3674         ComponentName comp = intent.getComponent();
3675         if (comp == null) {
3676             if (intent.getSelector() != null) {
3677                 intent = intent.getSelector(); 
3678                 comp = intent.getComponent();
3679             }
3680         }
3681         if (comp != null) {
3682             final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
3683             final ServiceInfo si = getServiceInfo(comp, flags, userId);
3684             if (si != null) {
3685                 final ResolveInfo ri = new ResolveInfo();
3686                 ri.serviceInfo = si;
3687                 list.add(ri);
3688             }
3689             return list;
3690         }
3691
3692         // reader
3693         synchronized (mPackages) {
3694             String pkgName = intent.getPackage();
3695             if (pkgName == null) {
3696                 return mServices.queryIntent(intent, resolvedType, flags, userId);
3697             }
3698             final PackageParser.Package pkg = mPackages.get(pkgName);
3699             if (pkg != null) {
3700                 return mServices.queryIntentForPackage(intent, resolvedType, flags, pkg.services,
3701                         userId);
3702             }
3703             return null;
3704         }
3705     }
3706
3707     @Override
3708     public List<ResolveInfo> queryIntentContentProviders(
3709             Intent intent, String resolvedType, int flags, int userId) {
3710         if (!sUserManager.exists(userId)) return Collections.emptyList();
3711         ComponentName comp = intent.getComponent();
3712         if (comp == null) {
3713             if (intent.getSelector() != null) {
3714                 intent = intent.getSelector();
3715                 comp = intent.getComponent();
3716             }
3717         }
3718         if (comp != null) {
3719             final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
3720             final ProviderInfo pi = getProviderInfo(comp, flags, userId);
3721             if (pi != null) {
3722                 final ResolveInfo ri = new ResolveInfo();
3723                 ri.providerInfo = pi;
3724                 list.add(ri);
3725             }
3726             return list;
3727         }
3728
3729         // reader
3730         synchronized (mPackages) {
3731             String pkgName = intent.getPackage();
3732             if (pkgName == null) {
3733                 return mProviders.queryIntent(intent, resolvedType, flags, userId);
3734             }
3735             final PackageParser.Package pkg = mPackages.get(pkgName);
3736             if (pkg != null) {
3737                 return mProviders.queryIntentForPackage(
3738                         intent, resolvedType, flags, pkg.providers, userId);
3739             }
3740             return null;
3741         }
3742     }
3743
3744     @Override
3745     public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) {
3746         final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0;
3747
3748         enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, "get installed packages");
3749
3750         // writer
3751         synchronized (mPackages) {
3752             ArrayList<PackageInfo> list;
3753             if (listUninstalled) {
3754                 list = new ArrayList<PackageInfo>(mSettings.mPackages.size());
3755                 for (PackageSetting ps : mSettings.mPackages.values()) {
3756                     PackageInfo pi;
3757                     if (ps.pkg != null) {
3758                         pi = generatePackageInfo(ps.pkg, flags, userId);
3759                     } else {
3760                         pi = generatePackageInfoFromSettingsLPw(ps.name, flags, userId);
3761                     }
3762                     if (pi != null) {
3763                         list.add(pi);
3764                     }
3765                 }
3766             } else {
3767                 list = new ArrayList<PackageInfo>(mPackages.size());
3768                 for (PackageParser.Package p : mPackages.values()) {
3769                     PackageInfo pi = generatePackageInfo(p, flags, userId);
3770                     if (pi != null) {
3771                         list.add(pi);
3772                     }
3773                 }
3774             }
3775
3776             return new ParceledListSlice<PackageInfo>(list);
3777         }
3778     }
3779
3780     private void addPackageHoldingPermissions(ArrayList<PackageInfo> list, PackageSetting ps,
3781             String[] permissions, boolean[] tmp, int flags, int userId) {
3782         int numMatch = 0;
3783         final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps;
3784         for (int i=0; i<permissions.length; i++) {
3785             if (gp.grantedPermissions.contains(permissions[i])) {
3786                 tmp[i] = true;
3787                 numMatch++;
3788             } else {
3789                 tmp[i] = false;
3790             }
3791         }
3792         if (numMatch == 0) {
3793             return;
3794         }
3795         PackageInfo pi;
3796         if (ps.pkg != null) {
3797             pi = generatePackageInfo(ps.pkg, flags, userId);
3798         } else {
3799             pi = generatePackageInfoFromSettingsLPw(ps.name, flags, userId);
3800         }
3801         // The above might return null in cases of uninstalled apps or install-state
3802         // skew across users/profiles.
3803         if (pi != null) {
3804             if ((flags&PackageManager.GET_PERMISSIONS) == 0) {
3805                 if (numMatch == permissions.length) {
3806                     pi.requestedPermissions = permissions;
3807                 } else {
3808                     pi.requestedPermissions = new String[numMatch];
3809                     numMatch = 0;
3810                     for (int i=0; i<permissions.length; i++) {
3811                         if (tmp[i]) {
3812                             pi.requestedPermissions[numMatch] = permissions[i];
3813                             numMatch++;
3814                         }
3815                     }
3816                 }
3817             }
3818             list.add(pi);
3819         }
3820     }
3821
3822     @Override
3823     public ParceledListSlice<PackageInfo> getPackagesHoldingPermissions(
3824             String[] permissions, int flags, int userId) {
3825         if (!sUserManager.exists(userId)) return null;
3826         final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0;
3827
3828         // writer
3829         synchronized (mPackages) {
3830             ArrayList<PackageInfo> list = new ArrayList<PackageInfo>();
3831             boolean[] tmpBools = new boolean[permissions.length];
3832             if (listUninstalled) {
3833                 for (PackageSetting ps : mSettings.mPackages.values()) {
3834                     addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags, userId);
3835                 }
3836             } else {
3837                 for (PackageParser.Package pkg : mPackages.values()) {
3838                     PackageSetting ps = (PackageSetting)pkg.mExtras;
3839                     if (ps != null) {
3840                         addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags,
3841                                 userId);
3842                     }
3843                 }
3844             }
3845
3846             return new ParceledListSlice<PackageInfo>(list);
3847         }
3848     }
3849
3850     @Override
3851     public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags, int userId) {
3852         if (!sUserManager.exists(userId)) return null;
3853         final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0;
3854
3855         // writer
3856         synchronized (mPackages) {
3857             ArrayList<ApplicationInfo> list;
3858             if (listUninstalled) {
3859                 list = new ArrayList<ApplicationInfo>(mSettings.mPackages.size());
3860                 for (PackageSetting ps : mSettings.mPackages.values()) {
3861                     ApplicationInfo ai;
3862                     if (ps.pkg != null) {
3863                         ai = PackageParser.generateApplicationInfo(ps.pkg, flags,
3864                                 ps.readUserState(userId), userId);
3865                     } else {
3866                         ai = generateApplicationInfoFromSettingsLPw(ps.name, flags, userId);
3867                     }
3868                     if (ai != null) {
3869                         list.add(ai);
3870                     }
3871                 }
3872             } else {
3873                 list = new ArrayList<ApplicationInfo>(mPackages.size());
3874                 for (PackageParser.Package p : mPackages.values()) {
3875                     if (p.mExtras != null) {
3876                         ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
3877                                 ((PackageSetting)p.mExtras).readUserState(userId), userId);
3878                         if (ai != null) {
3879                             list.add(ai);
3880                         }
3881                     }
3882                 }
3883             }
3884
3885             return new ParceledListSlice<ApplicationInfo>(list);
3886         }
3887     }
3888
3889     public List<ApplicationInfo> getPersistentApplications(int flags) {
3890         final ArrayList<ApplicationInfo> finalList = new ArrayList<ApplicationInfo>();
3891
3892         // reader
3893         synchronized (mPackages) {
3894             final Iterator<PackageParser.Package> i = mPackages.values().iterator();
3895             final int userId = UserHandle.getCallingUserId();
3896             while (i.hasNext()) {
3897                 final PackageParser.Package p = i.next();
3898                 if (p.applicationInfo != null
3899                         && (p.applicationInfo.flags&ApplicationInfo.FLAG_PERSISTENT) != 0
3900                         && (!mSafeMode || isSystemApp(p))) {
3901                     PackageSetting ps = mSettings.mPackages.get(p.packageName);
3902                     if (ps != null) {
3903                         ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
3904                                 ps.readUserState(userId), userId);
3905                         if (ai != null) {
3906                             finalList.add(ai);
3907                         }
3908                     }
3909                 }
3910             }
3911         }
3912
3913         return finalList;
3914     }
3915
3916     @Override
3917     public ProviderInfo resolveContentProvider(String name, int flags, int userId) {
3918         if (!sUserManager.exists(userId)) return null;
3919         // reader
3920         synchronized (mPackages) {
3921             final PackageParser.Provider provider = mProvidersByAuthority.get(name);
3922             PackageSetting ps = provider != null
3923                     ? mSettings.mPackages.get(provider.owner.packageName)
3924                     : null;
3925             return ps != null
3926                     && mSettings.isEnabledLPr(provider.info, flags, userId)
3927                     && (!mSafeMode || (provider.info.applicationInfo.flags
3928                             &ApplicationInfo.FLAG_SYSTEM) != 0)
3929                     ? PackageParser.generateProviderInfo(provider, flags,
3930                             ps.readUserState(userId), userId)
3931                     : null;
3932         }
3933     }
3934
3935     /**
3936      * @deprecated
3937      */
3938     @Deprecated
3939     public void querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo) {
3940         // reader
3941         synchronized (mPackages) {
3942             final Iterator<Map.Entry<String, PackageParser.Provider>> i = mProvidersByAuthority
3943                     .entrySet().iterator();
3944             final int userId = UserHandle.getCallingUserId();
3945             while (i.hasNext()) {
3946                 Map.Entry<String, PackageParser.Provider> entry = i.next();
3947                 PackageParser.Provider p = entry.getValue();
3948                 PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
3949
3950                 if (ps != null && p.syncable
3951                         && (!mSafeMode || (p.info.applicationInfo.flags
3952                                 &ApplicationInfo.FLAG_SYSTEM) != 0)) {
3953                     ProviderInfo info = PackageParser.generateProviderInfo(p, 0,
3954                             ps.readUserState(userId), userId);
3955                     if (info != null) {
3956                         outNames.add(entry.getKey());
3957                         outInfo.add(info);
3958                     }
3959                 }
3960             }
3961         }
3962     }
3963
3964     @Override
3965     public List<ProviderInfo> queryContentProviders(String processName,
3966             int uid, int flags) {
3967         ArrayList<ProviderInfo> finalList = null;
3968         // reader
3969         synchronized (mPackages) {
3970             final Iterator<PackageParser.Provider> i = mProviders.mProviders.values().iterator();
3971             final int userId = processName != null ?
3972                     UserHandle.getUserId(uid) : UserHandle.getCallingUserId();
3973             while (i.hasNext()) {
3974                 final PackageParser.Provider p = i.next();
3975                 PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
3976                 if (ps != null && p.info.authority != null
3977                         && (processName == null
3978                                 || (p.info.processName.equals(processName)
3979                                         && UserHandle.isSameApp(p.info.applicationInfo.uid, uid)))
3980                         && mSettings.isEnabledLPr(p.info, flags, userId)
3981                         && (!mSafeMode
3982                                 || (p.info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0)) {
3983                     if (finalList == null) {
3984                         finalList = new ArrayList<ProviderInfo>(3);
3985                     }
3986                     ProviderInfo info = PackageParser.generateProviderInfo(p, flags,
3987                             ps.readUserState(userId), userId);
3988                     if (info != null) {
3989                         finalList.add(info);
3990                     }
3991                 }
3992             }
3993         }
3994
3995         if (finalList != null) {
3996             Collections.sort(finalList, mProviderInitOrderSorter);
3997         }
3998
3999         return finalList;
4000     }
4001
4002     @Override
4003     public InstrumentationInfo getInstrumentationInfo(ComponentName name,
4004             int flags) {
4005         // reader
4006         synchronized (mPackages) {
4007             final PackageParser.Instrumentation i = mInstrumentation.get(name);
4008             return PackageParser.generateInstrumentationInfo(i, flags);
4009         }
4010     }
4011
4012     @Override
4013     public List<InstrumentationInfo> queryInstrumentation(String targetPackage,
4014             int flags) {
4015         ArrayList<InstrumentationInfo> finalList =
4016             new ArrayList<InstrumentationInfo>();
4017
4018         // reader
4019         synchronized (mPackages) {
4020             final Iterator<PackageParser.Instrumentation> i = mInstrumentation.values().iterator();
4021             while (i.hasNext()) {
4022                 final PackageParser.Instrumentation p = i.next();
4023                 if (targetPackage == null
4024                         || targetPackage.equals(p.info.targetPackage)) {
4025                     InstrumentationInfo ii = PackageParser.generateInstrumentationInfo(p,
4026                             flags);
4027                     if (ii != null) {
4028                         finalList.add(ii);
4029                     }
4030                 }
4031             }
4032         }
4033
4034         return finalList;
4035     }
4036
4037     private void createIdmapsForPackageLI(PackageParser.Package pkg) {
4038         ArrayMap<String, PackageParser.Package> overlays = mOverlays.get(pkg.packageName);
4039         if (overlays == null) {
4040             Slog.w(TAG, "Unable to create idmap for " + pkg.packageName + ": no overlay packages");
4041             return;
4042         }
4043         for (PackageParser.Package opkg : overlays.values()) {
4044             // Not much to do if idmap fails: we already logged the error
4045             // and we certainly don't want to abort installation of pkg simply
4046             // because an overlay didn't fit properly. For these reasons,
4047             // ignore the return value of createIdmapForPackagePairLI.
4048             createIdmapForPackagePairLI(pkg, opkg);
4049         }
4050     }
4051
4052     private boolean createIdmapForPackagePairLI(PackageParser.Package pkg,
4053             PackageParser.Package opkg) {
4054         if (!opkg.mTrustedOverlay) {
4055             Slog.w(TAG, "Skipping target and overlay pair " + pkg.baseCodePath + " and " +
4056                     opkg.baseCodePath + ": overlay not trusted");
4057             return false;
4058         }
4059         ArrayMap<String, PackageParser.Package> overlaySet = mOverlays.get(pkg.packageName);
4060         if (overlaySet == null) {
4061             Slog.e(TAG, "was about to create idmap for " + pkg.baseCodePath + " and " +
4062                     opkg.baseCodePath + " but target package has no known overlays");
4063             return false;
4064         }
4065         final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
4066         // TODO: generate idmap for split APKs
4067         if (mInstaller.idmap(pkg.baseCodePath, opkg.baseCodePath, sharedGid) != 0) {
4068             Slog.e(TAG, "Failed to generate idmap for " + pkg.baseCodePath + " and "
4069                     + opkg.baseCodePath);
4070             return false;
4071         }
4072         PackageParser.Package[] overlayArray =
4073             overlaySet.values().toArray(new PackageParser.Package[0]);
4074         Comparator<PackageParser.Package> cmp = new Comparator<PackageParser.Package>() {
4075             public int compare(PackageParser.Package p1, PackageParser.Package p2) {
4076                 return p1.mOverlayPriority - p2.mOverlayPriority;
4077             }
4078         };
4079         Arrays.sort(overlayArray, cmp);
4080
4081         pkg.applicationInfo.resourceDirs = new String[overlayArray.length];
4082         int i = 0;
4083         for (PackageParser.Package p : overlayArray) {
4084             pkg.applicationInfo.resourceDirs[i++] = p.baseCodePath;
4085         }
4086         return true;
4087     }
4088
4089     private void scanDirLI(File dir, int parseFlags, int scanFlags, long currentTime) {
4090         final File[] files = dir.listFiles();
4091         if (ArrayUtils.isEmpty(files)) {
4092             Log.d(TAG, "No files in app dir " + dir);
4093             return;
4094         }
4095
4096         if (DEBUG_PACKAGE_SCANNING) {
4097             Log.d(TAG, "Scanning app dir " + dir + " scanFlags=" + scanFlags
4098                     + " flags=0x" + Integer.toHexString(parseFlags));
4099         }
4100
4101         for (File file : files) {
4102             final boolean isPackage = (isApkFile(file) || file.isDirectory())
4103                     && !PackageInstallerService.isStageName(file.getName());
4104             if (!isPackage) {
4105                 // Ignore entries which are not packages
4106                 continue;
4107             }
4108             try {
4109                 scanPackageLI(file, parseFlags | PackageParser.PARSE_MUST_BE_APK,
4110                         scanFlags, currentTime, null);
4111             } catch (PackageManagerException e) {
4112                 Slog.w(TAG, "Failed to parse " + file + ": " + e.getMessage());
4113
4114                 // Delete invalid userdata apps
4115                 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM) == 0 &&
4116                         e.error == PackageManager.INSTALL_FAILED_INVALID_APK) {
4117                     logCriticalInfo(Log.WARN, "Deleting invalid package at " + file);
4118                     if (file.isDirectory()) {
4119                         FileUtils.deleteContents(file);
4120                     }
4121                     file.delete();
4122                 }
4123             }
4124         }
4125     }
4126
4127     private static File getSettingsProblemFile() {
4128         File dataDir = Environment.getDataDirectory();
4129         File systemDir = new File(dataDir, "system");
4130         File fname = new File(systemDir, "uiderrors.txt");
4131         return fname;
4132     }
4133
4134     static void reportSettingsProblem(int priority, String msg) {
4135         logCriticalInfo(priority, msg);
4136     }
4137
4138     static void logCriticalInfo(int priority, String msg) {
4139         Slog.println(priority, TAG, msg);
4140         EventLogTags.writePmCriticalInfo(msg);
4141         try {
4142             File fname = getSettingsProblemFile();
4143             FileOutputStream out = new FileOutputStream(fname, true);
4144             PrintWriter pw = new FastPrintWriter(out);
4145             SimpleDateFormat formatter = new SimpleDateFormat();
4146             String dateString = formatter.format(new Date(System.currentTimeMillis()));
4147             pw.println(dateString + ": " + msg);
4148             pw.close();
4149             FileUtils.setPermissions(
4150                     fname.toString(),
4151                     FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IROTH,
4152                     -1, -1);
4153         } catch (java.io.IOException e) {
4154         }
4155     }
4156
4157     private void collectCertificatesLI(PackageParser pp, PackageSetting ps,
4158             PackageParser.Package pkg, File srcFile, int parseFlags)
4159             throws PackageManagerException {
4160         if (ps != null
4161                 && ps.codePath.equals(srcFile)
4162                 && ps.timeStamp == srcFile.lastModified()
4163                 && !isCompatSignatureUpdateNeeded(pkg)) {
4164             long mSigningKeySetId = ps.keySetData.getProperSigningKeySet();
4165             if (ps.signatures.mSignatures != null
4166                     && ps.signatures.mSignatures.length != 0
4167                     && mSigningKeySetId != PackageKeySetData.KEYSET_UNASSIGNED) {
4168                 // Optimization: reuse the existing cached certificates
4169                 // if the package appears to be unchanged.
4170                 pkg.mSignatures = ps.signatures.mSignatures;
4171                 KeySetManagerService ksms = mSettings.mKeySetManagerService;
4172                 synchronized (mPackages) {
4173                     pkg.mSigningKeys = ksms.getPublicKeysFromKeySetLPr(mSigningKeySetId);
4174                 }
4175                 return;
4176             }
4177
4178             Slog.w(TAG, "PackageSetting for " + ps.name
4179                     + " is missing signatures.  Collecting certs again to recover them.");
4180         } else {
4181             Log.i(TAG, srcFile.toString() + " changed; collecting certs");
4182         }
4183
4184         try {
4185             pp.collectCertificates(pkg, parseFlags);
4186             pp.collectManifestDigest(pkg);
4187         } catch (PackageParserException e) {
4188             throw PackageManagerException.from(e);
4189         }
4190     }
4191
4192     /*
4193      *  Scan a package and return the newly parsed package.
4194      *  Returns null in case of errors and the error code is stored in mLastScanError
4195      */
4196     private PackageParser.Package scanPackageLI(File scanFile, int parseFlags, int scanFlags,
4197             long currentTime, UserHandle user) throws PackageManagerException {
4198         if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanFile);
4199         parseFlags |= mDefParseFlags;
4200         PackageParser pp = new PackageParser();
4201         pp.setSeparateProcesses(mSeparateProcesses);
4202         pp.setOnlyCoreApps(mOnlyCore);
4203         pp.setDisplayMetrics(mMetrics);
4204
4205         if ((scanFlags & SCAN_TRUSTED_OVERLAY) != 0) {
4206             parseFlags |= PackageParser.PARSE_TRUSTED_OVERLAY;
4207         }
4208
4209         final PackageParser.Package pkg;
4210         try {
4211             pkg = pp.parsePackage(scanFile, parseFlags);
4212         } catch (PackageParserException e) {
4213             throw PackageManagerException.from(e);
4214         }
4215
4216         PackageSetting ps = null;
4217         PackageSetting updatedPkg;
4218         // reader
4219         synchronized (mPackages) {
4220             // Look to see if we already know about this package.
4221             String oldName = mSettings.mRenamedPackages.get(pkg.packageName);
4222             if (pkg.mOriginalPackages != null && pkg.mOriginalPackages.contains(oldName)) {
4223                 // This package has been renamed to its original name.  Let's
4224                 // use that.
4225                 ps = mSettings.peekPackageLPr(oldName);
4226             }
4227             // If there was no original package, see one for the real package name.
4228             if (ps == null) {
4229                 ps = mSettings.peekPackageLPr(pkg.packageName);
4230             }
4231             // Check to see if this package could be hiding/updating a system
4232             // package.  Must look for it either under the original or real
4233             // package name depending on our state.
4234             updatedPkg = mSettings.getDisabledSystemPkgLPr(ps != null ? ps.name : pkg.packageName);
4235             if (DEBUG_INSTALL && updatedPkg != null) Slog.d(TAG, "updatedPkg = " + updatedPkg);
4236         }
4237         boolean updatedPkgBetter = false;
4238         // First check if this is a system package that may involve an update
4239         if (updatedPkg != null && (parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) {
4240             if (ps != null && !ps.codePath.equals(scanFile)) {
4241                 // The path has changed from what was last scanned...  check the
4242                 // version of the new path against what we have stored to determine
4243                 // what to do.
4244                 if (DEBUG_INSTALL) Slog.d(TAG, "Path changing from " + ps.codePath);
4245                 if (pkg.mVersionCode < ps.versionCode) {
4246                     // The system package has been updated and the code path does not match
4247                     // Ignore entry. Skip it.
4248                     logCriticalInfo(Log.INFO, "Package " + ps.name + " at " + scanFile
4249                             + " ignored: updated version " + ps.versionCode
4250                             + " better than this " + pkg.mVersionCode);
4251                     if (!updatedPkg.codePath.equals(scanFile)) {
4252                         Slog.w(PackageManagerService.TAG, "Code path for hidden system pkg : "
4253                                 + ps.name + " changing from " + updatedPkg.codePathString
4254                                 + " to " + scanFile);
4255                         updatedPkg.codePath = scanFile;
4256                         updatedPkg.codePathString = scanFile.toString();
4257                         // This is the point at which we know that the system-disk APK
4258                         // for this package has moved during a reboot (e.g. due to an OTA),
4259                         // so we need to reevaluate it for privilege policy.
4260                         if (locationIsPrivileged(scanFile)) {
4261                             updatedPkg.pkgFlags |= ApplicationInfo.FLAG_PRIVILEGED;
4262                         }
4263                     }
4264                     updatedPkg.pkg = pkg;
4265                     throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE, null);
4266                 } else {
4267                     // The current app on the system partition is better than
4268                     // what we have updated to on the data partition; switch
4269                     // back to the system partition version.
4270                     // At this point, its safely assumed that package installation for
4271                     // apps in system partition will go through. If not there won't be a working
4272                     // version of the app
4273                     // writer
4274                     synchronized (mPackages) {
4275                         // Just remove the loaded entries from package lists.
4276                         mPackages.remove(ps.name);
4277                     }
4278
4279                     logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile
4280                             + " reverting from " + ps.codePathString
4281                             + ": new version " + pkg.mVersionCode
4282                             + " better than installed " + ps.versionCode);
4283
4284                     InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
4285                             ps.codePathString, ps.resourcePathString, ps.legacyNativeLibraryPathString,
4286                             getAppDexInstructionSets(ps));
4287                     synchronized (mInstallLock) {
4288                         args.cleanUpResourcesLI();
4289                     }
4290                     synchronized (mPackages) {
4291                         mSettings.enableSystemPackageLPw(ps.name);
4292                     }
4293                     updatedPkgBetter = true;
4294                 }
4295             }
4296         }
4297
4298         if (updatedPkg != null) {
4299             // An updated system app will not have the PARSE_IS_SYSTEM flag set
4300             // initially
4301             parseFlags |= PackageParser.PARSE_IS_SYSTEM;
4302
4303             // An updated privileged app will not have the PARSE_IS_PRIVILEGED
4304             // flag set initially
4305             if ((updatedPkg.pkgFlags & ApplicationInfo.FLAG_PRIVILEGED) != 0) {
4306                 parseFlags |= PackageParser.PARSE_IS_PRIVILEGED;
4307             }
4308         }
4309
4310         // Verify certificates against what was last scanned
4311         collectCertificatesLI(pp, ps, pkg, scanFile, parseFlags);
4312
4313         /*
4314          * A new system app appeared, but we already had a non-system one of the
4315          * same name installed earlier.
4316          */
4317         boolean shouldHideSystemApp = false;
4318         if (updatedPkg == null && ps != null
4319                 && (parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0 && !isSystemApp(ps)) {
4320             /*
4321              * Check to make sure the signatures match first. If they don't,
4322              * wipe the installed application and its data.
4323              */
4324             if (compareSignatures(ps.signatures.mSignatures, pkg.mSignatures)
4325                     != PackageManager.SIGNATURE_MATCH) {
4326                 logCriticalInfo(Log.WARN, "Package " + ps.name + " appeared on system, but"
4327                         + " signatures don't match existing userdata copy; removing");
4328                 deletePackageLI(pkg.packageName, null, true, null, null, 0, null, false);
4329                 ps = null;
4330             } else {
4331                 /*
4332                  * If the newly-added system app is an older version than the
4333                  * already installed version, hide it. It will be scanned later
4334                  * and re-added like an update.
4335                  */
4336                 if (pkg.mVersionCode < ps.versionCode) {
4337                     shouldHideSystemApp = true;
4338                     logCriticalInfo(Log.INFO, "Package " + ps.name + " appeared at " + scanFile
4339                             + " but new version " + pkg.mVersionCode + " better than installed "
4340                             + ps.versionCode + "; hiding system");
4341                 } else {
4342                     /*
4343                      * The newly found system app is a newer version that the
4344                      * one previously installed. Simply remove the
4345                      * already-installed application and replace it with our own
4346                      * while keeping the application data.
4347                      */
4348                     logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile
4349                             + " reverting from " + ps.codePathString + ": new version "
4350                             + pkg.mVersionCode + " better than installed " + ps.versionCode);
4351                     InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
4352                             ps.codePathString, ps.resourcePathString, ps.legacyNativeLibraryPathString,
4353                             getAppDexInstructionSets(ps));
4354                     synchronized (mInstallLock) {
4355                         args.cleanUpResourcesLI();
4356                     }
4357                 }
4358             }
4359         }
4360
4361         // The apk is forward locked (not public) if its code and resources
4362         // are kept in different files. (except for app in either system or
4363         // vendor path).
4364         // TODO grab this value from PackageSettings
4365         if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
4366             if (ps != null && !ps.codePath.equals(ps.resourcePath)) {
4367                 parseFlags |= PackageParser.PARSE_FORWARD_LOCK;
4368             }
4369         }
4370
4371         // TODO: extend to support forward-locked splits
4372         String resourcePath = null;
4373         String baseResourcePath = null;
4374         if ((parseFlags & PackageParser.PARSE_FORWARD_LOCK) != 0 && !updatedPkgBetter) {
4375             if (ps != null && ps.resourcePathString != null) {
4376                 resourcePath = ps.resourcePathString;
4377                 baseResourcePath = ps.resourcePathString;
4378             } else {
4379                 // Should not happen at all. Just log an error.
4380                 Slog.e(TAG, "Resource path not set for pkg : " + pkg.packageName);
4381             }
4382         } else {
4383             resourcePath = pkg.codePath;
4384             baseResourcePath = pkg.baseCodePath;
4385         }
4386
4387         // Set application objects path explicitly.
4388         pkg.applicationInfo.setCodePath(pkg.codePath);
4389         pkg.applicationInfo.setBaseCodePath(pkg.baseCodePath);
4390         pkg.applicationInfo.setSplitCodePaths(pkg.splitCodePaths);
4391         pkg.applicationInfo.setResourcePath(resourcePath);
4392         pkg.applicationInfo.setBaseResourcePath(baseResourcePath);
4393         pkg.applicationInfo.setSplitResourcePaths(pkg.splitCodePaths);
4394
4395         // Note that we invoke the following method only if we are about to unpack an application
4396         PackageParser.Package scannedPkg = scanPackageLI(pkg, parseFlags, scanFlags
4397                 | SCAN_UPDATE_SIGNATURE, currentTime, user);
4398
4399         /*
4400          * If the system app should be overridden by a previously installed
4401          * data, hide the system app now and let the /data/app scan pick it up
4402          * again.
4403          */
4404         if (shouldHideSystemApp) {
4405             synchronized (mPackages) {
4406                 /*
4407                  * We have to grant systems permissions before we hide, because
4408                  * grantPermissions will assume the package update is trying to
4409                  * expand its permissions.
4410                  */
4411                 grantPermissionsLPw(pkg, true, pkg.packageName);
4412                 mSettings.disableSystemPackageLPw(pkg.packageName);
4413             }
4414         }
4415
4416         return scannedPkg;
4417     }
4418
4419     private static String fixProcessName(String defProcessName,
4420             String processName, int uid) {
4421         if (processName == null) {
4422             return defProcessName;
4423         }
4424         return processName;
4425     }
4426
4427     private void verifySignaturesLP(PackageSetting pkgSetting, PackageParser.Package pkg)
4428             throws PackageManagerException {
4429         if (pkgSetting.signatures.mSignatures != null) {
4430             // Already existing package. Make sure signatures match
4431             boolean match = compareSignatures(pkgSetting.signatures.mSignatures, pkg.mSignatures)
4432                     == PackageManager.SIGNATURE_MATCH;
4433             if (!match) {
4434                 match = compareSignaturesCompat(pkgSetting.signatures, pkg)
4435                         == PackageManager.SIGNATURE_MATCH;
4436             }
4437             if (!match) {
4438                 throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
4439                         + pkg.packageName + " signatures do not match the "
4440                         + "previously installed version; ignoring!");
4441             }
4442         }
4443
4444         // Check for shared user signatures
4445         if (pkgSetting.sharedUser != null && pkgSetting.sharedUser.signatures.mSignatures != null) {
4446             // Already existing package. Make sure signatures match
4447             boolean match = compareSignatures(pkgSetting.sharedUser.signatures.mSignatures,
4448                     pkg.mSignatures) == PackageManager.SIGNATURE_MATCH;
4449             if (!match) {
4450                 match = compareSignaturesCompat(pkgSetting.sharedUser.signatures, pkg)
4451                         == PackageManager.SIGNATURE_MATCH;
4452             }
4453             if (!match) {
4454                 throw new PackageManagerException(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
4455                         "Package " + pkg.packageName
4456                         + " has no signatures that match those in shared user "
4457                         + pkgSetting.sharedUser.name + "; ignoring!");
4458             }
4459         }
4460     }
4461
4462     /**
4463      * Enforces that only the system UID or root's UID can call a method exposed
4464      * via Binder.
4465      *
4466      * @param message used as message if SecurityException is thrown
4467      * @throws SecurityException if the caller is not system or root
4468      */
4469     private static final void enforceSystemOrRoot(String message) {
4470         final int uid = Binder.getCallingUid();
4471         if (uid != Process.SYSTEM_UID && uid != 0) {
4472             throw new SecurityException(message);
4473         }
4474     }
4475
4476     @Override
4477     public void performBootDexOpt() {
4478         enforceSystemOrRoot("Only the system can request dexopt be performed");
4479
4480         final ArraySet<PackageParser.Package> pkgs;
4481         synchronized (mPackages) {
4482             pkgs = mDeferredDexOpt;
4483             mDeferredDexOpt = null;
4484         }
4485
4486         if (pkgs != null) {
4487             // Sort apps by importance for dexopt ordering. Important apps are given more priority
4488             // in case the device runs out of space.
4489             ArrayList<PackageParser.Package> sortedPkgs = new ArrayList<PackageParser.Package>();
4490             // Give priority to core apps.
4491             for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) {
4492                 PackageParser.Package pkg = it.next();
4493                 if (pkg.coreApp) {
4494                     if (DEBUG_DEXOPT) {
4495                         Log.i(TAG, "Adding core app " + sortedPkgs.size() + ": " + pkg.packageName);
4496                     }
4497                     sortedPkgs.add(pkg);
4498                     it.remove();
4499                 }
4500             }
4501             // Give priority to system apps that listen for pre boot complete.
4502             Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
4503             ArraySet<String> pkgNames = getPackageNamesForIntent(intent);
4504             for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) {
4505                 PackageParser.Package pkg = it.next();
4506                 if (pkgNames.contains(pkg.packageName)) {
4507                     if (DEBUG_DEXOPT) {
4508                         Log.i(TAG, "Adding pre boot system app " + sortedPkgs.size() + ": " + pkg.packageName);
4509                     }
4510                     sortedPkgs.add(pkg);
4511                     it.remove();
4512                 }
4513             }
4514             // Give priority to system apps.
4515             for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) {
4516                 PackageParser.Package pkg = it.next();
4517                 if (isSystemApp(pkg) && !isUpdatedSystemApp(pkg)) {
4518                     if (DEBUG_DEXOPT) {
4519                         Log.i(TAG, "Adding system app " + sortedPkgs.size() + ": " + pkg.packageName);
4520                     }
4521                     sortedPkgs.add(pkg);
4522                     it.remove();
4523                 }
4524             }
4525             // Give priority to updated system apps.
4526             for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) {
4527                 PackageParser.Package pkg = it.next();
4528                 if (isUpdatedSystemApp(pkg)) {
4529                     if (DEBUG_DEXOPT) {
4530                         Log.i(TAG, "Adding updated system app " + sortedPkgs.size() + ": " + pkg.packageName);
4531                     }
4532                     sortedPkgs.add(pkg);
4533                     it.remove();
4534                 }
4535             }
4536             // Give priority to apps that listen for boot complete.
4537             intent = new Intent(Intent.ACTION_BOOT_COMPLETED);
4538             pkgNames = getPackageNamesForIntent(intent);
4539             for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) {
4540                 PackageParser.Package pkg = it.next();
4541                 if (pkgNames.contains(pkg.packageName)) {
4542                     if (DEBUG_DEXOPT) {
4543                         Log.i(TAG, "Adding boot app " + sortedPkgs.size() + ": " + pkg.packageName);
4544                     }
4545                     sortedPkgs.add(pkg);
4546                     it.remove();
4547                 }
4548             }
4549             // Filter out packages that aren't recently used.
4550             filterRecentlyUsedApps(pkgs);
4551             // Add all remaining apps.
4552             for (PackageParser.Package pkg : pkgs) {
4553                 if (DEBUG_DEXOPT) {
4554                     Log.i(TAG, "Adding app " + sortedPkgs.size() + ": " + pkg.packageName);
4555                 }
4556                 sortedPkgs.add(pkg);
4557             }
4558
4559             // If we want to be lazy, filter everything that wasn't recently used.
4560             if (mLazyDexOpt) {
4561                 filterRecentlyUsedApps(sortedPkgs);
4562             }
4563
4564             int i = 0;
4565             int total = sortedPkgs.size();
4566             File dataDir = Environment.getDataDirectory();
4567             long lowThreshold = StorageManager.from(mContext).getStorageLowBytes(dataDir);
4568             if (lowThreshold == 0) {
4569                 throw new IllegalStateException("Invalid low memory threshold");
4570             }
4571             for (PackageParser.Package pkg : sortedPkgs) {
4572                 long usableSpace = dataDir.getUsableSpace();
4573                 if (usableSpace < lowThreshold) {
4574                     Log.w(TAG, "Not running dexopt on remaining apps due to low memory: " + usableSpace);
4575                     break;
4576                 }
4577                 performBootDexOpt(pkg, ++i, total);
4578             }
4579         }
4580     }
4581
4582     private void filterRecentlyUsedApps(Collection<PackageParser.Package> pkgs) {
4583         // Filter out packages that aren't recently used.
4584         //
4585         // The exception is first boot of a non-eng device (aka !mLazyDexOpt), which
4586         // should do a full dexopt.
4587         if (mLazyDexOpt || (!isFirstBoot() && mPackageUsage.isHistoricalPackageUsageAvailable())) {
4588             int total = pkgs.size();
4589             int skipped = 0;
4590             long now = System.currentTimeMillis();
4591             for (Iterator<PackageParser.Package> i = pkgs.iterator(); i.hasNext();) {
4592                 PackageParser.Package pkg = i.next();
4593                 long then = pkg.mLastPackageUsageTimeInMills;
4594                 if (then + mDexOptLRUThresholdInMills < now) {
4595                     if (DEBUG_DEXOPT) {
4596                         Log.i(TAG, "Skipping dexopt of " + pkg.packageName + " last resumed: " +
4597                               ((then == 0) ? "never" : new Date(then)));
4598                     }
4599                     i.remove();
4600                     skipped++;
4601                 }
4602             }
4603             if (DEBUG_DEXOPT) {
4604                 Log.i(TAG, "Skipped optimizing " + skipped + " of " + total);
4605             }
4606         }
4607     }
4608
4609     private ArraySet<String> getPackageNamesForIntent(Intent intent) {
4610         List<ResolveInfo> ris = null;
4611         try {
4612             ris = AppGlobals.getPackageManager().queryIntentReceivers(
4613                     intent, null, 0, UserHandle.USER_OWNER);
4614         } catch (RemoteException e) {
4615         }
4616         ArraySet<String> pkgNames = new ArraySet<String>();
4617         if (ris != null) {
4618             for (ResolveInfo ri : ris) {
4619                 pkgNames.add(ri.activityInfo.packageName);
4620             }
4621         }
4622         return pkgNames;
4623     }
4624
4625     private void performBootDexOpt(PackageParser.Package pkg, int curr, int total) {
4626         if (DEBUG_DEXOPT) {
4627             Log.i(TAG, "Optimizing app " + curr + " of " + total + ": " + pkg.packageName);
4628         }
4629         if (!isFirstBoot()) {
4630             try {
4631                 ActivityManagerNative.getDefault().showBootMessage(
4632                         mContext.getResources().getString(R.string.android_upgrading_apk,
4633                                 curr, total), true);
4634             } catch (RemoteException e) {
4635             }
4636         }
4637         PackageParser.Package p = pkg;
4638         synchronized (mInstallLock) {
4639             performDexOptLI(p, null /* instruction sets */, false /* force dex */,
4640                             false /* defer */, true /* include dependencies */);
4641         }
4642     }
4643
4644     @Override
4645     public boolean performDexOptIfNeeded(String packageName, String instructionSet) {
4646         return performDexOpt(packageName, instructionSet, false);
4647     }
4648
4649     private static String getPrimaryInstructionSet(ApplicationInfo info) {
4650         if (info.primaryCpuAbi == null) {
4651             return getPreferredInstructionSet();
4652         }
4653
4654         return VMRuntime.getInstructionSet(info.primaryCpuAbi);
4655     }
4656
4657     public boolean performDexOpt(String packageName, String instructionSet, boolean backgroundDexopt) {
4658         boolean dexopt = mLazyDexOpt || backgroundDexopt;
4659         boolean updateUsage = !backgroundDexopt;  // Don't update usage if this is just a backgroundDexopt
4660         if (!dexopt && !updateUsage) {
4661             // We aren't going to dexopt or update usage, so bail early.
4662             return false;
4663         }
4664         PackageParser.Package p;
4665         final String targetInstructionSet;
4666         synchronized (mPackages) {
4667             p = mPackages.get(packageName);
4668             if (p == null) {
4669                 return false;
4670             }
4671             if (updateUsage) {
4672                 p.mLastPackageUsageTimeInMills = System.currentTimeMillis();
4673             }
4674             mPackageUsage.write(false);
4675             if (!dexopt) {
4676                 // We aren't going to dexopt, so bail early.
4677                 return false;
4678             }
4679
4680             targetInstructionSet = instructionSet != null ? instructionSet :
4681                     getPrimaryInstructionSet(p.applicationInfo);
4682             if (p.mDexOptPerformed.contains(targetInstructionSet)) {
4683                 return false;
4684             }
4685         }
4686
4687         synchronized (mInstallLock) {
4688             final String[] instructionSets = new String[] { targetInstructionSet };
4689             return performDexOptLI(p, instructionSets, false /* force dex */, false /* defer */,
4690                     true /* include dependencies */) == DEX_OPT_PERFORMED;
4691         }
4692     }
4693
4694     public ArraySet<String> getPackagesThatNeedDexOpt() {
4695         ArraySet<String> pkgs = null;
4696         synchronized (mPackages) {
4697             for (PackageParser.Package p : mPackages.values()) {
4698                 if (DEBUG_DEXOPT) {
4699                     Log.i(TAG, p.packageName + " mDexOptPerformed=" + p.mDexOptPerformed.toArray());
4700                 }
4701                 if (!p.mDexOptPerformed.isEmpty()) {
4702                     continue;
4703                 }
4704                 if (pkgs == null) {
4705                     pkgs = new ArraySet<String>();
4706                 }
4707                 pkgs.add(p.packageName);
4708             }
4709         }
4710         return pkgs;
4711     }
4712
4713     public void shutdown() {
4714         mPackageUsage.write(true);
4715     }
4716
4717     private void performDexOptLibsLI(ArrayList<String> libs, String[] instructionSets,
4718              boolean forceDex, boolean defer, ArraySet<String> done) {
4719         for (int i=0; i<libs.size(); i++) {
4720             PackageParser.Package libPkg;
4721             String libName;
4722             synchronized (mPackages) {
4723                 libName = libs.get(i);
4724                 SharedLibraryEntry lib = mSharedLibraries.get(libName);
4725                 if (lib != null && lib.apk != null) {
4726                     libPkg = mPackages.get(lib.apk);
4727                 } else {
4728                     libPkg = null;
4729                 }
4730             }
4731             if (libPkg != null && !done.contains(libName)) {
4732                 performDexOptLI(libPkg, instructionSets, forceDex, defer, done);
4733             }
4734         }
4735     }
4736
4737     static final int DEX_OPT_SKIPPED = 0;
4738     static final int DEX_OPT_PERFORMED = 1;
4739     static final int DEX_OPT_DEFERRED = 2;
4740     static final int DEX_OPT_FAILED = -1;
4741
4742     private int performDexOptLI(PackageParser.Package pkg, String[] targetInstructionSets,
4743             boolean forceDex, boolean defer, ArraySet<String> done) {
4744         final String[] instructionSets = targetInstructionSets != null ?
4745                 targetInstructionSets : getAppDexInstructionSets(pkg.applicationInfo);
4746
4747         if (done != null) {
4748             done.add(pkg.packageName);
4749             if (pkg.usesLibraries != null) {
4750                 performDexOptLibsLI(pkg.usesLibraries, instructionSets, forceDex, defer, done);
4751             }
4752             if (pkg.usesOptionalLibraries != null) {
4753                 performDexOptLibsLI(pkg.usesOptionalLibraries, instructionSets, forceDex, defer, done);
4754             }
4755         }
4756
4757         if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_HAS_CODE) == 0) {
4758             return DEX_OPT_SKIPPED;
4759         }
4760
4761         final boolean vmSafeMode = (pkg.applicationInfo.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0;
4762
4763         final List<String> paths = pkg.getAllCodePathsExcludingResourceOnly();
4764         boolean performedDexOpt = false;
4765         // There are three basic cases here:
4766         // 1.) we need to dexopt, either because we are forced or it is needed
4767         // 2.) we are defering a needed dexopt
4768         // 3.) we are skipping an unneeded dexopt
4769         final String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
4770         for (String dexCodeInstructionSet : dexCodeInstructionSets) {
4771             if (!forceDex && pkg.mDexOptPerformed.contains(dexCodeInstructionSet)) {
4772                 continue;
4773             }
4774
4775             for (String path : paths) {
4776                 try {
4777                     // This will return DEXOPT_NEEDED if we either cannot find any odex file for this
4778                     // patckage or the one we find does not match the image checksum (i.e. it was
4779                     // compiled against an old image). It will return PATCHOAT_NEEDED if we can find a
4780                     // odex file and it matches the checksum of the image but not its base address,
4781                     // meaning we need to move it.
4782                     final byte isDexOptNeeded = DexFile.isDexOptNeededInternal(path,
4783                             pkg.packageName, dexCodeInstructionSet, defer);
4784                     if (forceDex || (!defer && isDexOptNeeded == DexFile.DEXOPT_NEEDED)) {
4785                         Log.i(TAG, "Running dexopt on: " + path + " pkg="
4786                                 + pkg.applicationInfo.packageName + " isa=" + dexCodeInstructionSet
4787                                 + " vmSafeMode=" + vmSafeMode);
4788                         final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
4789                         final int ret = mInstaller.dexopt(path, sharedGid, !isForwardLocked(pkg),
4790                                 pkg.packageName, dexCodeInstructionSet, vmSafeMode);
4791
4792                         if (ret < 0) {
4793                             // Don't bother running dexopt again if we failed, it will probably
4794                             // just result in an error again. Also, don't bother dexopting for other
4795                             // paths & ISAs.
4796                             return DEX_OPT_FAILED;
4797                         }
4798
4799                         performedDexOpt = true;
4800                     } else if (!defer && isDexOptNeeded == DexFile.PATCHOAT_NEEDED) {
4801                         Log.i(TAG, "Running patchoat on: " + pkg.applicationInfo.packageName);
4802                         final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
4803                         final int ret = mInstaller.patchoat(path, sharedGid, !isForwardLocked(pkg),
4804                                 pkg.packageName, dexCodeInstructionSet);
4805
4806                         if (ret < 0) {
4807                             // Don't bother running patchoat again if we failed, it will probably
4808                             // just result in an error again. Also, don't bother dexopting for other
4809                             // paths & ISAs.
4810                             return DEX_OPT_FAILED;
4811                         }
4812
4813                         performedDexOpt = true;
4814                     }
4815
4816                     // We're deciding to defer a needed dexopt. Don't bother dexopting for other
4817                     // paths and instruction sets. We'll deal with them all together when we process
4818                     // our list of deferred dexopts.
4819                     if (defer && isDexOptNeeded != DexFile.UP_TO_DATE) {
4820                         if (mDeferredDexOpt == null) {
4821                             mDeferredDexOpt = new ArraySet<PackageParser.Package>();
4822                         }
4823                         mDeferredDexOpt.add(pkg);
4824                         return DEX_OPT_DEFERRED;
4825                     }
4826                 } catch (FileNotFoundException e) {
4827                     Slog.w(TAG, "Apk not found for dexopt: " + path);
4828                     return DEX_OPT_FAILED;
4829                 } catch (IOException e) {
4830                     Slog.w(TAG, "IOException reading apk: " + path, e);
4831                     return DEX_OPT_FAILED;
4832                 } catch (StaleDexCacheError e) {
4833                     Slog.w(TAG, "StaleDexCacheError when reading apk: " + path, e);
4834                     return DEX_OPT_FAILED;
4835                 } catch (Exception e) {
4836                     Slog.w(TAG, "Exception when doing dexopt : ", e);
4837                     return DEX_OPT_FAILED;
4838                 }
4839             }
4840
4841             // At this point we haven't failed dexopt and we haven't deferred dexopt. We must
4842             // either have either succeeded dexopt, or have had isDexOptNeededInternal tell us
4843             // it isn't required. We therefore mark that this package doesn't need dexopt unless
4844             // it's forced. performedDexOpt will tell us whether we performed dex-opt or skipped
4845             // it.
4846             pkg.mDexOptPerformed.add(dexCodeInstructionSet);
4847         }
4848
4849         // If we've gotten here, we're sure that no error occurred and that we haven't
4850         // deferred dex-opt. We've either dex-opted one more paths or instruction sets or
4851         // we've skipped all of them because they are up to date. In both cases this
4852         // package doesn't need dexopt any longer.
4853         return performedDexOpt ? DEX_OPT_PERFORMED : DEX_OPT_SKIPPED;
4854     }
4855
4856     private static String[] getAppDexInstructionSets(ApplicationInfo info) {
4857         if (info.primaryCpuAbi != null) {
4858             if (info.secondaryCpuAbi != null) {
4859                 return new String[] {
4860                         VMRuntime.getInstructionSet(info.primaryCpuAbi),
4861                         VMRuntime.getInstructionSet(info.secondaryCpuAbi) };
4862             } else {
4863                 return new String[] {
4864                         VMRuntime.getInstructionSet(info.primaryCpuAbi) };
4865             }
4866         }
4867
4868         return new String[] { getPreferredInstructionSet() };
4869     }
4870
4871     private static String[] getAppDexInstructionSets(PackageSetting ps) {
4872         if (ps.primaryCpuAbiString != null) {
4873             if (ps.secondaryCpuAbiString != null) {
4874                 return new String[] {
4875                         VMRuntime.getInstructionSet(ps.primaryCpuAbiString),
4876                         VMRuntime.getInstructionSet(ps.secondaryCpuAbiString) };
4877             } else {
4878                 return new String[] {
4879                         VMRuntime.getInstructionSet(ps.primaryCpuAbiString) };
4880             }
4881         }
4882
4883         return new String[] { getPreferredInstructionSet() };
4884     }
4885
4886     private static String getPreferredInstructionSet() {
4887         if (sPreferredInstructionSet == null) {
4888             sPreferredInstructionSet = VMRuntime.getInstructionSet(Build.SUPPORTED_ABIS[0]);
4889         }
4890
4891         return sPreferredInstructionSet;
4892     }
4893
4894     private static List<String> getAllInstructionSets() {
4895         final String[] allAbis = Build.SUPPORTED_ABIS;
4896         final List<String> allInstructionSets = new ArrayList<String>(allAbis.length);
4897
4898         for (String abi : allAbis) {
4899             final String instructionSet = VMRuntime.getInstructionSet(abi);
4900             if (!allInstructionSets.contains(instructionSet)) {
4901                 allInstructionSets.add(instructionSet);
4902             }
4903         }
4904
4905         return allInstructionSets;
4906     }
4907
4908     /**
4909      * Returns the instruction set that should be used to compile dex code. In the presence of
4910      * a native bridge this might be different than the one shared libraries use.
4911      */
4912     private static String getDexCodeInstructionSet(String sharedLibraryIsa) {
4913         String dexCodeIsa = SystemProperties.get("ro.dalvik.vm.isa." + sharedLibraryIsa);
4914         return (dexCodeIsa.isEmpty() ? sharedLibraryIsa : dexCodeIsa);
4915     }
4916
4917     private static String[] getDexCodeInstructionSets(String[] instructionSets) {
4918         ArraySet<String> dexCodeInstructionSets = new ArraySet<String>(instructionSets.length);
4919         for (String instructionSet : instructionSets) {
4920             dexCodeInstructionSets.add(getDexCodeInstructionSet(instructionSet));
4921         }
4922         return dexCodeInstructionSets.toArray(new String[dexCodeInstructionSets.size()]);
4923     }
4924
4925     /**
4926      * Returns deduplicated list of supported instructions for dex code.
4927      */
4928     public static String[] getAllDexCodeInstructionSets() {
4929         String[] supportedInstructionSets = new String[Build.SUPPORTED_ABIS.length];
4930         for (int i = 0; i < supportedInstructionSets.length; i++) {
4931             String abi = Build.SUPPORTED_ABIS[i];
4932             supportedInstructionSets[i] = VMRuntime.getInstructionSet(abi);
4933         }
4934         return getDexCodeInstructionSets(supportedInstructionSets);
4935     }
4936
4937     @Override
4938     public void forceDexOpt(String packageName) {
4939         enforceSystemOrRoot("forceDexOpt");
4940
4941         PackageParser.Package pkg;
4942         synchronized (mPackages) {
4943             pkg = mPackages.get(packageName);
4944             if (pkg == null) {
4945                 throw new IllegalArgumentException("Missing package: " + packageName);
4946             }
4947         }
4948
4949         synchronized (mInstallLock) {
4950             final String[] instructionSets = new String[] {
4951                     getPrimaryInstructionSet(pkg.applicationInfo) };
4952             final int res = performDexOptLI(pkg, instructionSets, true, false, true);
4953             if (res != DEX_OPT_PERFORMED) {
4954                 throw new IllegalStateException("Failed to dexopt: " + res);
4955             }
4956         }
4957     }
4958
4959     private int performDexOptLI(PackageParser.Package pkg, String[] instructionSets,
4960                                 boolean forceDex, boolean defer, boolean inclDependencies) {
4961         ArraySet<String> done;
4962         if (inclDependencies && (pkg.usesLibraries != null || pkg.usesOptionalLibraries != null)) {
4963             done = new ArraySet<String>();
4964             done.add(pkg.packageName);
4965         } else {
4966             done = null;
4967         }
4968         return performDexOptLI(pkg, instructionSets,  forceDex, defer, done);
4969     }
4970
4971     private boolean verifyPackageUpdateLPr(PackageSetting oldPkg, PackageParser.Package newPkg) {
4972         if ((oldPkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) {
4973             Slog.w(TAG, "Unable to update from " + oldPkg.name
4974                     + " to " + newPkg.packageName
4975                     + ": old package not in system partition");
4976             return false;
4977         } else if (mPackages.get(oldPkg.name) != null) {
4978             Slog.w(TAG, "Unable to update from " + oldPkg.name
4979                     + " to " + newPkg.packageName
4980                     + ": old package still exists");
4981             return false;
4982         }
4983         return true;
4984     }
4985
4986     File getDataPathForUser(int userId) {
4987         return new File(mUserAppDataDir.getAbsolutePath() + File.separator + userId);
4988     }
4989
4990     private File getDataPathForPackage(String packageName, int userId) {
4991         /*
4992          * Until we fully support multiple users, return the directory we
4993          * previously would have. The PackageManagerTests will need to be
4994          * revised when this is changed back..
4995          */
4996         if (userId == 0) {
4997             return new File(mAppDataDir, packageName);
4998         } else {
4999             return new File(mUserAppDataDir.getAbsolutePath() + File.separator + userId
5000                 + File.separator + packageName);
5001         }
5002     }
5003
5004     private int createDataDirsLI(String packageName, int uid, String seinfo) {
5005         int[] users = sUserManager.getUserIds();
5006         int res = mInstaller.install(packageName, uid, uid, seinfo);
5007         if (res < 0) {
5008             return res;
5009         }
5010         for (int user : users) {
5011             if (user != 0) {
5012                 res = mInstaller.createUserData(packageName,
5013                         UserHandle.getUid(user, uid), user, seinfo);
5014                 if (res < 0) {
5015                     return res;
5016                 }
5017             }
5018         }
5019         return res;
5020     }
5021
5022     private int removeDataDirsLI(String packageName) {
5023         int[] users = sUserManager.getUserIds();
5024         int res = 0;
5025         for (int user : users) {
5026             int resInner = mInstaller.remove(packageName, user);
5027             if (resInner < 0) {
5028                 res = resInner;
5029             }
5030         }
5031
5032         return res;
5033     }
5034
5035     private int deleteCodeCacheDirsLI(String packageName) {
5036         int[] users = sUserManager.getUserIds();
5037         int res = 0;
5038         for (int user : users) {
5039             int resInner = mInstaller.deleteCodeCacheFiles(packageName, user);
5040             if (resInner < 0) {
5041                 res = resInner;
5042             }
5043         }
5044         return res;
5045     }
5046
5047     private void addSharedLibraryLPw(ArraySet<String> usesLibraryFiles, SharedLibraryEntry file,
5048             PackageParser.Package changingLib) {
5049         if (file.path != null) {
5050             usesLibraryFiles.add(file.path);
5051             return;
5052         }
5053         PackageParser.Package p = mPackages.get(file.apk);
5054         if (changingLib != null && changingLib.packageName.equals(file.apk)) {
5055             // If we are doing this while in the middle of updating a library apk,
5056             // then we need to make sure to use that new apk for determining the
5057             // dependencies here.  (We haven't yet finished committing the new apk
5058             // to the package manager state.)
5059             if (p == null || p.packageName.equals(changingLib.packageName)) {
5060                 p = changingLib;
5061             }
5062         }
5063         if (p != null) {
5064             usesLibraryFiles.addAll(p.getAllCodePaths());
5065         }
5066     }
5067
5068     private void updateSharedLibrariesLPw(PackageParser.Package pkg,
5069             PackageParser.Package changingLib) throws PackageManagerException {
5070         if (pkg.usesLibraries != null || pkg.usesOptionalLibraries != null) {
5071             final ArraySet<String> usesLibraryFiles = new ArraySet<>();
5072             int N = pkg.usesLibraries != null ? pkg.usesLibraries.size() : 0;
5073             for (int i=0; i<N; i++) {
5074                 final SharedLibraryEntry file = mSharedLibraries.get(pkg.usesLibraries.get(i));
5075                 if (file == null) {
5076                     throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
5077                             "Package " + pkg.packageName + " requires unavailable shared library "
5078                             + pkg.usesLibraries.get(i) + "; failing!");
5079                 }
5080                 addSharedLibraryLPw(usesLibraryFiles, file, changingLib);
5081             }
5082             N = pkg.usesOptionalLibraries != null ? pkg.usesOptionalLibraries.size() : 0;
5083             for (int i=0; i<N; i++) {
5084                 final SharedLibraryEntry file = mSharedLibraries.get(pkg.usesOptionalLibraries.get(i));
5085                 if (file == null) {
5086                     Slog.w(TAG, "Package " + pkg.packageName
5087                             + " desires unavailable shared library "
5088                             + pkg.usesOptionalLibraries.get(i) + "; ignoring!");
5089                 } else {
5090                     addSharedLibraryLPw(usesLibraryFiles, file, changingLib);
5091                 }
5092             }
5093             N = usesLibraryFiles.size();
5094             if (N > 0) {
5095                 pkg.usesLibraryFiles = usesLibraryFiles.toArray(new String[N]);
5096             } else {
5097                 pkg.usesLibraryFiles = null;
5098             }
5099         }
5100     }
5101
5102     private static boolean hasString(List<String> list, List<String> which) {
5103         if (list == null) {
5104             return false;
5105         }
5106         for (int i=list.size()-1; i>=0; i--) {
5107             for (int j=which.size()-1; j>=0; j--) {
5108                 if (which.get(j).equals(list.get(i))) {
5109                     return true;
5110                 }
5111             }
5112         }
5113         return false;
5114     }
5115
5116     private void updateAllSharedLibrariesLPw() {
5117         for (PackageParser.Package pkg : mPackages.values()) {
5118             try {
5119                 updateSharedLibrariesLPw(pkg, null);
5120             } catch (PackageManagerException e) {
5121                 Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
5122             }
5123         }
5124     }
5125
5126     private ArrayList<PackageParser.Package> updateAllSharedLibrariesLPw(
5127             PackageParser.Package changingPkg) {
5128         ArrayList<PackageParser.Package> res = null;
5129         for (PackageParser.Package pkg : mPackages.values()) {
5130             if (hasString(pkg.usesLibraries, changingPkg.libraryNames)
5131                     || hasString(pkg.usesOptionalLibraries, changingPkg.libraryNames)) {
5132                 if (res == null) {
5133                     res = new ArrayList<PackageParser.Package>();
5134                 }
5135                 res.add(pkg);
5136                 try {
5137                     updateSharedLibrariesLPw(pkg, changingPkg);
5138                 } catch (PackageManagerException e) {
5139                     Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
5140                 }
5141             }
5142         }
5143         return res;
5144     }
5145
5146     /**
5147      * Derive the value of the {@code cpuAbiOverride} based on the provided
5148      * value and an optional stored value from the package settings.
5149      */
5150     private static String deriveAbiOverride(String abiOverride, PackageSetting settings) {
5151         String cpuAbiOverride = null;
5152
5153         if (NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(abiOverride)) {
5154             cpuAbiOverride = null;
5155         } else if (abiOverride != null) {
5156             cpuAbiOverride = abiOverride;
5157         } else if (settings != null) {
5158             cpuAbiOverride = settings.cpuAbiOverrideString;
5159         }
5160
5161         return cpuAbiOverride;
5162     }
5163
5164     private PackageParser.Package scanPackageLI(PackageParser.Package pkg, int parseFlags,
5165             int scanFlags, long currentTime, UserHandle user) throws PackageManagerException {
5166         boolean success = false;
5167         try {
5168             final PackageParser.Package res = scanPackageDirtyLI(pkg, parseFlags, scanFlags,
5169                     currentTime, user);
5170             success = true;
5171             return res;
5172         } finally {
5173             if (!success && (scanFlags & SCAN_DELETE_DATA_ON_FAILURES) != 0) {
5174                 removeDataDirsLI(pkg.packageName);
5175             }
5176         }
5177     }
5178
5179     private PackageParser.Package scanPackageDirtyLI(PackageParser.Package pkg, int parseFlags,
5180             int scanFlags, long currentTime, UserHandle user) throws PackageManagerException {
5181         final File scanFile = new File(pkg.codePath);
5182         if (pkg.applicationInfo.getCodePath() == null ||
5183                 pkg.applicationInfo.getResourcePath() == null) {
5184             // Bail out. The resource and code paths haven't been set.
5185             throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
5186                     "Code and resource paths haven't been set correctly");
5187         }
5188
5189         if ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) {
5190             pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
5191         } else {
5192             // Only allow system apps to be flagged as core apps.
5193             pkg.coreApp = false;
5194         }
5195
5196         if ((parseFlags&PackageParser.PARSE_IS_PRIVILEGED) != 0) {
5197             pkg.applicationInfo.flags |= ApplicationInfo.FLAG_PRIVILEGED;
5198         }
5199
5200         if (mCustomResolverComponentName != null &&
5201                 mCustomResolverComponentName.getPackageName().equals(pkg.packageName)) {
5202             setUpCustomResolverActivity(pkg);
5203         }
5204
5205         if (pkg.packageName.equals("android")) {
5206             synchronized (mPackages) {
5207                 if (mAndroidApplication != null) {
5208                     Slog.w(TAG, "*************************************************");
5209                     Slog.w(TAG, "Core android package being redefined.  Skipping.");
5210                     Slog.w(TAG, " file=" + scanFile);
5211                     Slog.w(TAG, "*************************************************");
5212                     throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
5213                             "Core android package being redefined.  Skipping.");
5214                 }
5215
5216                 // Set up information for our fall-back user intent resolution activity.
5217                 mPlatformPackage = pkg;
5218                 pkg.mVersionCode = mSdkVersion;
5219                 mAndroidApplication = pkg.applicationInfo;
5220
5221                 if (!mResolverReplaced) {
5222                     mResolveActivity.applicationInfo = mAndroidApplication;
5223                     mResolveActivity.name = ResolverActivity.class.getName();
5224                     mResolveActivity.packageName = mAndroidApplication.packageName;
5225                     mResolveActivity.processName = "system:ui";
5226                     mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
5227                     mResolveActivity.documentLaunchMode = ActivityInfo.DOCUMENT_LAUNCH_NEVER;
5228                     mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS;
5229                     mResolveActivity.theme = R.style.Theme_Holo_Dialog_Alert;
5230                     mResolveActivity.exported = true;
5231                     mResolveActivity.enabled = true;
5232                     mResolveInfo.activityInfo = mResolveActivity;
5233                     mResolveInfo.priority = 0;
5234                     mResolveInfo.preferredOrder = 0;
5235                     mResolveInfo.match = 0;
5236                     mResolveComponentName = new ComponentName(
5237                             mAndroidApplication.packageName, mResolveActivity.name);
5238                 }
5239             }
5240         }
5241
5242         if (DEBUG_PACKAGE_SCANNING) {
5243             if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
5244                 Log.d(TAG, "Scanning package " + pkg.packageName);
5245         }
5246
5247         if (mPackages.containsKey(pkg.packageName)
5248                 || mSharedLibraries.containsKey(pkg.packageName)) {
5249             throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
5250                     "Application package " + pkg.packageName
5251                     + " already installed.  Skipping duplicate.");
5252         }
5253
5254         // Initialize package source and resource directories
5255         File destCodeFile = new File(pkg.applicationInfo.getCodePath());
5256         File destResourceFile = new File(pkg.applicationInfo.getResourcePath());
5257
5258         SharedUserSetting suid = null;
5259         PackageSetting pkgSetting = null;
5260
5261         if (!isSystemApp(pkg)) {
5262             // Only system apps can use these features.
5263             pkg.mOriginalPackages = null;
5264             pkg.mRealPackage = null;
5265             pkg.mAdoptPermissions = null;
5266         }
5267
5268         // writer
5269         synchronized (mPackages) {
5270             if (pkg.mSharedUserId != null) {
5271                 suid = mSettings.getSharedUserLPw(pkg.mSharedUserId, 0, true);
5272                 if (suid == null) {
5273                     throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE,
5274                             "Creating application package " + pkg.packageName
5275                             + " for shared user failed");
5276                 }
5277                 if (DEBUG_PACKAGE_SCANNING) {
5278                     if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
5279                         Log.d(TAG, "Shared UserID " + pkg.mSharedUserId + " (uid=" + suid.userId
5280                                 + "): packages=" + suid.packages);
5281                 }
5282             }
5283             
5284             // Check if we are renaming from an original package name.
5285             PackageSetting origPackage = null;
5286             String realName = null;
5287             if (pkg.mOriginalPackages != null) {
5288                 // This package may need to be renamed to a previously
5289                 // installed name.  Let's check on that...
5290                 final String renamed = mSettings.mRenamedPackages.get(pkg.mRealPackage);
5291                 if (pkg.mOriginalPackages.contains(renamed)) {
5292                     // This package had originally been installed as the
5293                     // original name, and we have already taken care of
5294                     // transitioning to the new one.  Just update the new
5295                     // one to continue using the old name.
5296                     realName = pkg.mRealPackage;
5297                     if (!pkg.packageName.equals(renamed)) {
5298                         // Callers into this function may have already taken
5299                         // care of renaming the package; only do it here if
5300                         // it is not already done.
5301                         pkg.setPackageName(renamed);
5302                     }
5303                     
5304                 } else {
5305                     for (int i=pkg.mOriginalPackages.size()-1; i>=0; i--) {
5306                         if ((origPackage = mSettings.peekPackageLPr(
5307                                 pkg.mOriginalPackages.get(i))) != null) {
5308                             // We do have the package already installed under its
5309                             // original name...  should we use it?
5310                             if (!verifyPackageUpdateLPr(origPackage, pkg)) {
5311                                 // New package is not compatible with original.
5312                                 origPackage = null;
5313                                 continue;
5314                             } else if (origPackage.sharedUser != null) {
5315                                 // Make sure uid is compatible between packages.
5316                                 if (!origPackage.sharedUser.name.equals(pkg.mSharedUserId)) {
5317                                     Slog.w(TAG, "Unable to migrate data from " + origPackage.name
5318                                             + " to " + pkg.packageName + ": old uid "
5319                                             + origPackage.sharedUser.name
5320                                             + " differs from " + pkg.mSharedUserId);
5321                                     origPackage = null;
5322                                     continue;
5323                                 }
5324                             } else {
5325                                 if (DEBUG_UPGRADE) Log.v(TAG, "Renaming new package "
5326                                         + pkg.packageName + " to old name " + origPackage.name);
5327                             }
5328                             break;
5329                         }
5330                     }
5331                 }
5332             }
5333             
5334             if (mTransferedPackages.contains(pkg.packageName)) {
5335                 Slog.w(TAG, "Package " + pkg.packageName
5336                         + " was transferred to another, but its .apk remains");
5337             }
5338
5339             // Just create the setting, don't add it yet. For already existing packages
5340             // the PkgSetting exists already and doesn't have to be created.
5341             pkgSetting = mSettings.getPackageLPw(pkg, origPackage, realName, suid, destCodeFile,
5342                     destResourceFile, pkg.applicationInfo.nativeLibraryRootDir,
5343                     pkg.applicationInfo.primaryCpuAbi,
5344                     pkg.applicationInfo.secondaryCpuAbi,
5345                     pkg.applicationInfo.flags, user, false);
5346             if (pkgSetting == null) {
5347                 throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE,
5348                         "Creating application package " + pkg.packageName + " failed");
5349             }
5350
5351             if (pkgSetting.origPackage != null) {
5352                 // If we are first transitioning from an original package,
5353                 // fix up the new package's name now.  We need to do this after
5354                 // looking up the package under its new name, so getPackageLP
5355                 // can take care of fiddling things correctly.
5356                 pkg.setPackageName(origPackage.name);
5357                 
5358                 // File a report about this.
5359                 String msg = "New package " + pkgSetting.realName
5360                         + " renamed to replace old package " + pkgSetting.name;
5361                 reportSettingsProblem(Log.WARN, msg);
5362                 
5363                 // Make a note of it.
5364                 mTransferedPackages.add(origPackage.name);
5365                 
5366                 // No longer need to retain this.
5367                 pkgSetting.origPackage = null;
5368             }
5369             
5370             if (realName != null) {
5371                 // Make a note of it.
5372                 mTransferedPackages.add(pkg.packageName);
5373             }
5374             
5375             if (mSettings.isDisabledSystemPackageLPr(pkg.packageName)) {
5376                 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
5377             }
5378
5379             if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
5380                 // Check all shared libraries and map to their actual file path.
5381                 // We only do this here for apps not on a system dir, because those
5382                 // are the only ones that can fail an install due to this.  We
5383                 // will take care of the system apps by updating all of their
5384                 // library paths after the scan is done.
5385                 updateSharedLibrariesLPw(pkg, null);
5386             }
5387
5388             if (mFoundPolicyFile) {
5389                 SELinuxMMAC.assignSeinfoValue(pkg);
5390             }
5391
5392             pkg.applicationInfo.uid = pkgSetting.appId;
5393             pkg.mExtras = pkgSetting;
5394             if (!pkgSetting.keySetData.isUsingUpgradeKeySets() || pkgSetting.sharedUser != null) {
5395                 try {
5396                     verifySignaturesLP(pkgSetting, pkg);
5397                 } catch (PackageManagerException e) {
5398                     if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
5399                         throw e;
5400                     }
5401                     // The signature has changed, but this package is in the system
5402                     // image...  let's recover!
5403                     pkgSetting.signatures.mSignatures = pkg.mSignatures;
5404                     // However...  if this package is part of a shared user, but it
5405                     // doesn't match the signature of the shared user, let's fail.
5406                     // What this means is that you can't change the signatures
5407                     // associated with an overall shared user, which doesn't seem all
5408                     // that unreasonable.
5409                     if (pkgSetting.sharedUser != null) {
5410                         if (compareSignatures(pkgSetting.sharedUser.signatures.mSignatures,
5411                                               pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) {
5412                             throw new PackageManagerException(
5413                                     INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES,
5414                                             "Signature mismatch for shared user : "
5415                                             + pkgSetting.sharedUser);
5416                         }
5417                     }
5418                     // File a report about this.
5419                     String msg = "System package " + pkg.packageName
5420                         + " signature changed; retaining data.";
5421                     reportSettingsProblem(Log.WARN, msg);
5422                 }
5423             } else {
5424                 if (!checkUpgradeKeySetLP(pkgSetting, pkg)) {
5425                     throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
5426                             + pkg.packageName + " upgrade keys do not match the "
5427                             + "previously installed version");
5428                 } else {
5429                     // signatures may have changed as result of upgrade
5430                     pkgSetting.signatures.mSignatures = pkg.mSignatures;
5431                 }
5432             }
5433             // Verify that this new package doesn't have any content providers
5434             // that conflict with existing packages.  Only do this if the
5435             // package isn't already installed, since we don't want to break
5436             // things that are installed.
5437             if ((scanFlags & SCAN_NEW_INSTALL) != 0) {
5438                 final int N = pkg.providers.size();
5439                 int i;
5440                 for (i=0; i<N; i++) {
5441                     PackageParser.Provider p = pkg.providers.get(i);
5442                     if (p.info.authority != null) {
5443                         String names[] = p.info.authority.split(";");
5444                         for (int j = 0; j < names.length; j++) {
5445                             if (mProvidersByAuthority.containsKey(names[j])) {
5446                                 PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
5447                                 final String otherPackageName =
5448                                         ((other != null && other.getComponentName() != null) ?
5449                                                 other.getComponentName().getPackageName() : "?");
5450                                 throw new PackageManagerException(
5451                                         INSTALL_FAILED_CONFLICTING_PROVIDER,
5452                                                 "Can't install because provider name " + names[j]
5453                                                 + " (in package " + pkg.applicationInfo.packageName
5454                                                 + ") is already used by " + otherPackageName);
5455                             }
5456                         }
5457                     }
5458                 }
5459             }
5460
5461             if (pkg.mAdoptPermissions != null) {
5462                 // This package wants to adopt ownership of permissions from
5463                 // another package.
5464                 for (int i = pkg.mAdoptPermissions.size() - 1; i >= 0; i--) {
5465                     final String origName = pkg.mAdoptPermissions.get(i);
5466                     final PackageSetting orig = mSettings.peekPackageLPr(origName);
5467                     if (orig != null) {
5468                         if (verifyPackageUpdateLPr(orig, pkg)) {
5469                             Slog.i(TAG, "Adopting permissions from " + origName + " to "
5470                                     + pkg.packageName);
5471                             mSettings.transferPermissionsLPw(origName, pkg.packageName);
5472                         }
5473                     }
5474                 }
5475             }
5476         }
5477
5478         final String pkgName = pkg.packageName;
5479         
5480         final long scanFileTime = scanFile.lastModified();
5481         final boolean forceDex = (scanFlags & SCAN_FORCE_DEX) != 0;
5482         pkg.applicationInfo.processName = fixProcessName(
5483                 pkg.applicationInfo.packageName,
5484                 pkg.applicationInfo.processName,
5485                 pkg.applicationInfo.uid);
5486
5487         File dataPath;
5488         if (mPlatformPackage == pkg) {
5489             // The system package is special.
5490             dataPath = new File(Environment.getDataDirectory(), "system");
5491
5492             pkg.applicationInfo.dataDir = dataPath.getPath();
5493
5494         } else {
5495             // This is a normal package, need to make its data directory.
5496             dataPath = getDataPathForPackage(pkg.packageName, 0);
5497
5498             boolean uidError = false;
5499             if (dataPath.exists()) {
5500                 int currentUid = 0;
5501                 try {
5502                     StructStat stat = Os.stat(dataPath.getPath());
5503                     currentUid = stat.st_uid;
5504                 } catch (ErrnoException e) {
5505                     Slog.e(TAG, "Couldn't stat path " + dataPath.getPath(), e);
5506                 }
5507
5508                 // If we have mismatched owners for the data path, we have a problem.
5509                 if (currentUid != pkg.applicationInfo.uid) {
5510                     boolean recovered = false;
5511                     if (currentUid == 0) {
5512                         // The directory somehow became owned by root.  Wow.
5513                         // This is probably because the system was stopped while
5514                         // installd was in the middle of messing with its libs
5515                         // directory.  Ask installd to fix that.
5516                         int ret = mInstaller.fixUid(pkgName, pkg.applicationInfo.uid,
5517                                 pkg.applicationInfo.uid);
5518                         if (ret >= 0) {
5519                             recovered = true;
5520                             String msg = "Package " + pkg.packageName
5521                                     + " unexpectedly changed to uid 0; recovered to " +
5522                                     + pkg.applicationInfo.uid;
5523                             reportSettingsProblem(Log.WARN, msg);
5524                         }
5525                     }
5526                     if (!recovered && ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0
5527                             || (scanFlags&SCAN_BOOTING) != 0)) {
5528                         // If this is a system app, we can at least delete its
5529                         // current data so the application will still work.
5530                         int ret = removeDataDirsLI(pkgName);
5531                         if (ret >= 0) {
5532                             // TODO: Kill the processes first
5533                             // Old data gone!
5534                             String prefix = (parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0
5535                                     ? "System package " : "Third party package ";
5536                             String msg = prefix + pkg.packageName
5537                                     + " has changed from uid: "
5538                                     + currentUid + " to "
5539                                     + pkg.applicationInfo.uid + "; old data erased";
5540                             reportSettingsProblem(Log.WARN, msg);
5541                             recovered = true;
5542
5543                             // And now re-install the app.
5544                             ret = createDataDirsLI(pkgName, pkg.applicationInfo.uid,
5545                                                    pkg.applicationInfo.seinfo);
5546                             if (ret == -1) {
5547                                 // Ack should not happen!
5548                                 msg = prefix + pkg.packageName
5549                                         + " could not have data directory re-created after delete.";
5550                                 reportSettingsProblem(Log.WARN, msg);
5551                                 throw new PackageManagerException(
5552                                         INSTALL_FAILED_INSUFFICIENT_STORAGE, msg);
5553                             }
5554                         }
5555                         if (!recovered) {
5556                             mHasSystemUidErrors = true;
5557                         }
5558                     } else if (!recovered) {
5559                         // If we allow this install to proceed, we will be broken.
5560                         // Abort, abort!
5561                         throw new PackageManagerException(INSTALL_FAILED_UID_CHANGED,
5562                                 "scanPackageLI");
5563                     }
5564                     if (!recovered) {
5565                         pkg.applicationInfo.dataDir = "/mismatched_uid/settings_"
5566                             + pkg.applicationInfo.uid + "/fs_"
5567                             + currentUid;
5568                         pkg.applicationInfo.nativeLibraryDir = pkg.applicationInfo.dataDir;
5569                         pkg.applicationInfo.nativeLibraryRootDir = pkg.applicationInfo.dataDir;
5570                         String msg = "Package " + pkg.packageName
5571                                 + " has mismatched uid: "
5572                                 + currentUid + " on disk, "
5573                                 + pkg.applicationInfo.uid + " in settings";
5574                         // writer
5575                         synchronized (mPackages) {
5576                             mSettings.mReadMessages.append(msg);
5577                             mSettings.mReadMessages.append('\n');
5578                             uidError = true;
5579                             if (!pkgSetting.uidError) {
5580                                 reportSettingsProblem(Log.ERROR, msg);
5581                             }
5582                         }
5583                     }
5584                 }
5585                 pkg.applicationInfo.dataDir = dataPath.getPath();
5586                 if (mShouldRestoreconData) {
5587                     Slog.i(TAG, "SELinux relabeling of " + pkg.packageName + " issued.");
5588                     mInstaller.restoreconData(pkg.packageName, pkg.applicationInfo.seinfo,
5589                                 pkg.applicationInfo.uid);
5590                 }
5591             } else {
5592                 if (DEBUG_PACKAGE_SCANNING) {
5593                     if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
5594                         Log.v(TAG, "Want this data dir: " + dataPath);
5595                 }
5596                 //invoke installer to do the actual installation
5597                 int ret = createDataDirsLI(pkgName, pkg.applicationInfo.uid,
5598                                            pkg.applicationInfo.seinfo);
5599                 if (ret < 0) {
5600                     // Error from installer
5601                     throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE,
5602                             "Unable to create data dirs [errorCode=" + ret + "]");
5603                 }
5604
5605                 if (dataPath.exists()) {
5606                     pkg.applicationInfo.dataDir = dataPath.getPath();
5607                 } else {
5608                     Slog.w(TAG, "Unable to create data directory: " + dataPath);
5609                     pkg.applicationInfo.dataDir = null;
5610                 }
5611             }
5612
5613             pkgSetting.uidError = uidError;
5614         }
5615
5616         final String path = scanFile.getPath();
5617         final String codePath = pkg.applicationInfo.getCodePath();
5618         final String cpuAbiOverride = deriveAbiOverride(pkg.cpuAbiOverride, pkgSetting);
5619         if (isSystemApp(pkg) && !isUpdatedSystemApp(pkg)) {
5620             setBundledAppAbisAndRoots(pkg, pkgSetting);
5621
5622             // If we haven't found any native libraries for the app, check if it has
5623             // renderscript code. We'll need to force the app to 32 bit if it has
5624             // renderscript bitcode.
5625             if (pkg.applicationInfo.primaryCpuAbi == null
5626                     && pkg.applicationInfo.secondaryCpuAbi == null
5627                     && Build.SUPPORTED_64_BIT_ABIS.length >  0) {
5628                 NativeLibraryHelper.Handle handle = null;
5629                 try {
5630                     handle = NativeLibraryHelper.Handle.create(scanFile);
5631                     if (NativeLibraryHelper.hasRenderscriptBitcode(handle)) {
5632                         pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
5633                     }
5634                 } catch (IOException ioe) {
5635                     Slog.w(TAG, "Error scanning system app : " + ioe);
5636                 } finally {
5637                     IoUtils.closeQuietly(handle);
5638                 }
5639             }
5640
5641             setNativeLibraryPaths(pkg);
5642         } else {
5643             // TODO: We can probably be smarter about this stuff. For installed apps,
5644             // we can calculate this information at install time once and for all. For
5645             // system apps, we can probably assume that this information doesn't change
5646             // after the first boot scan. As things stand, we do lots of unnecessary work.
5647
5648             // Give ourselves some initial paths; we'll come back for another
5649             // pass once we've determined ABI below.
5650             setNativeLibraryPaths(pkg);
5651
5652             final boolean isAsec = isForwardLocked(pkg) || isExternal(pkg);
5653             final String nativeLibraryRootStr = pkg.applicationInfo.nativeLibraryRootDir;
5654             final boolean useIsaSpecificSubdirs = pkg.applicationInfo.nativeLibraryRootRequiresIsa;
5655
5656             NativeLibraryHelper.Handle handle = null;
5657             try {
5658                 handle = NativeLibraryHelper.Handle.create(scanFile);
5659                 // TODO(multiArch): This can be null for apps that didn't go through the
5660                 // usual installation process. We can calculate it again, like we
5661                 // do during install time.
5662                 //
5663                 // TODO(multiArch): Why do we need to rescan ASEC apps again ? It seems totally
5664                 // unnecessary.
5665                 final File nativeLibraryRoot = new File(nativeLibraryRootStr);
5666
5667                 // Null out the abis so that they can be recalculated.
5668                 pkg.applicationInfo.primaryCpuAbi = null;
5669                 pkg.applicationInfo.secondaryCpuAbi = null;
5670                 if (isMultiArch(pkg.applicationInfo)) {
5671                     // Warn if we've set an abiOverride for multi-lib packages..
5672                     // By definition, we need to copy both 32 and 64 bit libraries for
5673                     // such packages.
5674                     if (pkg.cpuAbiOverride != null
5675                             && !NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(pkg.cpuAbiOverride)) {
5676                         Slog.w(TAG, "Ignoring abiOverride for multi arch application.");
5677                     }
5678
5679                     int abi32 = PackageManager.NO_NATIVE_LIBRARIES;
5680                     int abi64 = PackageManager.NO_NATIVE_LIBRARIES;
5681                     if (Build.SUPPORTED_32_BIT_ABIS.length > 0) {
5682                         if (isAsec) {
5683                             abi32 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_32_BIT_ABIS);
5684                         } else {
5685                             abi32 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
5686                                     nativeLibraryRoot, Build.SUPPORTED_32_BIT_ABIS,
5687                                     useIsaSpecificSubdirs);
5688                         }
5689                     }
5690
5691                     maybeThrowExceptionForMultiArchCopy(
5692                             "Error unpackaging 32 bit native libs for multiarch app.", abi32);
5693
5694                     if (Build.SUPPORTED_64_BIT_ABIS.length > 0) {
5695                         if (isAsec) {
5696                             abi64 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_64_BIT_ABIS);
5697                         } else {
5698                             abi64 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
5699                                     nativeLibraryRoot, Build.SUPPORTED_64_BIT_ABIS,
5700                                     useIsaSpecificSubdirs);
5701                         }
5702                     }
5703
5704                     maybeThrowExceptionForMultiArchCopy(
5705                             "Error unpackaging 64 bit native libs for multiarch app.", abi64);
5706
5707                     if (abi64 >= 0) {
5708                         pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[abi64];
5709                     }
5710
5711                     if (abi32 >= 0) {
5712                         final String abi = Build.SUPPORTED_32_BIT_ABIS[abi32];
5713                         if (abi64 >= 0) {
5714                             pkg.applicationInfo.secondaryCpuAbi = abi;
5715                         } else {
5716                             pkg.applicationInfo.primaryCpuAbi = abi;
5717                         }
5718                     }
5719                 } else {
5720                     String[] abiList = (cpuAbiOverride != null) ?
5721                             new String[] { cpuAbiOverride } : Build.SUPPORTED_ABIS;
5722
5723                     // Enable gross and lame hacks for apps that are built with old
5724                     // SDK tools. We must scan their APKs for renderscript bitcode and
5725                     // not launch them if it's present. Don't bother checking on devices
5726                     // that don't have 64 bit support.
5727                     boolean needsRenderScriptOverride = false;
5728                     if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && cpuAbiOverride == null &&
5729                             NativeLibraryHelper.hasRenderscriptBitcode(handle)) {
5730                         abiList = Build.SUPPORTED_32_BIT_ABIS;
5731                         needsRenderScriptOverride = true;
5732                     }
5733
5734                     final int copyRet;
5735                     if (isAsec) {
5736                         copyRet = NativeLibraryHelper.findSupportedAbi(handle, abiList);
5737                     } else {
5738                         copyRet = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
5739                                 nativeLibraryRoot, abiList, useIsaSpecificSubdirs);
5740                     }
5741
5742                     if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) {
5743                         throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
5744                                 "Error unpackaging native libs for app, errorCode=" + copyRet);
5745                     }
5746
5747                     if (copyRet >= 0) {
5748                         pkg.applicationInfo.primaryCpuAbi = abiList[copyRet];
5749                     } else if (copyRet == PackageManager.NO_NATIVE_LIBRARIES && cpuAbiOverride != null) {
5750                         pkg.applicationInfo.primaryCpuAbi = cpuAbiOverride;
5751                     } else if (needsRenderScriptOverride) {
5752                         pkg.applicationInfo.primaryCpuAbi = abiList[0];
5753                     }
5754                 }
5755             } catch (IOException ioe) {
5756                 Slog.e(TAG, "Unable to get canonical file " + ioe.toString());
5757             } finally {
5758                 IoUtils.closeQuietly(handle);
5759             }
5760
5761             // Now that we've calculated the ABIs and determined if it's an internal app,
5762             // we will go ahead and populate the nativeLibraryPath.
5763             setNativeLibraryPaths(pkg);
5764
5765             if (DEBUG_INSTALL) Slog.i(TAG, "Linking native library dir for " + path);
5766             final int[] userIds = sUserManager.getUserIds();
5767             synchronized (mInstallLock) {
5768                 // Create a native library symlink only if we have native libraries
5769                 // and if the native libraries are 32 bit libraries. We do not provide
5770                 // this symlink for 64 bit libraries.
5771                 if (pkg.applicationInfo.primaryCpuAbi != null &&
5772                         !VMRuntime.is64BitAbi(pkg.applicationInfo.primaryCpuAbi)) {
5773                     final String nativeLibPath = pkg.applicationInfo.nativeLibraryDir;
5774                     for (int userId : userIds) {
5775                         if (mInstaller.linkNativeLibraryDirectory(pkg.packageName, nativeLibPath, userId) < 0) {
5776                             throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
5777                                     "Failed linking native library dir (user=" + userId + ")");
5778                         }
5779                     }
5780                 }
5781             }
5782         }
5783
5784         // This is a special case for the "system" package, where the ABI is
5785         // dictated by the zygote configuration (and init.rc). We should keep track
5786         // of this ABI so that we can deal with "normal" applications that run under
5787         // the same UID correctly.
5788         if (mPlatformPackage == pkg) {
5789             pkg.applicationInfo.primaryCpuAbi = VMRuntime.getRuntime().is64Bit() ?
5790                     Build.SUPPORTED_64_BIT_ABIS[0] : Build.SUPPORTED_32_BIT_ABIS[0];
5791         }
5792
5793         pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
5794         pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
5795         pkgSetting.cpuAbiOverrideString = cpuAbiOverride;
5796         // Copy the derived override back to the parsed package, so that we can
5797         // update the package settings accordingly.
5798         pkg.cpuAbiOverride = cpuAbiOverride;
5799
5800         if (DEBUG_ABI_SELECTION) {
5801             Slog.d(TAG, "Resolved nativeLibraryRoot for " + pkg.applicationInfo.packageName
5802                     + " to root=" + pkg.applicationInfo.nativeLibraryRootDir + ", isa="
5803                     + pkg.applicationInfo.nativeLibraryRootRequiresIsa);
5804         }
5805
5806         // Push the derived path down into PackageSettings so we know what to
5807         // clean up at uninstall time.
5808         pkgSetting.legacyNativeLibraryPathString = pkg.applicationInfo.nativeLibraryRootDir;
5809
5810         if (DEBUG_ABI_SELECTION) {
5811             Log.d(TAG, "Abis for package[" + pkg.packageName + "] are" +
5812                     " primary=" + pkg.applicationInfo.primaryCpuAbi +
5813                     " secondary=" + pkg.applicationInfo.secondaryCpuAbi);
5814         }
5815
5816         if ((scanFlags&SCAN_BOOTING) == 0 && pkgSetting.sharedUser != null) {
5817             // We don't do this here during boot because we can do it all
5818             // at once after scanning all existing packages.
5819             //
5820             // We also do this *before* we perform dexopt on this package, so that
5821             // we can avoid redundant dexopts, and also to make sure we've got the
5822             // code and package path correct.
5823             adjustCpuAbisForSharedUserLPw(pkgSetting.sharedUser.packages,
5824                     pkg, forceDex, (scanFlags & SCAN_DEFER_DEX) != 0);
5825         }
5826
5827         if ((scanFlags & SCAN_NO_DEX) == 0) {
5828             if (performDexOptLI(pkg, null /* instruction sets */, forceDex,
5829                     (scanFlags & SCAN_DEFER_DEX) != 0, false) == DEX_OPT_FAILED) {
5830                 throw new PackageManagerException(INSTALL_FAILED_DEXOPT, "scanPackageLI");
5831             }
5832         }
5833
5834         if (mFactoryTest && pkg.requestedPermissions.contains(
5835                 android.Manifest.permission.FACTORY_TEST)) {
5836             pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST;
5837         }
5838
5839         ArrayList<PackageParser.Package> clientLibPkgs = null;
5840
5841         // writer
5842         synchronized (mPackages) {
5843             if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
5844                 // Only system apps can add new shared libraries.
5845                 if (pkg.libraryNames != null) {
5846                     for (int i=0; i<pkg.libraryNames.size(); i++) {
5847                         String name = pkg.libraryNames.get(i);
5848                         boolean allowed = false;
5849                         if (isUpdatedSystemApp(pkg)) {
5850                             // New library entries can only be added through the
5851                             // system image.  This is important to get rid of a lot
5852                             // of nasty edge cases: for example if we allowed a non-
5853                             // system update of the app to add a library, then uninstalling
5854                             // the update would make the library go away, and assumptions
5855                             // we made such as through app install filtering would now
5856                             // have allowed apps on the device which aren't compatible
5857                             // with it.  Better to just have the restriction here, be
5858                             // conservative, and create many fewer cases that can negatively
5859                             // impact the user experience.
5860                             final PackageSetting sysPs = mSettings
5861                                     .getDisabledSystemPkgLPr(pkg.packageName);
5862                             if (sysPs.pkg != null && sysPs.pkg.libraryNames != null) {
5863                                 for (int j=0; j<sysPs.pkg.libraryNames.size(); j++) {
5864                                     if (name.equals(sysPs.pkg.libraryNames.get(j))) {
5865                                         allowed = true;
5866                                         allowed = true;
5867                                         break;
5868                                     }
5869                                 }
5870                             }
5871                         } else {
5872                             allowed = true;
5873                         }
5874                         if (allowed) {
5875                             if (!mSharedLibraries.containsKey(name)) {
5876                                 mSharedLibraries.put(name, new SharedLibraryEntry(null, pkg.packageName));
5877                             } else if (!name.equals(pkg.packageName)) {
5878                                 Slog.w(TAG, "Package " + pkg.packageName + " library "
5879                                         + name + " already exists; skipping");
5880                             }
5881                         } else {
5882                             Slog.w(TAG, "Package " + pkg.packageName + " declares lib "
5883                                     + name + " that is not declared on system image; skipping");
5884                         }
5885                     }
5886                     if ((scanFlags&SCAN_BOOTING) == 0) {
5887                         // If we are not booting, we need to update any applications
5888                         // that are clients of our shared library.  If we are booting,
5889                         // this will all be done once the scan is complete.
5890                         clientLibPkgs = updateAllSharedLibrariesLPw(pkg);
5891                     }
5892                 }
5893             }
5894         }
5895
5896         // We also need to dexopt any apps that are dependent on this library.  Note that
5897         // if these fail, we should abort the install since installing the library will
5898         // result in some apps being broken.
5899         if (clientLibPkgs != null) {
5900             if ((scanFlags & SCAN_NO_DEX) == 0) {
5901                 for (int i = 0; i < clientLibPkgs.size(); i++) {
5902                     PackageParser.Package clientPkg = clientLibPkgs.get(i);
5903                     if (performDexOptLI(clientPkg, null /* instruction sets */, forceDex,
5904                             (scanFlags & SCAN_DEFER_DEX) != 0, false) == DEX_OPT_FAILED) {
5905                         throw new PackageManagerException(INSTALL_FAILED_DEXOPT,
5906                                 "scanPackageLI failed to dexopt clientLibPkgs");
5907                     }
5908                 }
5909             }
5910         }
5911
5912         // Request the ActivityManager to kill the process(only for existing packages)
5913         // so that we do not end up in a confused state while the user is still using the older
5914         // version of the application while the new one gets installed.
5915         if ((scanFlags & SCAN_REPLACING) != 0) {
5916             killApplication(pkg.applicationInfo.packageName,
5917                         pkg.applicationInfo.uid, "update pkg");
5918         }
5919
5920         // Also need to kill any apps that are dependent on the library.
5921         if (clientLibPkgs != null) {
5922             for (int i=0; i<clientLibPkgs.size(); i++) {
5923                 PackageParser.Package clientPkg = clientLibPkgs.get(i);
5924                 killApplication(clientPkg.applicationInfo.packageName,
5925                         clientPkg.applicationInfo.uid, "update lib");
5926             }
5927         }
5928
5929         // writer
5930         synchronized (mPackages) {
5931             // We don't expect installation to fail beyond this point
5932
5933             // Add the new setting to mSettings
5934             mSettings.insertPackageSettingLPw(pkgSetting, pkg);
5935             // Add the new setting to mPackages
5936             mPackages.put(pkg.applicationInfo.packageName, pkg);
5937             // Make sure we don't accidentally delete its data.
5938             final Iterator<PackageCleanItem> iter = mSettings.mPackagesToBeCleaned.iterator();
5939             while (iter.hasNext()) {
5940                 PackageCleanItem item = iter.next();
5941                 if (pkgName.equals(item.packageName)) {
5942                     iter.remove();
5943                 }
5944             }
5945
5946             // Take care of first install / last update times.
5947             if (currentTime != 0) {
5948                 if (pkgSetting.firstInstallTime == 0) {
5949                     pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = currentTime;
5950                 } else if ((scanFlags&SCAN_UPDATE_TIME) != 0) {
5951                     pkgSetting.lastUpdateTime = currentTime;
5952                 }
5953             } else if (pkgSetting.firstInstallTime == 0) {
5954                 // We need *something*.  Take time time stamp of the file.
5955                 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = scanFileTime;
5956             } else if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) != 0) {
5957                 if (scanFileTime != pkgSetting.timeStamp) {
5958                     // A package on the system image has changed; consider this
5959                     // to be an update.
5960                     pkgSetting.lastUpdateTime = scanFileTime;
5961                 }
5962             }
5963
5964             // Add the package's KeySets to the global KeySetManagerService
5965             KeySetManagerService ksms = mSettings.mKeySetManagerService;
5966             try {
5967                 // Old KeySetData no longer valid.
5968                 ksms.removeAppKeySetDataLPw(pkg.packageName);
5969                 ksms.addSigningKeySetToPackageLPw(pkg.packageName, pkg.mSigningKeys);
5970                 if (pkg.mKeySetMapping != null) {
5971                     for (Map.Entry<String, ArraySet<PublicKey>> entry :
5972                             pkg.mKeySetMapping.entrySet()) {
5973                         if (entry.getValue() != null) {
5974                             ksms.addDefinedKeySetToPackageLPw(pkg.packageName,
5975                                                           entry.getValue(), entry.getKey());
5976                         }
5977                     }
5978                     if (pkg.mUpgradeKeySets != null) {
5979                         for (String upgradeAlias : pkg.mUpgradeKeySets) {
5980                             ksms.addUpgradeKeySetToPackageLPw(pkg.packageName, upgradeAlias);
5981                         }
5982                     }
5983                 }
5984             } catch (NullPointerException e) {
5985                 Slog.e(TAG, "Could not add KeySet to " + pkg.packageName, e);
5986             } catch (IllegalArgumentException e) {
5987                 Slog.e(TAG, "Could not add KeySet to malformed package" + pkg.packageName, e);
5988             }
5989
5990             int N = pkg.providers.size();
5991             StringBuilder r = null;
5992             int i;
5993             for (i=0; i<N; i++) {
5994                 PackageParser.Provider p = pkg.providers.get(i);
5995                 p.info.processName = fixProcessName(pkg.applicationInfo.processName,
5996                         p.info.processName, pkg.applicationInfo.uid);
5997                 mProviders.addProvider(p);
5998                 p.syncable = p.info.isSyncable;
5999                 if (p.info.authority != null) {
6000                     String names[] = p.info.authority.split(";");
6001                     p.info.authority = null;
6002                     for (int j = 0; j < names.length; j++) {
6003                         if (j == 1 && p.syncable) {
6004                             // We only want the first authority for a provider to possibly be
6005                             // syncable, so if we already added this provider using a different
6006                             // authority clear the syncable flag. We copy the provider before
6007                             // changing it because the mProviders object contains a reference
6008                             // to a provider that we don't want to change.
6009                             // Only do this for the second authority since the resulting provider
6010                             // object can be the same for all future authorities for this provider.
6011                             p = new PackageParser.Provider(p);
6012                             p.syncable = false;
6013                         }
6014                         if (!mProvidersByAuthority.containsKey(names[j])) {
6015                             mProvidersByAuthority.put(names[j], p);
6016                             if (p.info.authority == null) {
6017                                 p.info.authority = names[j];
6018                             } else {
6019                                 p.info.authority = p.info.authority + ";" + names[j];
6020                             }
6021                             if (DEBUG_PACKAGE_SCANNING) {
6022                                 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
6023                                     Log.d(TAG, "Registered content provider: " + names[j]
6024                                             + ", className = " + p.info.name + ", isSyncable = "
6025                                             + p.info.isSyncable);
6026                             }
6027                         } else {
6028                             PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
6029                             Slog.w(TAG, "Skipping provider name " + names[j] +
6030                                     " (in package " + pkg.applicationInfo.packageName +
6031                                     "): name already used by "
6032                                     + ((other != null && other.getComponentName() != null)
6033                                             ? other.getComponentName().getPackageName() : "?"));
6034                         }
6035                     }
6036                 }
6037                 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
6038                     if (r == null) {
6039                         r = new StringBuilder(256);
6040                     } else {
6041                         r.append(' ');
6042                     }
6043                     r.append(p.info.name);
6044                 }
6045             }
6046             if (r != null) {
6047                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Providers: " + r);
6048             }
6049
6050             N = pkg.services.size();
6051             r = null;
6052             for (i=0; i<N; i++) {
6053                 PackageParser.Service s = pkg.services.get(i);
6054                 s.info.processName = fixProcessName(pkg.applicationInfo.processName,
6055                         s.info.processName, pkg.applicationInfo.uid);
6056                 mServices.addService(s);
6057                 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
6058                     if (r == null) {
6059                         r = new StringBuilder(256);
6060                     } else {
6061                         r.append(' ');
6062                     }
6063                     r.append(s.info.name);
6064                 }
6065             }
6066             if (r != null) {
6067                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Services: " + r);
6068             }
6069
6070             N = pkg.receivers.size();
6071             r = null;
6072             for (i=0; i<N; i++) {
6073                 PackageParser.Activity a = pkg.receivers.get(i);
6074                 a.info.processName = fixProcessName(pkg.applicationInfo.processName,
6075                         a.info.processName, pkg.applicationInfo.uid);
6076                 mReceivers.addActivity(a, "receiver");
6077                 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
6078                     if (r == null) {
6079                         r = new StringBuilder(256);
6080                     } else {
6081                         r.append(' ');
6082                     }
6083                     r.append(a.info.name);
6084                 }
6085             }
6086             if (r != null) {
6087                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Receivers: " + r);
6088             }
6089
6090             N = pkg.activities.size();
6091             r = null;
6092             for (i=0; i<N; i++) {
6093                 PackageParser.Activity a = pkg.activities.get(i);
6094                 a.info.processName = fixProcessName(pkg.applicationInfo.processName,
6095                         a.info.processName, pkg.applicationInfo.uid);
6096                 mActivities.addActivity(a, "activity");
6097                 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
6098                     if (r == null) {
6099                         r = new StringBuilder(256);
6100                     } else {
6101                         r.append(' ');
6102                     }
6103                     r.append(a.info.name);
6104                 }
6105             }
6106             if (r != null) {
6107                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Activities: " + r);
6108             }
6109
6110             N = pkg.permissionGroups.size();
6111             r = null;
6112             for (i=0; i<N; i++) {
6113                 PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i);
6114                 PackageParser.PermissionGroup cur = mPermissionGroups.get(pg.info.name);
6115                 if (cur == null) {
6116                     mPermissionGroups.put(pg.info.name, pg);
6117                     if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
6118                         if (r == null) {
6119                             r = new StringBuilder(256);
6120                         } else {
6121                             r.append(' ');
6122                         }
6123                         r.append(pg.info.name);
6124                     }
6125                 } else {
6126                     Slog.w(TAG, "Permission group " + pg.info.name + " from package "
6127                             + pg.info.packageName + " ignored: original from "
6128                             + cur.info.packageName);
6129                     if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
6130                         if (r == null) {
6131                             r = new StringBuilder(256);
6132                         } else {
6133                             r.append(' ');
6134                         }
6135                         r.append("DUP:");
6136                         r.append(pg.info.name);
6137                     }
6138                 }
6139             }
6140             if (r != null) {
6141                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Permission Groups: " + r);
6142             }
6143
6144             N = pkg.permissions.size();
6145             r = null;
6146             for (i=0; i<N; i++) {
6147                 PackageParser.Permission p = pkg.permissions.get(i);
6148                 ArrayMap<String, BasePermission> permissionMap =
6149                         p.tree ? mSettings.mPermissionTrees
6150                         : mSettings.mPermissions;
6151                 p.group = mPermissionGroups.get(p.info.group);
6152                 if (p.info.group == null || p.group != null) {
6153                     BasePermission bp = permissionMap.get(p.info.name);
6154
6155                     // Allow system apps to redefine non-system permissions
6156                     if (bp != null && !Objects.equals(bp.sourcePackage, p.info.packageName)) {
6157                         final boolean currentOwnerIsSystem = (bp.perm != null
6158                                 && isSystemApp(bp.perm.owner));
6159                         if (isSystemApp(p.owner)) {
6160                             if (bp.type == BasePermission.TYPE_BUILTIN && bp.perm == null) {
6161                                 // It's a built-in permission and no owner, take ownership now
6162                                 bp.packageSetting = pkgSetting;
6163                                 bp.perm = p;
6164                                 bp.uid = pkg.applicationInfo.uid;
6165                                 bp.sourcePackage = p.info.packageName;
6166                             } else if (!currentOwnerIsSystem) {
6167                                 String msg = "New decl " + p.owner + " of permission  "
6168                                         + p.info.name + " is system; overriding " + bp.sourcePackage;
6169                                 reportSettingsProblem(Log.WARN, msg);
6170                                 bp = null;
6171                             }
6172                         }
6173                     }
6174
6175                     if (bp == null) {
6176                         bp = new BasePermission(p.info.name, p.info.packageName,
6177                                 BasePermission.TYPE_NORMAL);
6178                         permissionMap.put(p.info.name, bp);
6179                     }
6180
6181                     if (bp.perm == null) {
6182                         if (bp.sourcePackage == null
6183                                 || bp.sourcePackage.equals(p.info.packageName)) {
6184                             BasePermission tree = findPermissionTreeLP(p.info.name);
6185                             if (tree == null
6186                                     || tree.sourcePackage.equals(p.info.packageName)) {
6187                                 bp.packageSetting = pkgSetting;
6188                                 bp.perm = p;
6189                                 bp.uid = pkg.applicationInfo.uid;
6190                                 bp.sourcePackage = p.info.packageName;
6191                                 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
6192                                     if (r == null) {
6193                                         r = new StringBuilder(256);
6194                                     } else {
6195                                         r.append(' ');
6196                                     }
6197                                     r.append(p.info.name);
6198                                 }
6199                             } else {
6200                                 Slog.w(TAG, "Permission " + p.info.name + " from package "
6201                                         + p.info.packageName + " ignored: base tree "
6202                                         + tree.name + " is from package "
6203                                         + tree.sourcePackage);
6204                             }
6205                         } else {
6206                             Slog.w(TAG, "Permission " + p.info.name + " from package "
6207                                     + p.info.packageName + " ignored: original from "
6208                                     + bp.sourcePackage);
6209                         }
6210                     } else if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
6211                         if (r == null) {
6212                             r = new StringBuilder(256);
6213                         } else {
6214                             r.append(' ');
6215                         }
6216                         r.append("DUP:");
6217                         r.append(p.info.name);
6218                     }
6219                     if (bp.perm == p) {
6220                         bp.protectionLevel = p.info.protectionLevel;
6221                     }
6222                 } else {
6223                     Slog.w(TAG, "Permission " + p.info.name + " from package "
6224                             + p.info.packageName + " ignored: no group "
6225                             + p.group);
6226                 }
6227             }
6228             if (r != null) {
6229                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Permissions: " + r);
6230             }
6231
6232             N = pkg.instrumentation.size();
6233             r = null;
6234             for (i=0; i<N; i++) {
6235                 PackageParser.Instrumentation a = pkg.instrumentation.get(i);
6236                 a.info.packageName = pkg.applicationInfo.packageName;
6237                 a.info.sourceDir = pkg.applicationInfo.sourceDir;
6238                 a.info.publicSourceDir = pkg.applicationInfo.publicSourceDir;
6239                 a.info.splitSourceDirs = pkg.applicationInfo.splitSourceDirs;
6240                 a.info.splitPublicSourceDirs = pkg.applicationInfo.splitPublicSourceDirs;
6241                 a.info.dataDir = pkg.applicationInfo.dataDir;
6242
6243                 // TODO: Update instrumentation.nativeLibraryDir as well ? Does it
6244                 // need other information about the application, like the ABI and what not ?
6245                 a.info.nativeLibraryDir = pkg.applicationInfo.nativeLibraryDir;
6246                 mInstrumentation.put(a.getComponentName(), a);
6247                 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
6248                     if (r == null) {
6249                         r = new StringBuilder(256);
6250                     } else {
6251                         r.append(' ');
6252                     }
6253                     r.append(a.info.name);
6254                 }
6255             }
6256             if (r != null) {
6257                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Instrumentation: " + r);
6258             }
6259
6260             if (pkg.protectedBroadcasts != null) {
6261                 N = pkg.protectedBroadcasts.size();
6262                 for (i=0; i<N; i++) {
6263                     mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i));
6264                 }
6265             }
6266
6267             pkgSetting.setTimeStamp(scanFileTime);
6268
6269             // Create idmap files for pairs of (packages, overlay packages).
6270             // Note: "android", ie framework-res.apk, is handled by native layers.
6271             if (pkg.mOverlayTarget != null) {
6272                 // This is an overlay package.
6273                 if (pkg.mOverlayTarget != null && !pkg.mOverlayTarget.equals("android")) {
6274                     if (!mOverlays.containsKey(pkg.mOverlayTarget)) {
6275                         mOverlays.put(pkg.mOverlayTarget,
6276                                 new ArrayMap<String, PackageParser.Package>());
6277                     }
6278                     ArrayMap<String, PackageParser.Package> map = mOverlays.get(pkg.mOverlayTarget);
6279                     map.put(pkg.packageName, pkg);
6280                     PackageParser.Package orig = mPackages.get(pkg.mOverlayTarget);
6281                     if (orig != null && !createIdmapForPackagePairLI(orig, pkg)) {
6282                         throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
6283                                 "scanPackageLI failed to createIdmap");
6284                     }
6285                 }
6286             } else if (mOverlays.containsKey(pkg.packageName) &&
6287                     !pkg.packageName.equals("android")) {
6288                 // This is a regular package, with one or more known overlay packages.
6289                 createIdmapsForPackageLI(pkg);
6290             }
6291         }
6292
6293         return pkg;
6294     }
6295
6296     /**
6297      * Adjusts ABIs for a set of packages belonging to a shared user so that they all match.
6298      * i.e, so that all packages can be run inside a single process if required.
6299      *
6300      * Optionally, callers can pass in a parsed package via {@code newPackage} in which case
6301      * this function will either try and make the ABI for all packages in {@code packagesForUser}
6302      * match {@code scannedPackage} or will update the ABI of {@code scannedPackage} to match
6303      * the ABI selected for {@code packagesForUser}. This variant is used when installing or
6304      * updating a package that belongs to a shared user.
6305      *
6306      * NOTE: We currently only match for the primary CPU abi string. Matching the secondary
6307      * adds unnecessary complexity.
6308      */
6309     private void adjustCpuAbisForSharedUserLPw(Set<PackageSetting> packagesForUser,
6310             PackageParser.Package scannedPackage, boolean forceDexOpt, boolean deferDexOpt) {
6311         String requiredInstructionSet = null;
6312         if (scannedPackage != null && scannedPackage.applicationInfo.primaryCpuAbi != null) {
6313             requiredInstructionSet = VMRuntime.getInstructionSet(
6314                      scannedPackage.applicationInfo.primaryCpuAbi);
6315         }
6316
6317         PackageSetting requirer = null;
6318         for (PackageSetting ps : packagesForUser) {
6319             // If packagesForUser contains scannedPackage, we skip it. This will happen
6320             // when scannedPackage is an update of an existing package. Without this check,
6321             // we will never be able to change the ABI of any package belonging to a shared
6322             // user, even if it's compatible with other packages.
6323             if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
6324                 if (ps.primaryCpuAbiString == null) {
6325                     continue;
6326                 }
6327
6328                 final String instructionSet = VMRuntime.getInstructionSet(ps.primaryCpuAbiString);
6329                 if (requiredInstructionSet != null && !instructionSet.equals(requiredInstructionSet)) {
6330                     // We have a mismatch between instruction sets (say arm vs arm64) warn about
6331                     // this but there's not much we can do.
6332                     String errorMessage = "Instruction set mismatch, "
6333                             + ((requirer == null) ? "[caller]" : requirer)
6334                             + " requires " + requiredInstructionSet + " whereas " + ps
6335                             + " requires " + instructionSet;
6336                     Slog.w(TAG, errorMessage);
6337                 }
6338
6339                 if (requiredInstructionSet == null) {
6340                     requiredInstructionSet = instructionSet;
6341                     requirer = ps;
6342                 }
6343             }
6344         }
6345
6346         if (requiredInstructionSet != null) {
6347             String adjustedAbi;
6348             if (requirer != null) {
6349                 // requirer != null implies that either scannedPackage was null or that scannedPackage
6350                 // did not require an ABI, in which case we have to adjust scannedPackage to match
6351                 // the ABI of the set (which is the same as requirer's ABI)
6352                 adjustedAbi = requirer.primaryCpuAbiString;
6353                 if (scannedPackage != null) {
6354                     scannedPackage.applicationInfo.primaryCpuAbi = adjustedAbi;
6355                 }
6356             } else {
6357                 // requirer == null implies that we're updating all ABIs in the set to
6358                 // match scannedPackage.
6359                 adjustedAbi =  scannedPackage.applicationInfo.primaryCpuAbi;
6360             }
6361
6362             for (PackageSetting ps : packagesForUser) {
6363                 if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
6364                     if (ps.primaryCpuAbiString != null) {
6365                         continue;
6366                     }
6367
6368                     ps.primaryCpuAbiString = adjustedAbi;
6369                     if (ps.pkg != null && ps.pkg.applicationInfo != null) {
6370                         ps.pkg.applicationInfo.primaryCpuAbi = adjustedAbi;
6371                         Slog.i(TAG, "Adjusting ABI for : " + ps.name + " to " + adjustedAbi);
6372
6373                         if (performDexOptLI(ps.pkg, null /* instruction sets */, forceDexOpt,
6374                                 deferDexOpt, true) == DEX_OPT_FAILED) {
6375                             ps.primaryCpuAbiString = null;
6376                             ps.pkg.applicationInfo.primaryCpuAbi = null;
6377                             return;
6378                         } else {
6379                             mInstaller.rmdex(ps.codePathString,
6380                                              getDexCodeInstructionSet(getPreferredInstructionSet()));
6381                         }
6382                     }
6383                 }
6384             }
6385         }
6386     }
6387
6388     private void setUpCustomResolverActivity(PackageParser.Package pkg) {
6389         synchronized (mPackages) {
6390             mResolverReplaced = true;
6391             // Set up information for custom user intent resolution activity.
6392             mResolveActivity.applicationInfo = pkg.applicationInfo;
6393             mResolveActivity.name = mCustomResolverComponentName.getClassName();
6394             mResolveActivity.packageName = pkg.applicationInfo.packageName;
6395             mResolveActivity.processName = null;
6396             mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
6397             mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS |
6398                     ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
6399             mResolveActivity.theme = 0;
6400             mResolveActivity.exported = true;
6401             mResolveActivity.enabled = true;
6402             mResolveInfo.activityInfo = mResolveActivity;
6403             mResolveInfo.priority = 0;
6404             mResolveInfo.preferredOrder = 0;
6405             mResolveInfo.match = 0;
6406             mResolveComponentName = mCustomResolverComponentName;
6407             Slog.i(TAG, "Replacing default ResolverActivity with custom activity: " +
6408                     mResolveComponentName);
6409         }
6410     }
6411
6412     private static String calculateBundledApkRoot(final String codePathString) {
6413         final File codePath = new File(codePathString);
6414         final File codeRoot;
6415         if (FileUtils.contains(Environment.getRootDirectory(), codePath)) {
6416             codeRoot = Environment.getRootDirectory();
6417         } else if (FileUtils.contains(Environment.getOemDirectory(), codePath)) {
6418             codeRoot = Environment.getOemDirectory();
6419         } else if (FileUtils.contains(Environment.getVendorDirectory(), codePath)) {
6420             codeRoot = Environment.getVendorDirectory();
6421         } else {
6422             // Unrecognized code path; take its top real segment as the apk root:
6423             // e.g. /something/app/blah.apk => /something
6424             try {
6425                 File f = codePath.getCanonicalFile();
6426                 File parent = f.getParentFile();    // non-null because codePath is a file
6427                 File tmp;
6428                 while ((tmp = parent.getParentFile()) != null) {
6429                     f = parent;
6430                     parent = tmp;
6431                 }
6432                 codeRoot = f;
6433                 Slog.w(TAG, "Unrecognized code path "
6434                         + codePath + " - using " + codeRoot);
6435             } catch (IOException e) {
6436                 // Can't canonicalize the code path -- shenanigans?
6437                 Slog.w(TAG, "Can't canonicalize code path " + codePath);
6438                 return Environment.getRootDirectory().getPath();
6439             }
6440         }
6441         return codeRoot.getPath();
6442     }
6443
6444     /**
6445      * Derive and set the location of native libraries for the given package,
6446      * which varies depending on where and how the package was installed.
6447      */
6448     private void setNativeLibraryPaths(PackageParser.Package pkg) {
6449         final ApplicationInfo info = pkg.applicationInfo;
6450         final String codePath = pkg.codePath;
6451         final File codeFile = new File(codePath);
6452         final boolean bundledApp = isSystemApp(info) && !isUpdatedSystemApp(info);
6453         final boolean asecApp = isForwardLocked(info) || isExternal(info);
6454
6455         info.nativeLibraryRootDir = null;
6456         info.nativeLibraryRootRequiresIsa = false;
6457         info.nativeLibraryDir = null;
6458         info.secondaryNativeLibraryDir = null;
6459
6460         if (isApkFile(codeFile)) {
6461             // Monolithic install
6462             if (bundledApp) {
6463                 // If "/system/lib64/apkname" exists, assume that is the per-package
6464                 // native library directory to use; otherwise use "/system/lib/apkname".
6465                 final String apkRoot = calculateBundledApkRoot(info.sourceDir);
6466                 final boolean is64Bit = VMRuntime.is64BitInstructionSet(
6467                         getPrimaryInstructionSet(info));
6468
6469                 // This is a bundled system app so choose the path based on the ABI.
6470                 // if it's a 64 bit abi, use lib64 otherwise use lib32. Note that this
6471                 // is just the default path.
6472                 final String apkName = deriveCodePathName(codePath);
6473                 final String libDir = is64Bit ? LIB64_DIR_NAME : LIB_DIR_NAME;
6474                 info.nativeLibraryRootDir = Environment.buildPath(new File(apkRoot), libDir,
6475                         apkName).getAbsolutePath();
6476
6477                 if (info.secondaryCpuAbi != null) {
6478                     final String secondaryLibDir = is64Bit ? LIB_DIR_NAME : LIB64_DIR_NAME;
6479                     info.secondaryNativeLibraryDir = Environment.buildPath(new File(apkRoot),
6480                             secondaryLibDir, apkName).getAbsolutePath();
6481                 }
6482             } else if (asecApp) {
6483                 info.nativeLibraryRootDir = new File(codeFile.getParentFile(), LIB_DIR_NAME)
6484                         .getAbsolutePath();
6485             } else {
6486                 final String apkName = deriveCodePathName(codePath);
6487                 info.nativeLibraryRootDir = new File(mAppLib32InstallDir, apkName)
6488                         .getAbsolutePath();
6489             }
6490
6491             info.nativeLibraryRootRequiresIsa = false;
6492             info.nativeLibraryDir = info.nativeLibraryRootDir;
6493         } else {
6494             // Cluster install
6495             info.nativeLibraryRootDir = new File(codeFile, LIB_DIR_NAME).getAbsolutePath();
6496             info.nativeLibraryRootRequiresIsa = true;
6497
6498             info.nativeLibraryDir = new File(info.nativeLibraryRootDir,
6499                     getPrimaryInstructionSet(info)).getAbsolutePath();
6500
6501             if (info.secondaryCpuAbi != null) {
6502                 info.secondaryNativeLibraryDir = new File(info.nativeLibraryRootDir,
6503                         VMRuntime.getInstructionSet(info.secondaryCpuAbi)).getAbsolutePath();
6504             }
6505         }
6506     }
6507
6508     /**
6509      * Calculate the abis and roots for a bundled app. These can uniquely
6510      * be determined from the contents of the system partition, i.e whether
6511      * it contains 64 or 32 bit shared libraries etc. We do not validate any
6512      * of this information, and instead assume that the system was built
6513      * sensibly.
6514      */
6515     private void setBundledAppAbisAndRoots(PackageParser.Package pkg,
6516                                            PackageSetting pkgSetting) {
6517         final String apkName = deriveCodePathName(pkg.applicationInfo.getCodePath());
6518
6519         // If "/system/lib64/apkname" exists, assume that is the per-package
6520         // native library directory to use; otherwise use "/system/lib/apkname".
6521         final String apkRoot = calculateBundledApkRoot(pkg.applicationInfo.sourceDir);
6522         setBundledAppAbi(pkg, apkRoot, apkName);
6523         // pkgSetting might be null during rescan following uninstall of updates
6524         // to a bundled app, so accommodate that possibility.  The settings in
6525         // that case will be established later from the parsed package.
6526         //
6527         // If the settings aren't null, sync them up with what we've just derived.
6528         // note that apkRoot isn't stored in the package settings.
6529         if (pkgSetting != null) {
6530             pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
6531             pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
6532         }
6533     }
6534
6535     /**
6536      * Deduces the ABI of a bundled app and sets the relevant fields on the
6537      * parsed pkg object.
6538      *
6539      * @param apkRoot the root of the installed apk, something like {@code /system} or {@code /oem}
6540      *        under which system libraries are installed.
6541      * @param apkName the name of the installed package.
6542      */
6543     private static void setBundledAppAbi(PackageParser.Package pkg, String apkRoot, String apkName) {
6544         final File codeFile = new File(pkg.codePath);
6545
6546         final boolean has64BitLibs;
6547         final boolean has32BitLibs;
6548         if (isApkFile(codeFile)) {
6549             // Monolithic install
6550             has64BitLibs = (new File(apkRoot, new File(LIB64_DIR_NAME, apkName).getPath())).exists();
6551             has32BitLibs = (new File(apkRoot, new File(LIB_DIR_NAME, apkName).getPath())).exists();
6552         } else {
6553             // Cluster install
6554             final File rootDir = new File(codeFile, LIB_DIR_NAME);
6555             if (!ArrayUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS)
6556                     && !TextUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS[0])) {
6557                 final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_64_BIT_ABIS[0]);
6558                 has64BitLibs = (new File(rootDir, isa)).exists();
6559             } else {
6560                 has64BitLibs = false;
6561             }
6562             if (!ArrayUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS)
6563                     && !TextUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS[0])) {
6564                 final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_32_BIT_ABIS[0]);
6565                 has32BitLibs = (new File(rootDir, isa)).exists();
6566             } else {
6567                 has32BitLibs = false;
6568             }
6569         }
6570
6571         if (has64BitLibs && !has32BitLibs) {
6572             // The package has 64 bit libs, but not 32 bit libs. Its primary
6573             // ABI should be 64 bit. We can safely assume here that the bundled
6574             // native libraries correspond to the most preferred ABI in the list.
6575
6576             pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
6577             pkg.applicationInfo.secondaryCpuAbi = null;
6578         } else if (has32BitLibs && !has64BitLibs) {
6579             // The package has 32 bit libs but not 64 bit libs. Its primary
6580             // ABI should be 32 bit.
6581
6582             pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
6583             pkg.applicationInfo.secondaryCpuAbi = null;
6584         } else if (has32BitLibs && has64BitLibs) {
6585             // The application has both 64 and 32 bit bundled libraries. We check
6586             // here that the app declares multiArch support, and warn if it doesn't.
6587             //
6588             // We will be lenient here and record both ABIs. The primary will be the
6589             // ABI that's higher on the list, i.e, a device that's configured to prefer
6590             // 64 bit apps will see a 64 bit primary ABI,
6591
6592             if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) == 0) {
6593                 Slog.e(TAG, "Package: " + pkg + " has multiple bundled libs, but is not multiarch.");
6594             }
6595
6596             if (VMRuntime.is64BitInstructionSet(getPreferredInstructionSet())) {
6597                 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
6598                 pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
6599             } else {
6600                 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
6601                 pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
6602             }
6603         } else {
6604             pkg.applicationInfo.primaryCpuAbi = null;
6605             pkg.applicationInfo.secondaryCpuAbi = null;
6606         }
6607     }
6608
6609     private void killApplication(String pkgName, int appId, String reason) {
6610         // Request the ActivityManager to kill the process(only for existing packages)
6611         // so that we do not end up in a confused state while the user is still using the older
6612         // version of the application while the new one gets installed.
6613         IActivityManager am = ActivityManagerNative.getDefault();
6614         if (am != null) {
6615             try {
6616                 am.killApplicationWithAppId(pkgName, appId, reason);
6617             } catch (RemoteException e) {
6618             }
6619         }
6620     }
6621
6622     void removePackageLI(PackageSetting ps, boolean chatty) {
6623         if (DEBUG_INSTALL) {
6624             if (chatty)
6625                 Log.d(TAG, "Removing package " + ps.name);
6626         }
6627
6628         // writer
6629         synchronized (mPackages) {
6630             mPackages.remove(ps.name);
6631             final PackageParser.Package pkg = ps.pkg;
6632             if (pkg != null) {
6633                 cleanPackageDataStructuresLILPw(pkg, chatty);
6634             }
6635         }
6636     }
6637
6638     void removeInstalledPackageLI(PackageParser.Package pkg, boolean chatty) {
6639         if (DEBUG_INSTALL) {
6640             if (chatty)
6641                 Log.d(TAG, "Removing package " + pkg.applicationInfo.packageName);
6642         }
6643
6644         // writer
6645         synchronized (mPackages) {
6646             mPackages.remove(pkg.applicationInfo.packageName);
6647             cleanPackageDataStructuresLILPw(pkg, chatty);
6648         }
6649     }
6650
6651     void cleanPackageDataStructuresLILPw(PackageParser.Package pkg, boolean chatty) {
6652         int N = pkg.providers.size();
6653         StringBuilder r = null;
6654         int i;
6655         for (i=0; i<N; i++) {
6656             PackageParser.Provider p = pkg.providers.get(i);
6657             mProviders.removeProvider(p);
6658             if (p.info.authority == null) {
6659
6660                 /* There was another ContentProvider with this authority when
6661                  * this app was installed so this authority is null,
6662                  * Ignore it as we don't have to unregister the provider.
6663                  */
6664                 continue;
6665             }
6666             String names[] = p.info.authority.split(";");
6667             for (int j = 0; j < names.length; j++) {
6668                 if (mProvidersByAuthority.get(names[j]) == p) {
6669                     mProvidersByAuthority.remove(names[j]);
6670                     if (DEBUG_REMOVE) {
6671                         if (chatty)
6672                             Log.d(TAG, "Unregistered content provider: " + names[j]
6673                                     + ", className = " + p.info.name + ", isSyncable = "
6674                                     + p.info.isSyncable);
6675                     }
6676                 }
6677             }
6678             if (DEBUG_REMOVE && chatty) {
6679                 if (r == null) {
6680                     r = new StringBuilder(256);
6681                 } else {
6682                     r.append(' ');
6683                 }
6684                 r.append(p.info.name);
6685             }
6686         }
6687         if (r != null) {
6688             if (DEBUG_REMOVE) Log.d(TAG, "  Providers: " + r);
6689         }
6690
6691         N = pkg.services.size();
6692         r = null;
6693         for (i=0; i<N; i++) {
6694             PackageParser.Service s = pkg.services.get(i);
6695             mServices.removeService(s);
6696             if (chatty) {
6697                 if (r == null) {
6698                     r = new StringBuilder(256);
6699                 } else {
6700                     r.append(' ');
6701                 }
6702                 r.append(s.info.name);
6703             }
6704         }
6705         if (r != null) {
6706             if (DEBUG_REMOVE) Log.d(TAG, "  Services: " + r);
6707         }
6708
6709         N = pkg.receivers.size();
6710         r = null;
6711         for (i=0; i<N; i++) {
6712             PackageParser.Activity a = pkg.receivers.get(i);
6713             mReceivers.removeActivity(a, "receiver");
6714             if (DEBUG_REMOVE && chatty) {
6715                 if (r == null) {
6716                     r = new StringBuilder(256);
6717                 } else {
6718                     r.append(' ');
6719                 }
6720                 r.append(a.info.name);
6721             }
6722         }
6723         if (r != null) {
6724             if (DEBUG_REMOVE) Log.d(TAG, "  Receivers: " + r);
6725         }
6726
6727         N = pkg.activities.size();
6728         r = null;
6729         for (i=0; i<N; i++) {
6730             PackageParser.Activity a = pkg.activities.get(i);
6731             mActivities.removeActivity(a, "activity");
6732             if (DEBUG_REMOVE && chatty) {
6733                 if (r == null) {
6734                     r = new StringBuilder(256);
6735                 } else {
6736                     r.append(' ');
6737                 }
6738                 r.append(a.info.name);
6739             }
6740         }
6741         if (r != null) {
6742             if (DEBUG_REMOVE) Log.d(TAG, "  Activities: " + r);
6743         }
6744
6745         N = pkg.permissions.size();
6746         r = null;
6747         for (i=0; i<N; i++) {
6748             PackageParser.Permission p = pkg.permissions.get(i);
6749             BasePermission bp = mSettings.mPermissions.get(p.info.name);
6750             if (bp == null) {
6751                 bp = mSettings.mPermissionTrees.get(p.info.name);
6752             }
6753             if (bp != null && bp.perm == p) {
6754                 bp.perm = null;
6755                 if (DEBUG_REMOVE && chatty) {
6756                     if (r == null) {
6757                         r = new StringBuilder(256);
6758                     } else {
6759                         r.append(' ');
6760                     }
6761                     r.append(p.info.name);
6762                 }
6763             }
6764             if ((p.info.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
6765                 ArraySet<String> appOpPerms = mAppOpPermissionPackages.get(p.info.name);
6766                 if (appOpPerms != null) {
6767                     appOpPerms.remove(pkg.packageName);
6768                 }
6769             }
6770         }
6771         if (r != null) {
6772             if (DEBUG_REMOVE) Log.d(TAG, "  Permissions: " + r);
6773         }
6774
6775         N = pkg.requestedPermissions.size();
6776         r = null;
6777         for (i=0; i<N; i++) {
6778             String perm = pkg.requestedPermissions.get(i);
6779             BasePermission bp = mSettings.mPermissions.get(perm);
6780             if (bp != null && (bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
6781                 ArraySet<String> appOpPerms = mAppOpPermissionPackages.get(perm);
6782                 if (appOpPerms != null) {
6783                     appOpPerms.remove(pkg.packageName);
6784                     if (appOpPerms.isEmpty()) {
6785                         mAppOpPermissionPackages.remove(perm);
6786                     }
6787                 }
6788             }
6789         }
6790         if (r != null) {
6791             if (DEBUG_REMOVE) Log.d(TAG, "  Permissions: " + r);
6792         }
6793
6794         N = pkg.instrumentation.size();
6795         r = null;
6796         for (i=0; i<N; i++) {
6797             PackageParser.Instrumentation a = pkg.instrumentation.get(i);
6798             mInstrumentation.remove(a.getComponentName());
6799             if (DEBUG_REMOVE && chatty) {
6800                 if (r == null) {
6801                     r = new StringBuilder(256);
6802                 } else {
6803                     r.append(' ');
6804                 }
6805                 r.append(a.info.name);
6806             }
6807         }
6808         if (r != null) {
6809             if (DEBUG_REMOVE) Log.d(TAG, "  Instrumentation: " + r);
6810         }
6811
6812         r = null;
6813         if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
6814             // Only system apps can hold shared libraries.
6815             if (pkg.libraryNames != null) {
6816                 for (i=0; i<pkg.libraryNames.size(); i++) {
6817                     String name = pkg.libraryNames.get(i);
6818                     SharedLibraryEntry cur = mSharedLibraries.get(name);
6819                     if (cur != null && cur.apk != null && cur.apk.equals(pkg.packageName)) {
6820                         mSharedLibraries.remove(name);
6821                         if (DEBUG_REMOVE && chatty) {
6822                             if (r == null) {
6823                                 r = new StringBuilder(256);
6824                             } else {
6825                                 r.append(' ');
6826                             }
6827                             r.append(name);
6828                         }
6829                     }
6830                 }
6831             }
6832         }
6833         if (r != null) {
6834             if (DEBUG_REMOVE) Log.d(TAG, "  Libraries: " + r);
6835         }
6836     }
6837
6838     private static boolean hasPermission(PackageParser.Package pkgInfo, String perm) {
6839         for (int i=pkgInfo.permissions.size()-1; i>=0; i--) {
6840             if (pkgInfo.permissions.get(i).info.name.equals(perm)) {
6841                 return true;
6842             }
6843         }
6844         return false;
6845     }
6846
6847     static final int UPDATE_PERMISSIONS_ALL = 1<<0;
6848     static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1<<1;
6849     static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1<<2;
6850
6851     private void updatePermissionsLPw(String changingPkg,
6852             PackageParser.Package pkgInfo, int flags) {
6853         // Make sure there are no dangling permission trees.
6854         Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator();
6855         while (it.hasNext()) {
6856             final BasePermission bp = it.next();
6857             if (bp.packageSetting == null) {
6858                 // We may not yet have parsed the package, so just see if
6859                 // we still know about its settings.
6860                 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage);
6861             }
6862             if (bp.packageSetting == null) {
6863                 Slog.w(TAG, "Removing dangling permission tree: " + bp.name
6864                         + " from package " + bp.sourcePackage);
6865                 it.remove();
6866             } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) {
6867                 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
6868                     Slog.i(TAG, "Removing old permission tree: " + bp.name
6869                             + " from package " + bp.sourcePackage);
6870                     flags |= UPDATE_PERMISSIONS_ALL;
6871                     it.remove();
6872                 }
6873             }
6874         }
6875
6876         // Make sure all dynamic permissions have been assigned to a package,
6877         // and make sure there are no dangling permissions.
6878         it = mSettings.mPermissions.values().iterator();
6879         while (it.hasNext()) {
6880             final BasePermission bp = it.next();
6881             if (bp.type == BasePermission.TYPE_DYNAMIC) {
6882                 if (DEBUG_SETTINGS) Log.v(TAG, "Dynamic permission: name="
6883                         + bp.name + " pkg=" + bp.sourcePackage
6884                         + " info=" + bp.pendingInfo);
6885                 if (bp.packageSetting == null && bp.pendingInfo != null) {
6886                     final BasePermission tree = findPermissionTreeLP(bp.name);
6887                     if (tree != null && tree.perm != null) {
6888                         bp.packageSetting = tree.packageSetting;
6889                         bp.perm = new PackageParser.Permission(tree.perm.owner,
6890                                 new PermissionInfo(bp.pendingInfo));
6891                         bp.perm.info.packageName = tree.perm.info.packageName;
6892                         bp.perm.info.name = bp.name;
6893                         bp.uid = tree.uid;
6894                     }
6895                 }
6896             }
6897             if (bp.packageSetting == null) {
6898                 // We may not yet have parsed the package, so just see if
6899                 // we still know about its settings.
6900                 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage);
6901             }
6902             if (bp.packageSetting == null) {
6903                 Slog.w(TAG, "Removing dangling permission: " + bp.name
6904                         + " from package " + bp.sourcePackage);
6905                 it.remove();
6906             } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) {
6907                 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
6908                     Slog.i(TAG, "Removing old permission: " + bp.name
6909                             + " from package " + bp.sourcePackage);
6910                     flags |= UPDATE_PERMISSIONS_ALL;
6911                     it.remove();
6912                 }
6913             }
6914         }
6915
6916         // Now update the permissions for all packages, in particular
6917         // replace the granted permissions of the system packages.
6918         if ((flags&UPDATE_PERMISSIONS_ALL) != 0) {
6919             for (PackageParser.Package pkg : mPackages.values()) {
6920                 if (pkg != pkgInfo) {
6921                     grantPermissionsLPw(pkg, (flags&UPDATE_PERMISSIONS_REPLACE_ALL) != 0,
6922                             changingPkg);
6923                 }
6924             }
6925         }
6926         
6927         if (pkgInfo != null) {
6928             grantPermissionsLPw(pkgInfo, (flags&UPDATE_PERMISSIONS_REPLACE_PKG) != 0, changingPkg);
6929         }
6930     }
6931
6932     private void grantPermissionsLPw(PackageParser.Package pkg, boolean replace,
6933             String packageOfInterest) {
6934         final PackageSetting ps = (PackageSetting) pkg.mExtras;
6935         if (ps == null) {
6936             return;
6937         }
6938         final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps;
6939         ArraySet<String> origPermissions = gp.grantedPermissions;
6940         boolean changedPermission = false;
6941
6942         if (replace) {
6943             ps.permissionsFixed = false;
6944             if (gp == ps) {
6945                 origPermissions = new ArraySet<String>(gp.grantedPermissions);
6946                 gp.grantedPermissions.clear();
6947                 gp.gids = mGlobalGids;
6948             }
6949         }
6950
6951         if (gp.gids == null) {
6952             gp.gids = mGlobalGids;
6953         }
6954
6955         final int N = pkg.requestedPermissions.size();
6956         for (int i=0; i<N; i++) {
6957             final String name = pkg.requestedPermissions.get(i);
6958             final boolean required = pkg.requestedPermissionsRequired.get(i);
6959             final BasePermission bp = mSettings.mPermissions.get(name);
6960             if (DEBUG_INSTALL) {
6961                 if (gp != ps) {
6962                     Log.i(TAG, "Package " + pkg.packageName + " checking " + name + ": " + bp);
6963                 }
6964             }
6965
6966             if (bp == null || bp.packageSetting == null) {
6967                 if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) {
6968                     Slog.w(TAG, "Unknown permission " + name
6969                             + " in package " + pkg.packageName);
6970                 }
6971                 continue;
6972             }
6973
6974             final String perm = bp.name;
6975             boolean allowed;
6976             boolean allowedSig = false;
6977             if ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
6978                 // Keep track of app op permissions.
6979                 ArraySet<String> pkgs = mAppOpPermissionPackages.get(bp.name);
6980                 if (pkgs == null) {
6981                     pkgs = new ArraySet<>();
6982                     mAppOpPermissionPackages.put(bp.name, pkgs);
6983                 }
6984                 pkgs.add(pkg.packageName);
6985             }
6986             final int level = bp.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE;
6987             if (level == PermissionInfo.PROTECTION_NORMAL
6988                     || level == PermissionInfo.PROTECTION_DANGEROUS) {
6989                 // We grant a normal or dangerous permission if any of the following
6990                 // are true:
6991                 // 1) The permission is required
6992                 // 2) The permission is optional, but was granted in the past
6993                 // 3) The permission is optional, but was requested by an
6994                 //    app in /system (not /data)
6995                 //
6996                 // Otherwise, reject the permission.
6997                 allowed = (required || origPermissions.contains(perm)
6998                         || (isSystemApp(ps) && !isUpdatedSystemApp(ps)));
6999             } else if (bp.packageSetting == null) {
7000                 // This permission is invalid; skip it.
7001                 allowed = false;
7002             } else if (level == PermissionInfo.PROTECTION_SIGNATURE) {
7003                 allowed = grantSignaturePermission(perm, pkg, bp, origPermissions);
7004                 if (allowed) {
7005                     allowedSig = true;
7006                 }
7007             } else {
7008                 allowed = false;
7009             }
7010             if (DEBUG_INSTALL) {
7011                 if (gp != ps) {
7012                     Log.i(TAG, "Package " + pkg.packageName + " granting " + perm);
7013                 }
7014             }
7015             if (allowed) {
7016                 if (!isSystemApp(ps) && ps.permissionsFixed) {
7017                     // If this is an existing, non-system package, then
7018                     // we can't add any new permissions to it.
7019                     if (!allowedSig && !gp.grantedPermissions.contains(perm)) {
7020                         // Except...  if this is a permission that was added
7021                         // to the platform (note: need to only do this when
7022                         // updating the platform).
7023                         allowed = isNewPlatformPermissionForPackage(perm, pkg);
7024                     }
7025                 }
7026                 if (allowed) {
7027                     if (!gp.grantedPermissions.contains(perm)) {
7028                         changedPermission = true;
7029                         gp.grantedPermissions.add(perm);
7030                         gp.gids = appendInts(gp.gids, bp.gids);
7031                     } else if (!ps.haveGids) {
7032                         gp.gids = appendInts(gp.gids, bp.gids);
7033                     }
7034                 } else {
7035                     if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) {
7036                         Slog.w(TAG, "Not granting permission " + perm
7037                                 + " to package " + pkg.packageName
7038                                 + " because it was previously installed without");
7039                     }
7040                 }
7041             } else {
7042                 if (gp.grantedPermissions.remove(perm)) {
7043                     changedPermission = true;
7044                     gp.gids = removeInts(gp.gids, bp.gids);
7045                     Slog.i(TAG, "Un-granting permission " + perm
7046                             + " from package " + pkg.packageName
7047                             + " (protectionLevel=" + bp.protectionLevel
7048                             + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
7049                             + ")");
7050                 } else if ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) == 0) {
7051                     // Don't print warning for app op permissions, since it is fine for them
7052                     // not to be granted, there is a UI for the user to decide.
7053                     if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) {
7054                         Slog.w(TAG, "Not granting permission " + perm
7055                                 + " to package " + pkg.packageName
7056                                 + " (protectionLevel=" + bp.protectionLevel
7057                                 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
7058                                 + ")");
7059                     }
7060                 }
7061             }
7062         }
7063
7064         if ((changedPermission || replace) && !ps.permissionsFixed &&
7065                 !isSystemApp(ps) || isUpdatedSystemApp(ps)){
7066             // This is the first that we have heard about this package, so the
7067             // permissions we have now selected are fixed until explicitly
7068             // changed.
7069             ps.permissionsFixed = true;
7070         }
7071         ps.haveGids = true;
7072     }
7073
7074     private boolean isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg) {
7075         boolean allowed = false;
7076         final int NP = PackageParser.NEW_PERMISSIONS.length;
7077         for (int ip=0; ip<NP; ip++) {
7078             final PackageParser.NewPermissionInfo npi
7079                     = PackageParser.NEW_PERMISSIONS[ip];
7080             if (npi.name.equals(perm)
7081                     && pkg.applicationInfo.targetSdkVersion < npi.sdkVersion) {
7082                 allowed = true;
7083                 Log.i(TAG, "Auto-granting " + perm + " to old pkg "
7084                         + pkg.packageName);
7085                 break;
7086             }
7087         }
7088         return allowed;
7089     }
7090
7091     private boolean grantSignaturePermission(String perm, PackageParser.Package pkg,
7092                                           BasePermission bp, ArraySet<String> origPermissions) {
7093         boolean allowed;
7094         allowed = (compareSignatures(
7095                 bp.packageSetting.signatures.mSignatures, pkg.mSignatures)
7096                         == PackageManager.SIGNATURE_MATCH)
7097                 || (compareSignatures(mPlatformPackage.mSignatures, pkg.mSignatures)
7098                         == PackageManager.SIGNATURE_MATCH);
7099         if (!allowed && (bp.protectionLevel
7100                 & PermissionInfo.PROTECTION_FLAG_SYSTEM) != 0) {
7101             if (isSystemApp(pkg)) {
7102                 // For updated system applications, a system permission
7103                 // is granted only if it had been defined by the original application.
7104                 if (isUpdatedSystemApp(pkg)) {
7105                     final PackageSetting sysPs = mSettings
7106                             .getDisabledSystemPkgLPr(pkg.packageName);
7107                     final GrantedPermissions origGp = sysPs.sharedUser != null
7108                             ? sysPs.sharedUser : sysPs;
7109
7110                     if (origGp.grantedPermissions.contains(perm)) {
7111                         // If the original was granted this permission, we take
7112                         // that grant decision as read and propagate it to the
7113                         // update.
7114                         allowed = true;
7115                     } else {
7116                         // The system apk may have been updated with an older
7117                         // version of the one on the data partition, but which
7118                         // granted a new system permission that it didn't have
7119                         // before.  In this case we do want to allow the app to
7120                         // now get the new permission if the ancestral apk is
7121                         // privileged to get it.
7122                         if (sysPs.pkg != null && sysPs.isPrivileged()) {
7123                             for (int j=0;
7124                                     j<sysPs.pkg.requestedPermissions.size(); j++) {
7125                                 if (perm.equals(
7126                                         sysPs.pkg.requestedPermissions.get(j))) {
7127                                     allowed = true;
7128                                     break;
7129                                 }
7130                             }
7131                         }
7132                     }
7133                 } else {
7134                     allowed = isPrivilegedApp(pkg);
7135                 }
7136             }
7137         }
7138         if (!allowed && (bp.protectionLevel
7139                 & PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0) {
7140             // For development permissions, a development permission
7141             // is granted only if it was already granted.
7142             allowed = origPermissions.contains(perm);
7143         }
7144         return allowed;
7145     }
7146
7147     final class ActivityIntentResolver
7148             extends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo> {
7149         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
7150                 boolean defaultOnly, int userId) {
7151             if (!sUserManager.exists(userId)) return null;
7152             mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
7153             return super.queryIntent(intent, resolvedType, defaultOnly, userId);
7154         }
7155
7156         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
7157                 int userId) {
7158             if (!sUserManager.exists(userId)) return null;
7159             mFlags = flags;
7160             return super.queryIntent(intent, resolvedType,
7161                     (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId);
7162         }
7163
7164         public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
7165                 int flags, ArrayList<PackageParser.Activity> packageActivities, int userId) {
7166             if (!sUserManager.exists(userId)) return null;
7167             if (packageActivities == null) {
7168                 return null;
7169             }
7170             mFlags = flags;
7171             final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0;
7172             final int N = packageActivities.size();
7173             ArrayList<PackageParser.ActivityIntentInfo[]> listCut =
7174                 new ArrayList<PackageParser.ActivityIntentInfo[]>(N);
7175
7176             ArrayList<PackageParser.ActivityIntentInfo> intentFilters;
7177             for (int i = 0; i < N; ++i) {
7178                 intentFilters = packageActivities.get(i).intents;
7179                 if (intentFilters != null && intentFilters.size() > 0) {
7180                     PackageParser.ActivityIntentInfo[] array =
7181                             new PackageParser.ActivityIntentInfo[intentFilters.size()];
7182                     intentFilters.toArray(array);
7183                     listCut.add(array);
7184                 }
7185             }
7186             return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
7187         }
7188
7189         public final void addActivity(PackageParser.Activity a, String type) {
7190             final boolean systemApp = isSystemApp(a.info.applicationInfo);
7191             mActivities.put(a.getComponentName(), a);
7192             if (DEBUG_SHOW_INFO)
7193                 Log.v(
7194                 TAG, "  " + type + " " +
7195                 (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel : a.info.name) + ":");
7196             if (DEBUG_SHOW_INFO)
7197                 Log.v(TAG, "    Class=" + a.info.name);
7198             final int NI = a.intents.size();
7199             for (int j=0; j<NI; j++) {
7200                 PackageParser.ActivityIntentInfo intent = a.intents.get(j);
7201                 if (!systemApp && intent.getPriority() > 0 && "activity".equals(type)) {
7202                     intent.setPriority(0);
7203                     Log.w(TAG, "Package " + a.info.applicationInfo.packageName + " has activity "
7204                             + a.className + " with priority > 0, forcing to 0");
7205                 }
7206                 if (DEBUG_SHOW_INFO) {
7207                     Log.v(TAG, "    IntentFilter:");
7208                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
7209                 }
7210                 if (!intent.debugCheck()) {
7211                     Log.w(TAG, "==> For Activity " + a.info.name);
7212                 }
7213                 addFilter(intent);
7214             }
7215         }
7216
7217         public final void removeActivity(PackageParser.Activity a, String type) {
7218             mActivities.remove(a.getComponentName());
7219             if (DEBUG_SHOW_INFO) {
7220                 Log.v(TAG, "  " + type + " "
7221                         + (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel
7222                                 : a.info.name) + ":");
7223                 Log.v(TAG, "    Class=" + a.info.name);
7224             }
7225             final int NI = a.intents.size();
7226             for (int j=0; j<NI; j++) {
7227                 PackageParser.ActivityIntentInfo intent = a.intents.get(j);
7228                 if (DEBUG_SHOW_INFO) {
7229                     Log.v(TAG, "    IntentFilter:");
7230                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
7231                 }
7232                 removeFilter(intent);
7233             }
7234         }
7235
7236         @Override
7237         protected boolean allowFilterResult(
7238                 PackageParser.ActivityIntentInfo filter, List<ResolveInfo> dest) {
7239             ActivityInfo filterAi = filter.activity.info;
7240             for (int i=dest.size()-1; i>=0; i--) {
7241                 ActivityInfo destAi = dest.get(i).activityInfo;
7242                 if (destAi.name == filterAi.name
7243                         && destAi.packageName == filterAi.packageName) {
7244                     return false;
7245                 }
7246             }
7247             return true;
7248         }
7249
7250         @Override
7251         protected ActivityIntentInfo[] newArray(int size) {
7252             return new ActivityIntentInfo[size];
7253         }
7254
7255         @Override
7256         protected boolean isFilterStopped(PackageParser.ActivityIntentInfo filter, int userId) {
7257             if (!sUserManager.exists(userId)) return true;
7258             PackageParser.Package p = filter.activity.owner;
7259             if (p != null) {
7260                 PackageSetting ps = (PackageSetting)p.mExtras;
7261                 if (ps != null) {
7262                     // System apps are never considered stopped for purposes of
7263                     // filtering, because there may be no way for the user to
7264                     // actually re-launch them.
7265                     return (ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0
7266                             && ps.getStopped(userId);
7267                 }
7268             }
7269             return false;
7270         }
7271
7272         @Override
7273         protected boolean isPackageForFilter(String packageName,
7274                 PackageParser.ActivityIntentInfo info) {
7275             return packageName.equals(info.activity.owner.packageName);
7276         }
7277         
7278         @Override
7279         protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info,
7280                 int match, int userId) {
7281             if (!sUserManager.exists(userId)) return null;
7282             if (!mSettings.isEnabledLPr(info.activity.info, mFlags, userId)) {
7283                 return null;
7284             }
7285             final PackageParser.Activity activity = info.activity;
7286             if (mSafeMode && (activity.info.applicationInfo.flags
7287                     &ApplicationInfo.FLAG_SYSTEM) == 0) {
7288                 return null;
7289             }
7290             PackageSetting ps = (PackageSetting) activity.owner.mExtras;
7291             if (ps == null) {
7292                 return null;
7293             }
7294             ActivityInfo ai = PackageParser.generateActivityInfo(activity, mFlags,
7295                     ps.readUserState(userId), userId);
7296             if (ai == null) {
7297                 return null;
7298             }
7299             final ResolveInfo res = new ResolveInfo();
7300             res.activityInfo = ai;
7301             if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
7302                 res.filter = info;
7303             }
7304             res.priority = info.getPriority();
7305             res.preferredOrder = activity.owner.mPreferredOrder;
7306             //System.out.println("Result: " + res.activityInfo.className +
7307             //                   " = " + res.priority);
7308             res.match = match;
7309             res.isDefault = info.hasDefault;
7310             res.labelRes = info.labelRes;
7311             res.nonLocalizedLabel = info.nonLocalizedLabel;
7312             if (userNeedsBadging(userId)) {
7313                 res.noResourceId = true;
7314             } else {
7315                 res.icon = info.icon;
7316             }
7317             res.system = isSystemApp(res.activityInfo.applicationInfo);
7318             return res;
7319         }
7320
7321         @Override
7322         protected void sortResults(List<ResolveInfo> results) {
7323             Collections.sort(results, mResolvePrioritySorter);
7324         }
7325
7326         @Override
7327         protected void dumpFilter(PrintWriter out, String prefix,
7328                 PackageParser.ActivityIntentInfo filter) {
7329             out.print(prefix); out.print(
7330                     Integer.toHexString(System.identityHashCode(filter.activity)));
7331                     out.print(' ');
7332                     filter.activity.printComponentShortName(out);
7333                     out.print(" filter ");
7334                     out.println(Integer.toHexString(System.identityHashCode(filter)));
7335         }
7336
7337 //        List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) {
7338 //            final Iterator<ResolveInfo> i = resolveInfoList.iterator();
7339 //            final List<ResolveInfo> retList = Lists.newArrayList();
7340 //            while (i.hasNext()) {
7341 //                final ResolveInfo resolveInfo = i.next();
7342 //                if (isEnabledLP(resolveInfo.activityInfo)) {
7343 //                    retList.add(resolveInfo);
7344 //                }
7345 //            }
7346 //            return retList;
7347 //        }
7348
7349         // Keys are String (activity class name), values are Activity.
7350         private final ArrayMap<ComponentName, PackageParser.Activity> mActivities
7351                 = new ArrayMap<ComponentName, PackageParser.Activity>();
7352         private int mFlags;
7353     }
7354
7355     private final class ServiceIntentResolver
7356             extends IntentResolver<PackageParser.ServiceIntentInfo, ResolveInfo> {
7357         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
7358                 boolean defaultOnly, int userId) {
7359             mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
7360             return super.queryIntent(intent, resolvedType, defaultOnly, userId);
7361         }
7362
7363         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
7364                 int userId) {
7365             if (!sUserManager.exists(userId)) return null;
7366             mFlags = flags;
7367             return super.queryIntent(intent, resolvedType,
7368                     (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId);
7369         }
7370
7371         public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
7372                 int flags, ArrayList<PackageParser.Service> packageServices, int userId) {
7373             if (!sUserManager.exists(userId)) return null;
7374             if (packageServices == null) {
7375                 return null;
7376             }
7377             mFlags = flags;
7378             final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0;
7379             final int N = packageServices.size();
7380             ArrayList<PackageParser.ServiceIntentInfo[]> listCut =
7381                 new ArrayList<PackageParser.ServiceIntentInfo[]>(N);
7382
7383             ArrayList<PackageParser.ServiceIntentInfo> intentFilters;
7384             for (int i = 0; i < N; ++i) {
7385                 intentFilters = packageServices.get(i).intents;
7386                 if (intentFilters != null && intentFilters.size() > 0) {
7387                     PackageParser.ServiceIntentInfo[] array =
7388                             new PackageParser.ServiceIntentInfo[intentFilters.size()];
7389                     intentFilters.toArray(array);
7390                     listCut.add(array);
7391                 }
7392             }
7393             return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
7394         }
7395
7396         public final void addService(PackageParser.Service s) {
7397             mServices.put(s.getComponentName(), s);
7398             if (DEBUG_SHOW_INFO) {
7399                 Log.v(TAG, "  "
7400                         + (s.info.nonLocalizedLabel != null
7401                         ? s.info.nonLocalizedLabel : s.info.name) + ":");
7402                 Log.v(TAG, "    Class=" + s.info.name);
7403             }
7404             final int NI = s.intents.size();
7405             int j;
7406             for (j=0; j<NI; j++) {
7407                 PackageParser.ServiceIntentInfo intent = s.intents.get(j);
7408                 if (DEBUG_SHOW_INFO) {
7409                     Log.v(TAG, "    IntentFilter:");
7410                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
7411                 }
7412                 if (!intent.debugCheck()) {
7413                     Log.w(TAG, "==> For Service " + s.info.name);
7414                 }
7415                 addFilter(intent);
7416             }
7417         }
7418
7419         public final void removeService(PackageParser.Service s) {
7420             mServices.remove(s.getComponentName());
7421             if (DEBUG_SHOW_INFO) {
7422                 Log.v(TAG, "  " + (s.info.nonLocalizedLabel != null
7423                         ? s.info.nonLocalizedLabel : s.info.name) + ":");
7424                 Log.v(TAG, "    Class=" + s.info.name);
7425             }
7426             final int NI = s.intents.size();
7427             int j;
7428             for (j=0; j<NI; j++) {
7429                 PackageParser.ServiceIntentInfo intent = s.intents.get(j);
7430                 if (DEBUG_SHOW_INFO) {
7431                     Log.v(TAG, "    IntentFilter:");
7432                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
7433                 }
7434                 removeFilter(intent);
7435             }
7436         }
7437
7438         @Override
7439         protected boolean allowFilterResult(
7440                 PackageParser.ServiceIntentInfo filter, List<ResolveInfo> dest) {
7441             ServiceInfo filterSi = filter.service.info;
7442             for (int i=dest.size()-1; i>=0; i--) {
7443                 ServiceInfo destAi = dest.get(i).serviceInfo;
7444                 if (destAi.name == filterSi.name
7445                         && destAi.packageName == filterSi.packageName) {
7446                     return false;
7447                 }
7448             }
7449             return true;
7450         }
7451
7452         @Override
7453         protected PackageParser.ServiceIntentInfo[] newArray(int size) {
7454             return new PackageParser.ServiceIntentInfo[size];
7455         }
7456
7457         @Override
7458         protected boolean isFilterStopped(PackageParser.ServiceIntentInfo filter, int userId) {
7459             if (!sUserManager.exists(userId)) return true;
7460             PackageParser.Package p = filter.service.owner;
7461             if (p != null) {
7462                 PackageSetting ps = (PackageSetting)p.mExtras;
7463                 if (ps != null) {
7464                     // System apps are never considered stopped for purposes of
7465                     // filtering, because there may be no way for the user to
7466                     // actually re-launch them.
7467                     return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
7468                             && ps.getStopped(userId);
7469                 }
7470             }
7471             return false;
7472         }
7473
7474         @Override
7475         protected boolean isPackageForFilter(String packageName,
7476                 PackageParser.ServiceIntentInfo info) {
7477             return packageName.equals(info.service.owner.packageName);
7478         }
7479         
7480         @Override
7481         protected ResolveInfo newResult(PackageParser.ServiceIntentInfo filter,
7482                 int match, int userId) {
7483             if (!sUserManager.exists(userId)) return null;
7484             final PackageParser.ServiceIntentInfo info = (PackageParser.ServiceIntentInfo)filter;
7485             if (!mSettings.isEnabledLPr(info.service.info, mFlags, userId)) {
7486                 return null;
7487             }
7488             final PackageParser.Service service = info.service;
7489             if (mSafeMode && (service.info.applicationInfo.flags
7490                     &ApplicationInfo.FLAG_SYSTEM) == 0) {
7491                 return null;
7492             }
7493             PackageSetting ps = (PackageSetting) service.owner.mExtras;
7494             if (ps == null) {
7495                 return null;
7496             }
7497             ServiceInfo si = PackageParser.generateServiceInfo(service, mFlags,
7498                     ps.readUserState(userId), userId);
7499             if (si == null) {
7500                 return null;
7501             }
7502             final ResolveInfo res = new ResolveInfo();
7503             res.serviceInfo = si;
7504             if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
7505                 res.filter = filter;
7506             }
7507             res.priority = info.getPriority();
7508             res.preferredOrder = service.owner.mPreferredOrder;
7509             //System.out.println("Result: " + res.activityInfo.className +
7510             //                   " = " + res.priority);
7511             res.match = match;
7512             res.isDefault = info.hasDefault;
7513             res.labelRes = info.labelRes;
7514             res.nonLocalizedLabel = info.nonLocalizedLabel;
7515             res.icon = info.icon;
7516             res.system = isSystemApp(res.serviceInfo.applicationInfo);
7517             return res;
7518         }
7519
7520         @Override
7521         protected void sortResults(List<ResolveInfo> results) {
7522             Collections.sort(results, mResolvePrioritySorter);
7523         }
7524
7525         @Override
7526         protected void dumpFilter(PrintWriter out, String prefix,
7527                 PackageParser.ServiceIntentInfo filter) {
7528             out.print(prefix); out.print(
7529                     Integer.toHexString(System.identityHashCode(filter.service)));
7530                     out.print(' ');
7531                     filter.service.printComponentShortName(out);
7532                     out.print(" filter ");
7533                     out.println(Integer.toHexString(System.identityHashCode(filter)));
7534         }
7535
7536 //        List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) {
7537 //            final Iterator<ResolveInfo> i = resolveInfoList.iterator();
7538 //            final List<ResolveInfo> retList = Lists.newArrayList();
7539 //            while (i.hasNext()) {
7540 //                final ResolveInfo resolveInfo = (ResolveInfo) i;
7541 //                if (isEnabledLP(resolveInfo.serviceInfo)) {
7542 //                    retList.add(resolveInfo);
7543 //                }
7544 //            }
7545 //            return retList;
7546 //        }
7547
7548         // Keys are String (activity class name), values are Activity.
7549         private final ArrayMap<ComponentName, PackageParser.Service> mServices
7550                 = new ArrayMap<ComponentName, PackageParser.Service>();
7551         private int mFlags;
7552     };
7553
7554     private final class ProviderIntentResolver
7555             extends IntentResolver<PackageParser.ProviderIntentInfo, ResolveInfo> {
7556         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
7557                 boolean defaultOnly, int userId) {
7558             mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
7559             return super.queryIntent(intent, resolvedType, defaultOnly, userId);
7560         }
7561
7562         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
7563                 int userId) {
7564             if (!sUserManager.exists(userId))
7565                 return null;
7566             mFlags = flags;
7567             return super.queryIntent(intent, resolvedType,
7568                     (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId);
7569         }
7570
7571         public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
7572                 int flags, ArrayList<PackageParser.Provider> packageProviders, int userId) {
7573             if (!sUserManager.exists(userId))
7574                 return null;
7575             if (packageProviders == null) {
7576                 return null;
7577             }
7578             mFlags = flags;
7579             final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0;
7580             final int N = packageProviders.size();
7581             ArrayList<PackageParser.ProviderIntentInfo[]> listCut =
7582                     new ArrayList<PackageParser.ProviderIntentInfo[]>(N);
7583
7584             ArrayList<PackageParser.ProviderIntentInfo> intentFilters;
7585             for (int i = 0; i < N; ++i) {
7586                 intentFilters = packageProviders.get(i).intents;
7587                 if (intentFilters != null && intentFilters.size() > 0) {
7588                     PackageParser.ProviderIntentInfo[] array =
7589                             new PackageParser.ProviderIntentInfo[intentFilters.size()];
7590                     intentFilters.toArray(array);
7591                     listCut.add(array);
7592                 }
7593             }
7594             return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
7595         }
7596
7597         public final void addProvider(PackageParser.Provider p) {
7598             if (mProviders.containsKey(p.getComponentName())) {
7599                 Slog.w(TAG, "Provider " + p.getComponentName() + " already defined; ignoring");
7600                 return;
7601             }
7602
7603             mProviders.put(p.getComponentName(), p);
7604             if (DEBUG_SHOW_INFO) {
7605                 Log.v(TAG, "  "
7606                         + (p.info.nonLocalizedLabel != null
7607                                 ? p.info.nonLocalizedLabel : p.info.name) + ":");
7608                 Log.v(TAG, "    Class=" + p.info.name);
7609             }
7610             final int NI = p.intents.size();
7611             int j;
7612             for (j = 0; j < NI; j++) {
7613                 PackageParser.ProviderIntentInfo intent = p.intents.get(j);
7614                 if (DEBUG_SHOW_INFO) {
7615                     Log.v(TAG, "    IntentFilter:");
7616                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
7617                 }
7618                 if (!intent.debugCheck()) {
7619                     Log.w(TAG, "==> For Provider " + p.info.name);
7620                 }
7621                 addFilter(intent);
7622             }
7623         }
7624
7625         public final void removeProvider(PackageParser.Provider p) {
7626             mProviders.remove(p.getComponentName());
7627             if (DEBUG_SHOW_INFO) {
7628                 Log.v(TAG, "  " + (p.info.nonLocalizedLabel != null
7629                         ? p.info.nonLocalizedLabel : p.info.name) + ":");
7630                 Log.v(TAG, "    Class=" + p.info.name);
7631             }
7632             final int NI = p.intents.size();
7633             int j;
7634             for (j = 0; j < NI; j++) {
7635                 PackageParser.ProviderIntentInfo intent = p.intents.get(j);
7636                 if (DEBUG_SHOW_INFO) {
7637                     Log.v(TAG, "    IntentFilter:");
7638                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
7639                 }
7640                 removeFilter(intent);
7641             }
7642         }
7643
7644         @Override
7645         protected boolean allowFilterResult(
7646                 PackageParser.ProviderIntentInfo filter, List<ResolveInfo> dest) {
7647             ProviderInfo filterPi = filter.provider.info;
7648             for (int i = dest.size() - 1; i >= 0; i--) {
7649                 ProviderInfo destPi = dest.get(i).providerInfo;
7650                 if (destPi.name == filterPi.name
7651                         && destPi.packageName == filterPi.packageName) {
7652                     return false;
7653                 }
7654             }
7655             return true;
7656         }
7657
7658         @Override
7659         protected PackageParser.ProviderIntentInfo[] newArray(int size) {
7660             return new PackageParser.ProviderIntentInfo[size];
7661         }
7662
7663         @Override
7664         protected boolean isFilterStopped(PackageParser.ProviderIntentInfo filter, int userId) {
7665             if (!sUserManager.exists(userId))
7666                 return true;
7667             PackageParser.Package p = filter.provider.owner;
7668             if (p != null) {
7669                 PackageSetting ps = (PackageSetting) p.mExtras;
7670                 if (ps != null) {
7671                     // System apps are never considered stopped for purposes of
7672                     // filtering, because there may be no way for the user to
7673                     // actually re-launch them.
7674                     return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
7675                             && ps.getStopped(userId);
7676                 }
7677             }
7678             return false;
7679         }
7680
7681         @Override
7682         protected boolean isPackageForFilter(String packageName,
7683                 PackageParser.ProviderIntentInfo info) {
7684             return packageName.equals(info.provider.owner.packageName);
7685         }
7686
7687         @Override
7688         protected ResolveInfo newResult(PackageParser.ProviderIntentInfo filter,
7689                 int match, int userId) {
7690             if (!sUserManager.exists(userId))
7691                 return null;
7692             final PackageParser.ProviderIntentInfo info = filter;
7693             if (!mSettings.isEnabledLPr(info.provider.info, mFlags, userId)) {
7694                 return null;
7695             }
7696             final PackageParser.Provider provider = info.provider;
7697             if (mSafeMode && (provider.info.applicationInfo.flags
7698                     & ApplicationInfo.FLAG_SYSTEM) == 0) {
7699                 return null;
7700             }
7701             PackageSetting ps = (PackageSetting) provider.owner.mExtras;
7702             if (ps == null) {
7703                 return null;
7704             }
7705             ProviderInfo pi = PackageParser.generateProviderInfo(provider, mFlags,
7706                     ps.readUserState(userId), userId);
7707             if (pi == null) {
7708                 return null;
7709             }
7710             final ResolveInfo res = new ResolveInfo();
7711             res.providerInfo = pi;
7712             if ((mFlags & PackageManager.GET_RESOLVED_FILTER) != 0) {
7713                 res.filter = filter;
7714             }
7715             res.priority = info.getPriority();
7716             res.preferredOrder = provider.owner.mPreferredOrder;
7717             res.match = match;
7718             res.isDefault = info.hasDefault;
7719             res.labelRes = info.labelRes;
7720             res.nonLocalizedLabel = info.nonLocalizedLabel;
7721             res.icon = info.icon;
7722             res.system = isSystemApp(res.providerInfo.applicationInfo);
7723             return res;
7724         }
7725
7726         @Override
7727         protected void sortResults(List<ResolveInfo> results) {
7728             Collections.sort(results, mResolvePrioritySorter);
7729         }
7730
7731         @Override
7732         protected void dumpFilter(PrintWriter out, String prefix,
7733                 PackageParser.ProviderIntentInfo filter) {
7734             out.print(prefix);
7735             out.print(
7736                     Integer.toHexString(System.identityHashCode(filter.provider)));
7737             out.print(' ');
7738             filter.provider.printComponentShortName(out);
7739             out.print(" filter ");
7740             out.println(Integer.toHexString(System.identityHashCode(filter)));
7741         }
7742
7743         private final ArrayMap<ComponentName, PackageParser.Provider> mProviders
7744                 = new ArrayMap<ComponentName, PackageParser.Provider>();
7745         private int mFlags;
7746     };
7747
7748     private static final Comparator<ResolveInfo> mResolvePrioritySorter =
7749             new Comparator<ResolveInfo>() {
7750         public int compare(ResolveInfo r1, ResolveInfo r2) {
7751             int v1 = r1.priority;
7752             int v2 = r2.priority;
7753             //System.out.println("Comparing: q1=" + q1 + " q2=" + q2);
7754             if (v1 != v2) {
7755                 return (v1 > v2) ? -1 : 1;
7756             }
7757             v1 = r1.preferredOrder;
7758             v2 = r2.preferredOrder;
7759             if (v1 != v2) {
7760                 return (v1 > v2) ? -1 : 1;
7761             }
7762             if (r1.isDefault != r2.isDefault) {
7763                 return r1.isDefault ? -1 : 1;
7764             }
7765             v1 = r1.match;
7766             v2 = r2.match;
7767             //System.out.println("Comparing: m1=" + m1 + " m2=" + m2);
7768             if (v1 != v2) {
7769                 return (v1 > v2) ? -1 : 1;
7770             }
7771             if (r1.system != r2.system) {
7772                 return r1.system ? -1 : 1;
7773             }
7774             return 0;
7775         }
7776     };
7777
7778     private static final Comparator<ProviderInfo> mProviderInitOrderSorter =
7779             new Comparator<ProviderInfo>() {
7780         public int compare(ProviderInfo p1, ProviderInfo p2) {
7781             final int v1 = p1.initOrder;
7782             final int v2 = p2.initOrder;
7783             return (v1 > v2) ? -1 : ((v1 < v2) ? 1 : 0);
7784         }
7785     };
7786
7787     static final void sendPackageBroadcast(String action, String pkg,
7788             Bundle extras, String targetPkg, IIntentReceiver finishedReceiver,
7789             int[] userIds) {
7790         IActivityManager am = ActivityManagerNative.getDefault();
7791         if (am != null) {
7792             try {
7793                 if (userIds == null) {
7794                     userIds = am.getRunningUserIds();
7795                 }
7796                 for (int id : userIds) {
7797                     final Intent intent = new Intent(action,
7798                             pkg != null ? Uri.fromParts("package", pkg, null) : null);
7799                     if (extras != null) {
7800                         intent.putExtras(extras);
7801                     }
7802                     if (targetPkg != null) {
7803                         intent.setPackage(targetPkg);
7804                     }
7805                     // Modify the UID when posting to other users
7806                     int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
7807                     if (uid > 0 && UserHandle.getUserId(uid) != id) {
7808                         uid = UserHandle.getUid(id, UserHandle.getAppId(uid));
7809                         intent.putExtra(Intent.EXTRA_UID, uid);
7810                     }
7811                     intent.putExtra(Intent.EXTRA_USER_HANDLE, id);
7812                     intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
7813                     if (DEBUG_BROADCASTS) {
7814                         RuntimeException here = new RuntimeException("here");
7815                         here.fillInStackTrace();
7816                         Slog.d(TAG, "Sending to user " + id + ": "
7817                                 + intent.toShortString(false, true, false, false)
7818                                 + " " + intent.getExtras(), here);
7819                     }
7820                     am.broadcastIntent(null, intent, null, finishedReceiver,
7821                             0, null, null, null, android.app.AppOpsManager.OP_NONE,
7822                             finishedReceiver != null, false, id);
7823                 }
7824             } catch (RemoteException ex) {
7825             }
7826         }
7827     }
7828
7829     /**
7830      * Check if the external storage media is available. This is true if there
7831      * is a mounted external storage medium or if the external storage is
7832      * emulated.
7833      */
7834     private boolean isExternalMediaAvailable() {
7835         return mMediaMounted || Environment.isExternalStorageEmulated();
7836     }
7837
7838     @Override
7839     public PackageCleanItem nextPackageToClean(PackageCleanItem lastPackage) {
7840         // writer
7841         synchronized (mPackages) {
7842             if (!isExternalMediaAvailable()) {
7843                 // If the external storage is no longer mounted at this point,
7844                 // the caller may not have been able to delete all of this
7845                 // packages files and can not delete any more.  Bail.
7846                 return null;
7847             }
7848             final ArrayList<PackageCleanItem> pkgs = mSettings.mPackagesToBeCleaned;
7849             if (lastPackage != null) {
7850                 pkgs.remove(lastPackage);
7851             }
7852             if (pkgs.size() > 0) {
7853                 return pkgs.get(0);
7854             }
7855         }
7856         return null;
7857     }
7858
7859     void schedulePackageCleaning(String packageName, int userId, boolean andCode) {
7860         final Message msg = mHandler.obtainMessage(START_CLEANING_PACKAGE,
7861                 userId, andCode ? 1 : 0, packageName);
7862         if (mSystemReady) {
7863             msg.sendToTarget();
7864         } else {
7865             if (mPostSystemReadyMessages == null) {
7866                 mPostSystemReadyMessages = new ArrayList<>();
7867             }
7868             mPostSystemReadyMessages.add(msg);
7869         }
7870     }
7871
7872     void startCleaningPackages() {
7873         // reader
7874         synchronized (mPackages) {
7875             if (!isExternalMediaAvailable()) {
7876                 return;
7877             }
7878             if (mSettings.mPackagesToBeCleaned.isEmpty()) {
7879                 return;
7880             }
7881         }
7882         Intent intent = new Intent(PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE);
7883         intent.setComponent(DEFAULT_CONTAINER_COMPONENT);
7884         IActivityManager am = ActivityManagerNative.getDefault();
7885         if (am != null) {
7886             try {
7887                 am.startService(null, intent, null, UserHandle.USER_OWNER);
7888             } catch (RemoteException e) {
7889             }
7890         }
7891     }
7892
7893     @Override
7894     public void installPackage(String originPath, IPackageInstallObserver2 observer,
7895             int installFlags, String installerPackageName, VerificationParams verificationParams,
7896             String packageAbiOverride) {
7897         installPackageAsUser(originPath, observer, installFlags, installerPackageName, verificationParams,
7898                 packageAbiOverride, UserHandle.getCallingUserId());
7899     }
7900
7901     @Override
7902     public void installPackageAsUser(String originPath, IPackageInstallObserver2 observer,
7903             int installFlags, String installerPackageName, VerificationParams verificationParams,
7904             String packageAbiOverride, int userId) {
7905         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null);
7906
7907         final int callingUid = Binder.getCallingUid();
7908         enforceCrossUserPermission(callingUid, userId, true, true, "installPackageAsUser");
7909
7910         if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
7911             try {
7912                 if (observer != null) {
7913                     observer.onPackageInstalled("", INSTALL_FAILED_USER_RESTRICTED, null, null);
7914                 }
7915             } catch (RemoteException re) {
7916             }
7917             return;
7918         }
7919
7920         if ((callingUid == Process.SHELL_UID) || (callingUid == Process.ROOT_UID)) {
7921             installFlags |= PackageManager.INSTALL_FROM_ADB;
7922
7923         } else {
7924             // Caller holds INSTALL_PACKAGES permission, so we're less strict
7925             // about installerPackageName.
7926
7927             installFlags &= ~PackageManager.INSTALL_FROM_ADB;
7928             installFlags &= ~PackageManager.INSTALL_ALL_USERS;
7929         }
7930
7931         UserHandle user;
7932         if ((installFlags & PackageManager.INSTALL_ALL_USERS) != 0) {
7933             user = UserHandle.ALL;
7934         } else {
7935             user = new UserHandle(userId);
7936         }
7937
7938         verificationParams.setInstallerUid(callingUid);
7939
7940         final File originFile = new File(originPath);
7941         final OriginInfo origin = OriginInfo.fromUntrustedFile(originFile);
7942
7943         final Message msg = mHandler.obtainMessage(INIT_COPY);
7944         msg.obj = new InstallParams(origin, observer, installFlags,
7945                 installerPackageName, verificationParams, user, packageAbiOverride);
7946         mHandler.sendMessage(msg);
7947     }
7948
7949     void installStage(String packageName, File stagedDir, String stagedCid,
7950             IPackageInstallObserver2 observer, PackageInstaller.SessionParams params,
7951             String installerPackageName, int installerUid, UserHandle user) {
7952         final VerificationParams verifParams = new VerificationParams(null, params.originatingUri,
7953                 params.referrerUri, installerUid, null);
7954
7955         final OriginInfo origin;
7956         if (stagedDir != null) {
7957             origin = OriginInfo.fromStagedFile(stagedDir);
7958         } else {
7959             origin = OriginInfo.fromStagedContainer(stagedCid);
7960         }
7961
7962         final Message msg = mHandler.obtainMessage(INIT_COPY);
7963         msg.obj = new InstallParams(origin, observer, params.installFlags,
7964                 installerPackageName, verifParams, user, params.abiOverride);
7965         mHandler.sendMessage(msg);
7966     }
7967
7968     private void sendPackageAddedForUser(String packageName, PackageSetting pkgSetting, int userId) {
7969         Bundle extras = new Bundle(1);
7970         extras.putInt(Intent.EXTRA_UID, UserHandle.getUid(userId, pkgSetting.appId));
7971
7972         sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
7973                 packageName, extras, null, null, new int[] {userId});
7974         try {
7975             IActivityManager am = ActivityManagerNative.getDefault();
7976             final boolean isSystem =
7977                     isSystemApp(pkgSetting) || isUpdatedSystemApp(pkgSetting);
7978             if (isSystem && am.isUserRunning(userId, false)) {
7979                 // The just-installed/enabled app is bundled on the system, so presumed
7980                 // to be able to run automatically without needing an explicit launch.
7981                 // Send it a BOOT_COMPLETED if it would ordinarily have gotten one.
7982                 Intent bcIntent = new Intent(Intent.ACTION_BOOT_COMPLETED)
7983                         .addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES)
7984                         .setPackage(packageName);
7985                 am.broadcastIntent(null, bcIntent, null, null, 0, null, null, null,
7986                         android.app.AppOpsManager.OP_NONE, false, false, userId);
7987             }
7988         } catch (RemoteException e) {
7989             // shouldn't happen
7990             Slog.w(TAG, "Unable to bootstrap installed package", e);
7991         }
7992     }
7993
7994     @Override
7995     public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden,
7996             int userId) {
7997         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
7998         PackageSetting pkgSetting;
7999         final int uid = Binder.getCallingUid();
8000         enforceCrossUserPermission(uid, userId, true, true,
8001                 "setApplicationHiddenSetting for user " + userId);
8002
8003         if (hidden && isPackageDeviceAdmin(packageName, userId)) {
8004             Slog.w(TAG, "Not hiding package " + packageName + ": has active device admin");
8005             return false;
8006         }
8007
8008         long callingId = Binder.clearCallingIdentity();
8009         try {
8010             boolean sendAdded = false;
8011             boolean sendRemoved = false;
8012             // writer
8013             synchronized (mPackages) {
8014                 pkgSetting = mSettings.mPackages.get(packageName);
8015                 if (pkgSetting == null) {
8016                     return false;
8017                 }
8018                 if (pkgSetting.getHidden(userId) != hidden) {
8019                     pkgSetting.setHidden(hidden, userId);
8020                     mSettings.writePackageRestrictionsLPr(userId);
8021                     if (hidden) {
8022                         sendRemoved = true;
8023                     } else {
8024                         sendAdded = true;
8025                     }
8026                 }
8027             }
8028             if (sendAdded) {
8029                 sendPackageAddedForUser(packageName, pkgSetting, userId);
8030                 return true;
8031             }
8032             if (sendRemoved) {
8033                 killApplication(packageName, UserHandle.getUid(userId, pkgSetting.appId),
8034                         "hiding pkg");
8035                 sendApplicationHiddenForUser(packageName, pkgSetting, userId);
8036             }
8037         } finally {
8038             Binder.restoreCallingIdentity(callingId);
8039         }
8040         return false;
8041     }
8042
8043     private void sendApplicationHiddenForUser(String packageName, PackageSetting pkgSetting,
8044             int userId) {
8045         final PackageRemovedInfo info = new PackageRemovedInfo();
8046         info.removedPackage = packageName;
8047         info.removedUsers = new int[] {userId};
8048         info.uid = UserHandle.getUid(userId, pkgSetting.appId);
8049         info.sendBroadcast(false, false, false);
8050     }
8051
8052     /**
8053      * Returns true if application is not found or there was an error. Otherwise it returns
8054      * the hidden state of the package for the given user.
8055      */
8056     @Override
8057     public boolean getApplicationHiddenSettingAsUser(String packageName, int userId) {
8058         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
8059         enforceCrossUserPermission(Binder.getCallingUid(), userId, true,
8060                 false, "getApplicationHidden for user " + userId);
8061         PackageSetting pkgSetting;
8062         long callingId = Binder.clearCallingIdentity();
8063         try {
8064             // writer
8065             synchronized (mPackages) {
8066                 pkgSetting = mSettings.mPackages.get(packageName);
8067                 if (pkgSetting == null) {
8068                     return true;
8069                 }
8070                 return pkgSetting.getHidden(userId);
8071             }
8072         } finally {
8073             Binder.restoreCallingIdentity(callingId);
8074         }
8075     }
8076
8077     /**
8078      * @hide
8079      */
8080     @Override
8081     public int installExistingPackageAsUser(String packageName, int userId) {
8082         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES,
8083                 null);
8084         PackageSetting pkgSetting;
8085         final int uid = Binder.getCallingUid();
8086         enforceCrossUserPermission(uid, userId, true, true, "installExistingPackage for user "
8087                 + userId);
8088         if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
8089             return PackageManager.INSTALL_FAILED_USER_RESTRICTED;
8090         }
8091
8092         long callingId = Binder.clearCallingIdentity();
8093         try {
8094             boolean sendAdded = false;
8095             Bundle extras = new Bundle(1);
8096
8097             // writer
8098             synchronized (mPackages) {
8099                 pkgSetting = mSettings.mPackages.get(packageName);
8100                 if (pkgSetting == null) {
8101                     return PackageManager.INSTALL_FAILED_INVALID_URI;
8102                 }
8103                 if (!pkgSetting.getInstalled(userId)) {
8104                     pkgSetting.setInstalled(true, userId);
8105                     pkgSetting.setHidden(false, userId);
8106                     mSettings.writePackageRestrictionsLPr(userId);
8107                     sendAdded = true;
8108                 }
8109             }
8110
8111             if (sendAdded) {
8112                 sendPackageAddedForUser(packageName, pkgSetting, userId);
8113             }
8114         } finally {
8115             Binder.restoreCallingIdentity(callingId);
8116         }
8117
8118         return PackageManager.INSTALL_SUCCEEDED;
8119     }
8120
8121     boolean isUserRestricted(int userId, String restrictionKey) {
8122         Bundle restrictions = sUserManager.getUserRestrictions(userId);
8123         if (restrictions.getBoolean(restrictionKey, false)) {
8124             Log.w(TAG, "User is restricted: " + restrictionKey);
8125             return true;
8126         }
8127         return false;
8128     }
8129
8130     @Override
8131     public void verifyPendingInstall(int id, int verificationCode) throws RemoteException {
8132         mContext.enforceCallingOrSelfPermission(
8133                 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
8134                 "Only package verification agents can verify applications");
8135
8136         final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
8137         final PackageVerificationResponse response = new PackageVerificationResponse(
8138                 verificationCode, Binder.getCallingUid());
8139         msg.arg1 = id;
8140         msg.obj = response;
8141         mHandler.sendMessage(msg);
8142     }
8143
8144     @Override
8145     public void extendVerificationTimeout(int id, int verificationCodeAtTimeout,
8146             long millisecondsToDelay) {
8147         mContext.enforceCallingOrSelfPermission(
8148                 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
8149                 "Only package verification agents can extend verification timeouts");
8150
8151         final PackageVerificationState state = mPendingVerification.get(id);
8152         final PackageVerificationResponse response = new PackageVerificationResponse(
8153                 verificationCodeAtTimeout, Binder.getCallingUid());
8154
8155         if (millisecondsToDelay > PackageManager.MAXIMUM_VERIFICATION_TIMEOUT) {
8156             millisecondsToDelay = PackageManager.MAXIMUM_VERIFICATION_TIMEOUT;
8157         }
8158         if (millisecondsToDelay < 0) {
8159             millisecondsToDelay = 0;
8160         }
8161         if ((verificationCodeAtTimeout != PackageManager.VERIFICATION_ALLOW)
8162                 && (verificationCodeAtTimeout != PackageManager.VERIFICATION_REJECT)) {
8163             verificationCodeAtTimeout = PackageManager.VERIFICATION_REJECT;
8164         }
8165
8166         if ((state != null) && !state.timeoutExtended()) {
8167             state.extendTimeout();
8168
8169             final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
8170             msg.arg1 = id;
8171             msg.obj = response;
8172             mHandler.sendMessageDelayed(msg, millisecondsToDelay);
8173         }
8174     }
8175
8176     private void broadcastPackageVerified(int verificationId, Uri packageUri,
8177             int verificationCode, UserHandle user) {
8178         final Intent intent = new Intent(Intent.ACTION_PACKAGE_VERIFIED);
8179         intent.setDataAndType(packageUri, PACKAGE_MIME_TYPE);
8180         intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
8181         intent.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
8182         intent.putExtra(PackageManager.EXTRA_VERIFICATION_RESULT, verificationCode);
8183
8184         mContext.sendBroadcastAsUser(intent, user,
8185                 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT);
8186     }
8187
8188     private ComponentName matchComponentForVerifier(String packageName,
8189             List<ResolveInfo> receivers) {
8190         ActivityInfo targetReceiver = null;
8191
8192         final int NR = receivers.size();
8193         for (int i = 0; i < NR; i++) {
8194             final ResolveInfo info = receivers.get(i);
8195             if (info.activityInfo == null) {
8196                 continue;
8197             }
8198
8199             if (packageName.equals(info.activityInfo.packageName)) {
8200                 targetReceiver = info.activityInfo;
8201                 break;
8202             }
8203         }
8204
8205         if (targetReceiver == null) {
8206             return null;
8207         }
8208
8209         return new ComponentName(targetReceiver.packageName, targetReceiver.name);
8210     }
8211
8212     private List<ComponentName> matchVerifiers(PackageInfoLite pkgInfo,
8213             List<ResolveInfo> receivers, final PackageVerificationState verificationState) {
8214         if (pkgInfo.verifiers.length == 0) {
8215             return null;
8216         }
8217
8218         final int N = pkgInfo.verifiers.length;
8219         final List<ComponentName> sufficientVerifiers = new ArrayList<ComponentName>(N + 1);
8220         for (int i = 0; i < N; i++) {
8221             final VerifierInfo verifierInfo = pkgInfo.verifiers[i];
8222
8223             final ComponentName comp = matchComponentForVerifier(verifierInfo.packageName,
8224                     receivers);
8225             if (comp == null) {
8226                 continue;
8227             }
8228
8229             final int verifierUid = getUidForVerifier(verifierInfo);
8230             if (verifierUid == -1) {
8231                 continue;
8232             }
8233
8234             if (DEBUG_VERIFY) {
8235                 Slog.d(TAG, "Added sufficient verifier " + verifierInfo.packageName
8236                         + " with the correct signature");
8237             }
8238             sufficientVerifiers.add(comp);
8239             verificationState.addSufficientVerifier(verifierUid);
8240         }
8241
8242         return sufficientVerifiers;
8243     }
8244
8245     private int getUidForVerifier(VerifierInfo verifierInfo) {
8246         synchronized (mPackages) {
8247             final PackageParser.Package pkg = mPackages.get(verifierInfo.packageName);
8248             if (pkg == null) {
8249                 return -1;
8250             } else if (pkg.mSignatures.length != 1) {
8251                 Slog.i(TAG, "Verifier package " + verifierInfo.packageName
8252                         + " has more than one signature; ignoring");
8253                 return -1;
8254             }
8255
8256             /*
8257              * If the public key of the package's signature does not match
8258              * our expected public key, then this is a different package and
8259              * we should skip.
8260              */
8261
8262             final byte[] expectedPublicKey;
8263             try {
8264                 final Signature verifierSig = pkg.mSignatures[0];
8265                 final PublicKey publicKey = verifierSig.getPublicKey();
8266                 expectedPublicKey = publicKey.getEncoded();
8267             } catch (CertificateException e) {
8268                 return -1;
8269             }
8270
8271             final byte[] actualPublicKey = verifierInfo.publicKey.getEncoded();
8272
8273             if (!Arrays.equals(actualPublicKey, expectedPublicKey)) {
8274                 Slog.i(TAG, "Verifier package " + verifierInfo.packageName
8275                         + " does not have the expected public key; ignoring");
8276                 return -1;
8277             }
8278
8279             return pkg.applicationInfo.uid;
8280         }
8281     }
8282
8283     @Override
8284     public void finishPackageInstall(int token) {
8285         enforceSystemOrRoot("Only the system is allowed to finish installs");
8286
8287         if (DEBUG_INSTALL) {
8288             Slog.v(TAG, "BM finishing package install for " + token);
8289         }
8290
8291         final Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0);
8292         mHandler.sendMessage(msg);
8293     }
8294
8295     /**
8296      * Get the verification agent timeout.
8297      *
8298      * @return verification timeout in milliseconds
8299      */
8300     private long getVerificationTimeout() {
8301         return android.provider.Settings.Global.getLong(mContext.getContentResolver(),
8302                 android.provider.Settings.Global.PACKAGE_VERIFIER_TIMEOUT,
8303                 DEFAULT_VERIFICATION_TIMEOUT);
8304     }
8305
8306     /**
8307      * Get the default verification agent response code.
8308      *
8309      * @return default verification response code
8310      */
8311     private int getDefaultVerificationResponse() {
8312         return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
8313                 android.provider.Settings.Global.PACKAGE_VERIFIER_DEFAULT_RESPONSE,
8314                 DEFAULT_VERIFICATION_RESPONSE);
8315     }
8316
8317     /**
8318      * Check whether or not package verification has been enabled.
8319      *
8320      * @return true if verification should be performed
8321      */
8322     private boolean isVerificationEnabled(int userId, int installFlags) {
8323         if (!DEFAULT_VERIFY_ENABLE) {
8324             return false;
8325         }
8326
8327         boolean ensureVerifyAppsEnabled = isUserRestricted(userId, UserManager.ENSURE_VERIFY_APPS);
8328
8329         // Check if installing from ADB
8330         if ((installFlags & PackageManager.INSTALL_FROM_ADB) != 0) {
8331             // Do not run verification in a test harness environment
8332             if (ActivityManager.isRunningInTestHarness()) {
8333                 return false;
8334             }
8335             if (ensureVerifyAppsEnabled) {
8336                 return true;
8337             }
8338             // Check if the developer does not want package verification for ADB installs
8339             if (android.provider.Settings.Global.getInt(mContext.getContentResolver(),
8340                     android.provider.Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, 1) == 0) {
8341                 return false;
8342             }
8343         }
8344
8345         if (ensureVerifyAppsEnabled) {
8346             return true;
8347         }
8348
8349         return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
8350                 android.provider.Settings.Global.PACKAGE_VERIFIER_ENABLE, 1) == 1;
8351     }
8352
8353     /**
8354      * Get the "allow unknown sources" setting.
8355      *
8356      * @return the current "allow unknown sources" setting
8357      */
8358     private int getUnknownSourcesSettings() {
8359         return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
8360                 android.provider.Settings.Global.INSTALL_NON_MARKET_APPS,
8361                 -1);
8362     }
8363
8364     @Override
8365     public void setInstallerPackageName(String targetPackage, String installerPackageName) {
8366         final int uid = Binder.getCallingUid();
8367         // writer
8368         synchronized (mPackages) {
8369             PackageSetting targetPackageSetting = mSettings.mPackages.get(targetPackage);
8370             if (targetPackageSetting == null) {
8371                 throw new IllegalArgumentException("Unknown target package: " + targetPackage);
8372             }
8373
8374             PackageSetting installerPackageSetting;
8375             if (installerPackageName != null) {
8376                 installerPackageSetting = mSettings.mPackages.get(installerPackageName);
8377                 if (installerPackageSetting == null) {
8378                     throw new IllegalArgumentException("Unknown installer package: "
8379                             + installerPackageName);
8380                 }
8381             } else {
8382                 installerPackageSetting = null;
8383             }
8384
8385             Signature[] callerSignature;
8386             Object obj = mSettings.getUserIdLPr(uid);
8387             if (obj != null) {
8388                 if (obj instanceof SharedUserSetting) {
8389                     callerSignature = ((SharedUserSetting)obj).signatures.mSignatures;
8390                 } else if (obj instanceof PackageSetting) {
8391                     callerSignature = ((PackageSetting)obj).signatures.mSignatures;
8392                 } else {
8393                     throw new SecurityException("Bad object " + obj + " for uid " + uid);
8394                 }
8395             } else {
8396                 throw new SecurityException("Unknown calling uid " + uid);
8397             }
8398
8399             // Verify: can't set installerPackageName to a package that is
8400             // not signed with the same cert as the caller.
8401             if (installerPackageSetting != null) {
8402                 if (compareSignatures(callerSignature,
8403                         installerPackageSetting.signatures.mSignatures)
8404                         != PackageManager.SIGNATURE_MATCH) {
8405                     throw new SecurityException(
8406                             "Caller does not have same cert as new installer package "
8407                             + installerPackageName);
8408                 }
8409             }
8410
8411             // Verify: if target already has an installer package, it must
8412             // be signed with the same cert as the caller.
8413             if (targetPackageSetting.installerPackageName != null) {
8414                 PackageSetting setting = mSettings.mPackages.get(
8415                         targetPackageSetting.installerPackageName);
8416                 // If the currently set package isn't valid, then it's always
8417                 // okay to change it.
8418                 if (setting != null) {
8419                     if (compareSignatures(callerSignature,
8420                             setting.signatures.mSignatures)
8421                             != PackageManager.SIGNATURE_MATCH) {
8422                         throw new SecurityException(
8423                                 "Caller does not have same cert as old installer package "
8424                                 + targetPackageSetting.installerPackageName);
8425                     }
8426                 }
8427             }
8428
8429             // Okay!
8430             targetPackageSetting.installerPackageName = installerPackageName;
8431             scheduleWriteSettingsLocked();
8432         }
8433     }
8434
8435     private void processPendingInstall(final InstallArgs args, final int currentStatus) {
8436         // Queue up an async operation since the package installation may take a little while.
8437         mHandler.post(new Runnable() {
8438             public void run() {
8439                 mHandler.removeCallbacks(this);
8440                  // Result object to be returned
8441                 PackageInstalledInfo res = new PackageInstalledInfo();
8442                 res.returnCode = currentStatus;
8443                 res.uid = -1;
8444                 res.pkg = null;
8445                 res.removedInfo = new PackageRemovedInfo();
8446                 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
8447                     args.doPreInstall(res.returnCode);
8448                     synchronized (mInstallLock) {
8449                         installPackageLI(args, res);
8450                     }
8451                     args.doPostInstall(res.returnCode, res.uid);
8452                 }
8453
8454                 // A restore should be performed at this point if (a) the install
8455                 // succeeded, (b) the operation is not an update, and (c) the new
8456                 // package has not opted out of backup participation.
8457                 final boolean update = res.removedInfo.removedPackage != null;
8458                 final int flags = (res.pkg == null) ? 0 : res.pkg.applicationInfo.flags;
8459                 boolean doRestore = !update
8460                         && ((flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0);
8461
8462                 // Set up the post-install work request bookkeeping.  This will be used
8463                 // and cleaned up by the post-install event handling regardless of whether
8464                 // there's a restore pass performed.  Token values are >= 1.
8465                 int token;
8466                 if (mNextInstallToken < 0) mNextInstallToken = 1;
8467                 token = mNextInstallToken++;
8468
8469                 PostInstallData data = new PostInstallData(args, res);
8470                 mRunningInstalls.put(token, data);
8471                 if (DEBUG_INSTALL) Log.v(TAG, "+ starting restore round-trip " + token);
8472
8473                 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && doRestore) {
8474                     // Pass responsibility to the Backup Manager.  It will perform a
8475                     // restore if appropriate, then pass responsibility back to the
8476                     // Package Manager to run the post-install observer callbacks
8477                     // and broadcasts.
8478                     IBackupManager bm = IBackupManager.Stub.asInterface(
8479                             ServiceManager.getService(Context.BACKUP_SERVICE));
8480                     if (bm != null) {
8481                         if (DEBUG_INSTALL) Log.v(TAG, "token " + token
8482                                 + " to BM for possible restore");
8483                         try {
8484                             bm.restoreAtInstall(res.pkg.applicationInfo.packageName, token);
8485                         } catch (RemoteException e) {
8486                             // can't happen; the backup manager is local
8487                         } catch (Exception e) {
8488                             Slog.e(TAG, "Exception trying to enqueue restore", e);
8489                             doRestore = false;
8490                         }
8491                     } else {
8492                         Slog.e(TAG, "Backup Manager not found!");
8493                         doRestore = false;
8494                     }
8495                 }
8496
8497                 if (!doRestore) {
8498                     // No restore possible, or the Backup Manager was mysteriously not
8499                     // available -- just fire the post-install work request directly.
8500                     if (DEBUG_INSTALL) Log.v(TAG, "No restore - queue post-install for " + token);
8501                     Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0);
8502                     mHandler.sendMessage(msg);
8503                 }
8504             }
8505         });
8506     }
8507
8508     private abstract class HandlerParams {
8509         private static final int MAX_RETRIES = 4;
8510
8511         /**
8512          * Number of times startCopy() has been attempted and had a non-fatal
8513          * error.
8514          */
8515         private int mRetries = 0;
8516
8517         /** User handle for the user requesting the information or installation. */
8518         private final UserHandle mUser;
8519
8520         HandlerParams(UserHandle user) {
8521             mUser = user;
8522         }
8523
8524         UserHandle getUser() {
8525             return mUser;
8526         }
8527
8528         final boolean startCopy() {
8529             boolean res;
8530             try {
8531                 if (DEBUG_INSTALL) Slog.i(TAG, "startCopy " + mUser + ": " + this);
8532
8533                 if (++mRetries > MAX_RETRIES) {
8534                     Slog.w(TAG, "Failed to invoke remote methods on default container service. Giving up");
8535                     mHandler.sendEmptyMessage(MCS_GIVE_UP);
8536                     handleServiceError();
8537                     return false;
8538                 } else {
8539                     handleStartCopy();
8540                     res = true;
8541                 }
8542             } catch (RemoteException e) {
8543                 if (DEBUG_INSTALL) Slog.i(TAG, "Posting install MCS_RECONNECT");
8544                 mHandler.sendEmptyMessage(MCS_RECONNECT);
8545                 res = false;
8546             }
8547             handleReturnCode();
8548             return res;
8549         }
8550
8551         final void serviceError() {
8552             if (DEBUG_INSTALL) Slog.i(TAG, "serviceError");
8553             handleServiceError();
8554             handleReturnCode();
8555         }
8556
8557         abstract void handleStartCopy() throws RemoteException;
8558         abstract void handleServiceError();
8559         abstract void handleReturnCode();
8560     }
8561
8562     class MeasureParams extends HandlerParams {
8563         private final PackageStats mStats;
8564         private boolean mSuccess;
8565
8566         private final IPackageStatsObserver mObserver;
8567
8568         public MeasureParams(PackageStats stats, IPackageStatsObserver observer) {
8569             super(new UserHandle(stats.userHandle));
8570             mObserver = observer;
8571             mStats = stats;
8572         }
8573
8574         @Override
8575         public String toString() {
8576             return "MeasureParams{"
8577                 + Integer.toHexString(System.identityHashCode(this))
8578                 + " " + mStats.packageName + "}";
8579         }
8580
8581         @Override
8582         void handleStartCopy() throws RemoteException {
8583             synchronized (mInstallLock) {
8584                 mSuccess = getPackageSizeInfoLI(mStats.packageName, mStats.userHandle, mStats);
8585             }
8586
8587             if (mSuccess) {
8588                 final boolean mounted;
8589                 if (Environment.isExternalStorageEmulated()) {
8590                     mounted = true;
8591                 } else {
8592                     final String status = Environment.getExternalStorageState();
8593                     mounted = (Environment.MEDIA_MOUNTED.equals(status)
8594                             || Environment.MEDIA_MOUNTED_READ_ONLY.equals(status));
8595                 }
8596
8597                 if (mounted) {
8598                     final UserEnvironment userEnv = new UserEnvironment(mStats.userHandle);
8599
8600                     mStats.externalCacheSize = calculateDirectorySize(mContainerService,
8601                             userEnv.buildExternalStorageAppCacheDirs(mStats.packageName));
8602
8603                     mStats.externalDataSize = calculateDirectorySize(mContainerService,
8604                             userEnv.buildExternalStorageAppDataDirs(mStats.packageName));
8605
8606                     // Always subtract cache size, since it's a subdirectory
8607                     mStats.externalDataSize -= mStats.externalCacheSize;
8608
8609                     mStats.externalMediaSize = calculateDirectorySize(mContainerService,
8610                             userEnv.buildExternalStorageAppMediaDirs(mStats.packageName));
8611
8612                     mStats.externalObbSize = calculateDirectorySize(mContainerService,
8613                             userEnv.buildExternalStorageAppObbDirs(mStats.packageName));
8614                 }
8615             }
8616         }
8617
8618         @Override
8619         void handleReturnCode() {
8620             if (mObserver != null) {
8621                 try {
8622                     mObserver.onGetStatsCompleted(mStats, mSuccess);
8623                 } catch (RemoteException e) {
8624                     Slog.i(TAG, "Observer no longer exists.");
8625                 }
8626             }
8627         }
8628
8629         @Override
8630         void handleServiceError() {
8631             Slog.e(TAG, "Could not measure application " + mStats.packageName
8632                             + " external storage");
8633         }
8634     }
8635
8636     private static long calculateDirectorySize(IMediaContainerService mcs, File[] paths)
8637             throws RemoteException {
8638         long result = 0;
8639         for (File path : paths) {
8640             result += mcs.calculateDirectorySize(path.getAbsolutePath());
8641         }
8642         return result;
8643     }
8644
8645     private static void clearDirectory(IMediaContainerService mcs, File[] paths) {
8646         for (File path : paths) {
8647             try {
8648                 mcs.clearDirectory(path.getAbsolutePath());
8649             } catch (RemoteException e) {
8650             }
8651         }
8652     }
8653
8654     static class OriginInfo {
8655         /**
8656          * Location where install is coming from, before it has been
8657          * copied/renamed into place. This could be a single monolithic APK
8658          * file, or a cluster directory. This location may be untrusted.
8659          */
8660         final File file;
8661         final String cid;
8662
8663         /**
8664          * Flag indicating that {@link #file} or {@link #cid} has already been
8665          * staged, meaning downstream users don't need to defensively copy the
8666          * contents.
8667          */
8668         final boolean staged;
8669
8670         /**
8671          * Flag indicating that {@link #file} or {@link #cid} is an already
8672          * installed app that is being moved.
8673          */
8674         final boolean existing;
8675
8676         final String resolvedPath;
8677         final File resolvedFile;
8678
8679         static OriginInfo fromNothing() {
8680             return new OriginInfo(null, null, false, false);
8681         }
8682
8683         static OriginInfo fromUntrustedFile(File file) {
8684             return new OriginInfo(file, null, false, false);
8685         }
8686
8687         static OriginInfo fromExistingFile(File file) {
8688             return new OriginInfo(file, null, false, true);
8689         }
8690
8691         static OriginInfo fromStagedFile(File file) {
8692             return new OriginInfo(file, null, true, false);
8693         }
8694
8695         static OriginInfo fromStagedContainer(String cid) {
8696             return new OriginInfo(null, cid, true, false);
8697         }
8698
8699         private OriginInfo(File file, String cid, boolean staged, boolean existing) {
8700             this.file = file;
8701             this.cid = cid;
8702             this.staged = staged;
8703             this.existing = existing;
8704
8705             if (cid != null) {
8706                 resolvedPath = PackageHelper.getSdDir(cid);
8707                 resolvedFile = new File(resolvedPath);
8708             } else if (file != null) {
8709                 resolvedPath = file.getAbsolutePath();
8710                 resolvedFile = file;
8711             } else {
8712                 resolvedPath = null;
8713                 resolvedFile = null;
8714             }
8715         }
8716     }
8717
8718     class InstallParams extends HandlerParams {
8719         final OriginInfo origin;
8720         final IPackageInstallObserver2 observer;
8721         int installFlags;
8722         final String installerPackageName;
8723         final VerificationParams verificationParams;
8724         private InstallArgs mArgs;
8725         private int mRet;
8726         final String packageAbiOverride;
8727
8728         InstallParams(OriginInfo origin, IPackageInstallObserver2 observer, int installFlags,
8729                 String installerPackageName, VerificationParams verificationParams, UserHandle user,
8730                 String packageAbiOverride) {
8731             super(user);
8732             this.origin = origin;
8733             this.observer = observer;
8734             this.installFlags = installFlags;
8735             this.installerPackageName = installerPackageName;
8736             this.verificationParams = verificationParams;
8737             this.packageAbiOverride = packageAbiOverride;
8738         }
8739
8740         @Override
8741         public String toString() {
8742             return "InstallParams{" + Integer.toHexString(System.identityHashCode(this))
8743                     + " file=" + origin.file + " cid=" + origin.cid + "}";
8744         }
8745
8746         public ManifestDigest getManifestDigest() {
8747             if (verificationParams == null) {
8748                 return null;
8749             }
8750             return verificationParams.getManifestDigest();
8751         }
8752
8753         private int installLocationPolicy(PackageInfoLite pkgLite) {
8754             String packageName = pkgLite.packageName;
8755             int installLocation = pkgLite.installLocation;
8756             boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
8757             // reader
8758             synchronized (mPackages) {
8759                 PackageParser.Package pkg = mPackages.get(packageName);
8760                 if (pkg != null) {
8761                     if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
8762                         // Check for downgrading.
8763                         if ((installFlags & PackageManager.INSTALL_ALLOW_DOWNGRADE) == 0) {
8764                             if (pkgLite.versionCode < pkg.mVersionCode) {
8765                                 Slog.w(TAG, "Can't install update of " + packageName
8766                                         + " update version " + pkgLite.versionCode
8767                                         + " is older than installed version "
8768                                         + pkg.mVersionCode);
8769                                 return PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE;
8770                             }
8771                         }
8772                         // Check for updated system application.
8773                         if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
8774                             if (onSd) {
8775                                 Slog.w(TAG, "Cannot install update to system app on sdcard");
8776                                 return PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION;
8777                             }
8778                             return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
8779                         } else {
8780                             if (onSd) {
8781                                 // Install flag overrides everything.
8782                                 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
8783                             }
8784                             // If current upgrade specifies particular preference
8785                             if (installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) {
8786                                 // Application explicitly specified internal.
8787                                 return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
8788                             } else if (installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) {
8789                                 // App explictly prefers external. Let policy decide
8790                             } else {
8791                                 // Prefer previous location
8792                                 if (isExternal(pkg)) {
8793                                     return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
8794                                 }
8795                                 return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
8796                             }
8797                         }
8798                     } else {
8799                         // Invalid install. Return error code
8800                         return PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS;
8801                     }
8802                 }
8803             }
8804             // All the special cases have been taken care of.
8805             // Return result based on recommended install location.
8806             if (onSd) {
8807                 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
8808             }
8809             return pkgLite.recommendedInstallLocation;
8810         }
8811
8812         /*
8813          * Invoke remote method to get package information and install
8814          * location values. Override install location based on default
8815          * policy if needed and then create install arguments based
8816          * on the install location.
8817          */
8818         public void handleStartCopy() throws RemoteException {
8819             int ret = PackageManager.INSTALL_SUCCEEDED;
8820
8821             // If we're already staged, we've firmly committed to an install location
8822             if (origin.staged) {
8823                 if (origin.file != null) {
8824                     installFlags |= PackageManager.INSTALL_INTERNAL;
8825                     installFlags &= ~PackageManager.INSTALL_EXTERNAL;
8826                 } else if (origin.cid != null) {
8827                     installFlags |= PackageManager.INSTALL_EXTERNAL;
8828                     installFlags &= ~PackageManager.INSTALL_INTERNAL;
8829                 } else {
8830                     throw new IllegalStateException("Invalid stage location");
8831                 }
8832             }
8833
8834             final boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
8835             final boolean onInt = (installFlags & PackageManager.INSTALL_INTERNAL) != 0;
8836
8837             PackageInfoLite pkgLite = null;
8838
8839             if (onInt && onSd) {
8840                 // Check if both bits are set.
8841                 Slog.w(TAG, "Conflicting flags specified for installing on both internal and external");
8842                 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
8843             } else {
8844                 pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, installFlags,
8845                         packageAbiOverride);
8846
8847                 /*
8848                  * If we have too little free space, try to free cache
8849                  * before giving up.
8850                  */
8851                 if (!origin.staged && pkgLite.recommendedInstallLocation
8852                         == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
8853                     // TODO: focus freeing disk space on the target device
8854                     final StorageManager storage = StorageManager.from(mContext);
8855                     final long lowThreshold = storage.getStorageLowBytes(
8856                             Environment.getDataDirectory());
8857
8858                     final long sizeBytes = mContainerService.calculateInstalledSize(
8859                             origin.resolvedPath, isForwardLocked(), packageAbiOverride);
8860
8861                     if (mInstaller.freeCache(sizeBytes + lowThreshold) >= 0) {
8862                         pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath,
8863                                 installFlags, packageAbiOverride);
8864                     }
8865
8866                     /*
8867                      * The cache free must have deleted the file we
8868                      * downloaded to install.
8869                      *
8870                      * TODO: fix the "freeCache" call to not delete
8871                      *       the file we care about.
8872                      */
8873                     if (pkgLite.recommendedInstallLocation
8874                             == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
8875                         pkgLite.recommendedInstallLocation
8876                             = PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE;
8877                     }
8878                 }
8879             }
8880
8881             if (ret == PackageManager.INSTALL_SUCCEEDED) {
8882                 int loc = pkgLite.recommendedInstallLocation;
8883                 if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION) {
8884                     ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
8885                 } else if (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS) {
8886                     ret = PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
8887                 } else if (loc == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
8888                     ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
8889                 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_APK) {
8890                     ret = PackageManager.INSTALL_FAILED_INVALID_APK;
8891                 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
8892                     ret = PackageManager.INSTALL_FAILED_INVALID_URI;
8893                 } else if (loc == PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE) {
8894                     ret = PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE;
8895                 } else {
8896                     // Override with defaults if needed.
8897                     loc = installLocationPolicy(pkgLite);
8898                     if (loc == PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE) {
8899                         ret = PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
8900                     } else if (!onSd && !onInt) {
8901                         // Override install location with flags
8902                         if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) {
8903                             // Set the flag to install on external media.
8904                             installFlags |= PackageManager.INSTALL_EXTERNAL;
8905                             installFlags &= ~PackageManager.INSTALL_INTERNAL;
8906                         } else {
8907                             // Make sure the flag for installing on external
8908                             // media is unset
8909                             installFlags |= PackageManager.INSTALL_INTERNAL;
8910                             installFlags &= ~PackageManager.INSTALL_EXTERNAL;
8911                         }
8912                     }
8913                 }
8914             }
8915
8916             final InstallArgs args = createInstallArgs(this);
8917             mArgs = args;
8918
8919             if (ret == PackageManager.INSTALL_SUCCEEDED) {
8920                  /*
8921                  * ADB installs appear as UserHandle.USER_ALL, and can only be performed by
8922                  * UserHandle.USER_OWNER, so use the package verifier for UserHandle.USER_OWNER.
8923                  */
8924                 int userIdentifier = getUser().getIdentifier();
8925                 if (userIdentifier == UserHandle.USER_ALL
8926                         && ((installFlags & PackageManager.INSTALL_FROM_ADB) != 0)) {
8927                     userIdentifier = UserHandle.USER_OWNER;
8928                 }
8929
8930                 /*
8931                  * Determine if we have any installed package verifiers. If we
8932                  * do, then we'll defer to them to verify the packages.
8933                  */
8934                 final int requiredUid = mRequiredVerifierPackage == null ? -1
8935                         : getPackageUid(mRequiredVerifierPackage, userIdentifier);
8936                 if (!origin.existing && requiredUid != -1
8937                         && isVerificationEnabled(userIdentifier, installFlags)) {
8938                     final Intent verification = new Intent(
8939                             Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
8940                     verification.setDataAndType(Uri.fromFile(new File(origin.resolvedPath)),
8941                             PACKAGE_MIME_TYPE);
8942                     verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
8943
8944                     final List<ResolveInfo> receivers = queryIntentReceivers(verification,
8945                             PACKAGE_MIME_TYPE, PackageManager.GET_DISABLED_COMPONENTS,
8946                             0 /* TODO: Which userId? */);
8947
8948                     if (DEBUG_VERIFY) {
8949                         Slog.d(TAG, "Found " + receivers.size() + " verifiers for intent "
8950                                 + verification.toString() + " with " + pkgLite.verifiers.length
8951                                 + " optional verifiers");
8952                     }
8953
8954                     final int verificationId = mPendingVerificationToken++;
8955
8956                     verification.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
8957
8958                     verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_PACKAGE,
8959                             installerPackageName);
8960
8961                     verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALL_FLAGS,
8962                             installFlags);
8963
8964                     verification.putExtra(PackageManager.EXTRA_VERIFICATION_PACKAGE_NAME,
8965                             pkgLite.packageName);
8966
8967                     verification.putExtra(PackageManager.EXTRA_VERIFICATION_VERSION_CODE,
8968                             pkgLite.versionCode);
8969
8970                     if (verificationParams != null) {
8971                         if (verificationParams.getVerificationURI() != null) {
8972                            verification.putExtra(PackageManager.EXTRA_VERIFICATION_URI,
8973                                  verificationParams.getVerificationURI());
8974                         }
8975                         if (verificationParams.getOriginatingURI() != null) {
8976                             verification.putExtra(Intent.EXTRA_ORIGINATING_URI,
8977                                   verificationParams.getOriginatingURI());
8978                         }
8979                         if (verificationParams.getReferrer() != null) {
8980                             verification.putExtra(Intent.EXTRA_REFERRER,
8981                                   verificationParams.getReferrer());
8982                         }
8983                         if (verificationParams.getOriginatingUid() >= 0) {
8984                             verification.putExtra(Intent.EXTRA_ORIGINATING_UID,
8985                                   verificationParams.getOriginatingUid());
8986                         }
8987                         if (verificationParams.getInstallerUid() >= 0) {
8988                             verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_UID,
8989                                   verificationParams.getInstallerUid());
8990                         }
8991                     }
8992
8993                     final PackageVerificationState verificationState = new PackageVerificationState(
8994                             requiredUid, args);
8995
8996                     mPendingVerification.append(verificationId, verificationState);
8997
8998                     final List<ComponentName> sufficientVerifiers = matchVerifiers(pkgLite,
8999                             receivers, verificationState);
9000
9001                     /*
9002                      * If any sufficient verifiers were listed in the package
9003                      * manifest, attempt to ask them.
9004                      */
9005                     if (sufficientVerifiers != null) {
9006                         final int N = sufficientVerifiers.size();
9007                         if (N == 0) {
9008                             Slog.i(TAG, "Additional verifiers required, but none installed.");
9009                             ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
9010                         } else {
9011                             for (int i = 0; i < N; i++) {
9012                                 final ComponentName verifierComponent = sufficientVerifiers.get(i);
9013
9014                                 final Intent sufficientIntent = new Intent(verification);
9015                                 sufficientIntent.setComponent(verifierComponent);
9016
9017                                 mContext.sendBroadcastAsUser(sufficientIntent, getUser());
9018                             }
9019                         }
9020                     }
9021
9022                     final ComponentName requiredVerifierComponent = matchComponentForVerifier(
9023                             mRequiredVerifierPackage, receivers);
9024                     if (ret == PackageManager.INSTALL_SUCCEEDED
9025                             && mRequiredVerifierPackage != null) {
9026                         /*
9027                          * Send the intent to the required verification agent,
9028                          * but only start the verification timeout after the
9029                          * target BroadcastReceivers have run.
9030                          */
9031                         verification.setComponent(requiredVerifierComponent);
9032                         mContext.sendOrderedBroadcastAsUser(verification, getUser(),
9033                                 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
9034                                 new BroadcastReceiver() {
9035                                     @Override
9036                                     public void onReceive(Context context, Intent intent) {
9037                                         final Message msg = mHandler
9038                                                 .obtainMessage(CHECK_PENDING_VERIFICATION);
9039                                         msg.arg1 = verificationId;
9040                                         mHandler.sendMessageDelayed(msg, getVerificationTimeout());
9041                                     }
9042                                 }, null, 0, null, null);
9043
9044                         /*
9045                          * We don't want the copy to proceed until verification
9046                          * succeeds, so null out this field.
9047                          */
9048                         mArgs = null;
9049                     }
9050                 } else {
9051                     /*
9052                      * No package verification is enabled, so immediately start
9053                      * the remote call to initiate copy using temporary file.
9054                      */
9055                     ret = args.copyApk(mContainerService, true);
9056                 }
9057             }
9058
9059             mRet = ret;
9060         }
9061
9062         @Override
9063         void handleReturnCode() {
9064             // If mArgs is null, then MCS couldn't be reached. When it
9065             // reconnects, it will try again to install. At that point, this
9066             // will succeed.
9067             if (mArgs != null) {
9068                 processPendingInstall(mArgs, mRet);
9069             }
9070         }
9071
9072         @Override
9073         void handleServiceError() {
9074             mArgs = createInstallArgs(this);
9075             mRet = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
9076         }
9077
9078         public boolean isForwardLocked() {
9079             return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
9080         }
9081     }
9082
9083     /**
9084      * Used during creation of InstallArgs
9085      *
9086      * @param installFlags package installation flags
9087      * @return true if should be installed on external storage
9088      */
9089     private static boolean installOnSd(int installFlags) {
9090         if ((installFlags & PackageManager.INSTALL_INTERNAL) != 0) {
9091             return false;
9092         }
9093         if ((installFlags & PackageManager.INSTALL_EXTERNAL) != 0) {
9094             return true;
9095         }
9096         return false;
9097     }
9098
9099     /**
9100      * Used during creation of InstallArgs
9101      *
9102      * @param installFlags package installation flags
9103      * @return true if should be installed as forward locked
9104      */
9105     private static boolean installForwardLocked(int installFlags) {
9106         return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
9107     }
9108
9109     private InstallArgs createInstallArgs(InstallParams params) {
9110         if (installOnSd(params.installFlags) || params.isForwardLocked()) {
9111             return new AsecInstallArgs(params);
9112         } else {
9113             return new FileInstallArgs(params);
9114         }
9115     }
9116
9117     /**
9118      * Create args that describe an existing installed package. Typically used
9119      * when cleaning up old installs, or used as a move source.
9120      */
9121     private InstallArgs createInstallArgsForExisting(int installFlags, String codePath,
9122             String resourcePath, String nativeLibraryRoot, String[] instructionSets) {
9123         final boolean isInAsec;
9124         if (installOnSd(installFlags)) {
9125             /* Apps on SD card are always in ASEC containers. */
9126             isInAsec = true;
9127         } else if (installForwardLocked(installFlags)
9128                 && !codePath.startsWith(mDrmAppPrivateInstallDir.getAbsolutePath())) {
9129             /*
9130              * Forward-locked apps are only in ASEC containers if they're the
9131              * new style
9132              */
9133             isInAsec = true;
9134         } else {
9135             isInAsec = false;
9136         }
9137
9138         if (isInAsec) {
9139             return new AsecInstallArgs(codePath, instructionSets,
9140                     installOnSd(installFlags), installForwardLocked(installFlags));
9141         } else {
9142             return new FileInstallArgs(codePath, resourcePath, nativeLibraryRoot,
9143                     instructionSets);
9144         }
9145     }
9146
9147     static abstract class InstallArgs {
9148         /** @see InstallParams#origin */
9149         final OriginInfo origin;
9150
9151         final IPackageInstallObserver2 observer;
9152         // Always refers to PackageManager flags only
9153         final int installFlags;
9154         final String installerPackageName;
9155         final ManifestDigest manifestDigest;
9156         final UserHandle user;
9157         final String abiOverride;
9158
9159         // The list of instruction sets supported by this app. This is currently
9160         // only used during the rmdex() phase to clean up resources. We can get rid of this
9161         // if we move dex files under the common app path.
9162         /* nullable */ String[] instructionSets;
9163
9164         InstallArgs(OriginInfo origin, IPackageInstallObserver2 observer, int installFlags,
9165                 String installerPackageName, ManifestDigest manifestDigest, UserHandle user,
9166                 String[] instructionSets, String abiOverride) {
9167             this.origin = origin;
9168             this.installFlags = installFlags;
9169             this.observer = observer;
9170             this.installerPackageName = installerPackageName;
9171             this.manifestDigest = manifestDigest;
9172             this.user = user;
9173             this.instructionSets = instructionSets;
9174             this.abiOverride = abiOverride;
9175         }
9176
9177         abstract int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException;
9178         abstract int doPreInstall(int status);
9179
9180         /**
9181          * Rename package into final resting place. All paths on the given
9182          * scanned package should be updated to reflect the rename.
9183          */
9184         abstract boolean doRename(int status, PackageParser.Package pkg, String oldCodePath);
9185         abstract int doPostInstall(int status, int uid);
9186
9187         /** @see PackageSettingBase#codePathString */
9188         abstract String getCodePath();
9189         /** @see PackageSettingBase#resourcePathString */
9190         abstract String getResourcePath();
9191         abstract String getLegacyNativeLibraryPath();
9192
9193         // Need installer lock especially for dex file removal.
9194         abstract void cleanUpResourcesLI();
9195         abstract boolean doPostDeleteLI(boolean delete);
9196         abstract boolean checkFreeStorage(IMediaContainerService imcs) throws RemoteException;
9197
9198         /**
9199          * Called before the source arguments are copied. This is used mostly
9200          * for MoveParams when it needs to read the source file to put it in the
9201          * destination.
9202          */
9203         int doPreCopy() {
9204             return PackageManager.INSTALL_SUCCEEDED;
9205         }
9206
9207         /**
9208          * Called after the source arguments are copied. This is used mostly for
9209          * MoveParams when it needs to read the source file to put it in the
9210          * destination.
9211          *
9212          * @return
9213          */
9214         int doPostCopy(int uid) {
9215             return PackageManager.INSTALL_SUCCEEDED;
9216         }
9217
9218         protected boolean isFwdLocked() {
9219             return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
9220         }
9221
9222         protected boolean isExternal() {
9223             return (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
9224         }
9225
9226         UserHandle getUser() {
9227             return user;
9228         }
9229     }
9230
9231     /**
9232      * Logic to handle installation of non-ASEC applications, including copying
9233      * and renaming logic.
9234      */
9235     class FileInstallArgs extends InstallArgs {
9236         private File codeFile;
9237         private File resourceFile;
9238         private File legacyNativeLibraryPath;
9239
9240         // Example topology:
9241         // /data/app/com.example/base.apk
9242         // /data/app/com.example/split_foo.apk
9243         // /data/app/com.example/lib/arm/libfoo.so
9244         // /data/app/com.example/lib/arm64/libfoo.so
9245         // /data/app/com.example/dalvik/arm/base.apk@classes.dex
9246
9247         /** New install */
9248         FileInstallArgs(InstallParams params) {
9249             super(params.origin, params.observer, params.installFlags,
9250                     params.installerPackageName, params.getManifestDigest(), params.getUser(),
9251                     null /* instruction sets */, params.packageAbiOverride);
9252             if (isFwdLocked()) {
9253                 throw new IllegalArgumentException("Forward locking only supported in ASEC");
9254             }
9255         }
9256
9257         /** Existing install */
9258         FileInstallArgs(String codePath, String resourcePath, String legacyNativeLibraryPath,
9259                 String[] instructionSets) {
9260             super(OriginInfo.fromNothing(), null, 0, null, null, null, instructionSets, null);
9261             this.codeFile = (codePath != null) ? new File(codePath) : null;
9262             this.resourceFile = (resourcePath != null) ? new File(resourcePath) : null;
9263             this.legacyNativeLibraryPath = (legacyNativeLibraryPath != null) ?
9264                     new File(legacyNativeLibraryPath) : null;
9265         }
9266
9267         boolean checkFreeStorage(IMediaContainerService imcs) throws RemoteException {
9268             final long sizeBytes = imcs.calculateInstalledSize(origin.file.getAbsolutePath(),
9269                     isFwdLocked(), abiOverride);
9270
9271             final StorageManager storage = StorageManager.from(mContext);
9272             return (sizeBytes <= storage.getStorageBytesUntilLow(Environment.getDataDirectory()));
9273         }
9274
9275         int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
9276             if (origin.staged) {
9277                 Slog.d(TAG, origin.file + " already staged; skipping copy");
9278                 codeFile = origin.file;
9279                 resourceFile = origin.file;
9280                 return PackageManager.INSTALL_SUCCEEDED;
9281             }
9282
9283             try {
9284                 final File tempDir = mInstallerService.allocateInternalStageDirLegacy();
9285                 codeFile = tempDir;
9286                 resourceFile = tempDir;
9287             } catch (IOException e) {
9288                 Slog.w(TAG, "Failed to create copy file: " + e);
9289                 return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
9290             }
9291
9292             final IParcelFileDescriptorFactory target = new IParcelFileDescriptorFactory.Stub() {
9293                 @Override
9294                 public ParcelFileDescriptor open(String name, int mode) throws RemoteException {
9295                     if (!FileUtils.isValidExtFilename(name)) {
9296                         throw new IllegalArgumentException("Invalid filename: " + name);
9297                     }
9298                     try {
9299                         final File file = new File(codeFile, name);
9300                         final FileDescriptor fd = Os.open(file.getAbsolutePath(),
9301                                 O_RDWR | O_CREAT, 0644);
9302                         Os.chmod(file.getAbsolutePath(), 0644);
9303                         return new ParcelFileDescriptor(fd);
9304                     } catch (ErrnoException e) {
9305                         throw new RemoteException("Failed to open: " + e.getMessage());
9306                     }
9307                 }
9308             };
9309
9310             int ret = PackageManager.INSTALL_SUCCEEDED;
9311             ret = imcs.copyPackage(origin.file.getAbsolutePath(), target);
9312             if (ret != PackageManager.INSTALL_SUCCEEDED) {
9313                 Slog.e(TAG, "Failed to copy package");
9314                 return ret;
9315             }
9316
9317             final File libraryRoot = new File(codeFile, LIB_DIR_NAME);
9318             NativeLibraryHelper.Handle handle = null;
9319             try {
9320                 handle = NativeLibraryHelper.Handle.create(codeFile);
9321                 ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot,
9322                         abiOverride);
9323             } catch (IOException e) {
9324                 Slog.e(TAG, "Copying native libraries failed", e);
9325                 ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
9326             } finally {
9327                 IoUtils.closeQuietly(handle);
9328             }
9329
9330             return ret;
9331         }
9332
9333         int doPreInstall(int status) {
9334             if (status != PackageManager.INSTALL_SUCCEEDED) {
9335                 cleanUp();
9336             }
9337             return status;
9338         }
9339
9340         boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
9341             if (status != PackageManager.INSTALL_SUCCEEDED) {
9342                 cleanUp();
9343                 return false;
9344             } else {
9345                 final File beforeCodeFile = codeFile;
9346                 final File afterCodeFile = getNextCodePath(pkg.packageName);
9347
9348                 Slog.d(TAG, "Renaming " + beforeCodeFile + " to " + afterCodeFile);
9349                 try {
9350                     Os.rename(beforeCodeFile.getAbsolutePath(), afterCodeFile.getAbsolutePath());
9351                 } catch (ErrnoException e) {
9352                     Slog.d(TAG, "Failed to rename", e);
9353                     return false;
9354                 }
9355
9356                 if (!SELinux.restoreconRecursive(afterCodeFile)) {
9357                     Slog.d(TAG, "Failed to restorecon");
9358                     return false;
9359                 }
9360
9361                 // Reflect the rename internally
9362                 codeFile = afterCodeFile;
9363                 resourceFile = afterCodeFile;
9364
9365                 // Reflect the rename in scanned details
9366                 pkg.codePath = afterCodeFile.getAbsolutePath();
9367                 pkg.baseCodePath = FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile,
9368                         pkg.baseCodePath);
9369                 pkg.splitCodePaths = FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile,
9370                         pkg.splitCodePaths);
9371
9372                 // Reflect the rename in app info
9373                 pkg.applicationInfo.setCodePath(pkg.codePath);
9374                 pkg.applicationInfo.setBaseCodePath(pkg.baseCodePath);
9375                 pkg.applicationInfo.setSplitCodePaths(pkg.splitCodePaths);
9376                 pkg.applicationInfo.setResourcePath(pkg.codePath);
9377                 pkg.applicationInfo.setBaseResourcePath(pkg.baseCodePath);
9378                 pkg.applicationInfo.setSplitResourcePaths(pkg.splitCodePaths);
9379
9380                 return true;
9381             }
9382         }
9383
9384         int doPostInstall(int status, int uid) {
9385             if (status != PackageManager.INSTALL_SUCCEEDED) {
9386                 cleanUp();
9387             }
9388             return status;
9389         }
9390
9391         @Override
9392         String getCodePath() {
9393             return (codeFile != null) ? codeFile.getAbsolutePath() : null;
9394         }
9395
9396         @Override
9397         String getResourcePath() {
9398             return (resourceFile != null) ? resourceFile.getAbsolutePath() : null;
9399         }
9400
9401         @Override
9402         String getLegacyNativeLibraryPath() {
9403             return (legacyNativeLibraryPath != null) ? legacyNativeLibraryPath.getAbsolutePath() : null;
9404         }
9405
9406         private boolean cleanUp() {
9407             if (codeFile == null || !codeFile.exists()) {
9408                 return false;
9409             }
9410
9411             if (codeFile.isDirectory()) {
9412                 FileUtils.deleteContents(codeFile);
9413             }
9414             codeFile.delete();
9415
9416             if (resourceFile != null && !FileUtils.contains(codeFile, resourceFile)) {
9417                 resourceFile.delete();
9418             }
9419
9420             if (legacyNativeLibraryPath != null && !FileUtils.contains(codeFile, legacyNativeLibraryPath)) {
9421                 if (!FileUtils.deleteContents(legacyNativeLibraryPath)) {
9422                     Slog.w(TAG, "Couldn't delete native library directory " + legacyNativeLibraryPath);
9423                 }
9424                 legacyNativeLibraryPath.delete();
9425             }
9426
9427             return true;
9428         }
9429
9430         void cleanUpResourcesLI() {
9431             // Try enumerating all code paths before deleting
9432             List<String> allCodePaths = Collections.EMPTY_LIST;
9433             if (codeFile != null && codeFile.exists()) {
9434                 try {
9435                     final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0);
9436                     allCodePaths = pkg.getAllCodePaths();
9437                 } catch (PackageParserException e) {
9438                     // Ignored; we tried our best
9439                 }
9440             }
9441
9442             cleanUp();
9443
9444             if (!allCodePaths.isEmpty()) {
9445                 if (instructionSets == null) {
9446                     throw new IllegalStateException("instructionSet == null");
9447                 }
9448                 String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
9449                 for (String codePath : allCodePaths) {
9450                     for (String dexCodeInstructionSet : dexCodeInstructionSets) {
9451                         int retCode = mInstaller.rmdex(codePath, dexCodeInstructionSet);
9452                         if (retCode < 0) {
9453                             Slog.w(TAG, "Couldn't remove dex file for package: "
9454                                     + " at location " + codePath + ", retcode=" + retCode);
9455                             // we don't consider this to be a failure of the core package deletion
9456                         }
9457                     }
9458                 }
9459             }
9460         }
9461
9462         boolean doPostDeleteLI(boolean delete) {
9463             // XXX err, shouldn't we respect the delete flag?
9464             cleanUpResourcesLI();
9465             return true;
9466         }
9467     }
9468
9469     private boolean isAsecExternal(String cid) {
9470         final String asecPath = PackageHelper.getSdFilesystem(cid);
9471         return !asecPath.startsWith(mAsecInternalPath);
9472     }
9473
9474     private static void maybeThrowExceptionForMultiArchCopy(String message, int copyRet) throws
9475             PackageManagerException {
9476         if (copyRet < 0) {
9477             if (copyRet != PackageManager.NO_NATIVE_LIBRARIES &&
9478                     copyRet != PackageManager.INSTALL_FAILED_NO_MATCHING_ABIS) {
9479                 throw new PackageManagerException(copyRet, message);
9480             }
9481         }
9482     }
9483
9484     /**
9485      * Extract the MountService "container ID" from the full code path of an
9486      * .apk.
9487      */
9488     static String cidFromCodePath(String fullCodePath) {
9489         int eidx = fullCodePath.lastIndexOf("/");
9490         String subStr1 = fullCodePath.substring(0, eidx);
9491         int sidx = subStr1.lastIndexOf("/");
9492         return subStr1.substring(sidx+1, eidx);
9493     }
9494
9495     /**
9496      * Logic to handle installation of ASEC applications, including copying and
9497      * renaming logic.
9498      */
9499     class AsecInstallArgs extends InstallArgs {
9500         static final String RES_FILE_NAME = "pkg.apk";
9501         static final String PUBLIC_RES_FILE_NAME = "res.zip";
9502
9503         String cid;
9504         String packagePath;
9505         String resourcePath;
9506         String legacyNativeLibraryDir;
9507
9508         /** New install */
9509         AsecInstallArgs(InstallParams params) {
9510             super(params.origin, params.observer, params.installFlags,
9511                     params.installerPackageName, params.getManifestDigest(),
9512                     params.getUser(), null /* instruction sets */,
9513                     params.packageAbiOverride);
9514         }
9515
9516         /** Existing install */
9517         AsecInstallArgs(String fullCodePath, String[] instructionSets,
9518                         boolean isExternal, boolean isForwardLocked) {
9519             super(OriginInfo.fromNothing(), null, (isExternal ? INSTALL_EXTERNAL : 0)
9520                     | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null,
9521                     instructionSets, null);
9522             // Hackily pretend we're still looking at a full code path
9523             if (!fullCodePath.endsWith(RES_FILE_NAME)) {
9524                 fullCodePath = new File(fullCodePath, RES_FILE_NAME).getAbsolutePath();
9525             }
9526
9527             // Extract cid from fullCodePath
9528             int eidx = fullCodePath.lastIndexOf("/");
9529             String subStr1 = fullCodePath.substring(0, eidx);
9530             int sidx = subStr1.lastIndexOf("/");
9531             cid = subStr1.substring(sidx+1, eidx);
9532             setMountPath(subStr1);
9533         }
9534
9535         AsecInstallArgs(String cid, String[] instructionSets, boolean isForwardLocked) {
9536             super(OriginInfo.fromNothing(), null, (isAsecExternal(cid) ? INSTALL_EXTERNAL : 0)
9537                     | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null,
9538                     instructionSets, null);
9539             this.cid = cid;
9540             setMountPath(PackageHelper.getSdDir(cid));
9541         }
9542
9543         void createCopyFile() {
9544             cid = mInstallerService.allocateExternalStageCidLegacy();
9545         }
9546
9547         boolean checkFreeStorage(IMediaContainerService imcs) throws RemoteException {
9548             final long sizeBytes = imcs.calculateInstalledSize(packagePath, isFwdLocked(),
9549                     abiOverride);
9550
9551             final File target;
9552             if (isExternal()) {
9553                 target = new UserEnvironment(UserHandle.USER_OWNER).getExternalStorageDirectory();
9554             } else {
9555                 target = Environment.getDataDirectory();
9556             }
9557
9558             final StorageManager storage = StorageManager.from(mContext);
9559             return (sizeBytes <= storage.getStorageBytesUntilLow(target));
9560         }
9561
9562         int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
9563             if (origin.staged) {
9564                 Slog.d(TAG, origin.cid + " already staged; skipping copy");
9565                 cid = origin.cid;
9566                 setMountPath(PackageHelper.getSdDir(cid));
9567                 return PackageManager.INSTALL_SUCCEEDED;
9568             }
9569
9570             if (temp) {
9571                 createCopyFile();
9572             } else {
9573                 /*
9574                  * Pre-emptively destroy the container since it's destroyed if
9575                  * copying fails due to it existing anyway.
9576                  */
9577                 PackageHelper.destroySdDir(cid);
9578             }
9579
9580             final String newMountPath = imcs.copyPackageToContainer(
9581                     origin.file.getAbsolutePath(), cid, getEncryptKey(), isExternal(),
9582                     isFwdLocked(), deriveAbiOverride(abiOverride, null /* settings */));
9583
9584             if (newMountPath != null) {
9585                 setMountPath(newMountPath);
9586                 return PackageManager.INSTALL_SUCCEEDED;
9587             } else {
9588                 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
9589             }
9590         }
9591
9592         @Override
9593         String getCodePath() {
9594             return packagePath;
9595         }
9596
9597         @Override
9598         String getResourcePath() {
9599             return resourcePath;
9600         }
9601
9602         @Override
9603         String getLegacyNativeLibraryPath() {
9604             return legacyNativeLibraryDir;
9605         }
9606
9607         int doPreInstall(int status) {
9608             if (status != PackageManager.INSTALL_SUCCEEDED) {
9609                 // Destroy container
9610                 PackageHelper.destroySdDir(cid);
9611             } else {
9612                 boolean mounted = PackageHelper.isContainerMounted(cid);
9613                 if (!mounted) {
9614                     String newMountPath = PackageHelper.mountSdDir(cid, getEncryptKey(),
9615                             Process.SYSTEM_UID);
9616                     if (newMountPath != null) {
9617                         setMountPath(newMountPath);
9618                     } else {
9619                         return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
9620                     }
9621                 }
9622             }
9623             return status;
9624         }
9625
9626         boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
9627             String newCacheId = getNextCodePath(oldCodePath, pkg.packageName, "/" + RES_FILE_NAME);
9628             String newMountPath = null;
9629             if (PackageHelper.isContainerMounted(cid)) {
9630                 // Unmount the container
9631                 if (!PackageHelper.unMountSdDir(cid)) {
9632                     Slog.i(TAG, "Failed to unmount " + cid + " before renaming");
9633                     return false;
9634                 }
9635             }
9636             if (!PackageHelper.renameSdDir(cid, newCacheId)) {
9637                 Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId +
9638                         " which might be stale. Will try to clean up.");
9639                 // Clean up the stale container and proceed to recreate.
9640                 if (!PackageHelper.destroySdDir(newCacheId)) {
9641                     Slog.e(TAG, "Very strange. Cannot clean up stale container " + newCacheId);
9642                     return false;
9643                 }
9644                 // Successfully cleaned up stale container. Try to rename again.
9645                 if (!PackageHelper.renameSdDir(cid, newCacheId)) {
9646                     Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId
9647                             + " inspite of cleaning it up.");
9648                     return false;
9649                 }
9650             }
9651             if (!PackageHelper.isContainerMounted(newCacheId)) {
9652                 Slog.w(TAG, "Mounting container " + newCacheId);
9653                 newMountPath = PackageHelper.mountSdDir(newCacheId,
9654                         getEncryptKey(), Process.SYSTEM_UID);
9655             } else {
9656                 newMountPath = PackageHelper.getSdDir(newCacheId);
9657             }
9658             if (newMountPath == null) {
9659                 Slog.w(TAG, "Failed to get cache path for  " + newCacheId);
9660                 return false;
9661             }
9662             Log.i(TAG, "Succesfully renamed " + cid +
9663                     " to " + newCacheId +
9664                     " at new path: " + newMountPath);
9665             cid = newCacheId;
9666
9667             final File beforeCodeFile = new File(packagePath);
9668             setMountPath(newMountPath);
9669             final File afterCodeFile = new File(packagePath);
9670
9671             // Reflect the rename in scanned details
9672             pkg.codePath = afterCodeFile.getAbsolutePath();
9673             pkg.baseCodePath = FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile,
9674                     pkg.baseCodePath);
9675             pkg.splitCodePaths = FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile,
9676                     pkg.splitCodePaths);
9677
9678             // Reflect the rename in app info
9679             pkg.applicationInfo.setCodePath(pkg.codePath);
9680             pkg.applicationInfo.setBaseCodePath(pkg.baseCodePath);
9681             pkg.applicationInfo.setSplitCodePaths(pkg.splitCodePaths);
9682             pkg.applicationInfo.setResourcePath(pkg.codePath);
9683             pkg.applicationInfo.setBaseResourcePath(pkg.baseCodePath);
9684             pkg.applicationInfo.setSplitResourcePaths(pkg.splitCodePaths);
9685
9686             return true;
9687         }
9688
9689         private void setMountPath(String mountPath) {
9690             final File mountFile = new File(mountPath);
9691
9692             final File monolithicFile = new File(mountFile, RES_FILE_NAME);
9693             if (monolithicFile.exists()) {
9694                 packagePath = monolithicFile.getAbsolutePath();
9695                 if (isFwdLocked()) {
9696                     resourcePath = new File(mountFile, PUBLIC_RES_FILE_NAME).getAbsolutePath();
9697                 } else {
9698                     resourcePath = packagePath;
9699                 }
9700             } else {
9701                 packagePath = mountFile.getAbsolutePath();
9702                 resourcePath = packagePath;
9703             }
9704
9705             legacyNativeLibraryDir = new File(mountFile, LIB_DIR_NAME).getAbsolutePath();
9706         }
9707
9708         int doPostInstall(int status, int uid) {
9709             if (status != PackageManager.INSTALL_SUCCEEDED) {
9710                 cleanUp();
9711             } else {
9712                 final int groupOwner;
9713                 final String protectedFile;
9714                 if (isFwdLocked()) {
9715                     groupOwner = UserHandle.getSharedAppGid(uid);
9716                     protectedFile = RES_FILE_NAME;
9717                 } else {
9718                     groupOwner = -1;
9719                     protectedFile = null;
9720                 }
9721
9722                 if (uid < Process.FIRST_APPLICATION_UID
9723                         || !PackageHelper.fixSdPermissions(cid, groupOwner, protectedFile)) {
9724                     Slog.e(TAG, "Failed to finalize " + cid);
9725                     PackageHelper.destroySdDir(cid);
9726                     return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
9727                 }
9728
9729                 boolean mounted = PackageHelper.isContainerMounted(cid);
9730                 if (!mounted) {
9731                     PackageHelper.mountSdDir(cid, getEncryptKey(), Process.myUid());
9732                 }
9733             }
9734             return status;
9735         }
9736
9737         private void cleanUp() {
9738             if (DEBUG_SD_INSTALL) Slog.i(TAG, "cleanUp");
9739
9740             // Destroy secure container
9741             PackageHelper.destroySdDir(cid);
9742         }
9743
9744         private List<String> getAllCodePaths() {
9745             final File codeFile = new File(getCodePath());
9746             if (codeFile != null && codeFile.exists()) {
9747                 try {
9748                     final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0);
9749                     return pkg.getAllCodePaths();
9750                 } catch (PackageParserException e) {
9751                     // Ignored; we tried our best
9752                 }
9753             }
9754             return Collections.EMPTY_LIST;
9755         }
9756
9757         void cleanUpResourcesLI() {
9758             // Enumerate all code paths before deleting
9759             cleanUpResourcesLI(getAllCodePaths());
9760         }
9761
9762         private void cleanUpResourcesLI(List<String> allCodePaths) {
9763             cleanUp();
9764
9765             if (!allCodePaths.isEmpty()) {
9766                 if (instructionSets == null) {
9767                     throw new IllegalStateException("instructionSet == null");
9768                 }
9769                 String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
9770                 for (String codePath : allCodePaths) {
9771                     for (String dexCodeInstructionSet : dexCodeInstructionSets) {
9772                         int retCode = mInstaller.rmdex(codePath, dexCodeInstructionSet);
9773                         if (retCode < 0) {
9774                             Slog.w(TAG, "Couldn't remove dex file for package: "
9775                                     + " at location " + codePath + ", retcode=" + retCode);
9776                             // we don't consider this to be a failure of the core package deletion
9777                         }
9778                     }
9779                 }
9780             }
9781         }
9782
9783         boolean matchContainer(String app) {
9784             if (cid.startsWith(app)) {
9785                 return true;
9786             }
9787             return false;
9788         }
9789
9790         String getPackageName() {
9791             return getAsecPackageName(cid);
9792         }
9793
9794         boolean doPostDeleteLI(boolean delete) {
9795             if (DEBUG_SD_INSTALL) Slog.i(TAG, "doPostDeleteLI() del=" + delete);
9796             final List<String> allCodePaths = getAllCodePaths();
9797             boolean mounted = PackageHelper.isContainerMounted(cid);
9798             if (mounted) {
9799                 // Unmount first
9800                 if (PackageHelper.unMountSdDir(cid)) {
9801                     mounted = false;
9802                 }
9803             }
9804             if (!mounted && delete) {
9805                 cleanUpResourcesLI(allCodePaths);
9806             }
9807             return !mounted;
9808         }
9809
9810         @Override
9811         int doPreCopy() {
9812             if (isFwdLocked()) {
9813                 if (!PackageHelper.fixSdPermissions(cid,
9814                         getPackageUid(DEFAULT_CONTAINER_PACKAGE, 0), RES_FILE_NAME)) {
9815                     return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
9816                 }
9817             }
9818
9819             return PackageManager.INSTALL_SUCCEEDED;
9820         }
9821
9822         @Override
9823         int doPostCopy(int uid) {
9824             if (isFwdLocked()) {
9825                 if (uid < Process.FIRST_APPLICATION_UID
9826                         || !PackageHelper.fixSdPermissions(cid, UserHandle.getSharedAppGid(uid),
9827                                 RES_FILE_NAME)) {
9828                     Slog.e(TAG, "Failed to finalize " + cid);
9829                     PackageHelper.destroySdDir(cid);
9830                     return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
9831                 }
9832             }
9833
9834             return PackageManager.INSTALL_SUCCEEDED;
9835         }
9836     }
9837
9838     static String getAsecPackageName(String packageCid) {
9839         int idx = packageCid.lastIndexOf("-");
9840         if (idx == -1) {
9841             return packageCid;
9842         }
9843         return packageCid.substring(0, idx);
9844     }
9845
9846     // Utility method used to create code paths based on package name and available index.
9847     private static String getNextCodePath(String oldCodePath, String prefix, String suffix) {
9848         String idxStr = "";
9849         int idx = 1;
9850         // Fall back to default value of idx=1 if prefix is not
9851         // part of oldCodePath
9852         if (oldCodePath != null) {
9853             String subStr = oldCodePath;
9854             // Drop the suffix right away
9855             if (suffix != null && subStr.endsWith(suffix)) {
9856                 subStr = subStr.substring(0, subStr.length() - suffix.length());
9857             }
9858             // If oldCodePath already contains prefix find out the
9859             // ending index to either increment or decrement.
9860             int sidx = subStr.lastIndexOf(prefix);
9861             if (sidx != -1) {
9862                 subStr = subStr.substring(sidx + prefix.length());
9863                 if (subStr != null) {
9864                     if (subStr.startsWith(INSTALL_PACKAGE_SUFFIX)) {
9865                         subStr = subStr.substring(INSTALL_PACKAGE_SUFFIX.length());
9866                     }
9867                     try {
9868                         idx = Integer.parseInt(subStr);
9869                         if (idx <= 1) {
9870                             idx++;
9871                         } else {
9872                             idx--;
9873                         }
9874                     } catch(NumberFormatException e) {
9875                     }
9876                 }
9877             }
9878         }
9879         idxStr = INSTALL_PACKAGE_SUFFIX + Integer.toString(idx);
9880         return prefix + idxStr;
9881     }
9882
9883     private File getNextCodePath(String packageName) {
9884         int suffix = 1;
9885         File result;
9886         do {
9887             result = new File(mAppInstallDir, packageName + "-" + suffix);
9888             suffix++;
9889         } while (result.exists());
9890         return result;
9891     }
9892
9893     // Utility method used to ignore ADD/REMOVE events
9894     // by directory observer.
9895     private static boolean ignoreCodePath(String fullPathStr) {
9896         String apkName = deriveCodePathName(fullPathStr);
9897         int idx = apkName.lastIndexOf(INSTALL_PACKAGE_SUFFIX);
9898         if (idx != -1 && ((idx+1) < apkName.length())) {
9899             // Make sure the package ends with a numeral
9900             String version = apkName.substring(idx+1);
9901             try {
9902                 Integer.parseInt(version);
9903                 return true;
9904             } catch (NumberFormatException e) {}
9905         }
9906         return false;
9907     }
9908     
9909     // Utility method that returns the relative package path with respect
9910     // to the installation directory. Like say for /data/data/com.test-1.apk
9911     // string com.test-1 is returned.
9912     static String deriveCodePathName(String codePath) {
9913         if (codePath == null) {
9914             return null;
9915         }
9916         final File codeFile = new File(codePath);
9917         final String name = codeFile.getName();
9918         if (codeFile.isDirectory()) {
9919             return name;
9920         } else if (name.endsWith(".apk") || name.endsWith(".tmp")) {
9921             final int lastDot = name.lastIndexOf('.');
9922             return name.substring(0, lastDot);
9923         } else {
9924             Slog.w(TAG, "Odd, " + codePath + " doesn't look like an APK");
9925             return null;
9926         }
9927     }
9928
9929     class PackageInstalledInfo {
9930         String name;
9931         int uid;
9932         // The set of users that originally had this package installed.
9933         int[] origUsers;
9934         // The set of users that now have this package installed.
9935         int[] newUsers;
9936         PackageParser.Package pkg;
9937         int returnCode;
9938         String returnMsg;
9939         PackageRemovedInfo removedInfo;
9940
9941         public void setError(int code, String msg) {
9942             returnCode = code;
9943             returnMsg = msg;
9944             Slog.w(TAG, msg);
9945         }
9946
9947         public void setError(String msg, PackageParserException e) {
9948             returnCode = e.error;
9949             returnMsg = ExceptionUtils.getCompleteMessage(msg, e);
9950             Slog.w(TAG, msg, e);
9951         }
9952
9953         public void setError(String msg, PackageManagerException e) {
9954             returnCode = e.error;
9955             returnMsg = ExceptionUtils.getCompleteMessage(msg, e);
9956             Slog.w(TAG, msg, e);
9957         }
9958
9959         // In some error cases we want to convey more info back to the observer
9960         String origPackage;
9961         String origPermission;
9962     }
9963
9964     /*
9965      * Install a non-existing package.
9966      */
9967     private void installNewPackageLI(PackageParser.Package pkg,
9968             int parseFlags, int scanFlags, UserHandle user,
9969             String installerPackageName, PackageInstalledInfo res) {
9970         // Remember this for later, in case we need to rollback this install
9971         String pkgName = pkg.packageName;
9972
9973         if (DEBUG_INSTALL) Slog.d(TAG, "installNewPackageLI: " + pkg);
9974         boolean dataDirExists = getDataPathForPackage(pkg.packageName, 0).exists();
9975         synchronized(mPackages) {
9976             if (mSettings.mRenamedPackages.containsKey(pkgName)) {
9977                 // A package with the same name is already installed, though
9978                 // it has been renamed to an older name.  The package we
9979                 // are trying to install should be installed as an update to
9980                 // the existing one, but that has not been requested, so bail.
9981                 res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName
9982                         + " without first uninstalling package running as "
9983                         + mSettings.mRenamedPackages.get(pkgName));
9984                 return;
9985             }
9986             if (mPackages.containsKey(pkgName)) {
9987                 // Don't allow installation over an existing package with the same name.
9988                 res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName
9989                         + " without first uninstalling.");
9990                 return;
9991             }
9992         }
9993
9994         try {
9995             PackageParser.Package newPackage = scanPackageLI(pkg, parseFlags, scanFlags,
9996                     System.currentTimeMillis(), user);
9997
9998             updateSettingsLI(newPackage, installerPackageName, null, null, res);
9999             // delete the partially installed application. the data directory will have to be
10000             // restored if it was already existing
10001             if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
10002                 // remove package from internal structures.  Note that we want deletePackageX to
10003                 // delete the package data and cache directories that it created in
10004                 // scanPackageLocked, unless those directories existed before we even tried to
10005                 // install.
10006                 deletePackageLI(pkgName, UserHandle.ALL, false, null, null,
10007                         dataDirExists ? PackageManager.DELETE_KEEP_DATA : 0,
10008                                 res.removedInfo, true);
10009             }
10010
10011         } catch (PackageManagerException e) {
10012             res.setError("Package couldn't be installed in " + pkg.codePath, e);
10013         }
10014     }
10015
10016     private boolean checkUpgradeKeySetLP(PackageSetting oldPS, PackageParser.Package newPkg) {
10017         // Upgrade keysets are being used.  Determine if new package has a superset of the
10018         // required keys.
10019         long[] upgradeKeySets = oldPS.keySetData.getUpgradeKeySets();
10020         KeySetManagerService ksms = mSettings.mKeySetManagerService;
10021         for (int i = 0; i < upgradeKeySets.length; i++) {
10022             Set<PublicKey> upgradeSet = ksms.getPublicKeysFromKeySetLPr(upgradeKeySets[i]);
10023             if (newPkg.mSigningKeys.containsAll(upgradeSet)) {
10024                 return true;
10025             }
10026         }
10027         return false;
10028     }
10029
10030     private void replacePackageLI(PackageParser.Package pkg,
10031             int parseFlags, int scanFlags, UserHandle user,
10032             String installerPackageName, PackageInstalledInfo res) {
10033         PackageParser.Package oldPackage;
10034         String pkgName = pkg.packageName;
10035         int[] allUsers;
10036         boolean[] perUserInstalled;
10037
10038         // First find the old package info and check signatures
10039         synchronized(mPackages) {
10040             oldPackage = mPackages.get(pkgName);
10041             if (DEBUG_INSTALL) Slog.d(TAG, "replacePackageLI: new=" + pkg + ", old=" + oldPackage);
10042             PackageSetting ps = mSettings.mPackages.get(pkgName);
10043             if (ps == null || !ps.keySetData.isUsingUpgradeKeySets() || ps.sharedUser != null) {
10044                 // default to original signature matching
10045                 if (compareSignatures(oldPackage.mSignatures, pkg.mSignatures)
10046                     != PackageManager.SIGNATURE_MATCH) {
10047                     res.setError(INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES,
10048                             "New package has a different signature: " + pkgName);
10049                     return;
10050                 }
10051             } else {
10052                 if(!checkUpgradeKeySetLP(ps, pkg)) {
10053                     res.setError(INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES,
10054                             "New package not signed by keys specified by upgrade-keysets: "
10055                             + pkgName);
10056                     return;
10057                 }
10058             }
10059
10060             // In case of rollback, remember per-user/profile install state
10061             allUsers = sUserManager.getUserIds();
10062             perUserInstalled = new boolean[allUsers.length];
10063             for (int i = 0; i < allUsers.length; i++) {
10064                 perUserInstalled[i] = ps != null ? ps.getInstalled(allUsers[i]) : false;
10065             }
10066         }
10067
10068         boolean sysPkg = (isSystemApp(oldPackage));
10069         if (sysPkg) {
10070             replaceSystemPackageLI(oldPackage, pkg, parseFlags, scanFlags,
10071                     user, allUsers, perUserInstalled, installerPackageName, res);
10072         } else {
10073             replaceNonSystemPackageLI(oldPackage, pkg, parseFlags, scanFlags,
10074                     user, allUsers, perUserInstalled, installerPackageName, res);
10075         }
10076     }
10077
10078     private void replaceNonSystemPackageLI(PackageParser.Package deletedPackage,
10079             PackageParser.Package pkg, int parseFlags, int scanFlags, UserHandle user,
10080             int[] allUsers, boolean[] perUserInstalled,
10081             String installerPackageName, PackageInstalledInfo res) {
10082         String pkgName = deletedPackage.packageName;
10083         boolean deletedPkg = true;
10084         boolean updatedSettings = false;
10085
10086         if (DEBUG_INSTALL) Slog.d(TAG, "replaceNonSystemPackageLI: new=" + pkg + ", old="
10087                 + deletedPackage);
10088         long origUpdateTime;
10089         if (pkg.mExtras != null) {
10090             origUpdateTime = ((PackageSetting)pkg.mExtras).lastUpdateTime;
10091         } else {
10092             origUpdateTime = 0;
10093         }
10094
10095         // First delete the existing package while retaining the data directory
10096         if (!deletePackageLI(pkgName, null, true, null, null, PackageManager.DELETE_KEEP_DATA,
10097                 res.removedInfo, true)) {
10098             // If the existing package wasn't successfully deleted
10099             res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE, "replaceNonSystemPackageLI");
10100             deletedPkg = false;
10101         } else {
10102             // Successfully deleted the old package; proceed with replace.
10103
10104             // If deleted package lived in a container, give users a chance to
10105             // relinquish resources before killing.
10106             if (isForwardLocked(deletedPackage) || isExternal(deletedPackage)) {
10107                 if (DEBUG_INSTALL) {
10108                     Slog.i(TAG, "upgrading pkg " + deletedPackage + " is ASEC-hosted -> UNAVAILABLE");
10109                 }
10110                 final int[] uidArray = new int[] { deletedPackage.applicationInfo.uid };
10111                 final ArrayList<String> pkgList = new ArrayList<String>(1);
10112                 pkgList.add(deletedPackage.applicationInfo.packageName);
10113                 sendResourcesChangedBroadcast(false, true, pkgList, uidArray, null);
10114             }
10115
10116             deleteCodeCacheDirsLI(pkgName);
10117             try {
10118                 final PackageParser.Package newPackage = scanPackageLI(pkg, parseFlags,
10119                         scanFlags | SCAN_UPDATE_TIME, System.currentTimeMillis(), user);
10120                 updateSettingsLI(newPackage, installerPackageName, allUsers, perUserInstalled, res);
10121                 updatedSettings = true;
10122             } catch (PackageManagerException e) {
10123                 res.setError("Package couldn't be installed in " + pkg.codePath, e);
10124             }
10125         }
10126
10127         if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
10128             // remove package from internal structures.  Note that we want deletePackageX to
10129             // delete the package data and cache directories that it created in
10130             // scanPackageLocked, unless those directories existed before we even tried to
10131             // install.
10132             if(updatedSettings) {
10133                 if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, rolling pack: " + pkgName);
10134                 deletePackageLI(
10135                         pkgName, null, true, allUsers, perUserInstalled,
10136                         PackageManager.DELETE_KEEP_DATA,
10137                                 res.removedInfo, true);
10138             }
10139             // Since we failed to install the new package we need to restore the old
10140             // package that we deleted.
10141             if (deletedPkg) {
10142                 if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, reinstalling: " + deletedPackage);
10143                 File restoreFile = new File(deletedPackage.codePath);
10144                 // Parse old package
10145                 boolean oldOnSd = isExternal(deletedPackage);
10146                 int oldParseFlags  = mDefParseFlags | PackageParser.PARSE_CHATTY |
10147                         (isForwardLocked(deletedPackage) ? PackageParser.PARSE_FORWARD_LOCK : 0) |
10148                         (oldOnSd ? PackageParser.PARSE_ON_SDCARD : 0);
10149                 int oldScanFlags = SCAN_UPDATE_SIGNATURE | SCAN_UPDATE_TIME;
10150                 try {
10151                     scanPackageLI(restoreFile, oldParseFlags, oldScanFlags, origUpdateTime, null);
10152                 } catch (PackageManagerException e) {
10153                     Slog.e(TAG, "Failed to restore package : " + pkgName + " after failed upgrade: "
10154                             + e.getMessage());
10155                     return;
10156                 }
10157                 // Restore of old package succeeded. Update permissions.
10158                 // writer
10159                 synchronized (mPackages) {
10160                     updatePermissionsLPw(deletedPackage.packageName, deletedPackage,
10161                             UPDATE_PERMISSIONS_ALL);
10162                     // can downgrade to reader
10163                     mSettings.writeLPr();
10164                 }
10165                 Slog.i(TAG, "Successfully restored package : " + pkgName + " after failed upgrade");
10166             }
10167         }
10168     }
10169
10170     private void replaceSystemPackageLI(PackageParser.Package deletedPackage,
10171             PackageParser.Package pkg, int parseFlags, int scanFlags, UserHandle user,
10172             int[] allUsers, boolean[] perUserInstalled,
10173             String installerPackageName, PackageInstalledInfo res) {
10174         if (DEBUG_INSTALL) Slog.d(TAG, "replaceSystemPackageLI: new=" + pkg
10175                 + ", old=" + deletedPackage);
10176         boolean disabledSystem = false;
10177         boolean updatedSettings = false;
10178         parseFlags |= PackageParser.PARSE_IS_SYSTEM;
10179         if ((deletedPackage.applicationInfo.flags&ApplicationInfo.FLAG_PRIVILEGED) != 0) {
10180             parseFlags |= PackageParser.PARSE_IS_PRIVILEGED;
10181         }
10182         String packageName = deletedPackage.packageName;
10183         if (packageName == null) {
10184             res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE,
10185                     "Attempt to delete null packageName.");
10186             return;
10187         }
10188         PackageParser.Package oldPkg;
10189         PackageSetting oldPkgSetting;
10190         // reader
10191         synchronized (mPackages) {
10192             oldPkg = mPackages.get(packageName);
10193             oldPkgSetting = mSettings.mPackages.get(packageName);
10194             if((oldPkg == null) || (oldPkg.applicationInfo == null) ||
10195                     (oldPkgSetting == null)) {
10196                 res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE,
10197                         "Couldn't find package:" + packageName + " information");
10198                 return;
10199             }
10200         }
10201
10202         killApplication(packageName, oldPkg.applicationInfo.uid, "replace sys pkg");
10203
10204         res.removedInfo.uid = oldPkg.applicationInfo.uid;
10205         res.removedInfo.removedPackage = packageName;
10206         // Remove existing system package
10207         removePackageLI(oldPkgSetting, true);
10208         // writer
10209         synchronized (mPackages) {
10210             disabledSystem = mSettings.disableSystemPackageLPw(packageName);
10211             if (!disabledSystem && deletedPackage != null) {
10212                 // We didn't need to disable the .apk as a current system package,
10213                 // which means we are replacing another update that is already
10214                 // installed.  We need to make sure to delete the older one's .apk.
10215                 res.removedInfo.args = createInstallArgsForExisting(0,
10216                         deletedPackage.applicationInfo.getCodePath(),
10217                         deletedPackage.applicationInfo.getResourcePath(),
10218                         deletedPackage.applicationInfo.nativeLibraryRootDir,
10219                         getAppDexInstructionSets(deletedPackage.applicationInfo));
10220             } else {
10221                 res.removedInfo.args = null;
10222             }
10223         }
10224
10225         // Successfully disabled the old package. Now proceed with re-installation
10226         deleteCodeCacheDirsLI(packageName);
10227
10228         res.returnCode = PackageManager.INSTALL_SUCCEEDED;
10229         pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
10230
10231         PackageParser.Package newPackage = null;
10232         try {
10233             newPackage = scanPackageLI(pkg, parseFlags, scanFlags, 0, user);
10234             if (newPackage.mExtras != null) {
10235                 final PackageSetting newPkgSetting = (PackageSetting) newPackage.mExtras;
10236                 newPkgSetting.firstInstallTime = oldPkgSetting.firstInstallTime;
10237                 newPkgSetting.lastUpdateTime = System.currentTimeMillis();
10238
10239                 // is the update attempting to change shared user? that isn't going to work...
10240                 if (oldPkgSetting.sharedUser != newPkgSetting.sharedUser) {
10241                     res.setError(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
10242                             "Forbidding shared user change from " + oldPkgSetting.sharedUser
10243                             + " to " + newPkgSetting.sharedUser);
10244                     updatedSettings = true;
10245                 }
10246             }
10247
10248             if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
10249                 updateSettingsLI(newPackage, installerPackageName, allUsers, perUserInstalled, res);
10250                 updatedSettings = true;
10251             }
10252
10253         } catch (PackageManagerException e) {
10254             res.setError("Package couldn't be installed in " + pkg.codePath, e);
10255         }
10256
10257         if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
10258             // Re installation failed. Restore old information
10259             // Remove new pkg information
10260             if (newPackage != null) {
10261                 removeInstalledPackageLI(newPackage, true);
10262             }
10263             // Add back the old system package
10264             try {
10265                 scanPackageLI(oldPkg, parseFlags, SCAN_UPDATE_SIGNATURE, 0, user);
10266             } catch (PackageManagerException e) {
10267                 Slog.e(TAG, "Failed to restore original package: " + e.getMessage());
10268             }
10269             // Restore the old system information in Settings
10270             synchronized (mPackages) {
10271                 if (disabledSystem) {
10272                     mSettings.enableSystemPackageLPw(packageName);
10273                 }
10274                 if (updatedSettings) {
10275                     mSettings.setInstallerPackageName(packageName,
10276                             oldPkgSetting.installerPackageName);
10277                 }
10278                 mSettings.writeLPr();
10279             }
10280         }
10281     }
10282
10283     private void updateSettingsLI(PackageParser.Package newPackage, String installerPackageName,
10284             int[] allUsers, boolean[] perUserInstalled,
10285             PackageInstalledInfo res) {
10286         String pkgName = newPackage.packageName;
10287         synchronized (mPackages) {
10288             //write settings. the installStatus will be incomplete at this stage.
10289             //note that the new package setting would have already been
10290             //added to mPackages. It hasn't been persisted yet.
10291             mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_INCOMPLETE);
10292             mSettings.writeLPr();
10293         }
10294
10295         if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + newPackage.codePath);
10296
10297         synchronized (mPackages) {
10298             updatePermissionsLPw(newPackage.packageName, newPackage,
10299                     UPDATE_PERMISSIONS_REPLACE_PKG | (newPackage.permissions.size() > 0
10300                             ? UPDATE_PERMISSIONS_ALL : 0));
10301             // For system-bundled packages, we assume that installing an upgraded version
10302             // of the package implies that the user actually wants to run that new code,
10303             // so we enable the package.
10304             if (isSystemApp(newPackage)) {
10305                 // NB: implicit assumption that system package upgrades apply to all users
10306                 if (DEBUG_INSTALL) {
10307                     Slog.d(TAG, "Implicitly enabling system package on upgrade: " + pkgName);
10308                 }
10309                 PackageSetting ps = mSettings.mPackages.get(pkgName);
10310                 if (ps != null) {
10311                     if (res.origUsers != null) {
10312                         for (int userHandle : res.origUsers) {
10313                             ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT,
10314                                     userHandle, installerPackageName);
10315                         }
10316                     }
10317                     // Also convey the prior install/uninstall state
10318                     if (allUsers != null && perUserInstalled != null) {
10319                         for (int i = 0; i < allUsers.length; i++) {
10320                             if (DEBUG_INSTALL) {
10321                                 Slog.d(TAG, "    user " + allUsers[i]
10322                                         + " => " + perUserInstalled[i]);
10323                             }
10324                             ps.setInstalled(perUserInstalled[i], allUsers[i]);
10325                         }
10326                         // these install state changes will be persisted in the
10327                         // upcoming call to mSettings.writeLPr().
10328                     }
10329                 }
10330             }
10331             res.name = pkgName;
10332             res.uid = newPackage.applicationInfo.uid;
10333             res.pkg = newPackage;
10334             mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_COMPLETE);
10335             mSettings.setInstallerPackageName(pkgName, installerPackageName);
10336             res.returnCode = PackageManager.INSTALL_SUCCEEDED;
10337             //to update install status
10338             mSettings.writeLPr();
10339         }
10340     }
10341
10342     private void installPackageLI(InstallArgs args, PackageInstalledInfo res) {
10343         final int installFlags = args.installFlags;
10344         String installerPackageName = args.installerPackageName;
10345         File tmpPackageFile = new File(args.getCodePath());
10346         boolean forwardLocked = ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0);
10347         boolean onSd = ((installFlags & PackageManager.INSTALL_EXTERNAL) != 0);
10348         boolean replace = false;
10349         final int scanFlags = SCAN_NEW_INSTALL | SCAN_FORCE_DEX | SCAN_UPDATE_SIGNATURE;
10350         // Result object to be returned
10351         res.returnCode = PackageManager.INSTALL_SUCCEEDED;
10352
10353         if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile);
10354         // Retrieve PackageSettings and parse package
10355         final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY
10356                 | (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0)
10357                 | (onSd ? PackageParser.PARSE_ON_SDCARD : 0);
10358         PackageParser pp = new PackageParser();
10359         pp.setSeparateProcesses(mSeparateProcesses);
10360         pp.setDisplayMetrics(mMetrics);
10361
10362         final PackageParser.Package pkg;
10363         try {
10364             pkg = pp.parsePackage(tmpPackageFile, parseFlags);
10365         } catch (PackageParserException e) {
10366             res.setError("Failed parse during installPackageLI", e);
10367             return;
10368         }
10369
10370         // Mark that we have an install time CPU ABI override.
10371         pkg.cpuAbiOverride = args.abiOverride;
10372
10373         String pkgName = res.name = pkg.packageName;
10374         if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_TEST_ONLY) != 0) {
10375             if ((installFlags & PackageManager.INSTALL_ALLOW_TEST) == 0) {
10376                 res.setError(INSTALL_FAILED_TEST_ONLY, "installPackageLI");
10377                 return;
10378             }
10379         }
10380
10381         try {
10382             pp.collectCertificates(pkg, parseFlags);
10383             pp.collectManifestDigest(pkg);
10384         } catch (PackageParserException e) {
10385             res.setError("Failed collect during installPackageLI", e);
10386             return;
10387         }
10388
10389         /* If the installer passed in a manifest digest, compare it now. */
10390         if (args.manifestDigest != null) {
10391             if (DEBUG_INSTALL) {
10392                 final String parsedManifest = pkg.manifestDigest == null ? "null"
10393                         : pkg.manifestDigest.toString();
10394                 Slog.d(TAG, "Comparing manifests: " + args.manifestDigest.toString() + " vs. "
10395                         + parsedManifest);
10396             }
10397
10398             if (!args.manifestDigest.equals(pkg.manifestDigest)) {
10399                 res.setError(INSTALL_FAILED_PACKAGE_CHANGED, "Manifest digest changed");
10400                 return;
10401             }
10402         } else if (DEBUG_INSTALL) {
10403             final String parsedManifest = pkg.manifestDigest == null
10404                     ? "null" : pkg.manifestDigest.toString();
10405             Slog.d(TAG, "manifestDigest was not present, but parser got: " + parsedManifest);
10406         }
10407
10408         // Get rid of all references to package scan path via parser.
10409         pp = null;
10410         String oldCodePath = null;
10411         boolean systemApp = false;
10412         synchronized (mPackages) {
10413             // Check if installing already existing package
10414             if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
10415                 String oldName = mSettings.mRenamedPackages.get(pkgName);
10416                 if (pkg.mOriginalPackages != null
10417                         && pkg.mOriginalPackages.contains(oldName)
10418                         && mPackages.containsKey(oldName)) {
10419                     // This package is derived from an original package,
10420                     // and this device has been updating from that original
10421                     // name.  We must continue using the original name, so
10422                     // rename the new package here.
10423                     pkg.setPackageName(oldName);
10424                     pkgName = pkg.packageName;
10425                     replace = true;
10426                     if (DEBUG_INSTALL) Slog.d(TAG, "Replacing existing renamed package: oldName="
10427                             + oldName + " pkgName=" + pkgName);
10428                 } else if (mPackages.containsKey(pkgName)) {
10429                     // This package, under its official name, already exists
10430                     // on the device; we should replace it.
10431                     replace = true;
10432                     if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing pacakge: " + pkgName);
10433                 }
10434             }
10435
10436             PackageSetting ps = mSettings.mPackages.get(pkgName);
10437             if (ps != null) {
10438                 if (DEBUG_INSTALL) Slog.d(TAG, "Existing package: " + ps);
10439
10440                 // Quick sanity check that we're signed correctly if updating;
10441                 // we'll check this again later when scanning, but we want to
10442                 // bail early here before tripping over redefined permissions.
10443                 if (!ps.keySetData.isUsingUpgradeKeySets() || ps.sharedUser != null) {
10444                     try {
10445                         verifySignaturesLP(ps, pkg);
10446                     } catch (PackageManagerException e) {
10447                         res.setError(e.error, e.getMessage());
10448                         return;
10449                     }
10450                 } else {
10451                     if (!checkUpgradeKeySetLP(ps, pkg)) {
10452                         res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
10453                                 + pkg.packageName + " upgrade keys do not match the "
10454                                 + "previously installed version");
10455                         return;
10456                     }
10457                 }
10458
10459                 oldCodePath = mSettings.mPackages.get(pkgName).codePathString;
10460                 if (ps.pkg != null && ps.pkg.applicationInfo != null) {
10461                     systemApp = (ps.pkg.applicationInfo.flags &
10462                             ApplicationInfo.FLAG_SYSTEM) != 0;
10463                 }
10464                 res.origUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
10465             }
10466
10467             // Check whether the newly-scanned package wants to define an already-defined perm
10468             int N = pkg.permissions.size();
10469             for (int i = N-1; i >= 0; i--) {
10470                 PackageParser.Permission perm = pkg.permissions.get(i);
10471                 BasePermission bp = mSettings.mPermissions.get(perm.info.name);
10472                 if (bp != null) {
10473                     // If the defining package is signed with our cert, it's okay.  This
10474                     // also includes the "updating the same package" case, of course.
10475                     // "updating same package" could also involve key-rotation.
10476                     final boolean sigsOk;
10477                     if (!bp.sourcePackage.equals(pkg.packageName)
10478                             || !(bp.packageSetting instanceof PackageSetting)
10479                             || !bp.packageSetting.keySetData.isUsingUpgradeKeySets()
10480                             || ((PackageSetting) bp.packageSetting).sharedUser != null) {
10481                         sigsOk = compareSignatures(bp.packageSetting.signatures.mSignatures,
10482                                 pkg.mSignatures) == PackageManager.SIGNATURE_MATCH;
10483                     } else {
10484                         sigsOk = checkUpgradeKeySetLP((PackageSetting) bp.packageSetting, pkg);
10485                     }
10486                     if (!sigsOk) {
10487                         // If the owning package is the system itself, we log but allow
10488                         // install to proceed; we fail the install on all other permission
10489                         // redefinitions.
10490                         if (!bp.sourcePackage.equals("android")) {
10491                             res.setError(INSTALL_FAILED_DUPLICATE_PERMISSION, "Package "
10492                                     + pkg.packageName + " attempting to redeclare permission "
10493                                     + perm.info.name + " already owned by " + bp.sourcePackage);
10494                             res.origPermission = perm.info.name;
10495                             res.origPackage = bp.sourcePackage;
10496                             return;
10497                         } else {
10498                             Slog.w(TAG, "Package " + pkg.packageName
10499                                     + " attempting to redeclare system permission "
10500                                     + perm.info.name + "; ignoring new declaration");
10501                             pkg.permissions.remove(i);
10502                         }
10503                     }
10504                 }
10505             }
10506
10507         }
10508
10509         if (systemApp && onSd) {
10510             // Disable updates to system apps on sdcard
10511             res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
10512                     "Cannot install updates to system apps on sdcard");
10513             return;
10514         }
10515
10516         if (!args.doRename(res.returnCode, pkg, oldCodePath)) {
10517             res.setError(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename");
10518             return;
10519         }
10520
10521         if (replace) {
10522             replacePackageLI(pkg, parseFlags, scanFlags | SCAN_REPLACING, args.user,
10523                     installerPackageName, res);
10524         } else {
10525             installNewPackageLI(pkg, parseFlags, scanFlags | SCAN_DELETE_DATA_ON_FAILURES,
10526                     args.user, installerPackageName, res);
10527         }
10528         synchronized (mPackages) {
10529             final PackageSetting ps = mSettings.mPackages.get(pkgName);
10530             if (ps != null) {
10531                 res.newUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
10532             }
10533         }
10534     }
10535
10536     private static boolean isForwardLocked(PackageParser.Package pkg) {
10537         return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0;
10538     }
10539
10540     private static boolean isForwardLocked(ApplicationInfo info) {
10541         return (info.flags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0;
10542     }
10543
10544     private boolean isForwardLocked(PackageSetting ps) {
10545         return (ps.pkgFlags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0;
10546     }
10547
10548     private static boolean isMultiArch(PackageSetting ps) {
10549         return (ps.pkgFlags & ApplicationInfo.FLAG_MULTIARCH) != 0;
10550     }
10551
10552     private static boolean isMultiArch(ApplicationInfo info) {
10553         return (info.flags & ApplicationInfo.FLAG_MULTIARCH) != 0;
10554     }
10555
10556     private static boolean isExternal(PackageParser.Package pkg) {
10557         return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
10558     }
10559
10560     private static boolean isExternal(PackageSetting ps) {
10561         return (ps.pkgFlags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
10562     }
10563
10564     private static boolean isExternal(ApplicationInfo info) {
10565         return (info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
10566     }
10567
10568     private static boolean isSystemApp(PackageParser.Package pkg) {
10569         return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10570     }
10571
10572     private static boolean isPrivilegedApp(PackageParser.Package pkg) {
10573         return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_PRIVILEGED) != 0;
10574     }
10575
10576     private static boolean isSystemApp(ApplicationInfo info) {
10577         return (info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10578     }
10579
10580     private static boolean isSystemApp(PackageSetting ps) {
10581         return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0;
10582     }
10583
10584     private static boolean isUpdatedSystemApp(PackageSetting ps) {
10585         return (ps.pkgFlags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
10586     }
10587
10588     private static boolean isUpdatedSystemApp(PackageParser.Package pkg) {
10589         return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
10590     }
10591
10592     private static boolean isUpdatedSystemApp(ApplicationInfo info) {
10593         return (info.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
10594     }
10595
10596     private int packageFlagsToInstallFlags(PackageSetting ps) {
10597         int installFlags = 0;
10598         if (isExternal(ps)) {
10599             installFlags |= PackageManager.INSTALL_EXTERNAL;
10600         }
10601         if (isForwardLocked(ps)) {
10602             installFlags |= PackageManager.INSTALL_FORWARD_LOCK;
10603         }
10604         return installFlags;
10605     }
10606
10607     private void deleteTempPackageFiles() {
10608         final FilenameFilter filter = new FilenameFilter() {
10609             public boolean accept(File dir, String name) {
10610                 return name.startsWith("vmdl") && name.endsWith(".tmp");
10611             }
10612         };
10613         for (File file : mDrmAppPrivateInstallDir.listFiles(filter)) {
10614             file.delete();
10615         }
10616     }
10617
10618     @Override
10619     public void deletePackageAsUser(String packageName, IPackageDeleteObserver observer, int userId,
10620             int flags) {
10621         deletePackage(packageName, new LegacyPackageDeleteObserver(observer).getBinder(), userId,
10622                 flags);
10623     }
10624
10625     @Override
10626     public void deletePackage(final String packageName,
10627             final IPackageDeleteObserver2 observer, final int userId, final int flags) {
10628         mContext.enforceCallingOrSelfPermission(
10629                 android.Manifest.permission.DELETE_PACKAGES, null);
10630         final int uid = Binder.getCallingUid();
10631         if (UserHandle.getUserId(uid) != userId) {
10632             mContext.enforceCallingPermission(
10633                     android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10634                     "deletePackage for user " + userId);
10635         }
10636         if (isUserRestricted(userId, UserManager.DISALLOW_UNINSTALL_APPS)) {
10637             try {
10638                 observer.onPackageDeleted(packageName,
10639                         PackageManager.DELETE_FAILED_USER_RESTRICTED, null);
10640             } catch (RemoteException re) {
10641             }
10642             return;
10643         }
10644
10645         boolean uninstallBlocked = false;
10646         if ((flags & PackageManager.DELETE_ALL_USERS) != 0) {
10647             int[] users = sUserManager.getUserIds();
10648             for (int i = 0; i < users.length; ++i) {
10649                 if (getBlockUninstallForUser(packageName, users[i])) {
10650                     uninstallBlocked = true;
10651                     break;
10652                 }
10653             }
10654         } else {
10655             uninstallBlocked = getBlockUninstallForUser(packageName, userId);
10656         }
10657         if (uninstallBlocked) {
10658             try {
10659                 observer.onPackageDeleted(packageName, PackageManager.DELETE_FAILED_OWNER_BLOCKED,
10660                         null);
10661             } catch (RemoteException re) {
10662             }
10663             return;
10664         }
10665
10666         if (DEBUG_REMOVE) {
10667             Slog.d(TAG, "deletePackageAsUser: pkg=" + packageName + " user=" + userId);
10668         }
10669         // Queue up an async operation since the package deletion may take a little while.
10670         mHandler.post(new Runnable() {
10671             public void run() {
10672                 mHandler.removeCallbacks(this);
10673                 final int returnCode = deletePackageX(packageName, userId, flags);
10674                 if (observer != null) {
10675                     try {
10676                         observer.onPackageDeleted(packageName, returnCode, null);
10677                     } catch (RemoteException e) {
10678                         Log.i(TAG, "Observer no longer exists.");
10679                     } //end catch
10680                 } //end if
10681             } //end run
10682         });
10683     }
10684
10685     private boolean isPackageDeviceAdmin(String packageName, int userId) {
10686         IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
10687                 ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
10688         try {
10689             if (dpm != null) {
10690                 if (dpm.isDeviceOwner(packageName)) {
10691                     return true;
10692                 }
10693                 int[] users;
10694                 if (userId == UserHandle.USER_ALL) {
10695                     users = sUserManager.getUserIds();
10696                 } else {
10697                     users = new int[]{userId};
10698                 }
10699                 for (int i = 0; i < users.length; ++i) {
10700                     if (dpm.packageHasActiveAdmins(packageName, users[i])) {
10701                         return true;
10702                     }
10703                 }
10704             }
10705         } catch (RemoteException e) {
10706         }
10707         return false;
10708     }
10709
10710     /**
10711      *  This method is an internal method that could be get invoked either
10712      *  to delete an installed package or to clean up a failed installation.
10713      *  After deleting an installed package, a broadcast is sent to notify any
10714      *  listeners that the package has been installed. For cleaning up a failed
10715      *  installation, the broadcast is not necessary since the package's
10716      *  installation wouldn't have sent the initial broadcast either
10717      *  The key steps in deleting a package are
10718      *  deleting the package information in internal structures like mPackages,
10719      *  deleting the packages base directories through installd
10720      *  updating mSettings to reflect current status
10721      *  persisting settings for later use
10722      *  sending a broadcast if necessary
10723      */
10724     private int deletePackageX(String packageName, int userId, int flags) {
10725         final PackageRemovedInfo info = new PackageRemovedInfo();
10726         final boolean res;
10727
10728         final UserHandle removeForUser = (flags & PackageManager.DELETE_ALL_USERS) != 0
10729                 ? UserHandle.ALL : new UserHandle(userId);
10730
10731         if (isPackageDeviceAdmin(packageName, removeForUser.getIdentifier())) {
10732             Slog.w(TAG, "Not removing package " + packageName + ": has active device admin");
10733             return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER;
10734         }
10735
10736         boolean removedForAllUsers = false;
10737         boolean systemUpdate = false;
10738
10739         // for the uninstall-updates case and restricted profiles, remember the per-
10740         // userhandle installed state
10741         int[] allUsers;
10742         boolean[] perUserInstalled;
10743         synchronized (mPackages) {
10744             PackageSetting ps = mSettings.mPackages.get(packageName);
10745             allUsers = sUserManager.getUserIds();
10746             perUserInstalled = new boolean[allUsers.length];
10747             for (int i = 0; i < allUsers.length; i++) {
10748                 perUserInstalled[i] = ps != null ? ps.getInstalled(allUsers[i]) : false;
10749             }
10750         }
10751
10752         synchronized (mInstallLock) {
10753             if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageX: pkg=" + packageName + " user=" + userId);
10754             res = deletePackageLI(packageName, removeForUser,
10755                     true, allUsers, perUserInstalled,
10756                     flags | REMOVE_CHATTY, info, true);
10757             systemUpdate = info.isRemovedPackageSystemUpdate;
10758             if (res && !systemUpdate && mPackages.get(packageName) == null) {
10759                 removedForAllUsers = true;
10760             }
10761             if (DEBUG_REMOVE) Slog.d(TAG, "delete res: systemUpdate=" + systemUpdate
10762                     + " removedForAllUsers=" + removedForAllUsers);
10763         }
10764
10765         if (res) {
10766             info.sendBroadcast(true, systemUpdate, removedForAllUsers);
10767
10768             // If the removed package was a system update, the old system package
10769             // was re-enabled; we need to broadcast this information
10770             if (systemUpdate) {
10771                 Bundle extras = new Bundle(1);
10772                 extras.putInt(Intent.EXTRA_UID, info.removedAppId >= 0
10773                         ? info.removedAppId : info.uid);
10774                 extras.putBoolean(Intent.EXTRA_REPLACING, true);
10775
10776                 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
10777                         extras, null, null, null);
10778                 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, packageName,
10779                         extras, null, null, null);
10780                 sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, null,
10781                         null, packageName, null, null);
10782             }
10783         }
10784         // Force a gc here.
10785         Runtime.getRuntime().gc();
10786         // Delete the resources here after sending the broadcast to let
10787         // other processes clean up before deleting resources.
10788         if (info.args != null) {
10789             synchronized (mInstallLock) {
10790                 info.args.doPostDeleteLI(true);
10791             }
10792         }
10793
10794         return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR;
10795     }
10796
10797     static class PackageRemovedInfo {
10798         String removedPackage;
10799         int uid = -1;
10800         int removedAppId = -1;
10801         int[] removedUsers = null;
10802         boolean isRemovedPackageSystemUpdate = false;
10803         // Clean up resources deleted packages.
10804         InstallArgs args = null;
10805
10806         void sendBroadcast(boolean fullRemove, boolean replacing, boolean removedForAllUsers) {
10807             Bundle extras = new Bundle(1);
10808             extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid);
10809             extras.putBoolean(Intent.EXTRA_DATA_REMOVED, fullRemove);
10810             if (replacing) {
10811                 extras.putBoolean(Intent.EXTRA_REPLACING, true);
10812             }
10813             extras.putBoolean(Intent.EXTRA_REMOVED_FOR_ALL_USERS, removedForAllUsers);
10814             if (removedPackage != null) {
10815                 sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED, removedPackage,
10816                         extras, null, null, removedUsers);
10817                 if (fullRemove && !replacing) {
10818                     sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED, removedPackage,
10819                             extras, null, null, removedUsers);
10820                 }
10821             }
10822             if (removedAppId >= 0) {
10823                 sendPackageBroadcast(Intent.ACTION_UID_REMOVED, null, extras, null, null,
10824                         removedUsers);
10825             }
10826         }
10827     }
10828
10829     /*
10830      * This method deletes the package from internal data structures. If the DONT_DELETE_DATA
10831      * flag is not set, the data directory is removed as well.
10832      * make sure this flag is set for partially installed apps. If not its meaningless to
10833      * delete a partially installed application.
10834      */
10835     private void removePackageDataLI(PackageSetting ps,
10836             int[] allUserHandles, boolean[] perUserInstalled,
10837             PackageRemovedInfo outInfo, int flags, boolean writeSettings) {
10838         String packageName = ps.name;
10839         if (DEBUG_REMOVE) Slog.d(TAG, "removePackageDataLI: " + ps);
10840         removePackageLI(ps, (flags&REMOVE_CHATTY) != 0);
10841         // Retrieve object to delete permissions for shared user later on
10842         final PackageSetting deletedPs;
10843         // reader
10844         synchronized (mPackages) {
10845             deletedPs = mSettings.mPackages.get(packageName);
10846             if (outInfo != null) {
10847                 outInfo.removedPackage = packageName;
10848                 outInfo.removedUsers = deletedPs != null
10849                         ? deletedPs.queryInstalledUsers(sUserManager.getUserIds(), true)
10850                         : null;
10851             }
10852         }
10853         if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) {
10854             removeDataDirsLI(packageName);
10855             schedulePackageCleaning(packageName, UserHandle.USER_ALL, true);
10856         }
10857         // writer
10858         synchronized (mPackages) {
10859             if (deletedPs != null) {
10860                 if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) {
10861                     if (outInfo != null) {
10862                         mSettings.mKeySetManagerService.removeAppKeySetDataLPw(packageName);
10863                         outInfo.removedAppId = mSettings.removePackageLPw(packageName);
10864                     }
10865                     if (deletedPs != null) {
10866                         updatePermissionsLPw(deletedPs.name, null, 0);
10867                         if (deletedPs.sharedUser != null) {
10868                             // remove permissions associated with package
10869                             mSettings.updateSharedUserPermsLPw(deletedPs, mGlobalGids);
10870                         }
10871                     }
10872                     clearPackagePreferredActivitiesLPw(deletedPs.name, UserHandle.USER_ALL);
10873                 }
10874                 // make sure to preserve per-user disabled state if this removal was just
10875                 // a downgrade of a system app to the factory package
10876                 if (allUserHandles != null && perUserInstalled != null) {
10877                     if (DEBUG_REMOVE) {
10878                         Slog.d(TAG, "Propagating install state across downgrade");
10879                     }
10880                     for (int i = 0; i < allUserHandles.length; i++) {
10881                         if (DEBUG_REMOVE) {
10882                             Slog.d(TAG, "    user " + allUserHandles[i]
10883                                     + " => " + perUserInstalled[i]);
10884                         }
10885                         ps.setInstalled(perUserInstalled[i], allUserHandles[i]);
10886                     }
10887                 }
10888             }
10889             // can downgrade to reader
10890             if (writeSettings) {
10891                 // Save settings now
10892                 mSettings.writeLPr();
10893             }
10894         }
10895         if (outInfo != null) {
10896             // A user ID was deleted here. Go through all users and remove it
10897             // from KeyStore.
10898             removeKeystoreDataIfNeeded(UserHandle.USER_ALL, outInfo.removedAppId);
10899         }
10900     }
10901
10902     static boolean locationIsPrivileged(File path) {
10903         try {
10904             final String privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app")
10905                     .getCanonicalPath();
10906             return path.getCanonicalPath().startsWith(privilegedAppDir);
10907         } catch (IOException e) {
10908             Slog.e(TAG, "Unable to access code path " + path);
10909         }
10910         return false;
10911     }
10912
10913     /*
10914      * Tries to delete system package.
10915      */
10916     private boolean deleteSystemPackageLI(PackageSetting newPs,
10917             int[] allUserHandles, boolean[] perUserInstalled,
10918             int flags, PackageRemovedInfo outInfo, boolean writeSettings) {
10919         final boolean applyUserRestrictions
10920                 = (allUserHandles != null) && (perUserInstalled != null);
10921         PackageSetting disabledPs = null;
10922         // Confirm if the system package has been updated
10923         // An updated system app can be deleted. This will also have to restore
10924         // the system pkg from system partition
10925         // reader
10926         synchronized (mPackages) {
10927             disabledPs = mSettings.getDisabledSystemPkgLPr(newPs.name);
10928         }
10929         if (DEBUG_REMOVE) Slog.d(TAG, "deleteSystemPackageLI: newPs=" + newPs
10930                 + " disabledPs=" + disabledPs);
10931         if (disabledPs == null) {
10932             Slog.w(TAG, "Attempt to delete unknown system package "+ newPs.name);
10933             return false;
10934         } else if (DEBUG_REMOVE) {
10935             Slog.d(TAG, "Deleting system pkg from data partition");
10936         }
10937         if (DEBUG_REMOVE) {
10938             if (applyUserRestrictions) {
10939                 Slog.d(TAG, "Remembering install states:");
10940                 for (int i = 0; i < allUserHandles.length; i++) {
10941                     Slog.d(TAG, "   u=" + allUserHandles[i] + " inst=" + perUserInstalled[i]);
10942                 }
10943             }
10944         }
10945         // Delete the updated package
10946         outInfo.isRemovedPackageSystemUpdate = true;
10947         if (disabledPs.versionCode < newPs.versionCode) {
10948             // Delete data for downgrades
10949             flags &= ~PackageManager.DELETE_KEEP_DATA;
10950         } else {
10951             // Preserve data by setting flag
10952             flags |= PackageManager.DELETE_KEEP_DATA;
10953         }
10954         boolean ret = deleteInstalledPackageLI(newPs, true, flags,
10955                 allUserHandles, perUserInstalled, outInfo, writeSettings);
10956         if (!ret) {
10957             return false;
10958         }
10959         // writer
10960         synchronized (mPackages) {
10961             // Reinstate the old system package
10962             mSettings.enableSystemPackageLPw(newPs.name);
10963             // Remove any native libraries from the upgraded package.
10964             NativeLibraryHelper.removeNativeBinariesLI(newPs.legacyNativeLibraryPathString);
10965         }
10966         // Install the system package
10967         if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs);
10968         int parseFlags = PackageParser.PARSE_MUST_BE_APK | PackageParser.PARSE_IS_SYSTEM;
10969         if (locationIsPrivileged(disabledPs.codePath)) {
10970             parseFlags |= PackageParser.PARSE_IS_PRIVILEGED;
10971         }
10972
10973         final PackageParser.Package newPkg;
10974         try {
10975             newPkg = scanPackageLI(disabledPs.codePath, parseFlags, SCAN_NO_PATHS, 0, null);
10976         } catch (PackageManagerException e) {
10977             Slog.w(TAG, "Failed to restore system package:" + newPs.name + ": " + e.getMessage());
10978             return false;
10979         }
10980
10981         // writer
10982         synchronized (mPackages) {
10983             PackageSetting ps = mSettings.mPackages.get(newPkg.packageName);
10984             updatePermissionsLPw(newPkg.packageName, newPkg,
10985                     UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG);
10986             if (applyUserRestrictions) {
10987                 if (DEBUG_REMOVE) {
10988                     Slog.d(TAG, "Propagating install state across reinstall");
10989                 }
10990                 for (int i = 0; i < allUserHandles.length; i++) {
10991                     if (DEBUG_REMOVE) {
10992                         Slog.d(TAG, "    user " + allUserHandles[i]
10993                                 + " => " + perUserInstalled[i]);
10994                     }
10995                     ps.setInstalled(perUserInstalled[i], allUserHandles[i]);
10996                 }
10997                 // Regardless of writeSettings we need to ensure that this restriction
10998                 // state propagation is persisted
10999                 mSettings.writeAllUsersPackageRestrictionsLPr();
11000             }
11001             // can downgrade to reader here
11002             if (writeSettings) {
11003                 mSettings.writeLPr();
11004             }
11005         }
11006         return true;
11007     }
11008
11009     private boolean deleteInstalledPackageLI(PackageSetting ps,
11010             boolean deleteCodeAndResources, int flags,
11011             int[] allUserHandles, boolean[] perUserInstalled,
11012             PackageRemovedInfo outInfo, boolean writeSettings) {
11013         if (outInfo != null) {
11014             outInfo.uid = ps.appId;
11015         }
11016
11017         // Delete package data from internal structures and also remove data if flag is set
11018         removePackageDataLI(ps, allUserHandles, perUserInstalled, outInfo, flags, writeSettings);
11019
11020         // Delete application code and resources
11021         if (deleteCodeAndResources && (outInfo != null)) {
11022             outInfo.args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
11023                     ps.codePathString, ps.resourcePathString, ps.legacyNativeLibraryPathString,
11024                     getAppDexInstructionSets(ps));
11025             if (DEBUG_SD_INSTALL) Slog.i(TAG, "args=" + outInfo.args);
11026         }
11027         return true;
11028     }
11029
11030     @Override
11031     public boolean setBlockUninstallForUser(String packageName, boolean blockUninstall,
11032             int userId) {
11033         mContext.enforceCallingOrSelfPermission(
11034                 android.Manifest.permission.DELETE_PACKAGES, null);
11035         synchronized (mPackages) {
11036             PackageSetting ps = mSettings.mPackages.get(packageName);
11037             if (ps == null) {
11038                 Log.i(TAG, "Package doesn't exist in set block uninstall " + packageName);
11039                 return false;
11040             }
11041             if (!ps.getInstalled(userId)) {
11042                 // Can't block uninstall for an app that is not installed or enabled.
11043                 Log.i(TAG, "Package not installed in set block uninstall " + packageName);
11044                 return false;
11045             }
11046             ps.setBlockUninstall(blockUninstall, userId);
11047             mSettings.writePackageRestrictionsLPr(userId);
11048         }
11049         return true;
11050     }
11051
11052     @Override
11053     public boolean getBlockUninstallForUser(String packageName, int userId) {
11054         synchronized (mPackages) {
11055             PackageSetting ps = mSettings.mPackages.get(packageName);
11056             if (ps == null) {
11057                 Log.i(TAG, "Package doesn't exist in get block uninstall " + packageName);
11058                 return false;
11059             }
11060             return ps.getBlockUninstall(userId);
11061         }
11062     }
11063
11064     /*
11065      * This method handles package deletion in general
11066      */
11067     private boolean deletePackageLI(String packageName, UserHandle user,
11068             boolean deleteCodeAndResources, int[] allUserHandles, boolean[] perUserInstalled,
11069             int flags, PackageRemovedInfo outInfo,
11070             boolean writeSettings) {
11071         if (packageName == null) {
11072             Slog.w(TAG, "Attempt to delete null packageName.");
11073             return false;
11074         }
11075         if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: " + packageName + " user " + user);
11076         PackageSetting ps;
11077         boolean dataOnly = false;
11078         int removeUser = -1;
11079         int appId = -1;
11080         synchronized (mPackages) {
11081             ps = mSettings.mPackages.get(packageName);
11082             if (ps == null) {
11083                 Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
11084                 return false;
11085             }
11086             if ((!isSystemApp(ps) || (flags&PackageManager.DELETE_SYSTEM_APP) != 0) && user != null
11087                     && user.getIdentifier() != UserHandle.USER_ALL) {
11088                 // The caller is asking that the package only be deleted for a single
11089                 // user.  To do this, we just mark its uninstalled state and delete
11090                 // its data.  If this is a system app, we only allow this to happen if
11091                 // they have set the special DELETE_SYSTEM_APP which requests different
11092                 // semantics than normal for uninstalling system apps.
11093                 if (DEBUG_REMOVE) Slog.d(TAG, "Only deleting for single user");
11094                 ps.setUserState(user.getIdentifier(),
11095                         COMPONENT_ENABLED_STATE_DEFAULT,
11096                         false, //installed
11097                         true,  //stopped
11098                         true,  //notLaunched
11099                         false, //hidden
11100                         null, null, null,
11101                         false // blockUninstall
11102                         );
11103                 if (!isSystemApp(ps)) {
11104                     if (ps.isAnyInstalled(sUserManager.getUserIds())) {
11105                         // Other user still have this package installed, so all
11106                         // we need to do is clear this user's data and save that
11107                         // it is uninstalled.
11108                         if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users");
11109                         removeUser = user.getIdentifier();
11110                         appId = ps.appId;
11111                         mSettings.writePackageRestrictionsLPr(removeUser);
11112                     } else {
11113                         // We need to set it back to 'installed' so the uninstall
11114                         // broadcasts will be sent correctly.
11115                         if (DEBUG_REMOVE) Slog.d(TAG, "Not installed by other users, full delete");
11116                         ps.setInstalled(true, user.getIdentifier());
11117                     }
11118                 } else {
11119                     // This is a system app, so we assume that the
11120                     // other users still have this package installed, so all
11121                     // we need to do is clear this user's data and save that
11122                     // it is uninstalled.
11123                     if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app");
11124                     removeUser = user.getIdentifier();
11125                     appId = ps.appId;
11126                     mSettings.writePackageRestrictionsLPr(removeUser);
11127                 }
11128             }
11129         }
11130
11131         if (removeUser >= 0) {
11132             // From above, we determined that we are deleting this only
11133             // for a single user.  Continue the work here.
11134             if (DEBUG_REMOVE) Slog.d(TAG, "Updating install state for user: " + removeUser);
11135             if (outInfo != null) {
11136                 outInfo.removedPackage = packageName;
11137                 outInfo.removedAppId = appId;
11138                 outInfo.removedUsers = new int[] {removeUser};
11139             }
11140             mInstaller.clearUserData(packageName, removeUser);
11141             removeKeystoreDataIfNeeded(removeUser, appId);
11142             schedulePackageCleaning(packageName, removeUser, false);
11143             return true;
11144         }
11145
11146         if (dataOnly) {
11147             // Delete application data first
11148             if (DEBUG_REMOVE) Slog.d(TAG, "Removing package data only");
11149             removePackageDataLI(ps, null, null, outInfo, flags, writeSettings);
11150             return true;
11151         }
11152
11153         boolean ret = false;
11154         if (isSystemApp(ps)) {
11155             if (DEBUG_REMOVE) Slog.d(TAG, "Removing system package:" + ps.name);
11156             // When an updated system application is deleted we delete the existing resources as well and
11157             // fall back to existing code in system partition
11158             ret = deleteSystemPackageLI(ps, allUserHandles, perUserInstalled,
11159                     flags, outInfo, writeSettings);
11160         } else {
11161             if (DEBUG_REMOVE) Slog.d(TAG, "Removing non-system package:" + ps.name);
11162             // Kill application pre-emptively especially for apps on sd.
11163             killApplication(packageName, ps.appId, "uninstall pkg");
11164             ret = deleteInstalledPackageLI(ps, deleteCodeAndResources, flags,
11165                     allUserHandles, perUserInstalled,
11166                     outInfo, writeSettings);
11167         }
11168
11169         return ret;
11170     }
11171
11172     private final class ClearStorageConnection implements ServiceConnection {
11173         IMediaContainerService mContainerService;
11174
11175         @Override
11176         public void onServiceConnected(ComponentName name, IBinder service) {
11177             synchronized (this) {
11178                 mContainerService = IMediaContainerService.Stub.asInterface(service);
11179                 notifyAll();
11180             }
11181         }
11182
11183         @Override
11184         public void onServiceDisconnected(ComponentName name) {
11185         }
11186     }
11187
11188     private void clearExternalStorageDataSync(String packageName, int userId, boolean allData) {
11189         final boolean mounted;
11190         if (Environment.isExternalStorageEmulated()) {
11191             mounted = true;
11192         } else {
11193             final String status = Environment.getExternalStorageState();
11194
11195             mounted = status.equals(Environment.MEDIA_MOUNTED)
11196                     || status.equals(Environment.MEDIA_MOUNTED_READ_ONLY);
11197         }
11198
11199         if (!mounted) {
11200             return;
11201         }
11202
11203         final Intent containerIntent = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
11204         int[] users;
11205         if (userId == UserHandle.USER_ALL) {
11206             users = sUserManager.getUserIds();
11207         } else {
11208             users = new int[] { userId };
11209         }
11210         final ClearStorageConnection conn = new ClearStorageConnection();
11211         if (mContext.bindServiceAsUser(
11212                 containerIntent, conn, Context.BIND_AUTO_CREATE, UserHandle.OWNER)) {
11213             try {
11214                 for (int curUser : users) {
11215                     long timeout = SystemClock.uptimeMillis() + 5000;
11216                     synchronized (conn) {
11217                         long now = SystemClock.uptimeMillis();
11218                         while (conn.mContainerService == null && now < timeout) {
11219                             try {
11220                                 conn.wait(timeout - now);
11221                             } catch (InterruptedException e) {
11222                             }
11223                         }
11224                     }
11225                     if (conn.mContainerService == null) {
11226                         return;
11227                     }
11228
11229                     final UserEnvironment userEnv = new UserEnvironment(curUser);
11230                     clearDirectory(conn.mContainerService,
11231                             userEnv.buildExternalStorageAppCacheDirs(packageName));
11232                     if (allData) {
11233                         clearDirectory(conn.mContainerService,
11234                                 userEnv.buildExternalStorageAppDataDirs(packageName));
11235                         clearDirectory(conn.mContainerService,
11236                                 userEnv.buildExternalStorageAppMediaDirs(packageName));
11237                     }
11238                 }
11239             } finally {
11240                 mContext.unbindService(conn);
11241             }
11242         }
11243     }
11244
11245     @Override
11246     public void clearApplicationUserData(final String packageName,
11247             final IPackageDataObserver observer, final int userId) {
11248         mContext.enforceCallingOrSelfPermission(
11249                 android.Manifest.permission.CLEAR_APP_USER_DATA, null);
11250         enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, "clear application data");
11251         // Queue up an async operation since the package deletion may take a little while.
11252         mHandler.post(new Runnable() {
11253             public void run() {
11254                 mHandler.removeCallbacks(this);
11255                 final boolean succeeded;
11256                 synchronized (mInstallLock) {
11257                     succeeded = clearApplicationUserDataLI(packageName, userId);
11258                 }
11259                 clearExternalStorageDataSync(packageName, userId, true);
11260                 if (succeeded) {
11261                     // invoke DeviceStorageMonitor's update method to clear any notifications
11262                     DeviceStorageMonitorInternal
11263                             dsm = LocalServices.getService(DeviceStorageMonitorInternal.class);
11264                     if (dsm != null) {
11265                         dsm.checkMemory();
11266                     }
11267                 }
11268                 if(observer != null) {
11269                     try {
11270                         observer.onRemoveCompleted(packageName, succeeded);
11271                     } catch (RemoteException e) {
11272                         Log.i(TAG, "Observer no longer exists.");
11273                     }
11274                 } //end if observer
11275             } //end run
11276         });
11277     }
11278
11279     private boolean clearApplicationUserDataLI(String packageName, int userId) {
11280         if (packageName == null) {
11281             Slog.w(TAG, "Attempt to delete null packageName.");
11282             return false;
11283         }
11284
11285         // Try finding details about the requested package
11286         PackageParser.Package pkg;
11287         synchronized (mPackages) {
11288             pkg = mPackages.get(packageName);
11289             if (pkg == null) {
11290                 final PackageSetting ps = mSettings.mPackages.get(packageName);
11291                 if (ps != null) {
11292                     pkg = ps.pkg;
11293                 }
11294             }
11295         }
11296
11297         if (pkg == null) {
11298             Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
11299         }
11300
11301         // Always delete data directories for package, even if we found no other
11302         // record of app. This helps users recover from UID mismatches without
11303         // resorting to a full data wipe.
11304         int retCode = mInstaller.clearUserData(packageName, userId);
11305         if (retCode < 0) {
11306             Slog.w(TAG, "Couldn't remove cache files for package: " + packageName);
11307             return false;
11308         }
11309
11310         if (pkg == null) {
11311             return false;
11312         }
11313
11314         if (pkg != null && pkg.applicationInfo != null) {
11315             final int appId = pkg.applicationInfo.uid;
11316             removeKeystoreDataIfNeeded(userId, appId);
11317         }
11318
11319         // Create a native library symlink only if we have native libraries
11320         // and if the native libraries are 32 bit libraries. We do not provide
11321         // this symlink for 64 bit libraries.
11322         if (pkg != null && pkg.applicationInfo.primaryCpuAbi != null &&
11323                 !VMRuntime.is64BitAbi(pkg.applicationInfo.primaryCpuAbi)) {
11324             final String nativeLibPath = pkg.applicationInfo.nativeLibraryDir;
11325             if (mInstaller.linkNativeLibraryDirectory(pkg.packageName, nativeLibPath, userId) < 0) {
11326                 Slog.w(TAG, "Failed linking native library dir");
11327                 return false;
11328             }
11329         }
11330
11331         return true;
11332     }
11333
11334     /**
11335      * Remove entries from the keystore daemon. Will only remove it if the
11336      * {@code appId} is valid.
11337      */
11338     private static void removeKeystoreDataIfNeeded(int userId, int appId) {
11339         if (appId < 0) {
11340             return;
11341         }
11342
11343         final KeyStore keyStore = KeyStore.getInstance();
11344         if (keyStore != null) {
11345             if (userId == UserHandle.USER_ALL) {
11346                 for (final int individual : sUserManager.getUserIds()) {
11347                     keyStore.clearUid(UserHandle.getUid(individual, appId));
11348                 }
11349             } else {
11350                 keyStore.clearUid(UserHandle.getUid(userId, appId));
11351             }
11352         } else {
11353             Slog.w(TAG, "Could not contact keystore to clear entries for app id " + appId);
11354         }
11355     }
11356
11357     @Override
11358     public void deleteApplicationCacheFiles(final String packageName,
11359             final IPackageDataObserver observer) {
11360         mContext.enforceCallingOrSelfPermission(
11361                 android.Manifest.permission.DELETE_CACHE_FILES, null);
11362         // Queue up an async operation since the package deletion may take a little while.
11363         final int userId = UserHandle.getCallingUserId();
11364         mHandler.post(new Runnable() {
11365             public void run() {
11366                 mHandler.removeCallbacks(this);
11367                 final boolean succeded;
11368                 synchronized (mInstallLock) {
11369                     succeded = deleteApplicationCacheFilesLI(packageName, userId);
11370                 }
11371                 clearExternalStorageDataSync(packageName, userId, false);
11372                 if(observer != null) {
11373                     try {
11374                         observer.onRemoveCompleted(packageName, succeded);
11375                     } catch (RemoteException e) {
11376                         Log.i(TAG, "Observer no longer exists.");
11377                     }
11378                 } //end if observer
11379             } //end run
11380         });
11381     }
11382
11383     private boolean deleteApplicationCacheFilesLI(String packageName, int userId) {
11384         if (packageName == null) {
11385             Slog.w(TAG, "Attempt to delete null packageName.");
11386             return false;
11387         }
11388         PackageParser.Package p;
11389         synchronized (mPackages) {
11390             p = mPackages.get(packageName);
11391         }
11392         if (p == null) {
11393             Slog.w(TAG, "Package named '" + packageName +"' doesn't exist.");
11394             return false;
11395         }
11396         final ApplicationInfo applicationInfo = p.applicationInfo;
11397         if (applicationInfo == null) {
11398             Slog.w(TAG, "Package " + packageName + " has no applicationInfo.");
11399             return false;
11400         }
11401         int retCode = mInstaller.deleteCacheFiles(packageName, userId);
11402         if (retCode < 0) {
11403             Slog.w(TAG, "Couldn't remove cache files for package: "
11404                        + packageName + " u" + userId);
11405             return false;
11406         }
11407         return true;
11408     }
11409
11410     @Override
11411     public void getPackageSizeInfo(final String packageName, int userHandle,
11412             final IPackageStatsObserver observer) {
11413         mContext.enforceCallingOrSelfPermission(
11414                 android.Manifest.permission.GET_PACKAGE_SIZE, null);
11415         if (packageName == null) {
11416             throw new IllegalArgumentException("Attempt to get size of null packageName");
11417         }
11418
11419         PackageStats stats = new PackageStats(packageName, userHandle);
11420
11421         /*
11422          * Queue up an async operation since the package measurement may take a
11423          * little while.
11424          */
11425         Message msg = mHandler.obtainMessage(INIT_COPY);
11426         msg.obj = new MeasureParams(stats, observer);
11427         mHandler.sendMessage(msg);
11428     }
11429
11430     private boolean getPackageSizeInfoLI(String packageName, int userHandle,
11431             PackageStats pStats) {
11432         if (packageName == null) {
11433             Slog.w(TAG, "Attempt to get size of null packageName.");
11434             return false;
11435         }
11436         PackageParser.Package p;
11437         boolean dataOnly = false;
11438         String libDirRoot = null;
11439         String asecPath = null;
11440         PackageSetting ps = null;
11441         synchronized (mPackages) {
11442             p = mPackages.get(packageName);
11443             ps = mSettings.mPackages.get(packageName);
11444             if(p == null) {
11445                 dataOnly = true;
11446                 if((ps == null) || (ps.pkg == null)) {
11447                     Slog.w(TAG, "Package named '" + packageName +"' doesn't exist.");
11448                     return false;
11449                 }
11450                 p = ps.pkg;
11451             }
11452             if (ps != null) {
11453                 libDirRoot = ps.legacyNativeLibraryPathString;
11454             }
11455             if (p != null && (isExternal(p) || isForwardLocked(p))) {
11456                 String secureContainerId = cidFromCodePath(p.applicationInfo.getBaseCodePath());
11457                 if (secureContainerId != null) {
11458                     asecPath = PackageHelper.getSdFilesystem(secureContainerId);
11459                 }
11460             }
11461         }
11462         String publicSrcDir = null;
11463         if(!dataOnly) {
11464             final ApplicationInfo applicationInfo = p.applicationInfo;
11465             if (applicationInfo == null) {
11466                 Slog.w(TAG, "Package " + packageName + " has no applicationInfo.");
11467                 return false;
11468             }
11469             if (isForwardLocked(p)) {
11470                 publicSrcDir = applicationInfo.getBaseResourcePath();
11471             }
11472         }
11473         // TODO: extend to measure size of split APKs
11474         // TODO(multiArch): Extend getSizeInfo to look at the full subdirectory tree,
11475         // not just the first level.
11476         // TODO(multiArch): Extend getSizeInfo to look at *all* instruction sets, not
11477         // just the primary.
11478         String[] dexCodeInstructionSets = getDexCodeInstructionSets(getAppDexInstructionSets(ps));
11479         int res = mInstaller.getSizeInfo(packageName, userHandle, p.baseCodePath, libDirRoot,
11480                 publicSrcDir, asecPath, dexCodeInstructionSets, pStats);
11481         if (res < 0) {
11482             return false;
11483         }
11484
11485         // Fix-up for forward-locked applications in ASEC containers.
11486         if (!isExternal(p)) {
11487             pStats.codeSize += pStats.externalCodeSize;
11488             pStats.externalCodeSize = 0L;
11489         }
11490
11491         return true;
11492     }
11493
11494
11495     @Override
11496     public void addPackageToPreferred(String packageName) {
11497         Slog.w(TAG, "addPackageToPreferred: this is now a no-op");
11498     }
11499
11500     @Override
11501     public void removePackageFromPreferred(String packageName) {
11502         Slog.w(TAG, "removePackageFromPreferred: this is now a no-op");
11503     }
11504
11505     @Override
11506     public List<PackageInfo> getPreferredPackages(int flags) {
11507         return new ArrayList<PackageInfo>();
11508     }
11509
11510     private int getUidTargetSdkVersionLockedLPr(int uid) {
11511         Object obj = mSettings.getUserIdLPr(uid);
11512         if (obj instanceof SharedUserSetting) {
11513             final SharedUserSetting sus = (SharedUserSetting) obj;
11514             int vers = Build.VERSION_CODES.CUR_DEVELOPMENT;
11515             final Iterator<PackageSetting> it = sus.packages.iterator();
11516             while (it.hasNext()) {
11517                 final PackageSetting ps = it.next();
11518                 if (ps.pkg != null) {
11519                     int v = ps.pkg.applicationInfo.targetSdkVersion;
11520                     if (v < vers) vers = v;
11521                 }
11522             }
11523             return vers;
11524         } else if (obj instanceof PackageSetting) {
11525             final PackageSetting ps = (PackageSetting) obj;
11526             if (ps.pkg != null) {
11527                 return ps.pkg.applicationInfo.targetSdkVersion;
11528             }
11529         }
11530         return Build.VERSION_CODES.CUR_DEVELOPMENT;
11531     }
11532
11533     @Override
11534     public void addPreferredActivity(IntentFilter filter, int match,
11535             ComponentName[] set, ComponentName activity, int userId) {
11536         addPreferredActivityInternal(filter, match, set, activity, true, userId,
11537                 "Adding preferred");
11538     }
11539
11540     private void addPreferredActivityInternal(IntentFilter filter, int match,
11541             ComponentName[] set, ComponentName activity, boolean always, int userId,
11542             String opname) {
11543         // writer
11544         int callingUid = Binder.getCallingUid();
11545         enforceCrossUserPermission(callingUid, userId, true, false, "add preferred activity");
11546         if (filter.countActions() == 0) {
11547             Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
11548             return;
11549         }
11550         synchronized (mPackages) {
11551             if (mContext.checkCallingOrSelfPermission(
11552                     android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
11553                     != PackageManager.PERMISSION_GRANTED) {
11554                 if (getUidTargetSdkVersionLockedLPr(callingUid)
11555                         < Build.VERSION_CODES.FROYO) {
11556                     Slog.w(TAG, "Ignoring addPreferredActivity() from uid "
11557                             + callingUid);
11558                     return;
11559                 }
11560                 mContext.enforceCallingOrSelfPermission(
11561                         android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
11562             }
11563
11564             PreferredIntentResolver pir = mSettings.editPreferredActivitiesLPw(userId);
11565             Slog.i(TAG, opname + " activity " + activity.flattenToShortString() + " for user "
11566                     + userId + ":");
11567             filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
11568             pir.addFilter(new PreferredActivity(filter, match, set, activity, always));
11569             scheduleWritePackageRestrictionsLocked(userId);
11570         }
11571     }
11572
11573     @Override
11574     public void replacePreferredActivity(IntentFilter filter, int match,
11575             ComponentName[] set, ComponentName activity, int userId) {
11576         if (filter.countActions() != 1) {
11577             throw new IllegalArgumentException(
11578                     "replacePreferredActivity expects filter to have only 1 action.");
11579         }
11580         if (filter.countDataAuthorities() != 0
11581                 || filter.countDataPaths() != 0
11582                 || filter.countDataSchemes() > 1
11583                 || filter.countDataTypes() != 0) {
11584             throw new IllegalArgumentException(
11585                     "replacePreferredActivity expects filter to have no data authorities, " +
11586                     "paths, or types; and at most one scheme.");
11587         }
11588
11589         final int callingUid = Binder.getCallingUid();
11590         enforceCrossUserPermission(callingUid, userId, true, false, "replace preferred activity");
11591         synchronized (mPackages) {
11592             if (mContext.checkCallingOrSelfPermission(
11593                     android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
11594                     != PackageManager.PERMISSION_GRANTED) {
11595                 if (getUidTargetSdkVersionLockedLPr(callingUid)
11596                         < Build.VERSION_CODES.FROYO) {
11597                     Slog.w(TAG, "Ignoring replacePreferredActivity() from uid "
11598                             + Binder.getCallingUid());
11599                     return;
11600                 }
11601                 mContext.enforceCallingOrSelfPermission(
11602                         android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
11603             }
11604
11605             PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
11606             if (pir != null) {
11607                 // Get all of the existing entries that exactly match this filter.
11608                 ArrayList<PreferredActivity> existing = pir.findFilters(filter);
11609                 if (existing != null && existing.size() == 1) {
11610                     PreferredActivity cur = existing.get(0);
11611                     if (DEBUG_PREFERRED) {
11612                         Slog.i(TAG, "Checking replace of preferred:");
11613                         filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
11614                         if (!cur.mPref.mAlways) {
11615                             Slog.i(TAG, "  -- CUR; not mAlways!");
11616                         } else {
11617                             Slog.i(TAG, "  -- CUR: mMatch=" + cur.mPref.mMatch);
11618                             Slog.i(TAG, "  -- CUR: mSet="
11619                                     + Arrays.toString(cur.mPref.mSetComponents));
11620                             Slog.i(TAG, "  -- CUR: mComponent=" + cur.mPref.mShortComponent);
11621                             Slog.i(TAG, "  -- NEW: mMatch="
11622                                     + (match&IntentFilter.MATCH_CATEGORY_MASK));
11623                             Slog.i(TAG, "  -- CUR: mSet=" + Arrays.toString(set));
11624                             Slog.i(TAG, "  -- CUR: mComponent=" + activity.flattenToShortString());
11625                         }
11626                     }
11627                     if (cur.mPref.mAlways && cur.mPref.mComponent.equals(activity)
11628                             && cur.mPref.mMatch == (match&IntentFilter.MATCH_CATEGORY_MASK)
11629                             && cur.mPref.sameSet(set)) {
11630                         // Setting the preferred activity to what it happens to be already
11631                         if (DEBUG_PREFERRED) {
11632                             Slog.i(TAG, "Replacing with same preferred activity "
11633                                     + cur.mPref.mShortComponent + " for user "
11634                                     + userId + ":");
11635                             filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
11636                         }
11637                         return;
11638                     }
11639                 }
11640
11641                 if (existing != null) {
11642                     if (DEBUG_PREFERRED) {
11643                         Slog.i(TAG, existing.size() + " existing preferred matches for:");
11644                         filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
11645                     }
11646                     for (int i = 0; i < existing.size(); i++) {
11647                         PreferredActivity pa = existing.get(i);
11648                         if (DEBUG_PREFERRED) {
11649                             Slog.i(TAG, "Removing existing preferred activity "
11650                                     + pa.mPref.mComponent + ":");
11651                             pa.dump(new LogPrinter(Log.INFO, TAG), "  ");
11652                         }
11653                         pir.removeFilter(pa);
11654                     }
11655                 }
11656             }
11657             addPreferredActivityInternal(filter, match, set, activity, true, userId,
11658                     "Replacing preferred");
11659         }
11660     }
11661
11662     @Override
11663     public void clearPackagePreferredActivities(String packageName) {
11664         final int uid = Binder.getCallingUid();
11665         // writer
11666         synchronized (mPackages) {
11667             PackageParser.Package pkg = mPackages.get(packageName);
11668             if (pkg == null || pkg.applicationInfo.uid != uid) {
11669                 if (mContext.checkCallingOrSelfPermission(
11670                         android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
11671                         != PackageManager.PERMISSION_GRANTED) {
11672                     if (getUidTargetSdkVersionLockedLPr(Binder.getCallingUid())
11673                             < Build.VERSION_CODES.FROYO) {
11674                         Slog.w(TAG, "Ignoring clearPackagePreferredActivities() from uid "
11675                                 + Binder.getCallingUid());
11676                         return;
11677                     }
11678                     mContext.enforceCallingOrSelfPermission(
11679                             android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
11680                 }
11681             }
11682
11683             int user = UserHandle.getCallingUserId();
11684             if (clearPackagePreferredActivitiesLPw(packageName, user)) {
11685                 scheduleWritePackageRestrictionsLocked(user);
11686             }
11687         }
11688     }
11689
11690     /** This method takes a specific user id as well as UserHandle.USER_ALL. */
11691     boolean clearPackagePreferredActivitiesLPw(String packageName, int userId) {
11692         ArrayList<PreferredActivity> removed = null;
11693         boolean changed = false;
11694         for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
11695             final int thisUserId = mSettings.mPreferredActivities.keyAt(i);
11696             PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
11697             if (userId != UserHandle.USER_ALL && userId != thisUserId) {
11698                 continue;
11699             }
11700             Iterator<PreferredActivity> it = pir.filterIterator();
11701             while (it.hasNext()) {
11702                 PreferredActivity pa = it.next();
11703                 // Mark entry for removal only if it matches the package name
11704                 // and the entry is of type "always".
11705                 if (packageName == null ||
11706                         (pa.mPref.mComponent.getPackageName().equals(packageName)
11707                                 && pa.mPref.mAlways)) {
11708                     if (removed == null) {
11709                         removed = new ArrayList<PreferredActivity>();
11710                     }
11711                     removed.add(pa);
11712                 }
11713             }
11714             if (removed != null) {
11715                 for (int j=0; j<removed.size(); j++) {
11716                     PreferredActivity pa = removed.get(j);
11717                     pir.removeFilter(pa);
11718                 }
11719                 changed = true;
11720             }
11721         }
11722         return changed;
11723     }
11724
11725     @Override
11726     public void resetPreferredActivities(int userId) {
11727         /* TODO: Actually use userId. Why is it being passed in? */
11728         mContext.enforceCallingOrSelfPermission(
11729                 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
11730         // writer
11731         synchronized (mPackages) {
11732             int user = UserHandle.getCallingUserId();
11733             clearPackagePreferredActivitiesLPw(null, user);
11734             mSettings.readDefaultPreferredAppsLPw(this, user);
11735             scheduleWritePackageRestrictionsLocked(user);
11736         }
11737     }
11738
11739     @Override
11740     public int getPreferredActivities(List<IntentFilter> outFilters,
11741             List<ComponentName> outActivities, String packageName) {
11742
11743         int num = 0;
11744         final int userId = UserHandle.getCallingUserId();
11745         // reader
11746         synchronized (mPackages) {
11747             PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
11748             if (pir != null) {
11749                 final Iterator<PreferredActivity> it = pir.filterIterator();
11750                 while (it.hasNext()) {
11751                     final PreferredActivity pa = it.next();
11752                     if (packageName == null
11753                             || (pa.mPref.mComponent.getPackageName().equals(packageName)
11754                                     && pa.mPref.mAlways)) {
11755                         if (outFilters != null) {
11756                             outFilters.add(new IntentFilter(pa));
11757                         }
11758                         if (outActivities != null) {
11759                             outActivities.add(pa.mPref.mComponent);
11760                         }
11761                     }
11762                 }
11763             }
11764         }
11765
11766         return num;
11767     }
11768
11769     @Override
11770     public void addPersistentPreferredActivity(IntentFilter filter, ComponentName activity,
11771             int userId) {
11772         int callingUid = Binder.getCallingUid();
11773         if (callingUid != Process.SYSTEM_UID) {
11774             throw new SecurityException(
11775                     "addPersistentPreferredActivity can only be run by the system");
11776         }
11777         if (filter.countActions() == 0) {
11778             Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
11779             return;
11780         }
11781         synchronized (mPackages) {
11782             Slog.i(TAG, "Adding persistent preferred activity " + activity + " for user " + userId +
11783                     " :");
11784             filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
11785             mSettings.editPersistentPreferredActivitiesLPw(userId).addFilter(
11786                     new PersistentPreferredActivity(filter, activity));
11787             scheduleWritePackageRestrictionsLocked(userId);
11788         }
11789     }
11790
11791     @Override
11792     public void clearPackagePersistentPreferredActivities(String packageName, int userId) {
11793         int callingUid = Binder.getCallingUid();
11794         if (callingUid != Process.SYSTEM_UID) {
11795             throw new SecurityException(
11796                     "clearPackagePersistentPreferredActivities can only be run by the system");
11797         }
11798         ArrayList<PersistentPreferredActivity> removed = null;
11799         boolean changed = false;
11800         synchronized (mPackages) {
11801             for (int i=0; i<mSettings.mPersistentPreferredActivities.size(); i++) {
11802                 final int thisUserId = mSettings.mPersistentPreferredActivities.keyAt(i);
11803                 PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
11804                         .valueAt(i);
11805                 if (userId != thisUserId) {
11806                     continue;
11807                 }
11808                 Iterator<PersistentPreferredActivity> it = ppir.filterIterator();
11809                 while (it.hasNext()) {
11810                     PersistentPreferredActivity ppa = it.next();
11811                     // Mark entry for removal only if it matches the package name.
11812                     if (ppa.mComponent.getPackageName().equals(packageName)) {
11813                         if (removed == null) {
11814                             removed = new ArrayList<PersistentPreferredActivity>();
11815                         }
11816                         removed.add(ppa);
11817                     }
11818                 }
11819                 if (removed != null) {
11820                     for (int j=0; j<removed.size(); j++) {
11821                         PersistentPreferredActivity ppa = removed.get(j);
11822                         ppir.removeFilter(ppa);
11823                     }
11824                     changed = true;
11825                 }
11826             }
11827
11828             if (changed) {
11829                 scheduleWritePackageRestrictionsLocked(userId);
11830             }
11831         }
11832     }
11833
11834     @Override
11835     public void addCrossProfileIntentFilter(IntentFilter intentFilter, String ownerPackage,
11836             int ownerUserId, int sourceUserId, int targetUserId, int flags) {
11837         mContext.enforceCallingOrSelfPermission(
11838                         android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
11839         int callingUid = Binder.getCallingUid();
11840         enforceOwnerRights(ownerPackage, ownerUserId, callingUid);
11841         enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
11842         if (intentFilter.countActions() == 0) {
11843             Slog.w(TAG, "Cannot set a crossProfile intent filter with no filter actions");
11844             return;
11845         }
11846         synchronized (mPackages) {
11847             CrossProfileIntentFilter newFilter = new CrossProfileIntentFilter(intentFilter,
11848                     ownerPackage, UserHandle.getUserId(callingUid), targetUserId, flags);
11849             CrossProfileIntentResolver resolver =
11850                     mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
11851             ArrayList<CrossProfileIntentFilter> existing = resolver.findFilters(intentFilter);
11852             // We have all those whose filter is equal. Now checking if the rest is equal as well.
11853             if (existing != null) {
11854                 int size = existing.size();
11855                 for (int i = 0; i < size; i++) {
11856                     if (newFilter.equalsIgnoreFilter(existing.get(i))) {
11857                         return;
11858                     }
11859                 }
11860             }
11861             resolver.addFilter(newFilter);
11862             scheduleWritePackageRestrictionsLocked(sourceUserId);
11863         }
11864     }
11865
11866     @Override
11867     public void clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage,
11868             int ownerUserId) {
11869         mContext.enforceCallingOrSelfPermission(
11870                         android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
11871         int callingUid = Binder.getCallingUid();
11872         enforceOwnerRights(ownerPackage, ownerUserId, callingUid);
11873         enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
11874         int callingUserId = UserHandle.getUserId(callingUid);
11875         synchronized (mPackages) {
11876             CrossProfileIntentResolver resolver =
11877                     mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
11878             ArraySet<CrossProfileIntentFilter> set =
11879                     new ArraySet<CrossProfileIntentFilter>(resolver.filterSet());
11880             for (CrossProfileIntentFilter filter : set) {
11881                 if (filter.getOwnerPackage().equals(ownerPackage)
11882                         && filter.getOwnerUserId() == callingUserId) {
11883                     resolver.removeFilter(filter);
11884                 }
11885             }
11886             scheduleWritePackageRestrictionsLocked(sourceUserId);
11887         }
11888     }
11889
11890     // Enforcing that callingUid is owning pkg on userId
11891     private void enforceOwnerRights(String pkg, int userId, int callingUid) {
11892         // The system owns everything.
11893         if (UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) {
11894             return;
11895         }
11896         int callingUserId = UserHandle.getUserId(callingUid);
11897         if (callingUserId != userId) {
11898             throw new SecurityException("calling uid " + callingUid
11899                     + " pretends to own " + pkg + " on user " + userId + " but belongs to user "
11900                     + callingUserId);
11901         }
11902         PackageInfo pi = getPackageInfo(pkg, 0, callingUserId);
11903         if (pi == null) {
11904             throw new IllegalArgumentException("Unknown package " + pkg + " on user "
11905                     + callingUserId);
11906         }
11907         if (!UserHandle.isSameApp(pi.applicationInfo.uid, callingUid)) {
11908             throw new SecurityException("Calling uid " + callingUid
11909                     + " does not own package " + pkg);
11910         }
11911     }
11912
11913     @Override
11914     public ComponentName getHomeActivities(List<ResolveInfo> allHomeCandidates) {
11915         Intent intent = new Intent(Intent.ACTION_MAIN);
11916         intent.addCategory(Intent.CATEGORY_HOME);
11917
11918         final int callingUserId = UserHandle.getCallingUserId();
11919         List<ResolveInfo> list = queryIntentActivities(intent, null,
11920                 PackageManager.GET_META_DATA, callingUserId);
11921         ResolveInfo preferred = findPreferredActivity(intent, null, 0, list, 0,
11922                 true, false, false, callingUserId);
11923
11924         allHomeCandidates.clear();
11925         if (list != null) {
11926             for (ResolveInfo ri : list) {
11927                 allHomeCandidates.add(ri);
11928             }
11929         }
11930         return (preferred == null || preferred.activityInfo == null)
11931                 ? null
11932                 : new ComponentName(preferred.activityInfo.packageName,
11933                         preferred.activityInfo.name);
11934     }
11935
11936     @Override
11937     public void setApplicationEnabledSetting(String appPackageName,
11938             int newState, int flags, int userId, String callingPackage) {
11939         if (!sUserManager.exists(userId)) return;
11940         if (callingPackage == null) {
11941             callingPackage = Integer.toString(Binder.getCallingUid());
11942         }
11943         setEnabledSetting(appPackageName, null, newState, flags, userId, callingPackage);
11944     }
11945
11946     @Override
11947     public void setComponentEnabledSetting(ComponentName componentName,
11948             int newState, int flags, int userId) {
11949         if (!sUserManager.exists(userId)) return;
11950         setEnabledSetting(componentName.getPackageName(),
11951                 componentName.getClassName(), newState, flags, userId, null);
11952     }
11953
11954     private void setEnabledSetting(final String packageName, String className, int newState,
11955             final int flags, int userId, String callingPackage) {
11956         if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT
11957               || newState == COMPONENT_ENABLED_STATE_ENABLED
11958               || newState == COMPONENT_ENABLED_STATE_DISABLED
11959               || newState == COMPONENT_ENABLED_STATE_DISABLED_USER
11960               || newState == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED)) {
11961             throw new IllegalArgumentException("Invalid new component state: "
11962                     + newState);
11963         }
11964         PackageSetting pkgSetting;
11965         final int uid = Binder.getCallingUid();
11966         final int permission = mContext.checkCallingOrSelfPermission(
11967                 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
11968         enforceCrossUserPermission(uid, userId, false, true, "set enabled");
11969         final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
11970         boolean sendNow = false;
11971         boolean isApp = (className == null);
11972         String componentName = isApp ? packageName : className;
11973         int packageUid = -1;
11974         ArrayList<String> components;
11975
11976         // writer
11977         synchronized (mPackages) {
11978             pkgSetting = mSettings.mPackages.get(packageName);
11979             if (pkgSetting == null) {
11980                 if (className == null) {
11981                     throw new IllegalArgumentException(
11982                             "Unknown package: " + packageName);
11983                 }
11984                 throw new IllegalArgumentException(
11985                         "Unknown component: " + packageName
11986                         + "/" + className);
11987             }
11988             // Allow root and verify that userId is not being specified by a different user
11989             if (!allowedByPermission && !UserHandle.isSameApp(uid, pkgSetting.appId)) {
11990                 throw new SecurityException(
11991                         "Permission Denial: attempt to change component state from pid="
11992                         + Binder.getCallingPid()
11993                         + ", uid=" + uid + ", package uid=" + pkgSetting.appId);
11994             }
11995             if (className == null) {
11996                 // We're dealing with an application/package level state change
11997                 if (pkgSetting.getEnabled(userId) == newState) {
11998                     // Nothing to do
11999                     return;
12000                 }
12001                 if (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
12002                     || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {
12003                     // Don't care about who enables an app.
12004                     callingPackage = null;
12005                 }
12006                 pkgSetting.setEnabled(newState, userId, callingPackage);
12007                 // pkgSetting.pkg.mSetEnabled = newState;
12008             } else {
12009                 // We're dealing with a component level state change
12010                 // First, verify that this is a valid class name.
12011                 PackageParser.Package pkg = pkgSetting.pkg;
12012                 if (pkg == null || !pkg.hasComponentClassName(className)) {
12013                     if (pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.JELLY_BEAN) {
12014                         throw new IllegalArgumentException("Component class " + className
12015                                 + " does not exist in " + packageName);
12016                     } else {
12017                         Slog.w(TAG, "Failed setComponentEnabledSetting: component class "
12018                                 + className + " does not exist in " + packageName);
12019                     }
12020                 }
12021                 switch (newState) {
12022                 case COMPONENT_ENABLED_STATE_ENABLED:
12023                     if (!pkgSetting.enableComponentLPw(className, userId)) {
12024                         return;
12025                     }
12026                     break;
12027                 case COMPONENT_ENABLED_STATE_DISABLED:
12028                     if (!pkgSetting.disableComponentLPw(className, userId)) {
12029                         return;
12030                     }
12031                     break;
12032                 case COMPONENT_ENABLED_STATE_DEFAULT:
12033                     if (!pkgSetting.restoreComponentLPw(className, userId)) {
12034                         return;
12035                     }
12036                     break;
12037                 default:
12038                     Slog.e(TAG, "Invalid new component state: " + newState);
12039                     return;
12040                 }
12041             }
12042             mSettings.writePackageRestrictionsLPr(userId);
12043             components = mPendingBroadcasts.get(userId, packageName);
12044             final boolean newPackage = components == null;
12045             if (newPackage) {
12046                 components = new ArrayList<String>();
12047             }
12048             if (!components.contains(componentName)) {
12049                 components.add(componentName);
12050             }
12051             if ((flags&PackageManager.DONT_KILL_APP) == 0) {
12052                 sendNow = true;
12053                 // Purge entry from pending broadcast list if another one exists already
12054                 // since we are sending one right away.
12055                 mPendingBroadcasts.remove(userId, packageName);
12056             } else {
12057                 if (newPackage) {
12058                     mPendingBroadcasts.put(userId, packageName, components);
12059                 }
12060                 if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) {
12061                     // Schedule a message
12062                     mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, BROADCAST_DELAY);
12063                 }
12064             }
12065         }
12066
12067         long callingId = Binder.clearCallingIdentity();
12068         try {
12069             if (sendNow) {
12070                 packageUid = UserHandle.getUid(userId, pkgSetting.appId);
12071                 sendPackageChangedBroadcast(packageName,
12072                         (flags&PackageManager.DONT_KILL_APP) != 0, components, packageUid);
12073             }
12074         } finally {
12075             Binder.restoreCallingIdentity(callingId);
12076         }
12077     }
12078
12079     private void sendPackageChangedBroadcast(String packageName,
12080             boolean killFlag, ArrayList<String> componentNames, int packageUid) {
12081         if (DEBUG_INSTALL)
12082             Log.v(TAG, "Sending package changed: package=" + packageName + " components="
12083                     + componentNames);
12084         Bundle extras = new Bundle(4);
12085         extras.putString(Intent.EXTRA_CHANGED_COMPONENT_NAME, componentNames.get(0));
12086         String nameList[] = new String[componentNames.size()];
12087         componentNames.toArray(nameList);
12088         extras.putStringArray(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST, nameList);
12089         extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, killFlag);
12090         extras.putInt(Intent.EXTRA_UID, packageUid);
12091         sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED,  packageName, extras, null, null,
12092                 new int[] {UserHandle.getUserId(packageUid)});
12093     }
12094
12095     @Override
12096     public void setPackageStoppedState(String packageName, boolean stopped, int userId) {
12097         if (!sUserManager.exists(userId)) return;
12098         final int uid = Binder.getCallingUid();
12099         final int permission = mContext.checkCallingOrSelfPermission(
12100                 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
12101         final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
12102         enforceCrossUserPermission(uid, userId, true, true, "stop package");
12103         // writer
12104         synchronized (mPackages) {
12105             if (mSettings.setPackageStoppedStateLPw(packageName, stopped, allowedByPermission,
12106                     uid, userId)) {
12107                 scheduleWritePackageRestrictionsLocked(userId);
12108             }
12109         }
12110     }
12111
12112     @Override
12113     public String getInstallerPackageName(String packageName) {
12114         // reader
12115         synchronized (mPackages) {
12116             return mSettings.getInstallerPackageNameLPr(packageName);
12117         }
12118     }
12119
12120     @Override
12121     public int getApplicationEnabledSetting(String packageName, int userId) {
12122         if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
12123         int uid = Binder.getCallingUid();
12124         enforceCrossUserPermission(uid, userId, false, false, "get enabled");
12125         // reader
12126         synchronized (mPackages) {
12127             return mSettings.getApplicationEnabledSettingLPr(packageName, userId);
12128         }
12129     }
12130
12131     @Override
12132     public int getComponentEnabledSetting(ComponentName componentName, int userId) {
12133         if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
12134         int uid = Binder.getCallingUid();
12135         enforceCrossUserPermission(uid, userId, false, false, "get component enabled");
12136         // reader
12137         synchronized (mPackages) {
12138             return mSettings.getComponentEnabledSettingLPr(componentName, userId);
12139         }
12140     }
12141
12142     @Override
12143     public void enterSafeMode() {
12144         enforceSystemOrRoot("Only the system can request entering safe mode");
12145
12146         if (!mSystemReady) {
12147             mSafeMode = true;
12148         }
12149     }
12150
12151     @Override
12152     public void systemReady() {
12153         mSystemReady = true;
12154
12155         // Read the compatibilty setting when the system is ready.
12156         boolean compatibilityModeEnabled = android.provider.Settings.Global.getInt(
12157                 mContext.getContentResolver(),
12158                 android.provider.Settings.Global.COMPATIBILITY_MODE, 1) == 1;
12159         PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled);
12160         if (DEBUG_SETTINGS) {
12161             Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled);
12162         }
12163
12164         synchronized (mPackages) {
12165             // Verify that all of the preferred activity components actually
12166             // exist.  It is possible for applications to be updated and at
12167             // that point remove a previously declared activity component that
12168             // had been set as a preferred activity.  We try to clean this up
12169             // the next time we encounter that preferred activity, but it is
12170             // possible for the user flow to never be able to return to that
12171             // situation so here we do a sanity check to make sure we haven't
12172             // left any junk around.
12173             ArrayList<PreferredActivity> removed = new ArrayList<PreferredActivity>();
12174             for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
12175                 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
12176                 removed.clear();
12177                 for (PreferredActivity pa : pir.filterSet()) {
12178                     if (mActivities.mActivities.get(pa.mPref.mComponent) == null) {
12179                         removed.add(pa);
12180                     }
12181                 }
12182                 if (removed.size() > 0) {
12183                     for (int r=0; r<removed.size(); r++) {
12184                         PreferredActivity pa = removed.get(r);
12185                         Slog.w(TAG, "Removing dangling preferred activity: "
12186                                 + pa.mPref.mComponent);
12187                         pir.removeFilter(pa);
12188                     }
12189                     mSettings.writePackageRestrictionsLPr(
12190                             mSettings.mPreferredActivities.keyAt(i));
12191                 }
12192             }
12193         }
12194         sUserManager.systemReady();
12195
12196         // Kick off any messages waiting for system ready
12197         if (mPostSystemReadyMessages != null) {
12198             for (Message msg : mPostSystemReadyMessages) {
12199                 msg.sendToTarget();
12200             }
12201             mPostSystemReadyMessages = null;
12202         }
12203     }
12204
12205     @Override
12206     public boolean isSafeMode() {
12207         return mSafeMode;
12208     }
12209
12210     @Override
12211     public boolean hasSystemUidErrors() {
12212         return mHasSystemUidErrors;
12213     }
12214
12215     static String arrayToString(int[] array) {
12216         StringBuffer buf = new StringBuffer(128);
12217         buf.append('[');
12218         if (array != null) {
12219             for (int i=0; i<array.length; i++) {
12220                 if (i > 0) buf.append(", ");
12221                 buf.append(array[i]);
12222             }
12223         }
12224         buf.append(']');
12225         return buf.toString();
12226     }
12227
12228     static class DumpState {
12229         public static final int DUMP_LIBS = 1 << 0;
12230         public static final int DUMP_FEATURES = 1 << 1;
12231         public static final int DUMP_RESOLVERS = 1 << 2;
12232         public static final int DUMP_PERMISSIONS = 1 << 3;
12233         public static final int DUMP_PACKAGES = 1 << 4;
12234         public static final int DUMP_SHARED_USERS = 1 << 5;
12235         public static final int DUMP_MESSAGES = 1 << 6;
12236         public static final int DUMP_PROVIDERS = 1 << 7;
12237         public static final int DUMP_VERIFIERS = 1 << 8;
12238         public static final int DUMP_PREFERRED = 1 << 9;
12239         public static final int DUMP_PREFERRED_XML = 1 << 10;
12240         public static final int DUMP_KEYSETS = 1 << 11;
12241         public static final int DUMP_VERSION = 1 << 12;
12242         public static final int DUMP_INSTALLS = 1 << 13;
12243
12244         public static final int OPTION_SHOW_FILTERS = 1 << 0;
12245
12246         private int mTypes;
12247
12248         private int mOptions;
12249
12250         private boolean mTitlePrinted;
12251
12252         private SharedUserSetting mSharedUser;
12253
12254         public boolean isDumping(int type) {
12255             if (mTypes == 0 && type != DUMP_PREFERRED_XML) {
12256                 return true;
12257             }
12258
12259             return (mTypes & type) != 0;
12260         }
12261
12262         public void setDump(int type) {
12263             mTypes |= type;
12264         }
12265
12266         public boolean isOptionEnabled(int option) {
12267             return (mOptions & option) != 0;
12268         }
12269
12270         public void setOptionEnabled(int option) {
12271             mOptions |= option;
12272         }
12273
12274         public boolean onTitlePrinted() {
12275             final boolean printed = mTitlePrinted;
12276             mTitlePrinted = true;
12277             return printed;
12278         }
12279
12280         public boolean getTitlePrinted() {
12281             return mTitlePrinted;
12282         }
12283
12284         public void setTitlePrinted(boolean enabled) {
12285             mTitlePrinted = enabled;
12286         }
12287
12288         public SharedUserSetting getSharedUser() {
12289             return mSharedUser;
12290         }
12291
12292         public void setSharedUser(SharedUserSetting user) {
12293             mSharedUser = user;
12294         }
12295     }
12296
12297     @Override
12298     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12299         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
12300                 != PackageManager.PERMISSION_GRANTED) {
12301             pw.println("Permission Denial: can't dump ActivityManager from from pid="
12302                     + Binder.getCallingPid()
12303                     + ", uid=" + Binder.getCallingUid()
12304                     + " without permission "
12305                     + android.Manifest.permission.DUMP);
12306             return;
12307         }
12308
12309         DumpState dumpState = new DumpState();
12310         boolean fullPreferred = false;
12311         boolean checkin = false;
12312
12313         String packageName = null;
12314         
12315         int opti = 0;
12316         while (opti < args.length) {
12317             String opt = args[opti];
12318             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12319                 break;
12320             }
12321             opti++;
12322
12323             if ("-a".equals(opt)) {
12324                 // Right now we only know how to print all.
12325             } else if ("-h".equals(opt)) {
12326                 pw.println("Package manager dump options:");
12327                 pw.println("  [-h] [-f] [--checkin] [cmd] ...");
12328                 pw.println("    --checkin: dump for a checkin");
12329                 pw.println("    -f: print details of intent filters");
12330                 pw.println("    -h: print this help");
12331                 pw.println("  cmd may be one of:");
12332                 pw.println("    l[ibraries]: list known shared libraries");
12333                 pw.println("    f[ibraries]: list device features");
12334                 pw.println("    k[eysets]: print known keysets");
12335                 pw.println("    r[esolvers]: dump intent resolvers");
12336                 pw.println("    perm[issions]: dump permissions");
12337                 pw.println("    pref[erred]: print preferred package settings");
12338                 pw.println("    preferred-xml [--full]: print preferred package settings as xml");
12339                 pw.println("    prov[iders]: dump content providers");
12340                 pw.println("    p[ackages]: dump installed packages");
12341                 pw.println("    s[hared-users]: dump shared user IDs");
12342                 pw.println("    m[essages]: print collected runtime messages");
12343                 pw.println("    v[erifiers]: print package verifier info");
12344                 pw.println("    version: print database version info");
12345                 pw.println("    write: write current settings now");
12346                 pw.println("    <package.name>: info about given package");
12347                 pw.println("    installs: details about install sessions");
12348                 return;
12349             } else if ("--checkin".equals(opt)) {
12350                 checkin = true;
12351             } else if ("-f".equals(opt)) {
12352                 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
12353             } else {
12354                 pw.println("Unknown argument: " + opt + "; use -h for help");
12355             }
12356         }
12357
12358         // Is the caller requesting to dump a particular piece of data?
12359         if (opti < args.length) {
12360             String cmd = args[opti];
12361             opti++;
12362             // Is this a package name?
12363             if ("android".equals(cmd) || cmd.contains(".")) {
12364                 packageName = cmd;
12365                 // When dumping a single package, we always dump all of its
12366                 // filter information since the amount of data will be reasonable.
12367                 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
12368             } else if ("l".equals(cmd) || "libraries".equals(cmd)) {
12369                 dumpState.setDump(DumpState.DUMP_LIBS);
12370             } else if ("f".equals(cmd) || "features".equals(cmd)) {
12371                 dumpState.setDump(DumpState.DUMP_FEATURES);
12372             } else if ("r".equals(cmd) || "resolvers".equals(cmd)) {
12373                 dumpState.setDump(DumpState.DUMP_RESOLVERS);
12374             } else if ("perm".equals(cmd) || "permissions".equals(cmd)) {
12375                 dumpState.setDump(DumpState.DUMP_PERMISSIONS);
12376             } else if ("pref".equals(cmd) || "preferred".equals(cmd)) {
12377                 dumpState.setDump(DumpState.DUMP_PREFERRED);
12378             } else if ("preferred-xml".equals(cmd)) {
12379                 dumpState.setDump(DumpState.DUMP_PREFERRED_XML);
12380                 if (opti < args.length && "--full".equals(args[opti])) {
12381                     fullPreferred = true;
12382                     opti++;
12383                 }
12384             } else if ("p".equals(cmd) || "packages".equals(cmd)) {
12385                 dumpState.setDump(DumpState.DUMP_PACKAGES);
12386             } else if ("s".equals(cmd) || "shared-users".equals(cmd)) {
12387                 dumpState.setDump(DumpState.DUMP_SHARED_USERS);
12388             } else if ("prov".equals(cmd) || "providers".equals(cmd)) {
12389                 dumpState.setDump(DumpState.DUMP_PROVIDERS);
12390             } else if ("m".equals(cmd) || "messages".equals(cmd)) {
12391                 dumpState.setDump(DumpState.DUMP_MESSAGES);
12392             } else if ("v".equals(cmd) || "verifiers".equals(cmd)) {
12393                 dumpState.setDump(DumpState.DUMP_VERIFIERS);
12394             } else if ("version".equals(cmd)) {
12395                 dumpState.setDump(DumpState.DUMP_VERSION);
12396             } else if ("k".equals(cmd) || "keysets".equals(cmd)) {
12397                 dumpState.setDump(DumpState.DUMP_KEYSETS);
12398             } else if ("installs".equals(cmd)) {
12399                 dumpState.setDump(DumpState.DUMP_INSTALLS);
12400             } else if ("write".equals(cmd)) {
12401                 synchronized (mPackages) {
12402                     mSettings.writeLPr();
12403                     pw.println("Settings written.");
12404                     return;
12405                 }
12406             }
12407         }
12408
12409         if (checkin) {
12410             pw.println("vers,1");
12411         }
12412
12413         // reader
12414         synchronized (mPackages) {
12415             if (dumpState.isDumping(DumpState.DUMP_VERSION) && packageName == null) {
12416                 if (!checkin) {
12417                     if (dumpState.onTitlePrinted())
12418                         pw.println();
12419                     pw.println("Database versions:");
12420                     pw.print("  SDK Version:");
12421                     pw.print(" internal=");
12422                     pw.print(mSettings.mInternalSdkPlatform);
12423                     pw.print(" external=");
12424                     pw.println(mSettings.mExternalSdkPlatform);
12425                     pw.print("  DB Version:");
12426                     pw.print(" internal=");
12427                     pw.print(mSettings.mInternalDatabaseVersion);
12428                     pw.print(" external=");
12429                     pw.println(mSettings.mExternalDatabaseVersion);
12430                 }
12431             }
12432
12433             if (dumpState.isDumping(DumpState.DUMP_VERIFIERS) && packageName == null) {
12434                 if (!checkin) {
12435                     if (dumpState.onTitlePrinted())
12436                         pw.println();
12437                     pw.println("Verifiers:");
12438                     pw.print("  Required: ");
12439                     pw.print(mRequiredVerifierPackage);
12440                     pw.print(" (uid=");
12441                     pw.print(getPackageUid(mRequiredVerifierPackage, 0));
12442                     pw.println(")");
12443                 } else if (mRequiredVerifierPackage != null) {
12444                     pw.print("vrfy,"); pw.print(mRequiredVerifierPackage);
12445                     pw.print(","); pw.println(getPackageUid(mRequiredVerifierPackage, 0));
12446                 }
12447             }
12448
12449             if (dumpState.isDumping(DumpState.DUMP_LIBS) && packageName == null) {
12450                 boolean printedHeader = false;
12451                 final Iterator<String> it = mSharedLibraries.keySet().iterator();
12452                 while (it.hasNext()) {
12453                     String name = it.next();
12454                     SharedLibraryEntry ent = mSharedLibraries.get(name);
12455                     if (!checkin) {
12456                         if (!printedHeader) {
12457                             if (dumpState.onTitlePrinted())
12458                                 pw.println();
12459                             pw.println("Libraries:");
12460                             printedHeader = true;
12461                         }
12462                         pw.print("  ");
12463                     } else {
12464                         pw.print("lib,");
12465                     }
12466                     pw.print(name);
12467                     if (!checkin) {
12468                         pw.print(" -> ");
12469                     }
12470                     if (ent.path != null) {
12471                         if (!checkin) {
12472                             pw.print("(jar) ");
12473                             pw.print(ent.path);
12474                         } else {
12475                             pw.print(",jar,");
12476                             pw.print(ent.path);
12477                         }
12478                     } else {
12479                         if (!checkin) {
12480                             pw.print("(apk) ");
12481                             pw.print(ent.apk);
12482                         } else {
12483                             pw.print(",apk,");
12484                             pw.print(ent.apk);
12485                         }
12486                     }
12487                     pw.println();
12488                 }
12489             }
12490
12491             if (dumpState.isDumping(DumpState.DUMP_FEATURES) && packageName == null) {
12492                 if (dumpState.onTitlePrinted())
12493                     pw.println();
12494                 if (!checkin) {
12495                     pw.println("Features:");
12496                 }
12497                 Iterator<String> it = mAvailableFeatures.keySet().iterator();
12498                 while (it.hasNext()) {
12499                     String name = it.next();
12500                     if (!checkin) {
12501                         pw.print("  ");
12502                     } else {
12503                         pw.print("feat,");
12504                     }
12505                     pw.println(name);
12506                 }
12507             }
12508
12509             if (!checkin && dumpState.isDumping(DumpState.DUMP_RESOLVERS)) {
12510                 if (mActivities.dump(pw, dumpState.getTitlePrinted() ? "\nActivity Resolver Table:"
12511                         : "Activity Resolver Table:", "  ", packageName,
12512                         dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS))) {
12513                     dumpState.setTitlePrinted(true);
12514                 }
12515                 if (mReceivers.dump(pw, dumpState.getTitlePrinted() ? "\nReceiver Resolver Table:"
12516                         : "Receiver Resolver Table:", "  ", packageName,
12517                         dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS))) {
12518                     dumpState.setTitlePrinted(true);
12519                 }
12520                 if (mServices.dump(pw, dumpState.getTitlePrinted() ? "\nService Resolver Table:"
12521                         : "Service Resolver Table:", "  ", packageName,
12522                         dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS))) {
12523                     dumpState.setTitlePrinted(true);
12524                 }
12525                 if (mProviders.dump(pw, dumpState.getTitlePrinted() ? "\nProvider Resolver Table:"
12526                         : "Provider Resolver Table:", "  ", packageName,
12527                         dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS))) {
12528                     dumpState.setTitlePrinted(true);
12529                 }
12530             }
12531
12532             if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED)) {
12533                 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
12534                     PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
12535                     int user = mSettings.mPreferredActivities.keyAt(i);
12536                     if (pir.dump(pw,
12537                             dumpState.getTitlePrinted()
12538                                 ? "\nPreferred Activities User " + user + ":"
12539                                 : "Preferred Activities User " + user + ":", "  ",
12540                             packageName, true)) {
12541                         dumpState.setTitlePrinted(true);
12542                     }
12543                 }
12544             }
12545
12546             if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED_XML)) {
12547                 pw.flush();
12548                 FileOutputStream fout = new FileOutputStream(fd);
12549                 BufferedOutputStream str = new BufferedOutputStream(fout);
12550                 XmlSerializer serializer = new FastXmlSerializer();
12551                 try {
12552                     serializer.setOutput(str, "utf-8");
12553                     serializer.startDocument(null, true);
12554                     serializer.setFeature(
12555                             "http://xmlpull.org/v1/doc/features.html#indent-output", true);
12556                     mSettings.writePreferredActivitiesLPr(serializer, 0, fullPreferred);
12557                     serializer.endDocument();
12558                     serializer.flush();
12559                 } catch (IllegalArgumentException e) {
12560                     pw.println("Failed writing: " + e);
12561                 } catch (IllegalStateException e) {
12562                     pw.println("Failed writing: " + e);
12563                 } catch (IOException e) {
12564                     pw.println("Failed writing: " + e);
12565                 }
12566             }
12567
12568             if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) {
12569                 mSettings.dumpPermissionsLPr(pw, packageName, dumpState);
12570                 if (packageName == null) {
12571                     for (int iperm=0; iperm<mAppOpPermissionPackages.size(); iperm++) {
12572                         if (iperm == 0) {
12573                             if (dumpState.onTitlePrinted())
12574                                 pw.println();
12575                             pw.println("AppOp Permissions:");
12576                         }
12577                         pw.print("  AppOp Permission ");
12578                         pw.print(mAppOpPermissionPackages.keyAt(iperm));
12579                         pw.println(":");
12580                         ArraySet<String> pkgs = mAppOpPermissionPackages.valueAt(iperm);
12581                         for (int ipkg=0; ipkg<pkgs.size(); ipkg++) {
12582                             pw.print("    "); pw.println(pkgs.valueAt(ipkg));
12583                         }
12584                     }
12585                 }
12586             }
12587
12588             if (!checkin && dumpState.isDumping(DumpState.DUMP_PROVIDERS)) {
12589                 boolean printedSomething = false;
12590                 for (PackageParser.Provider p : mProviders.mProviders.values()) {
12591                     if (packageName != null && !packageName.equals(p.info.packageName)) {
12592                         continue;
12593                     }
12594                     if (!printedSomething) {
12595                         if (dumpState.onTitlePrinted())
12596                             pw.println();
12597                         pw.println("Registered ContentProviders:");
12598                         printedSomething = true;
12599                     }
12600                     pw.print("  "); p.printComponentShortName(pw); pw.println(":");
12601                     pw.print("    "); pw.println(p.toString());
12602                 }
12603                 printedSomething = false;
12604                 for (Map.Entry<String, PackageParser.Provider> entry :
12605                         mProvidersByAuthority.entrySet()) {
12606                     PackageParser.Provider p = entry.getValue();
12607                     if (packageName != null && !packageName.equals(p.info.packageName)) {
12608                         continue;
12609                     }
12610                     if (!printedSomething) {
12611                         if (dumpState.onTitlePrinted())
12612                             pw.println();
12613                         pw.println("ContentProvider Authorities:");
12614                         printedSomething = true;
12615                     }
12616                     pw.print("  ["); pw.print(entry.getKey()); pw.println("]:");
12617                     pw.print("    "); pw.println(p.toString());
12618                     if (p.info != null && p.info.applicationInfo != null) {
12619                         final String appInfo = p.info.applicationInfo.toString();
12620                         pw.print("      applicationInfo="); pw.println(appInfo);
12621                     }
12622                 }
12623             }
12624
12625             if (!checkin && dumpState.isDumping(DumpState.DUMP_KEYSETS)) {
12626                 mSettings.mKeySetManagerService.dumpLPr(pw, packageName, dumpState);
12627             }
12628
12629             if (dumpState.isDumping(DumpState.DUMP_PACKAGES)) {
12630                 mSettings.dumpPackagesLPr(pw, packageName, dumpState, checkin);
12631             }
12632
12633             if (!checkin && dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) {
12634                 mSettings.dumpSharedUsersLPr(pw, packageName, dumpState);
12635             }
12636
12637             if (!checkin && dumpState.isDumping(DumpState.DUMP_INSTALLS) && packageName == null) {
12638                 // XXX should handle packageName != null by dumping only install data that
12639                 // the given package is involved with.
12640                 if (dumpState.onTitlePrinted()) pw.println();
12641                 mInstallerService.dump(new IndentingPrintWriter(pw, "  ", 120));
12642             }
12643
12644             if (!checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES) && packageName == null) {
12645                 if (dumpState.onTitlePrinted()) pw.println();
12646                 mSettings.dumpReadMessagesLPr(pw, dumpState);
12647
12648                 pw.println();
12649                 pw.println("Package warning messages:");
12650                 final File fname = getSettingsProblemFile();
12651                 FileInputStream in = null;
12652                 try {
12653                     in = new FileInputStream(fname);
12654                     final int avail = in.available();
12655                     final byte[] data = new byte[avail];
12656                     in.read(data);
12657                     pw.print(new String(data));
12658                 } catch (FileNotFoundException e) {
12659                 } catch (IOException e) {
12660                 } finally {
12661                     if (in != null) {
12662                         try {
12663                             in.close();
12664                         } catch (IOException e) {
12665                         }
12666                     }
12667                 }
12668             }
12669
12670             if (checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES)) {
12671                 BufferedReader in = null;
12672                 String line = null;
12673                 try {
12674                     in = new BufferedReader(new FileReader(getSettingsProblemFile()));
12675                     while ((line = in.readLine()) != null) {
12676                         pw.print("msg,");
12677                         pw.println(line);
12678                     }
12679                 } catch (IOException ignored) {
12680                 } finally {
12681                     IoUtils.closeQuietly(in);
12682                 }
12683             }
12684         }
12685     }
12686
12687     // ------- apps on sdcard specific code -------
12688     static final boolean DEBUG_SD_INSTALL = false;
12689
12690     private static final String SD_ENCRYPTION_KEYSTORE_NAME = "AppsOnSD";
12691
12692     private static final String SD_ENCRYPTION_ALGORITHM = "AES";
12693
12694     private boolean mMediaMounted = false;
12695
12696     static String getEncryptKey() {
12697         try {
12698             String sdEncKey = SystemKeyStore.getInstance().retrieveKeyHexString(
12699                     SD_ENCRYPTION_KEYSTORE_NAME);
12700             if (sdEncKey == null) {
12701                 sdEncKey = SystemKeyStore.getInstance().generateNewKeyHexString(128,
12702                         SD_ENCRYPTION_ALGORITHM, SD_ENCRYPTION_KEYSTORE_NAME);
12703                 if (sdEncKey == null) {
12704                     Slog.e(TAG, "Failed to create encryption keys");
12705                     return null;
12706                 }
12707             }
12708             return sdEncKey;
12709         } catch (NoSuchAlgorithmException nsae) {
12710             Slog.e(TAG, "Failed to create encryption keys with exception: " + nsae);
12711             return null;
12712         } catch (IOException ioe) {
12713             Slog.e(TAG, "Failed to retrieve encryption keys with exception: " + ioe);
12714             return null;
12715         }
12716     }
12717
12718     /*
12719      * Update media status on PackageManager.
12720      */
12721     @Override
12722     public void updateExternalMediaStatus(final boolean mediaStatus, final boolean reportStatus) {
12723         int callingUid = Binder.getCallingUid();
12724         if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
12725             throw new SecurityException("Media status can only be updated by the system");
12726         }
12727         // reader; this apparently protects mMediaMounted, but should probably
12728         // be a different lock in that case.
12729         synchronized (mPackages) {
12730             Log.i(TAG, "Updating external media status from "
12731                     + (mMediaMounted ? "mounted" : "unmounted") + " to "
12732                     + (mediaStatus ? "mounted" : "unmounted"));
12733             if (DEBUG_SD_INSTALL)
12734                 Log.i(TAG, "updateExternalMediaStatus:: mediaStatus=" + mediaStatus
12735                         + ", mMediaMounted=" + mMediaMounted);
12736             if (mediaStatus == mMediaMounted) {
12737                 final Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1
12738                         : 0, -1);
12739                 mHandler.sendMessage(msg);
12740                 return;
12741             }
12742             mMediaMounted = mediaStatus;
12743         }
12744         // Queue up an async operation since the package installation may take a
12745         // little while.
12746         mHandler.post(new Runnable() {
12747             public void run() {
12748                 updateExternalMediaStatusInner(mediaStatus, reportStatus, true);
12749             }
12750         });
12751     }
12752
12753     /**
12754      * Called by MountService when the initial ASECs to scan are available.
12755      * Should block until all the ASEC containers are finished being scanned.
12756      */
12757     public void scanAvailableAsecs() {
12758         updateExternalMediaStatusInner(true, false, false);
12759         if (mShouldRestoreconData) {
12760             SELinuxMMAC.setRestoreconDone();
12761             mShouldRestoreconData = false;
12762         }
12763     }
12764
12765     /*
12766      * Collect information of applications on external media, map them against
12767      * existing containers and update information based on current mount status.
12768      * Please note that we always have to report status if reportStatus has been
12769      * set to true especially when unloading packages.
12770      */
12771     private void updateExternalMediaStatusInner(boolean isMounted, boolean reportStatus,
12772             boolean externalStorage) {
12773         ArrayMap<AsecInstallArgs, String> processCids = new ArrayMap<>();
12774         int[] uidArr = EmptyArray.INT;
12775
12776         final String[] list = PackageHelper.getSecureContainerList();
12777         if (ArrayUtils.isEmpty(list)) {
12778             Log.i(TAG, "No secure containers found");
12779         } else {
12780             // Process list of secure containers and categorize them
12781             // as active or stale based on their package internal state.
12782
12783             // reader
12784             synchronized (mPackages) {
12785                 for (String cid : list) {
12786                     // Leave stages untouched for now; installer service owns them
12787                     if (PackageInstallerService.isStageName(cid)) continue;
12788
12789                     if (DEBUG_SD_INSTALL)
12790                         Log.i(TAG, "Processing container " + cid);
12791                     String pkgName = getAsecPackageName(cid);
12792                     if (pkgName == null) {
12793                         Slog.i(TAG, "Found stale container " + cid + " with no package name");
12794                         continue;
12795                     }
12796                     if (DEBUG_SD_INSTALL)
12797                         Log.i(TAG, "Looking for pkg : " + pkgName);
12798
12799                     final PackageSetting ps = mSettings.mPackages.get(pkgName);
12800                     if (ps == null) {
12801                         Slog.i(TAG, "Found stale container " + cid + " with no matching settings");
12802                         continue;
12803                     }
12804
12805                     /*
12806                      * Skip packages that are not external if we're unmounting
12807                      * external storage.
12808                      */
12809                     if (externalStorage && !isMounted && !isExternal(ps)) {
12810                         continue;
12811                     }
12812
12813                     final AsecInstallArgs args = new AsecInstallArgs(cid,
12814                             getAppDexInstructionSets(ps), isForwardLocked(ps));
12815                     // The package status is changed only if the code path
12816                     // matches between settings and the container id.
12817                     if (ps.codePathString != null
12818                             && ps.codePathString.startsWith(args.getCodePath())) {
12819                         if (DEBUG_SD_INSTALL) {
12820                             Log.i(TAG, "Container : " + cid + " corresponds to pkg : " + pkgName
12821                                     + " at code path: " + ps.codePathString);
12822                         }
12823
12824                         // We do have a valid package installed on sdcard
12825                         processCids.put(args, ps.codePathString);
12826                         final int uid = ps.appId;
12827                         if (uid != -1) {
12828                             uidArr = ArrayUtils.appendInt(uidArr, uid);
12829                         }
12830                     } else {
12831                         Slog.i(TAG, "Found stale container " + cid + ": expected codePath="
12832                                 + ps.codePathString);
12833                     }
12834                 }
12835             }
12836
12837             Arrays.sort(uidArr);
12838         }
12839
12840         // Process packages with valid entries.
12841         if (isMounted) {
12842             if (DEBUG_SD_INSTALL)
12843                 Log.i(TAG, "Loading packages");
12844             loadMediaPackages(processCids, uidArr);
12845             startCleaningPackages();
12846             mInstallerService.onSecureContainersAvailable();
12847         } else {
12848             if (DEBUG_SD_INSTALL)
12849                 Log.i(TAG, "Unloading packages");
12850             unloadMediaPackages(processCids, uidArr, reportStatus);
12851         }
12852     }
12853
12854     private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
12855             ArrayList<String> pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
12856         int size = pkgList.size();
12857         if (size > 0) {
12858             // Send broadcasts here
12859             Bundle extras = new Bundle();
12860             extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList
12861                     .toArray(new String[size]));
12862             if (uidArr != null) {
12863                 extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidArr);
12864             }
12865             if (replacing) {
12866                 extras.putBoolean(Intent.EXTRA_REPLACING, replacing);
12867             }
12868             String action = mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE
12869                     : Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE;
12870             sendPackageBroadcast(action, null, extras, null, finishedReceiver, null);
12871         }
12872     }
12873
12874    /*
12875      * Look at potentially valid container ids from processCids If package
12876      * information doesn't match the one on record or package scanning fails,
12877      * the cid is added to list of removeCids. We currently don't delete stale
12878      * containers.
12879      */
12880     private void loadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int[] uidArr) {
12881         ArrayList<String> pkgList = new ArrayList<String>();
12882         Set<AsecInstallArgs> keys = processCids.keySet();
12883
12884         for (AsecInstallArgs args : keys) {
12885             String codePath = processCids.get(args);
12886             if (DEBUG_SD_INSTALL)
12887                 Log.i(TAG, "Loading container : " + args.cid);
12888             int retCode = PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
12889             try {
12890                 // Make sure there are no container errors first.
12891                 if (args.doPreInstall(PackageManager.INSTALL_SUCCEEDED) != PackageManager.INSTALL_SUCCEEDED) {
12892                     Slog.e(TAG, "Failed to mount cid : " + args.cid
12893                             + " when installing from sdcard");
12894                     continue;
12895                 }
12896                 // Check code path here.
12897                 if (codePath == null || !codePath.startsWith(args.getCodePath())) {
12898                     Slog.e(TAG, "Container " + args.cid + " cachepath " + args.getCodePath()
12899                             + " does not match one in settings " + codePath);
12900                     continue;
12901                 }
12902                 // Parse package
12903                 int parseFlags = mDefParseFlags;
12904                 if (args.isExternal()) {
12905                     parseFlags |= PackageParser.PARSE_ON_SDCARD;
12906                 }
12907                 if (args.isFwdLocked()) {
12908                     parseFlags |= PackageParser.PARSE_FORWARD_LOCK;
12909                 }
12910
12911                 synchronized (mInstallLock) {
12912                     PackageParser.Package pkg = null;
12913                     try {
12914                         pkg = scanPackageLI(new File(codePath), parseFlags, 0, 0, null);
12915                     } catch (PackageManagerException e) {
12916                         Slog.w(TAG, "Failed to scan " + codePath + ": " + e.getMessage());
12917                     }
12918                     // Scan the package
12919                     if (pkg != null) {
12920                         /*
12921                          * TODO why is the lock being held? doPostInstall is
12922                          * called in other places without the lock. This needs
12923                          * to be straightened out.
12924                          */
12925                         // writer
12926                         synchronized (mPackages) {
12927                             retCode = PackageManager.INSTALL_SUCCEEDED;
12928                             pkgList.add(pkg.packageName);
12929                             // Post process args
12930                             args.doPostInstall(PackageManager.INSTALL_SUCCEEDED,
12931                                     pkg.applicationInfo.uid);
12932                         }
12933                     } else {
12934                         Slog.i(TAG, "Failed to install pkg from  " + codePath + " from sdcard");
12935                     }
12936                 }
12937
12938             } finally {
12939                 if (retCode != PackageManager.INSTALL_SUCCEEDED) {
12940                     Log.w(TAG, "Container " + args.cid + " is stale, retCode=" + retCode);
12941                 }
12942             }
12943         }
12944         // writer
12945         synchronized (mPackages) {
12946             // If the platform SDK has changed since the last time we booted,
12947             // we need to re-grant app permission to catch any new ones that
12948             // appear. This is really a hack, and means that apps can in some
12949             // cases get permissions that the user didn't initially explicitly
12950             // allow... it would be nice to have some better way to handle
12951             // this situation.
12952             final boolean regrantPermissions = mSettings.mExternalSdkPlatform != mSdkVersion;
12953             if (regrantPermissions)
12954                 Slog.i(TAG, "Platform changed from " + mSettings.mExternalSdkPlatform + " to "
12955                         + mSdkVersion + "; regranting permissions for external storage");
12956             mSettings.mExternalSdkPlatform = mSdkVersion;
12957
12958             // Make sure group IDs have been assigned, and any permission
12959             // changes in other apps are accounted for
12960             updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL
12961                     | (regrantPermissions
12962                             ? (UPDATE_PERMISSIONS_REPLACE_PKG|UPDATE_PERMISSIONS_REPLACE_ALL)
12963                             : 0));
12964
12965             mSettings.updateExternalDatabaseVersion();
12966
12967             // can downgrade to reader
12968             // Persist settings
12969             mSettings.writeLPr();
12970         }
12971         // Send a broadcast to let everyone know we are done processing
12972         if (pkgList.size() > 0) {
12973             sendResourcesChangedBroadcast(true, false, pkgList, uidArr, null);
12974         }
12975     }
12976
12977    /*
12978      * Utility method to unload a list of specified containers
12979      */
12980     private void unloadAllContainers(Set<AsecInstallArgs> cidArgs) {
12981         // Just unmount all valid containers.
12982         for (AsecInstallArgs arg : cidArgs) {
12983             synchronized (mInstallLock) {
12984                 arg.doPostDeleteLI(false);
12985            }
12986        }
12987    }
12988
12989     /*
12990      * Unload packages mounted on external media. This involves deleting package
12991      * data from internal structures, sending broadcasts about diabled packages,
12992      * gc'ing to free up references, unmounting all secure containers
12993      * corresponding to packages on external media, and posting a
12994      * UPDATED_MEDIA_STATUS message if status has been requested. Please note
12995      * that we always have to post this message if status has been requested no
12996      * matter what.
12997      */
12998     private void unloadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int uidArr[],
12999             final boolean reportStatus) {
13000         if (DEBUG_SD_INSTALL)
13001             Log.i(TAG, "unloading media packages");
13002         ArrayList<String> pkgList = new ArrayList<String>();
13003         ArrayList<AsecInstallArgs> failedList = new ArrayList<AsecInstallArgs>();
13004         final Set<AsecInstallArgs> keys = processCids.keySet();
13005         for (AsecInstallArgs args : keys) {
13006             String pkgName = args.getPackageName();
13007             if (DEBUG_SD_INSTALL)
13008                 Log.i(TAG, "Trying to unload pkg : " + pkgName);
13009             // Delete package internally
13010             PackageRemovedInfo outInfo = new PackageRemovedInfo();
13011             synchronized (mInstallLock) {
13012                 boolean res = deletePackageLI(pkgName, null, false, null, null,
13013                         PackageManager.DELETE_KEEP_DATA, outInfo, false);
13014                 if (res) {
13015                     pkgList.add(pkgName);
13016                 } else {
13017                     Slog.e(TAG, "Failed to delete pkg from sdcard : " + pkgName);
13018                     failedList.add(args);
13019                 }
13020             }
13021         }
13022
13023         // reader
13024         synchronized (mPackages) {
13025             // We didn't update the settings after removing each package;
13026             // write them now for all packages.
13027             mSettings.writeLPr();
13028         }
13029
13030         // We have to absolutely send UPDATED_MEDIA_STATUS only
13031         // after confirming that all the receivers processed the ordered
13032         // broadcast when packages get disabled, force a gc to clean things up.
13033         // and unload all the containers.
13034         if (pkgList.size() > 0) {
13035             sendResourcesChangedBroadcast(false, false, pkgList, uidArr,
13036                     new IIntentReceiver.Stub() {
13037                 public void performReceive(Intent intent, int resultCode, String data,
13038                         Bundle extras, boolean ordered, boolean sticky,
13039                         int sendingUser) throws RemoteException {
13040                     Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS,
13041                             reportStatus ? 1 : 0, 1, keys);
13042                     mHandler.sendMessage(msg);
13043                 }
13044             });
13045         } else {
13046             Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1 : 0, -1,
13047                     keys);
13048             mHandler.sendMessage(msg);
13049         }
13050     }
13051
13052     /** Binder call */
13053     @Override
13054     public void movePackage(final String packageName, final IPackageMoveObserver observer,
13055             final int flags) {
13056         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
13057         UserHandle user = new UserHandle(UserHandle.getCallingUserId());
13058         int returnCode = PackageManager.MOVE_SUCCEEDED;
13059         int currInstallFlags = 0;
13060         int newInstallFlags = 0;
13061
13062         File codeFile = null;
13063         String installerPackageName = null;
13064         String packageAbiOverride = null;
13065
13066         // reader
13067         synchronized (mPackages) {
13068             final PackageParser.Package pkg = mPackages.get(packageName);
13069             final PackageSetting ps = mSettings.mPackages.get(packageName);
13070             if (pkg == null || ps == null) {
13071                 returnCode = PackageManager.MOVE_FAILED_DOESNT_EXIST;
13072             } else {
13073                 // Disable moving fwd locked apps and system packages
13074                 if (pkg.applicationInfo != null && isSystemApp(pkg)) {
13075                     Slog.w(TAG, "Cannot move system application");
13076                     returnCode = PackageManager.MOVE_FAILED_SYSTEM_PACKAGE;
13077                 } else if (pkg.mOperationPending) {
13078                     Slog.w(TAG, "Attempt to move package which has pending operations");
13079                     returnCode = PackageManager.MOVE_FAILED_OPERATION_PENDING;
13080                 } else {
13081                     // Find install location first
13082                     if ((flags & PackageManager.MOVE_EXTERNAL_MEDIA) != 0
13083                             && (flags & PackageManager.MOVE_INTERNAL) != 0) {
13084                         Slog.w(TAG, "Ambigous flags specified for move location.");
13085                         returnCode = PackageManager.MOVE_FAILED_INVALID_LOCATION;
13086                     } else {
13087                         newInstallFlags = (flags & PackageManager.MOVE_EXTERNAL_MEDIA) != 0
13088                                 ? PackageManager.INSTALL_EXTERNAL : PackageManager.INSTALL_INTERNAL;
13089                         currInstallFlags = isExternal(pkg)
13090                                 ? PackageManager.INSTALL_EXTERNAL : PackageManager.INSTALL_INTERNAL;
13091
13092                         if (newInstallFlags == currInstallFlags) {
13093                             Slog.w(TAG, "No move required. Trying to move to same location");
13094                             returnCode = PackageManager.MOVE_FAILED_INVALID_LOCATION;
13095                         } else {
13096                             if (isForwardLocked(pkg)) {
13097                                 currInstallFlags |= PackageManager.INSTALL_FORWARD_LOCK;
13098                                 newInstallFlags |= PackageManager.INSTALL_FORWARD_LOCK;
13099                             }
13100                         }
13101                     }
13102                     if (returnCode == PackageManager.MOVE_SUCCEEDED) {
13103                         pkg.mOperationPending = true;
13104                     }
13105                 }
13106
13107                 codeFile = new File(pkg.codePath);
13108                 installerPackageName = ps.installerPackageName;
13109                 packageAbiOverride = ps.cpuAbiOverrideString;
13110             }
13111         }
13112
13113         if (returnCode != PackageManager.MOVE_SUCCEEDED) {
13114             try {
13115                 observer.packageMoved(packageName, returnCode);
13116             } catch (RemoteException ignored) {
13117             }
13118             return;
13119         }
13120
13121         final IPackageInstallObserver2 installObserver = new IPackageInstallObserver2.Stub() {
13122             @Override
13123             public void onUserActionRequired(Intent intent) throws RemoteException {
13124                 throw new IllegalStateException();
13125             }
13126
13127             @Override
13128             public void onPackageInstalled(String basePackageName, int returnCode, String msg,
13129                     Bundle extras) throws RemoteException {
13130                 Slog.d(TAG, "Install result for move: "
13131                         + PackageManager.installStatusToString(returnCode, msg));
13132
13133                 // We usually have a new package now after the install, but if
13134                 // we failed we need to clear the pending flag on the original
13135                 // package object.
13136                 synchronized (mPackages) {
13137                     final PackageParser.Package pkg = mPackages.get(packageName);
13138                     if (pkg != null) {
13139                         pkg.mOperationPending = false;
13140                     }
13141                 }
13142
13143                 final int status = PackageManager.installStatusToPublicStatus(returnCode);
13144                 switch (status) {
13145                     case PackageInstaller.STATUS_SUCCESS:
13146                         observer.packageMoved(packageName, PackageManager.MOVE_SUCCEEDED);
13147                         break;
13148                     case PackageInstaller.STATUS_FAILURE_STORAGE:
13149                         observer.packageMoved(packageName, PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE);
13150                         break;
13151                     default:
13152                         observer.packageMoved(packageName, PackageManager.MOVE_FAILED_INTERNAL_ERROR);
13153                         break;
13154                 }
13155             }
13156         };
13157
13158         // Treat a move like reinstalling an existing app, which ensures that we
13159         // process everythign uniformly, like unpacking native libraries.
13160         newInstallFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
13161
13162         final Message msg = mHandler.obtainMessage(INIT_COPY);
13163         final OriginInfo origin = OriginInfo.fromExistingFile(codeFile);
13164         msg.obj = new InstallParams(origin, installObserver, newInstallFlags,
13165                 installerPackageName, null, user, packageAbiOverride);
13166         mHandler.sendMessage(msg);
13167     }
13168
13169     @Override
13170     public boolean setInstallLocation(int loc) {
13171         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS,
13172                 null);
13173         if (getInstallLocation() == loc) {
13174             return true;
13175         }
13176         if (loc == PackageHelper.APP_INSTALL_AUTO || loc == PackageHelper.APP_INSTALL_INTERNAL
13177                 || loc == PackageHelper.APP_INSTALL_EXTERNAL) {
13178             android.provider.Settings.Global.putInt(mContext.getContentResolver(),
13179                     android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, loc);
13180             return true;
13181         }
13182         return false;
13183    }
13184
13185     @Override
13186     public int getInstallLocation() {
13187         return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
13188                 android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION,
13189                 PackageHelper.APP_INSTALL_AUTO);
13190     }
13191
13192     /** Called by UserManagerService */
13193     void cleanUpUserLILPw(UserManagerService userManager, int userHandle) {
13194         mDirtyUsers.remove(userHandle);
13195         mSettings.removeUserLPw(userHandle);
13196         mPendingBroadcasts.remove(userHandle);
13197         if (mInstaller != null) {
13198             // Technically, we shouldn't be doing this with the package lock
13199             // held.  However, this is very rare, and there is already so much
13200             // other disk I/O going on, that we'll let it slide for now.
13201             mInstaller.removeUserDataDirs(userHandle);
13202         }
13203         mUserNeedsBadging.delete(userHandle);
13204         removeUnusedPackagesLILPw(userManager, userHandle);
13205     }
13206
13207     /**
13208      * We're removing userHandle and would like to remove any downloaded packages
13209      * that are no longer in use by any other user.
13210      * @param userHandle the user being removed
13211      */
13212     private void removeUnusedPackagesLILPw(UserManagerService userManager, final int userHandle) {
13213         final boolean DEBUG_CLEAN_APKS = false;
13214         int [] users = userManager.getUserIdsLPr();
13215         Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
13216         while (psit.hasNext()) {
13217             PackageSetting ps = psit.next();
13218             if (ps.pkg == null) {
13219                 continue;
13220             }
13221             final String packageName = ps.pkg.packageName;
13222             // Skip over if system app
13223             if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13224                 continue;
13225             }
13226             if (DEBUG_CLEAN_APKS) {
13227                 Slog.i(TAG, "Checking package " + packageName);
13228             }
13229             boolean keep = false;
13230             for (int i = 0; i < users.length; i++) {
13231                 if (users[i] != userHandle && ps.getInstalled(users[i])) {
13232                     keep = true;
13233                     if (DEBUG_CLEAN_APKS) {
13234                         Slog.i(TAG, "  Keeping package " + packageName + " for user "
13235                                 + users[i]);
13236                     }
13237                     break;
13238                 }
13239             }
13240             if (!keep) {
13241                 if (DEBUG_CLEAN_APKS) {
13242                     Slog.i(TAG, "  Removing package " + packageName);
13243                 }
13244                 mHandler.post(new Runnable() {
13245                     public void run() {
13246                         deletePackageX(packageName, userHandle, 0);
13247                     } //end run
13248                 });
13249             }
13250         }
13251     }
13252
13253     /** Called by UserManagerService */
13254     void createNewUserLILPw(int userHandle, File path) {
13255         if (mInstaller != null) {
13256             mInstaller.createUserConfig(userHandle);
13257             mSettings.createNewUserLILPw(this, mInstaller, userHandle, path);
13258         }
13259     }
13260
13261     @Override
13262     public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException {
13263         mContext.enforceCallingOrSelfPermission(
13264                 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
13265                 "Only package verification agents can read the verifier device identity");
13266
13267         synchronized (mPackages) {
13268             return mSettings.getVerifierDeviceIdentityLPw();
13269         }
13270     }
13271
13272     @Override
13273     public void setPermissionEnforced(String permission, boolean enforced) {
13274         mContext.enforceCallingOrSelfPermission(GRANT_REVOKE_PERMISSIONS, null);
13275         if (READ_EXTERNAL_STORAGE.equals(permission)) {
13276             synchronized (mPackages) {
13277                 if (mSettings.mReadExternalStorageEnforced == null
13278                         || mSettings.mReadExternalStorageEnforced != enforced) {
13279                     mSettings.mReadExternalStorageEnforced = enforced;
13280                     mSettings.writeLPr();
13281                 }
13282             }
13283             // kill any non-foreground processes so we restart them and
13284             // grant/revoke the GID.
13285             final IActivityManager am = ActivityManagerNative.getDefault();
13286             if (am != null) {
13287                 final long token = Binder.clearCallingIdentity();
13288                 try {
13289                     am.killProcessesBelowForeground("setPermissionEnforcement");
13290                 } catch (RemoteException e) {
13291                 } finally {
13292                     Binder.restoreCallingIdentity(token);
13293                 }
13294             }
13295         } else {
13296             throw new IllegalArgumentException("No selective enforcement for " + permission);
13297         }
13298     }
13299
13300     @Override
13301     @Deprecated
13302     public boolean isPermissionEnforced(String permission) {
13303         return true;
13304     }
13305
13306     @Override
13307     public boolean isStorageLow() {
13308         final long token = Binder.clearCallingIdentity();
13309         try {
13310             final DeviceStorageMonitorInternal
13311                     dsm = LocalServices.getService(DeviceStorageMonitorInternal.class);
13312             if (dsm != null) {
13313                 return dsm.isMemoryLow();
13314             } else {
13315                 return false;
13316             }
13317         } finally {
13318             Binder.restoreCallingIdentity(token);
13319         }
13320     }
13321
13322     @Override
13323     public IPackageInstaller getPackageInstaller() {
13324         return mInstallerService;
13325     }
13326
13327     private boolean userNeedsBadging(int userId) {
13328         int index = mUserNeedsBadging.indexOfKey(userId);
13329         if (index < 0) {
13330             final UserInfo userInfo;
13331             final long token = Binder.clearCallingIdentity();
13332             try {
13333                 userInfo = sUserManager.getUserInfo(userId);
13334             } finally {
13335                 Binder.restoreCallingIdentity(token);
13336             }
13337             final boolean b;
13338             if (userInfo != null && userInfo.isManagedProfile()) {
13339                 b = true;
13340             } else {
13341                 b = false;
13342             }
13343             mUserNeedsBadging.put(userId, b);
13344             return b;
13345         }
13346         return mUserNeedsBadging.valueAt(index);
13347     }
13348
13349     @Override
13350     public KeySet getKeySetByAlias(String packageName, String alias) {
13351         if (packageName == null || alias == null) {
13352             return null;
13353         }
13354         synchronized(mPackages) {
13355             final PackageParser.Package pkg = mPackages.get(packageName);
13356             if (pkg == null) {
13357                 Slog.w(TAG, "KeySet requested for unknown package:" + packageName);
13358                 throw new IllegalArgumentException("Unknown package: " + packageName);
13359             }
13360             KeySetManagerService ksms = mSettings.mKeySetManagerService;
13361             return new KeySet(ksms.getKeySetByAliasAndPackageNameLPr(packageName, alias));
13362         }
13363     }
13364
13365     @Override
13366     public KeySet getSigningKeySet(String packageName) {
13367         if (packageName == null) {
13368             return null;
13369         }
13370         synchronized(mPackages) {
13371             final PackageParser.Package pkg = mPackages.get(packageName);
13372             if (pkg == null) {
13373                 Slog.w(TAG, "KeySet requested for unknown package:" + packageName);
13374                 throw new IllegalArgumentException("Unknown package: " + packageName);
13375             }
13376             if (pkg.applicationInfo.uid != Binder.getCallingUid()
13377                     && Process.SYSTEM_UID != Binder.getCallingUid()) {
13378                 throw new SecurityException("May not access signing KeySet of other apps.");
13379             }
13380             KeySetManagerService ksms = mSettings.mKeySetManagerService;
13381             return new KeySet(ksms.getSigningKeySetByPackageNameLPr(packageName));
13382         }
13383     }
13384
13385     @Override
13386     public boolean isPackageSignedByKeySet(String packageName, KeySet ks) {
13387         if (packageName == null || ks == null) {
13388             return false;
13389         }
13390         synchronized(mPackages) {
13391             final PackageParser.Package pkg = mPackages.get(packageName);
13392             if (pkg == null) {
13393                 Slog.w(TAG, "KeySet requested for unknown package:" + packageName);
13394                 throw new IllegalArgumentException("Unknown package: " + packageName);
13395             }
13396             IBinder ksh = ks.getToken();
13397             if (ksh instanceof KeySetHandle) {
13398                 KeySetManagerService ksms = mSettings.mKeySetManagerService;
13399                 return ksms.packageIsSignedByLPr(packageName, (KeySetHandle) ksh);
13400             }
13401             return false;
13402         }
13403     }
13404
13405     @Override
13406     public boolean isPackageSignedByKeySetExactly(String packageName, KeySet ks) {
13407         if (packageName == null || ks == null) {
13408             return false;
13409         }
13410         synchronized(mPackages) {
13411             final PackageParser.Package pkg = mPackages.get(packageName);
13412             if (pkg == null) {
13413                 Slog.w(TAG, "KeySet requested for unknown package:" + packageName);
13414                 throw new IllegalArgumentException("Unknown package: " + packageName);
13415             }
13416             IBinder ksh = ks.getToken();
13417             if (ksh instanceof KeySetHandle) {
13418                 KeySetManagerService ksms = mSettings.mKeySetManagerService;
13419                 return ksms.packageIsSignedByExactlyLPr(packageName, (KeySetHandle) ksh);
13420             }
13421             return false;
13422         }
13423     }
13424
13425     public void getUsageStatsIfNoPackageUsageInfo() {
13426         if (!mPackageUsage.isHistoricalPackageUsageAvailable()) {
13427             UsageStatsManager usm = (UsageStatsManager) mContext.getSystemService(Context.USAGE_STATS_SERVICE);
13428             if (usm == null) {
13429                 throw new IllegalStateException("UsageStatsManager must be initialized");
13430             }
13431             long now = System.currentTimeMillis();
13432             Map<String, UsageStats> stats = usm.queryAndAggregateUsageStats(now - mDexOptLRUThresholdInMills, now);
13433             for (Map.Entry<String, UsageStats> entry : stats.entrySet()) {
13434                 String packageName = entry.getKey();
13435                 PackageParser.Package pkg = mPackages.get(packageName);
13436                 if (pkg == null) {
13437                     continue;
13438                 }
13439                 UsageStats usage = entry.getValue();
13440                 pkg.mLastPackageUsageTimeInMills = usage.getLastTimeUsed();
13441                 mPackageUsage.mIsHistoricalPackageUsageAvailable = true;
13442             }
13443         }
13444     }
13445 }